ckb-next  v0.2.8 at branch master
ckb-next driver for corsair devices
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
keymap.c
Go to the documentation of this file.
1 #include "device.h"
2 #include "includes.h"
3 #include "keymap.h"
4 
6  // Keyboard keys
7  { "esc", 0x00, KEY_ESC },
8  { "f1", 0x0c, KEY_F1 },
9  { "f2", 0x18, KEY_F2 },
10  { "f3", 0x24, KEY_F3 },
11  { "f4", 0x30, KEY_F4 },
12  { "f5", 0x3c, KEY_F5 },
13  { "f6", 0x48, KEY_F6 },
14  { "f7", 0x54, KEY_F7 },
15  { "f8", 0x60, KEY_F8 },
16  { "f9", 0x6c, KEY_F9 },
17  { "f10", 0x78, KEY_F10 },
18  { "f11", 0x84, KEY_F11 },
19  { "grave", 0x01, KEY_GRAVE },
20  { "1", 0x0d, KEY_1 },
21  { "2", 0x19, KEY_2 },
22  { "3", 0x25, KEY_3 },
23  { "4", 0x31, KEY_4 },
24  { "5", 0x3d, KEY_5 },
25  { "6", 0x49, KEY_6 },
26  { "7", 0x55, KEY_7 },
27  { "8", 0x61, KEY_8 },
28  { "9", 0x6d, KEY_9 },
29  { "0", 0x79, KEY_0 },
30  { "minus", 0x85, KEY_MINUS },
31  { "tab", 0x02, KEY_TAB },
32  { "q", 0x0e, KEY_Q },
33  { "w", 0x1a, KEY_W },
34  { "e", 0x26, KEY_E },
35  { "r", 0x32, KEY_R },
36  { "t", 0x3e, KEY_T },
37  { "y", 0x4a, KEY_Y },
38  { "u", 0x56, KEY_U },
39  { "i", 0x62, KEY_I },
40  { "o", 0x6e, KEY_O },
41  { "p", 0x7a, KEY_P },
42  { "lbrace", 0x86, KEY_LEFTBRACE },
43  { "caps", 0x03, KEY_CAPSLOCK },
44  { "a", 0x0f, KEY_A },
45  { "s", 0x1b, KEY_S },
46  { "d", 0x27, KEY_D },
47  { "f", 0x33, KEY_F },
48  { "g", 0x3f, KEY_G },
49  { "h", 0x4b, KEY_H },
50  { "j", 0x57, KEY_J },
51  { "k", 0x63, KEY_K },
52  { "l", 0x6f, KEY_L },
53  { "colon", 0x7b, KEY_SEMICOLON },
54  { "quote", 0x87, KEY_APOSTROPHE },
55  { "lshift", 0x04, KEY_LEFTSHIFT },
56  { "bslash_iso", 0x10, KEY_102ND },
57  { "z", 0x1c, KEY_Z },
58  { "x", 0x28, KEY_X },
59  { "c", 0x34, KEY_C },
60  { "v", 0x40, KEY_V },
61  { "b", 0x4c, KEY_B },
62  { "n", 0x58, KEY_N },
63  { "m", 0x64, KEY_M },
64  { "comma", 0x70, KEY_COMMA },
65  { "dot", 0x7c, KEY_DOT },
66  { "slash", 0x88, KEY_SLASH },
67  { "lctrl", 0x05, KEY_LEFTCTRL },
68  { "lwin", 0x11, KEY_LEFTMETA },
69  { "lalt", 0x1d, KEY_LEFTALT },
70  { 0, -1, KEY_NONE },
71  { "space", 0x35, KEY_SPACE },
72  { 0, -1, KEY_NONE },
73  { "katahira", 0x4d, KEY_KATAKANAHIRAGANA },
74  { "ralt", 0x59, KEY_RIGHTALT },
75  { "rwin", 0x65, KEY_RIGHTMETA },
76  { "rmenu", 0x71, KEY_COMPOSE },
77  { 0, -1, KEY_NONE },
78  { "light", 0x89, KEY_CORSAIR },
79  { "f12", 0x06, KEY_F12 },
80  { "prtscn", 0x12, KEY_SYSRQ },
81  { "scroll", 0x1e, KEY_SCROLLLOCK },
82  { "pause", 0x2a, KEY_PAUSE },
83  { "ins", 0x36, KEY_INSERT },
84  { "home", 0x42, KEY_HOME },
85  { "pgup", 0x4e, KEY_PAGEUP },
86  { "rbrace", 0x5a, KEY_RIGHTBRACE },
87  { "bslash", 0x66, KEY_BACKSLASH },
88  { "hash", 0x72, KEY_BACKSLASH_ISO },
89  { "enter", 0x7e, KEY_ENTER },
90  { "ro", 0x8a, KEY_RO },
91  { "equal", 0x07, KEY_EQUAL },
92  { "yen", 0x13, KEY_YEN },
93  { "bspace", 0x1f, KEY_BACKSPACE },
94  { "del", 0x2b, KEY_DELETE },
95  { "end", 0x37, KEY_END },
96  { "pgdn", 0x43, KEY_PAGEDOWN },
97  { "rshift", 0x4f, KEY_RIGHTSHIFT },
98  { "rctrl", 0x5b, KEY_RIGHTCTRL },
99  { "up", 0x67, KEY_UP },
100  { "left", 0x73, KEY_LEFT },
101  { "down", 0x7f, KEY_DOWN },
102  { "right", 0x8b, KEY_RIGHT },
103  { "lock", 0x08, KEY_CORSAIR },
104  { "mute", 0x14, KEY_MUTE },
105  { "stop", 0x20, KEY_STOPCD },
106  { "prev", 0x2c, KEY_PREVIOUSSONG },
107  { "play", 0x38, KEY_PLAYPAUSE },
108  { "next", 0x44, KEY_NEXTSONG },
109  { "numlock", 0x50, KEY_NUMLOCK },
110  { "numslash", 0x5c, KEY_KPSLASH },
111  { "numstar", 0x68, KEY_KPASTERISK },
112  { "numminus", 0x74, KEY_KPMINUS },
113  { "numplus", 0x80, KEY_KPPLUS },
114  { "numenter", 0x8c, KEY_KPENTER },
115  { "num7", 0x09, KEY_KP7 },
116  { "num8", 0x15, KEY_KP8 },
117  { "num9", 0x21, KEY_KP9 },
118  { 0, -1, KEY_NONE },
119  { "num4", 0x39, KEY_KP4 },
120  { "num5", 0x45, KEY_KP5 },
121  { "num6", 0x51, KEY_KP6 },
122  { "num1", 0x5d, KEY_KP1 },
123  { "num2", 0x69, KEY_KP2 },
124  { "num3", 0x75, KEY_KP3 },
125  { "num0", 0x81, KEY_KP0 },
126  { "numdot", 0x8d, KEY_KPDOT },
127  { "g1", 0x0a, KEY_CORSAIR },
128  { "g2", 0x16, KEY_CORSAIR },
129  { "g3", 0x22, KEY_CORSAIR },
130  { "g4", 0x2e, KEY_CORSAIR },
131  { "g5", 0x3a, KEY_CORSAIR },
132  { "g6", 0x46, KEY_CORSAIR },
133  { "g7", 0x52, KEY_CORSAIR },
134  { "g8", 0x5e, KEY_CORSAIR },
135  { "g9", 0x6a, KEY_CORSAIR },
136  { "g10", 0x76, KEY_CORSAIR },
137  { "volup", 0x20, KEY_VOLUMEUP },
138  { "voldn", 0x2c, KEY_VOLUMEDOWN },
139  { "mr", 0x0b, KEY_CORSAIR },
140  { "m1", 0x17, KEY_CORSAIR },
141  { "m2", 0x23, KEY_CORSAIR },
142  { "m3", 0x2f, KEY_CORSAIR },
143  { "g11", 0x3b, KEY_CORSAIR },
144  { "g12", 0x47, KEY_CORSAIR },
145  { "g13", 0x53, KEY_CORSAIR },
146  { "g14", 0x5f, KEY_CORSAIR },
147  { "g15", 0x6b, KEY_CORSAIR },
148  { "g16", 0x77, KEY_CORSAIR },
149  { "g17", 0x83, KEY_CORSAIR },
150  { "g18", 0x8f, KEY_CORSAIR },
151  { "muhenkan", 0x29, KEY_MUHENKAN },
152  { "henkan", 0x41, KEY_HENKAN },
153  { "fn", 0x65, KEY_FN }, // STRAFE Fn - rwin on other keyboards
154  { 0, -1, KEY_NONE },
155  { 0, -1, KEY_NONE },
156  { 0, -1, KEY_NONE },
157  { 0, -1, KEY_NONE },
158  { 0, -1, KEY_NONE },
159 
160  // K95 Platinum
161  { "topbar1", 0x90, KEY_NONE },
162  { "topbar2", 0x91, KEY_NONE },
163  { "topbar3", 0x92, KEY_NONE },
164  { "topbar4", 0x9E, KEY_NONE },
165  { "topbar5", 0xA0, KEY_NONE },
166  { "topbar6", 0x93, KEY_NONE },
167  { "topbar7", 0x94, KEY_NONE },
168  { "topbar8", 0x95, KEY_NONE },
169  { "topbar9", 0x96, KEY_NONE },
170  { "topbar10", 0x97, KEY_NONE },
171  { "topbar11", 0x98, KEY_NONE },
172  { "topbar12", 0x99, KEY_NONE },
173  { "topbar13", 0x9A, KEY_NONE },
174  { "topbar14", 0x9B, KEY_NONE },
175  { "topbar15", 0x9F, KEY_NONE },
176  { "topbar16", 0xA2, KEY_NONE },
177  { "topbar17", 0xA1, KEY_NONE },
178  { "topbar18", 0x9C, KEY_NONE },
179  { "topbar19", 0x9D, KEY_NONE },
180 
181  // Strafe specific side leds, that are set via a special command
182  { "lsidel", -2, KEY_CORSAIR },
183  { "rsidel", -2, KEY_CORSAIR },
184  // Strafe logo backlight
185  { "logo", 0x7d, KEY_CORSAIR },
186 
187  // Keys not present on any device
188  { "lightup", -1, KEY_BRIGHTNESSUP },
189  { "lightdn", -1, KEY_BRIGHTNESSDOWN },
190  { "eject", -1, KEY_EJECTCD },
191  { "power", -1, KEY_POWER },
192  { "f13", -1, KEY_F13 },
193  { "f14", -1, KEY_F14 },
194  { "f15", -1, KEY_F15 },
195  { "f16", -1, KEY_F16 },
196  { "f17", -1, KEY_F17 },
197  { "f18", -1, KEY_F18 },
198  { "f19", -1, KEY_F19 },
199  { "f20", -1, KEY_F20 },
200 
201  // Mouse buttons
202  { "mouse1", -1, SCAN_MOUSE | BTN_LEFT },
203  { "mouse2", -1, SCAN_MOUSE | BTN_RIGHT },
204  { "mouse3", -1, SCAN_MOUSE | BTN_MIDDLE },
205  { "mouse4", -1, SCAN_MOUSE | BTN_SIDE },
206  { "mouse5", -1, SCAN_MOUSE | BTN_EXTRA },
207  { "dpiup", -1, KEY_CORSAIR },
208  { "dpidn", -1, KEY_CORSAIR },
209  { "sniper", -1, KEY_CORSAIR },
210  { "thumb1", -1, KEY_CORSAIR },
211  { "thumb2", -1, KEY_CORSAIR },
212  { "thumb3", -1, KEY_CORSAIR },
213  { "thumb4", -1, KEY_CORSAIR },
214  { "thumb5", -1, KEY_CORSAIR },
215  { "thumb6", -1, KEY_CORSAIR },
216  { "thumb7", -1, KEY_CORSAIR },
217  { "thumb8", -1, KEY_CORSAIR },
218  { "thumb9", -1, KEY_CORSAIR },
219  { "thumb10", -1, KEY_CORSAIR },
220  { "thumb11", -1, KEY_CORSAIR },
221  { "thumb12", -1, KEY_CORSAIR },
222 
223  // Extended mouse buttons (wheel is an axis in HW, 6-8 are recognized by the OS but not present in HW)
224  { "wheelup", -1, SCAN_MOUSE | BTN_WHEELUP },
225  { "wheeldn", -1, SCAN_MOUSE | BTN_WHEELDOWN },
226  { "mouse6", -1, SCAN_MOUSE | BTN_FORWARD },
227  { "mouse7", -1, SCAN_MOUSE | BTN_BACK },
228  { "mouse8", -1, SCAN_MOUSE | BTN_TASK },
229 
230  // RGB mouse zones
231  { "front", LED_MOUSE, KEY_NONE },
232  { "back", LED_MOUSE + 1, KEY_NONE },
233  { "dpi", LED_MOUSE + 2, KEY_NONE }, // SW DPI light
234  { "wheel", LED_MOUSE + 3, KEY_NONE },
235  { "thumb", LED_MOUSE + 4, KEY_NONE },
236  { "side", LED_MOUSE + 5, KEY_NONE },
237  { "dpi0", LED_MOUSE + 6, KEY_NONE }, // HW DPI light levels (0 = sniper, 1..5 = modes)
238  { "dpi1", LED_MOUSE + 7, KEY_NONE },
239  { "dpi2", LED_MOUSE + 8, KEY_NONE },
240  { "dpi3", LED_MOUSE + 9, KEY_NONE },
241  { "dpi4", LED_MOUSE + 10, KEY_NONE },
242  { "dpi5", LED_MOUSE + 11, KEY_NONE },
243 
244 };
245 
246 void hid_kb_translate(unsigned char* kbinput, int endpoint, int length, const unsigned char* urbinput){
247  if(length < 1)
248  return;
249  // LUT for HID -> Corsair scancodes (-1 for no scan code, -2 for currently unsupported)
250  // Modified from Linux drivers/hid/usbhid/usbkbd.c, key codes replaced with keymap array indices and K95 keys added
251  // Make sure the indices match the keyindex as passed to nprintkey() in notify.c
252  static const short hid_codes[256] = {
253  -1, -1, -1, -1, 37, 54, 52, 39, 27, 40, 41, 42, 32, 43, 44, 45,
254  56, 55, 33, 34, 25, 28, 38, 29, 31, 53, 26, 51, 30, 50, 13, 14,
255  15, 16, 17, 18, 19, 20, 21, 22, 82, 0, 86, 24, 64, 23, 84, 35,
256  79, 80, 81, 46, 47, 12, 57, 58, 59, 36, 1, 2, 3, 4, 5, 6,
257  7, 8, 9, 10, 11, 72, 73, 74, 75, 76, 77, 78, 87, 88, 89, 95,
258  93, 94, 92, 102, 103, 104, 105, 106, 107, 115, 116, 117, 112, 113, 114, 108,
259  109, 110, 118, 119, 49, 69, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
260  -2, -2, -2, -2, -2, -2, -2, -2, 98, -2, -2, -2, -2, -2, -2, 97,
261  130, 131, -1, -1, -1, -2, -1, 83, 66, 85, 145, 144, -2, -1, -1, -1,
262  -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
263  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
264  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
265  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -3, -1, -1, -1, // <- -3 = non-RGB program key
266  120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 136, 137, 138, 139, 140, 141,
267  60, 48, 62, 61, 91, 90, 67, 68, 142, 143, 99, 101, -2, 130, 131, 97,
268  -2, 133, 134, 135, -2, 96, -2, 132, -2, -2, 71, 71, 71, 71, -1, -1,
269  };
270  switch(endpoint){
271  case 1:
272  case -1:
273  // EP 1: 6KRO input (RGB and non-RGB)
274  // Clear previous input
275  for(int i = 0; i < 256; i++){
276  if(hid_codes[i] >= 0)
277  CLEAR_KEYBIT(kbinput, hid_codes[i]);
278  }
279  // Set new input
280  for(int i = 0; i < 8; i++){
281  if((urbinput[0] >> i) & 1)
282  SET_KEYBIT(kbinput, hid_codes[i + 224]);
283  }
284  for(int i = 2; i < length; i++){
285  if(urbinput[i] > 3){
286  int scan = hid_codes[urbinput[i]];
287  if(scan >= 0)
288  SET_KEYBIT(kbinput, scan);
289  else
290  ckb_warn("Got unknown key press %d on EP 1\n", urbinput[i]);
291  }
292  }
293  break;
294  case -2:
295  // EP 2 RGB: NKRO input
296  if(urbinput[0] == 1){
297  // Type 1: standard key
298  if(length != 21)
299  return;
300  for(int bit = 0; bit < 8; bit++){
301  if((urbinput[1] >> bit) & 1)
302  SET_KEYBIT(kbinput, hid_codes[bit + 224]);
303  else
304  CLEAR_KEYBIT(kbinput, hid_codes[bit + 224]);
305  }
306  for(int byte = 0; byte < 19; byte++){
307  char input = urbinput[byte + 2];
308  for(int bit = 0; bit < 8; bit++){
309  int keybit = byte * 8 + bit;
310  int scan = hid_codes[keybit];
311  if((input >> bit) & 1){
312  if(scan >= 0)
313  SET_KEYBIT(kbinput, hid_codes[keybit]);
314  else
315  ckb_warn("Got unknown key press %d on EP 2\n", keybit);
316  } else if(scan >= 0)
317  CLEAR_KEYBIT(kbinput, hid_codes[keybit]);
318  }
319  }
320  break;
321  } else if (urbinput[0] == 2)
322  ; // Type 2: media key (implicitly falls through)
323  else
324  break; // No other known types
325  /* FALLTHRU */
326  case 2:
327  // EP 2 Non-RGB: media keys
328  CLEAR_KEYBIT(kbinput, 97); // mute
329  CLEAR_KEYBIT(kbinput, 98); // stop
330  CLEAR_KEYBIT(kbinput, 99); // prev
331  CLEAR_KEYBIT(kbinput, 100); // play
332  CLEAR_KEYBIT(kbinput, 101); // next
333  CLEAR_KEYBIT(kbinput, 130); // volup
334  CLEAR_KEYBIT(kbinput, 131); // voldn
335  for(int i = 0; i < length; i++){
336  switch(urbinput[i]){
337  case 181:
338  SET_KEYBIT(kbinput, 101); // next
339  break;
340  case 182:
341  SET_KEYBIT(kbinput, 99); // prev
342  break;
343  case 183:
344  SET_KEYBIT(kbinput, 98); // stop
345  break;
346  case 205:
347  SET_KEYBIT(kbinput, 100); // play
348  break;
349  case 226:
350  SET_KEYBIT(kbinput, 97); // mute
351  break;
352  case 233:
353  SET_KEYBIT(kbinput, 130); // volup
354  break;
355  case 234:
356  SET_KEYBIT(kbinput, 131); // voldn
357  break;
358  }
359  }
360  break;
361  case 3:
362  // EP 3 non-RGB: NKRO input
363  if(length != 15)
364  return;
365  for(int bit = 0; bit < 8; bit++){
366  if((urbinput[0] >> bit) & 1)
367  SET_KEYBIT(kbinput, hid_codes[bit + 224]);
368  else
369  CLEAR_KEYBIT(kbinput, hid_codes[bit + 224]);
370  }
371  for(int byte = 0; byte < 14; byte++){
372  char input = urbinput[byte + 1];
373  for(int bit = 0; bit < 8; bit++){
374  int keybit = byte * 8 + bit;
375  int scan = hid_codes[keybit];
376  if((input >> bit) & 1){
377  if(scan >= 0)
378  SET_KEYBIT(kbinput, hid_codes[keybit]);
379  else
380  ckb_warn("Got unknown key press %d on EP 3\n", keybit);
381  } else if(scan >= 0)
382  CLEAR_KEYBIT(kbinput, hid_codes[keybit]);
383  }
384  }
385  break;
386  }
387 }
388 
389 #define BUTTON_HID_COUNT 5
390 
391 void hid_mouse_translate(unsigned char* kbinput, short* xaxis, short* yaxis, int endpoint, int length, const unsigned char* urbinput, ushort fwversion){
392  //The HID Input Endpoint on FWv3 is 64 bytes, so we can't check for length.
393  if((endpoint != 2 && endpoint != -2) || (fwversion < 0x300 && length < 10))
394  return;
395  // EP 2: mouse input
396  if(urbinput[0] != 1)
397  return;
398  // Byte 1 = mouse buttons (bitfield)
399  for(int bit = 0; bit < BUTTON_HID_COUNT; bit++){
400  if(urbinput[1] & (1 << bit))
401  SET_KEYBIT(kbinput, MOUSE_BUTTON_FIRST + bit);
402  else
403  CLEAR_KEYBIT(kbinput, MOUSE_BUTTON_FIRST + bit);
404  }
405  // Bytes 5 - 8: movement
406  *xaxis += *(short*)(urbinput + 5);
407  *yaxis += *(short*)(urbinput + 7);
408  // Byte 9: wheel
409  char wheel = urbinput[9];
410  if(wheel > 0)
411  SET_KEYBIT(kbinput, MOUSE_EXTRA_FIRST); // wheelup
412  else
414  if(wheel < 0)
415  SET_KEYBIT(kbinput, MOUSE_EXTRA_FIRST + 1); // wheeldn
416  else
417  CLEAR_KEYBIT(kbinput, MOUSE_EXTRA_FIRST + 1);
418 }
419 
420 void corsair_kbcopy(unsigned char* kbinput, int endpoint, const unsigned char* urbinput){
421  if(endpoint == 2 || endpoint == -2){
422  if(urbinput[0] != 3)
423  return;
424  urbinput++;
425  }
426  memcpy(kbinput, urbinput, N_KEYBYTES_HW);
427 }
428 
429 void corsair_mousecopy(unsigned char* kbinput, int endpoint, const unsigned char* urbinput){
430  if(endpoint == 2 || endpoint == -2){
431  if(urbinput[0] != 3)
432  return;
433  urbinput++;
434  }
435  for(int bit = BUTTON_HID_COUNT; bit < N_BUTTONS_HW; bit++){
436  int byte = bit / 8;
437  uchar test = 1 << (bit % 8);
438  if(urbinput[byte] & test)
439  SET_KEYBIT(kbinput, MOUSE_BUTTON_FIRST + bit);
440  else
441  CLEAR_KEYBIT(kbinput, MOUSE_BUTTON_FIRST + bit);
442  }
443 }
#define N_KEYBYTES_HW
Definition: keymap.h:25
#define KEY_CORSAIR
Definition: keymap.h:8
#define MOUSE_BUTTON_FIRST
Definition: keymap.h:33
#define LED_MOUSE
Definition: keymap.h:39
#define CLEAR_KEYBIT(array, index)
Definition: structures.h:16
const key keymap[(((152+22+12)+25)+12)]
Definition: keymap.c:5
#define KEY_BACKSLASH_ISO
Definition: keymap.h:20
Definition: keymap.h:49
#define BUTTON_HID_COUNT
Definition: keymap.c:389
#define SET_KEYBIT(array, index)
Definition: structures.h:15
#define BTN_WHEELUP
Definition: keymap.h:12
unsigned char uchar
Definition: includes.h:24
#define KEY_NONE
Definition: keymap.h:7
#define ckb_warn(fmt, args...)
Definition: includes.h:52
void corsair_mousecopy(unsigned char *kbinput, int endpoint, const unsigned char *urbinput)
Definition: keymap.c:429
void hid_mouse_translate(unsigned char *kbinput, short *xaxis, short *yaxis, int endpoint, int length, const unsigned char *urbinput, ushort fwversion)
Definition: keymap.c:391
unsigned short ushort
Definition: includes.h:25
void hid_kb_translate(unsigned char *kbinput, int endpoint, int length, const unsigned char *urbinput)
Definition: keymap.c:246
#define N_BUTTONS_HW
Definition: keymap.h:31
#define N_KEYS_EXTENDED
Definition: keymap.h:45
#define MOUSE_EXTRA_FIRST
Definition: keymap.h:34
void corsair_kbcopy(unsigned char *kbinput, int endpoint, const unsigned char *urbinput)
Definition: keymap.c:420
#define SCAN_MOUSE
Definition: keymap.h:58
#define BTN_WHEELDOWN
Definition: keymap.h:13