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
device_keyboard.c
Go to the documentation of this file.
1 #include "command.h"
2 #include "device.h"
3 #include "devnode.h"
4 #include "firmware.h"
5 #include "input.h"
6 #include "profile.h"
7 #include "usb.h"
8 
9 int start_kb_nrgb(usbdevice* kb, int makeactive){
10  (void)makeactive;
11 
12  // Put the non-RGB K95 into software mode. Nothing else needs to be done hardware wise
13  nk95cmd(kb, NK95_HWOFF);
14  // Fill out RGB features for consistency, even though the keyboard doesn't have them
15  kb->active = 1;
16  kb->pollrate = -1;
17  return 0;
18 }
19 
20 int setactive_kb(usbdevice* kb, int active){
21  if(NEEDS_FW_UPDATE(kb))
22  return 0;
23 
24  pthread_mutex_lock(imutex(kb));
25  kb->active = !!active;
26  kb->profile->lastlight.forceupdate = 1;
27  // Clear input
28  memset(&kb->input.keys, 0, sizeof(kb->input.keys));
29  inputupdate(kb);
30  pthread_mutex_unlock(imutex(kb));
31 
32  uchar msg[3][MSG_SIZE] = {
33  { 0x07, 0x04, 0 }, // Disables or enables HW control for top row
34  { 0x07, 0x40, 0 }, // Selects key input
35  { 0x07, 0x05, 2, 0, 0x03, 0x00 } // Commits key input selection
36  };
37  if(active){
38  // Put the M-keys (K95) as well as the Brightness/Lock keys into software-controlled mode.
39  msg[0][2] = 2;
40  if(!usbsend(kb, msg[0], 1))
41  return -1;
42  DELAY_MEDIUM(kb);
43  // Set input mode on the keys. They must be grouped into packets of 60 bytes (+ 4 bytes header)
44  // Keys are referenced in byte pairs, with the first byte representing the key and the second byte representing the mode.
45  for(int key = 0; key < N_KEYS_HW; ){
46  int pair;
47  for(pair = 0; pair < 30 && key < N_KEYS_HW; pair++, key++){
48  // Select both standard and Corsair input. The standard input will be ignored except in BIOS mode.
49  uchar action = IN_HID | IN_CORSAIR;
50  // Additionally, make MR activate the MR ring (this is disabled for now, may be back later)
51  //if(keymap[key].name && !strcmp(keymap[key].name, "mr"))
52  // action |= ACT_MR_RING;
53  msg[1][4 + pair * 2] = key;
54  msg[1][5 + pair * 2] = action;
55  }
56  // Byte 2 = pair count (usually 30, less on final message)
57  msg[1][2] = pair;
58  if(!usbsend(kb, msg[1], 1))
59  return -1;
60  }
61  // Commit new input settings
62  if(!usbsend(kb, msg[2], 1))
63  return -1;
64  DELAY_MEDIUM(kb);
65  } else {
66  // Set the M-keys back into hardware mode, restore hardware RGB profile. It has to be sent twice for some reason.
67  msg[0][2] = 1;
68  if(!usbsend(kb, msg[0], 1))
69  return -1;
70  DELAY_MEDIUM(kb);
71  if(!usbsend(kb, msg[0], 1))
72  return -1;
73  DELAY_MEDIUM(kb);
74 #ifdef OS_LINUX
75  // On OSX the default key mappings are fine. On Linux, the G keys will freeze the keyboard. Set the keyboard entirely to HID input.
76  for(int key = 0; key < N_KEYS_HW; ){
77  int pair;
78  for(pair = 0; pair < 30 && key < N_KEYS_HW; pair++, key++){
79  uchar action = IN_HID;
80  // Enable hardware actions
81  if(keymap[key].name){
82  if(!strcmp(keymap[key].name, "mr"))
83  action = ACT_MR_RING;
84  else if(!strcmp(keymap[key].name, "m1"))
85  action = ACT_M1;
86  else if(!strcmp(keymap[key].name, "m2"))
87  action = ACT_M2;
88  else if(!strcmp(keymap[key].name, "m3"))
89  action = ACT_M3;
90  else if(!strcmp(keymap[key].name, "light"))
91  action = ACT_LIGHT;
92  else if(!strcmp(keymap[key].name, "lock"))
93  action = ACT_LOCK;
94  }
95  msg[1][4 + pair * 2] = key;
96  msg[1][5 + pair * 2] = action;
97  }
98  // Byte 2 = pair count (usually 30, less on final message)
99  msg[1][2] = pair;
100  if(!usbsend(kb, msg[1], 1))
101  return -1;
102  }
103  // Commit new input settings
104  if(!usbsend(kb, msg[2], 1))
105  return -1;
106  DELAY_MEDIUM(kb);
107 #endif
108  }
109  // Update indicator LEDs if the profile contains settings for them
110  kb->vtable->updateindicators(kb, 0);
111  return 0;
112 }
113 
114 int cmd_active_kb(usbdevice* kb, usbmode* dummy1, int dummy2, int dummy3, const char* dummy4){
115  (void)dummy1;
116  (void)dummy2;
117  (void)dummy3;
118  (void)dummy4;
119 
120  return setactive_kb(kb, 1);
121 }
122 
123 int cmd_idle_kb(usbdevice* kb, usbmode* dummy1, int dummy2, int dummy3, const char* dummy4){
124  (void)dummy1;
125  (void)dummy2;
126  (void)dummy3;
127  (void)dummy4;
128 
129  return setactive_kb(kb, 0);
130 }
131 
132 void setmodeindex_nrgb(usbdevice *kb, int index){
133  switch(index % 3){
134  case 0:
135  nk95cmd(kb, NK95_M1);
136  break;
137  case 1:
138  nk95cmd(kb, NK95_M2);
139  break;
140  case 2:
141  nk95cmd(kb, NK95_M3);
142  break;
143  }
144 }
#define nk95cmd(kb, command)
nk95cmd() macro is used to wrap _nk95cmd() with debugging information (file and lineno). the command structure is different: Just the bits 23..16 are used as bits 7..0 for bRequest Bits 15..0 are used as wValue
Definition: usb.h:328
#define MSG_SIZE
Definition: structures.h:176
lighting lastlight
Definition: structures.h:107
void setmodeindex_nrgb(usbdevice *kb, int index)
usbprofile * profile
Definition: structures.h:221
#define ACT_MR_RING
Definition: device.h:72
#define DELAY_MEDIUM(kb)
the medium delay is used after sending a command before waiting for the answer.
Definition: usb.h:182
#define ACT_LIGHT
Definition: device.h:68
usbinput input
Definition: structures.h:245
#define ACT_LOCK
Definition: device.h:71
const key keymap[(((152+22+12)+25)+12)]
Definition: keymap.c:5
#define NK95_M1
Switch to mode 1.
Definition: usb.h:339
#define ACT_M2
Definition: device.h:74
#define NK95_M3
Switch to mode 3.
Definition: usb.h:345
Definition: keymap.h:49
char active
Definition: structures.h:231
#define NK95_HWOFF
Hardware-specific commands for the K95 nonRGB,.
Definition: usb.h:333
void inputupdate(usbdevice *kb)
Definition: input.c:241
unsigned char uchar
Definition: includes.h:24
uchar forceupdate
Definition: structures.h:77
#define IN_HID
Definition: device.h:64
int cmd_idle_kb(usbdevice *kb, usbmode *dummy1, int dummy2, int dummy3, const char *dummy4)
int start_kb_nrgb(usbdevice *kb, int makeactive)
#define N_KEYS_HW
Definition: keymap.h:24
char pollrate
Definition: structures.h:241
#define NEEDS_FW_UPDATE(kb)
Definition: structures.h:161
#define NK95_M2
Switch to mode 2.
Definition: usb.h:342
const union devcmd * vtable
Definition: structures.h:180
int setactive_kb(usbdevice *kb, int active)
#define imutex(kb)
Definition: device.h:22
#define ACT_M3
Definition: device.h:75
Definitions for using USB interface.
#define ACT_M1
Definition: device.h:73
#define usbsend(kb, messages, count)
usbsend macro is used to wrap _usbsend() with debugging information (file and lineno) ...
Definition: usb.h:271
uchar keys[((((152+22+12)+25)+7)/8)]
Definition: structures.h:130
int cmd_active_kb(usbdevice *kb, usbmode *dummy1, int dummy2, int dummy3, const char *dummy4)
#define IN_CORSAIR
Definition: device.h:65