Kaynağa Gözat

vendor the Impact 80's definition file

The tool reads effect names from a definition file, and this is the file for
the board it was built against. Keeping it in the repository means the board
works from a fresh clone with no network and no command to run first, and it
keeps the file under review like any other input: the test that reads it fails
if it stops parsing, if its identifiers change, if a channel's effect count
moves, or if the vendor's spelling stops resolving alongside the tool's.

The file is the vendor's, as their Driver & Firmware page serves it, and that
page is the reference in definitions/README.md. It is here rather than fetched
because the Impact 80 is not in VIA's collection, so `definition fetch` cannot
get it — which is also the case the setup path has to cover.
Paul Klumpp 1 hafta önce
ebeveyn
işleme
45bcc51ff3

+ 40 - 0
definitions/README.md

@@ -0,0 +1,40 @@
+# Definitions
+
+VIA definition files. A keyboard holds effect numbers, not names, and the names
+live in one of these — the same file VIA reads when you open a board in its web
+app, which is why the tool depends on them the way VIA does.
+
+## What belongs here
+
+One JSON file per keyboard, and a file is used for the board whose
+`vendorId`/`productId` it carries, so the name of the file does not matter. A
+file for another board is refused by name rather than used, because applying one
+board's effect names to another board writes wrong IDs.
+
+`qmk-rgb-tool definition fetch` puts a file here for the connected keyboard.
+Drop one in by hand when the vendor publishes one and VIA does not carry it.
+
+## The files here
+
+| File | Board | From |
+|------|-------|------|
+| `impact80.json` | Wobkey Impact 80 | [the vendor's Driver & Firmware page](https://wiki.wobkey.com/en/Products/PMOKEY-Impact-80/Driver-Firmware), which links it as the Impact 80 VIA JSON |
+
+Wobkey's file is the vendor's own, kept as it is served. It names three lighting
+channels — `logo`, `Backlight`, `side` — and their effect lists: 7, 46 and 7
+entries, IDs 0 to 6, 0 to 45 and 0 to 6.
+
+This board is **not** in VIA's own collection, so `definition fetch` cannot get
+it. That is why the file is here rather than fetched.
+
+## Two things a file does not tell the tool
+
+The names it carries are the manufacturer's spelling, which need not be the
+tool's. The tool's aliases and its own spellings resolve alongside them — a
+definition writing `fixed wave` still answers to `fixed_wave` — and
+`qmk-rgb-tool info` reports whichever spelling the source in use has.
+
+A file also names only the effects a board's firmware implements, so it may
+stop short of the board's highest effect ID. This one's backlight channel stops
+at 45 while the board takes ID 46 as well, which the compiled-in catalog in
+`internal/rgb/impact80.go` names `freeze`.

+ 352 - 0
definitions/impact80.json

@@ -0,0 +1,352 @@
+{
+	"name": "Impact 80",
+	"vendorId": "0x36B0",
+	"productId": "0x309F",
+	"keycodes": ["qmk_lighting"],
+	"menus":
+	[
+		{
+			"label": "Lighting",
+			"content":
+			[
+				{
+					"label": "logo",
+					"content":
+					[
+						{
+							"showIf": "{id_qmk_rgblight_effect} != 0",
+							"label": "Brightness",
+							"type": "range",
+							"options": [0, 160],
+							"content": ["id_qmk_rgblight_brightness", 2, 1]
+						},
+						{
+							"label": "Effect",
+							"type": "dropdown",
+							"content": ["id_qmk_rgblight_effect", 2, 2],
+							"options":
+							[
+								[ "none", 0 ],
+								[ "wave", 1 ],
+								[ "fixed wave", 2 ],
+								[ "spectrum", 3 ],
+								[ "breathe", 4 ],
+								[ "light", 5 ],
+								[ "shutdown",6 ]
+							]
+						},
+						{
+							"showIf": "{id_qmk_rgblight_effect} != 0",
+							"label": "Effect Speed",
+							"type": "range",
+							"options": [0, 4],
+							"content": ["id_qmk_rgblight_effect_speed", 2, 3]
+						},
+						{
+							"showIf": "{id_qmk_rgblight_effect} != 0 && {id_qmk_rgblight_effect} != 1 && {id_qmk_rgblight_effect} != 3 && {id_qmk_rgblight_effect} != 6",
+							"label": "Color",
+							"type": "color",
+							"content": ["id_qmk_rgblight_color", 2, 4]
+						}
+					]
+				},
+
+				{
+					"label": "Backlight",
+					"content":
+					[
+						{
+							"showIf": "{id_qmk_rgb_matrix_effect} != 0",
+							"label": "Brightness",
+							"type": "range",
+							"options": [0, 160],
+							"content": ["id_qmk_rgb_matrix_brightness", 3, 1]
+						},
+						{
+							"label": "Effect",
+							"type": "dropdown",
+							"content": ["id_qmk_rgb_matrix_effect", 3, 2],
+							"options":
+							[
+								[ "none", 0 ],
+								[ "solid_color", 1 ],
+								[ "alphas_mods", 2 ],
+								[ "gradient_up_down", 3 ],
+								[ "gradient_left_right", 4 ],
+								[ "breathing", 5 ],
+								[ "band_sat", 6 ],
+								[ "band_val", 7 ],
+								[ "band_pinwheel_sat", 8 ],
+								[ "band_pinwheel_val", 9 ],
+								[ "band_spiral_sat", 10 ],
+								[ "band_spiral_val", 11 ],
+								[ "cycle_all", 12 ],
+								[ "cycle_left_right", 13 ],
+								[ "cycle_up_down", 14 ],
+								[ "cycle_out_in", 15 ],
+								[ "cycle_out_in_dual", 16 ],
+								[ "rainbow_moving_chevron", 17 ],
+								[ "cycle_pinwheel", 18 ],
+								[ "cycle_spiral", 19 ],
+								[ "dual_beacon", 20 ],
+								[ "rainbow_beacon", 21 ],
+								[ "rainbow_pinwheels", 22 ],
+								[ "flower_blooming", 23 ],
+								[ "raindrops", 24 ],
+								[ "jellybean_raindrops", 25 ],
+								[ "hue_breathing", 26 ],
+								[ "hue_pendulum", 27 ],
+								[ "hue_wave", 28 ],
+								[ "pixel_flow", 29 ],
+								[ "digital_rain", 30 ],
+								[ "solid_reactive", 31 ],
+								[ "solid_reactive_wide", 32 ],
+								[ "solid_reactive_multiwide", 33 ],
+								[ "solid_reactive_cross", 34 ],
+								[ "solid_reactive_multicross", 35 ],
+								[ "solid_reactive_nexus", 36 ],
+								[ "solid_reactive_multinexus", 37 ],
+								[ "splash", 38 ],
+								[ "multisplash", 39 ],
+								[ "solid_splash", 40 ],
+								[ "solid_multisplash", 41 ],
+								[ "starlight", 42 ],
+								[ "starlight_dual_hue", 43 ],
+								[ "starlight_dual_sat", 44 ],
+								[ "riverflow", 45 ]
+							]
+						},
+						{
+							"showIf": "{id_qmk_rgb_matrix_effect} != 0",
+							"label": "Effect Speed",
+							"type": "range",
+							"options": [0, 255],
+							"content": ["id_qmk_rgb_matrix_effect_speed", 3, 3]
+						},
+						{
+							"showIf": "{id_qmk_rgb_matrix_effect} != 0 && {id_qmk_rgb_matrix_effect} != 24 && {id_qmk_rgb_matrix_effect} != 28 && {id_qmk_rgb_matrix_effect} != 29 && {id_qmk_rgb_matrix_effect} != 32",
+							"label": "Color",
+							"type": "color",
+							"content": ["id_qmk_rgb_matrix_color", 3, 4]
+						}
+					]
+				},
+
+				{
+					"label": "side",
+					"content":
+					[
+						{
+							"showIf": "{id_qmk_audio_effect} != 0",
+							"label": "Brightness",
+							"type": "range",
+							"options": [0, 160],
+							"content": ["id_qmk_audio_brightness", 4, 1]
+						},
+						{
+							"label": "Effect",
+							"type": "dropdown",
+							"content": ["id_qmk_audio_effect", 4, 2],
+							"options":
+							[
+								[ "none", 0 ],
+								[ "wave", 1 ],
+								[ "fixed wave", 2 ],
+								[ "spectrum", 3 ],
+								[ "breathe", 4 ],
+								[ "light", 5 ],
+								[ "shutdown",6 ]
+							]
+						},
+						{
+							"showIf": "{id_qmk_audio_effect} != 0",
+							"label": "Effect Speed",
+							"type": "range",
+							"options": [0, 4],
+							"content": ["id_qmk_audio_effect_speed", 4, 3]
+						},
+						{
+							"showIf": "{id_qmk_audio_effect} != 0 && {id_qmk_audio_effect} != 1 && {id_qmk_audio_effect} != 3 && {id_qmk_audio_effect} != 6",
+							"label": "Color",
+							"type": "color",
+							"content": ["id_qmk_audio_color", 4, 4]
+						}
+					]
+				}
+			]
+		}
+	],
+	"customKeycodes": [
+		{"name": "2.4G",     "title": "Set to 2.4G working mode",                "shortName": "MD_24G" },
+		{"name": "BLE1",     "title": "Set to Bluetooth Channel 1 working mode", "shortName": "MD_BLE1"},
+		{"name": "BLE2",     "title": "Set to Bluetooth Channel 2 working mode", "shortName": "MD_BLE2"},
+		{"name": "BLE3",     "title": "Set to Bluetooth Channel 3 working mode", "shortName": "MD_BLE3"},
+		{"name": "USB",	     "title": "Set to USB working mode",                 "shortName": "MD_USB" },
+		{"name": "BAT",      "title": "Querying Battery Status",                 "shortName": "QK_BAT" },
+		{"name": "WLO",      "title": "Lock WIN",                                "shortName": "QK_WLO" },
+		{"name": "SIX_N",    "title": "Full-key six-key switch",                 "shortName": "SIX_N"  },
+		{"name": "TEST",     "title": "Test Keyboard Colour",                    "shortName": "TEST"   },
+        {"name": "KbPrSlp",  "title": "Keyboard primary sleep",                  "shortName": "KbPrSlp"},
+		{"name": "KbdSecS",  "title": "Keyboard secondary sleep",                "shortName": "KbdSecS"},
+		{"name": "KEY_DEB",  "title": "Toggle the number of de-chattering",      "shortName": "KEY_DEB"},
+        {"name": "RTOG",     "title": "Toggle led lighting on or off",           "shortName": "RGB_RTOG"},
+		{"name": "LG_TOG",   "title": "Toggle logo lighting on or off",          "shortName": "LG_TOG" },
+		{"name": "LG_MO",    "title": "Cycle through modes",                     "shortName": "LG_MOD" },
+		{"name": "LG_RM",    "title": "Cycle through modes in reverse",          "shortName": "LG_RMOD"},
+		{"name": "LG_HUI",   "title": "logo Increase hue",                       "shortName": "LG_HUI" },
+		{"name": "LG_HUD",   "title": "logo Decrease hue",                       "shortName": "LG_HUD" },
+		{"name": "LG_SAI",   "title": "logo Increase saturation",                "shortName": "LG_SAI" },
+		{"name": "LG_SAD",   "title": "logo Decrease saturation",                "shortName": "LG_SAD" },
+		{"name": "LG_VAI",   "title": "logo Increase value (brightness)",        "shortName": "LG_VAI" },
+		{"name": "LG_VAD",   "title": "logo Decrease value (brightness)",        "shortName": "LG_VAD" },
+		{"name": "LG_SPI",   "title": "logo Increase effect speed",              "shortName": "LG_SPI" },
+		{"name": "LG_SPD",   "title": "logo Decrease effect speed",              "shortName": "LG_SPD" },
+		{"name": "SI_TOG",   "title": "Toggle side lighting on or off",          "shortName": "SI_TOG" },
+		{"name": "SI_MO",    "title": "side Cycle through modes",                "shortName": "SI_MOD" },
+		{"name": "SI_RM",    "title": "side Cycle through modes in reverse",     "shortName": "SI_RMOD"},
+		{"name": "SI_HUI",   "title": "side Increase hue",                       "shortName": "SI_HUI" },
+		{"name": "SI_HUD",   "title": "side Decrease hue",                       "shortName": "SI_HUD" },
+		{"name": "SI_SAI",   "title": "side Increase saturation",                "shortName": "SI_SAI" },
+		{"name": "SI_SAD",   "title": "side Decrease saturation",                "shortName": "SI_SAD" },
+		{"name": "SI_VAI",   "title": "side Increase value (brightness)",        "shortName": "SI_VAI" },
+		{"name": "SI_VAD",   "title": "side Decrease value (brightness)",        "shortName": "SI_VAD" },
+		{"name": "SI_SPI",   "title": "side Increase effect speed",              "shortName": "SI_SPI" },
+		{"name": "SI_SPD",   "title": "side Decrease effect speed",              "shortName": "SI_SPD" }
+	],
+	"matrix": { "rows": 6, "cols": 16 },
+	"layouts": {
+		"labels": [
+			"ISO Enter"
+		],
+		"keymap": [
+			[
+				{ "c":"#777777" },
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "0,0",
+				{ "c":"#aaaaaa" },
+				{ "w":1.0,  "h":1.0,  "x":1.0 },  "0,1",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "0,2",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "0,3",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "0,4",
+				{ "w":1.0,  "h":1.0,  "x":0.5 },  "0,5",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "0,6",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "0,7",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "0,8",
+				{ "w":1.0,  "h":1.0,  "x":0.5 },  "0,9",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "0,10",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "0,11",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "0,12",
+				{ "w":1.0,  "h":1.0,  "x":0.25},  "0,13",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "0,14",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "0,15"
+			],
+
+			[
+				{ "y":0.25 },
+				{ "c":"#cccccc" },
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,0",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,1",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,2",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,3",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,4",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,5",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,6",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,7",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,8",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,9",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,10",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,11",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,12",
+				{ "c":"#aaaaaa" },
+				{ "w":2.0,  "h":1.0,  "x":0.0 },  "1,13",
+				{ "w":1.0,  "h":1.0,  "x":0.25},  "1,14",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "1,15",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "3,14"
+			],
+
+			[
+				{ "c":"#aaaaaa" },
+				{ "w":1.5,  "h":1.0,  "x":0.0 },  "2,0",
+				{ "c":"#cccccc" },
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,1",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,2",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,3",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,4",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,5",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,6",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,7",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,8",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,9",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,10",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,11",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,12",
+				{ "c":"#aaaaaa" },
+				{ "w":1.5,  "h":1.0,  "x":0.0 },  "2,13\n\n\n0,0",
+				{ "c":"#777777" },
+				{ "w":1.25, "h":2.0,  "x":0.75,	 "w2":1.5, "h2":1.0, "x2":0.0},  "3,13\n\n\n0,1",
+				{ "c":"#aaaaaa" },
+				{ "w":1.0,  "h":1.0, "x":-1.75},  "2,14",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "2,15",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "3,15"
+			],
+
+			[
+				{ "c":"#aaaaaa" },
+				{ "w":1.75, "h":1.0,  "x":0.0 },  "3,0",
+				{ "c":"#cccccc" },
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "3,1",
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "3,2",
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "3,3",
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "3,4",
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "3,5",
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "3,6",
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "3,7",
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "3,8",
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "3,9",
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "3,10",
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "3,11",
+				{ "c":"#777777" },
+				{ "w":2.25, "h":1.0,  "x":0.0 },  "3,13\n\n\n0,0",
+				{ "c":"#cccccc" },
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "3,12\n\n\n0,1"
+			],
+
+			[
+				{ "c":"#aaaaaa" },
+				{ "w":2.25, "h":1.0,  "x":0.0 },  "4,0",
+				{ "c":"#cccccc" },
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "4,2",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "4,3",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "4,4",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "4,5",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "4,6",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "4,7",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "4,8",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "4,9",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "4,10",
+				{ "w":1.0,  "h":1.0,  "x":0.0 },  "4,11",
+				{ "c":"#aaaaaa" },
+				{ "w":2.75, "h":1.0,  "x":0.0 },  "4,13",
+				{ "c":"#777777" },
+				{ "w":1.0,  "h":1.0,  "x":1.25},  "4,14"
+			],
+
+			[
+				{ "c":"#aaaaaa" },
+				{ "w":1.25,	"h":1.0,  "x":0.0 },  "5,0",
+				{ "w":1.25,	"h":1.0,  "x":0.0 },  "5,1",
+				{ "w":1.25,	"h":1.0,  "x":0.0 },  "5,2",
+				{ "c":"#cccccc" },
+				{ "w":6.25,	"h":1.0,  "x":0.0 },  "5,5",
+				{ "c":"#aaaaaa" },
+				{ "w":1.25,	"h":1.0,  "x":0.0 },  "5,9",
+				{ "w":1.25,	"h":1.0,  "x":0.0 },  "5,10",
+				{ "w":1.25,	"h":1.0,  "x":0.0 },  "5,11",
+				{ "w":1.25,	"h":1.0,  "x":0.0 },  "5,12",
+				{ "c":"#777777" },
+				{ "w":1.0,	"h":1.0,  "x":0.25},  "5,13",
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "5,14",
+				{ "w":1.0,	"h":1.0,  "x":0.0 },  "5,15"
+			]
+		]
+	}
+}

+ 37 - 0
internal/rgb/definition_test.go

@@ -289,3 +289,40 @@ func TestDefinitionTakesWhateverTheChannelIsCalled(t *testing.T) {
 		t.Errorf("Labels = %v, want only the channel the definition names", def.Labels)
 		t.Errorf("Labels = %v, want only the channel the definition names", def.Labels)
 	}
 	}
 }
 }
+
+// The definition files in the repository are read at runtime, so a truncated or
+// edited one would fail every command that names an effect rather than fail a
+// test. This parses the vendored Impact 80 file and checks what it has to
+// contain.
+func TestVendoredImpact80DefinitionIsUsable(t *testing.T) {
+	def, err := LoadDefinition(filepath.Join("..", "..", "definitions", "impact80.json"))
+	if err != nil {
+		t.Fatalf("LoadDefinition(definitions/impact80.json) error = %v", err)
+	}
+
+	if def.VendorID != 0x36B0 || def.ProductID != 0x309F {
+		t.Errorf("identifiers = 0x%04X/0x%04X, want 0x36B0/0x309F", def.VendorID, def.ProductID)
+	}
+
+	want := map[via.Channel]int{
+		via.ChannelRgblight:  7,
+		via.ChannelRgbMatrix: 46,
+		via.ChannelAudio:     7,
+	}
+	for ch, count := range want {
+		if got := len(def.Catalog.Effects(ch)); got != count {
+			t.Errorf("channel %v has %d effects, want %d", ch, got, count)
+		}
+	}
+
+	// The names are the vendor's, and the tool's spelling has to resolve too.
+	if id, ok := def.Catalog.EffectID(via.ChannelRgblight, "fixed wave"); !ok || id != 2 {
+		t.Errorf("EffectID(rgblight, \"fixed wave\") = %d, %t, want 2, true", id, ok)
+	}
+	if id, ok := def.Catalog.EffectID(via.ChannelRgblight, "fixed_wave"); !ok || id != 2 {
+		t.Errorf("EffectID(rgblight, \"fixed_wave\") = %d, %t, want 2, true", id, ok)
+	}
+	if got := def.Labels[3]; got != "Backlight" {
+		t.Errorf("Labels[3] = %q, want %q", got, "Backlight")
+	}
+}