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.h File Reference
#include "includes.h"
#include "keymap.h"
+ Include dependency graph for device.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define DEV_MAX   9
 
#define IS_CONNECTED(kb)   ((kb) && (kb)->handle && (kb)->uinput_kb && (kb)->uinput_mouse)
 
#define dmutex(kb)   (devmutex + INDEX_OF(kb, keyboard))
 
#define imutex(kb)   (inputmutex + INDEX_OF(kb, keyboard))
 
#define mmutex(kb)   (macromutex + INDEX_OF(kb, keyboard))
 
#define mmutex2(kb)   (macromutex2 + INDEX_OF(kb, keyboard))
 
#define mvar(kb)   (macrovar + INDEX_OF(kb, keyboard))
 
#define setactive(kb, makeactive)   ((makeactive) ? (kb)->vtable->active((kb), 0, 0, 0, 0) : (kb)->vtable->idle((kb), 0, 0, 0, 0))
 setactive() calls via the corresponding kb->vtable either the active() or the idle() function.
active() is called if the parameter makeactive is true, idle if it is false.
What function is called effectively is device dependent. Have a look at device_vtable.c for more information. More...
 
#define IN_HID   0x80
 
#define IN_CORSAIR   0x40
 
#define ACT_LIGHT   1
 
#define ACT_NEXT   3
 
#define ACT_NEXT_NOWRAP   5
 
#define ACT_LOCK   8
 
#define ACT_MR_RING   9
 
#define ACT_M1   10
 
#define ACT_M2   11
 
#define ACT_M3   12
 

Functions

int start_dev (usbdevice *kb, int makeactive)
 
int start_kb_nrgb (usbdevice *kb, int makeactive)
 
int setactive_kb (usbdevice *kb, int active)
 
int setactive_mouse (usbdevice *kb, int active)
 
int cmd_active_kb (usbdevice *kb, usbmode *dummy1, int dummy2, int dummy3, const char *dummy4)
 
int cmd_active_mouse (usbdevice *kb, usbmode *dummy1, int dummy2, int dummy3, const char *dummy4)
 
int cmd_idle_kb (usbdevice *kb, usbmode *dummy1, int dummy2, int dummy3, const char *dummy4)
 
int cmd_idle_mouse (usbdevice *kb, usbmode *dummy1, int dummy2, int dummy3, const char *dummy4)
 
int cmd_pollrate (usbdevice *kb, usbmode *dummy1, int dummy2, int rate, const char *dummy3)
 
void setmodeindex_nrgb (usbdevice *kb, int index)
 

Variables

usbdevice keyboard [9]
 remember all usb devices. Needed for closeusb(). More...
 
pthread_mutex_t devmutex [9]
 Mutex for handling the usbdevice structure. More...
 
pthread_mutex_t inputmutex [9]
 Mutex for dealing with usb input frames. More...
 
pthread_mutex_t macromutex [9]
 Protecting macros against lightning: Both use usb_send. More...
 
pthread_mutex_t macromutex2 [9]
 Protecting the single link list of threads and the macrovar. More...
 
pthread_cond_t macrovar [9]
 This variable is used to stop and wakeup all macro threads which have to wait. More...
 

Macro Definition Documentation

#define ACT_LIGHT   1

Definition at line 68 of file device.h.

Referenced by setactive_kb().

#define ACT_LOCK   8

Definition at line 71 of file device.h.

Referenced by setactive_kb().

#define ACT_M1   10

Definition at line 73 of file device.h.

Referenced by setactive_kb().

#define ACT_M2   11

Definition at line 74 of file device.h.

Referenced by setactive_kb().

#define ACT_M3   12

Definition at line 75 of file device.h.

Referenced by setactive_kb().

#define ACT_MR_RING   9

Definition at line 72 of file device.h.

Referenced by setactive_kb().

#define ACT_NEXT   3

Definition at line 69 of file device.h.

#define ACT_NEXT_NOWRAP   5

Definition at line 70 of file device.h.

#define DEV_MAX   9

Definition at line 8 of file device.h.

Referenced by _start_dev(), _updateconnected(), quitWithLock(), usb_rm_device(), and usbadd().

#define dmutex (   kb)    (devmutex + INDEX_OF(kb, keyboard))

Definition at line 18 of file device.h.

Referenced by _ledthread(), _setupusb(), closeusb(), devmain(), and usbadd().

#define IN_CORSAIR   0x40

Definition at line 65 of file device.h.

Referenced by setactive_kb(), and setactive_mouse().

#define IN_HID   0x80

Definition at line 64 of file device.h.

Referenced by setactive_kb(), and setactive_mouse().

#define IS_CONNECTED (   kb)    ((kb) && (kb)->handle && (kb)->uinput_kb && (kb)->uinput_mouse)

Definition at line 12 of file device.h.

Referenced by _updateconnected(), devmain(), quitWithLock(), and usbadd().

#define mmutex (   kb)    (macromutex + INDEX_OF(kb, keyboard))

Definition at line 26 of file device.h.

Referenced by _usbrecv(), _usbsend(), and play_macro().

#define mmutex2 (   kb)    (macromutex2 + INDEX_OF(kb, keyboard))

Definition at line 28 of file device.h.

Referenced by play_macro().

#define mvar (   kb)    (macrovar + INDEX_OF(kb, keyboard))

Definition at line 30 of file device.h.

Referenced by play_macro().

#define setactive (   kb,
  makeactive 
)    ((makeactive) ? (kb)->vtable->active((kb), 0, 0, 0, 0) : (kb)->vtable->idle((kb), 0, 0, 0, 0))

Definition at line 44 of file device.h.

Referenced by _start_dev(), and revertusb().

Function Documentation

int cmd_active_kb ( usbdevice kb,
usbmode dummy1,
int  dummy2,
int  dummy3,
const char *  dummy4 
)

Definition at line 114 of file device_keyboard.c.

References setactive_kb().

114  {
115  (void)dummy1;
116  (void)dummy2;
117  (void)dummy3;
118  (void)dummy4;
119 
120  return setactive_kb(kb, 1);
121 }
int setactive_kb(usbdevice *kb, int active)

+ Here is the call graph for this function:

int cmd_active_mouse ( usbdevice kb,
usbmode dummy1,
int  dummy2,
int  dummy3,
const char *  dummy4 
)

Definition at line 44 of file device_mouse.c.

References setactive_mouse().

44  {
45  (void)dummy1;
46  (void)dummy2;
47  (void)dummy3;
48  (void)dummy4;
49 
50  return setactive_mouse(kb, 1);
51 }
int setactive_mouse(usbdevice *kb, int active)
Definition: device_mouse.c:9

+ Here is the call graph for this function:

int cmd_idle_kb ( usbdevice kb,
usbmode dummy1,
int  dummy2,
int  dummy3,
const char *  dummy4 
)

Definition at line 123 of file device_keyboard.c.

References setactive_kb().

123  {
124  (void)dummy1;
125  (void)dummy2;
126  (void)dummy3;
127  (void)dummy4;
128 
129  return setactive_kb(kb, 0);
130 }
int setactive_kb(usbdevice *kb, int active)

+ Here is the call graph for this function:

int cmd_idle_mouse ( usbdevice kb,
usbmode dummy1,
int  dummy2,
int  dummy3,
const char *  dummy4 
)

Definition at line 53 of file device_mouse.c.

References setactive_mouse().

53  {
54  (void)dummy1;
55  (void)dummy2;
56  (void)dummy3;
57  (void)dummy4;
58 
59  return setactive_mouse(kb, 0);
60 }
int setactive_mouse(usbdevice *kb, int active)
Definition: device_mouse.c:9

+ Here is the call graph for this function:

int cmd_pollrate ( usbdevice kb,
usbmode dummy1,
int  dummy2,
int  rate,
const char *  dummy3 
)

Definition at line 62 of file device_mouse.c.

References MSG_SIZE, usbdevice::pollrate, and usbsend.

62  {
63  (void)dummy1;
64  (void)dummy2;
65  (void)dummy3;
66 
67  uchar msg[MSG_SIZE] = {
68  0x07, 0x0a, 0, 0, (uchar)rate
69  };
70  if(!usbsend(kb, msg, 1))
71  return -1;
72  // Device should disconnect+reconnect, but update the poll rate field in case it doesn't
73  kb->pollrate = rate;
74  return 0;
75 }
#define MSG_SIZE
Definition: structures.h:176
unsigned char uchar
Definition: includes.h:24
char pollrate
Definition: structures.h:241
#define usbsend(kb, messages, count)
usbsend macro is used to wrap _usbsend() with debugging information (file and lineno) ...
Definition: usb.h:271
int setactive_kb ( usbdevice kb,
int  active 
)

Definition at line 20 of file device_keyboard.c.

References ACT_LIGHT, ACT_LOCK, ACT_M1, ACT_M2, ACT_M3, ACT_MR_RING, usbdevice::active, DELAY_MEDIUM, lighting::forceupdate, imutex, IN_CORSAIR, IN_HID, usbdevice::input, inputupdate(), keymap, usbinput::keys, usbprofile::lastlight, MSG_SIZE, N_KEYS_HW, NEEDS_FW_UPDATE, usbdevice::profile, usbsend, and usbdevice::vtable.

Referenced by cmd_active_kb(), and cmd_idle_kb().

20  {
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 }
#define MSG_SIZE
Definition: structures.h:176
lighting lastlight
Definition: structures.h:107
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 ACT_M2
Definition: device.h:74
Definition: keymap.h:49
char active
Definition: structures.h:231
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
#define N_KEYS_HW
Definition: keymap.h:24
#define NEEDS_FW_UPDATE(kb)
Definition: structures.h:161
const union devcmd * vtable
Definition: structures.h:180
#define imutex(kb)
Definition: device.h:22
#define ACT_M3
Definition: device.h:75
#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
#define IN_CORSAIR
Definition: device.h:65

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int setactive_mouse ( usbdevice kb,
int  active 
)

Definition at line 9 of file device_mouse.c.

References usbdevice::active, lighting::forceupdate, imutex, IN_CORSAIR, IN_HID, usbdevice::input, inputupdate(), usbinput::keys, usbprofile::lastlight, MSG_SIZE, NEEDS_FW_UPDATE, usbdevice::profile, and usbsend.

Referenced by cmd_active_mouse(), and cmd_idle_mouse().

9  {
10  if(NEEDS_FW_UPDATE(kb))
11  return 0;
12  const int keycount = 20;
13  uchar msg[2][MSG_SIZE] = {
14  { 0x07, 0x04, 0 }, // Disables or enables HW control for DPI and Sniper button
15  { 0x07, 0x40, keycount, 0 }, // Select button input (simlilar to the packet sent to keyboards, but lacks a commit packet)
16  };
17  if(active)
18  // Put the mouse into SW mode
19  msg[0][2] = 2;
20  else
21  // Restore HW mode
22  msg[0][2] = 1;
23  pthread_mutex_lock(imutex(kb));
24  kb->active = !!active;
25  kb->profile->lastlight.forceupdate = 1;
26  // Clear input
27  memset(&kb->input.keys, 0, sizeof(kb->input.keys));
28  inputupdate(kb);
29  pthread_mutex_unlock(imutex(kb));
30  if(!usbsend(kb, msg[0], 1))
31  return -1;
32  if(active){
33  // Set up key input
34  if(!usbsend(kb, msg[1], 1))
35  return -1;
36  for(int i = 0; i < keycount; i++){
37  msg[1][i * 2 + 4] = i + 1;
38  msg[1][i * 2 + 5] = (i < 6 ? IN_HID : IN_CORSAIR);
39  }
40  }
41  return 0;
42 }
#define MSG_SIZE
Definition: structures.h:176
lighting lastlight
Definition: structures.h:107
usbprofile * profile
Definition: structures.h:221
usbinput input
Definition: structures.h:245
char active
Definition: structures.h:231
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
#define NEEDS_FW_UPDATE(kb)
Definition: structures.h:161
#define imutex(kb)
Definition: device.h:22
#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
#define IN_CORSAIR
Definition: device.h:65

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void setmodeindex_nrgb ( usbdevice kb,
int  index 
)

Definition at line 132 of file device_keyboard.c.

References NK95_M1, NK95_M2, NK95_M3, and nk95cmd.

132  {
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 NK95_M1
Switch to mode 1.
Definition: usb.h:339
#define NK95_M3
Switch to mode 3.
Definition: usb.h:345
#define NK95_M2
Switch to mode 2.
Definition: usb.h:342
int start_dev ( usbdevice kb,
int  makeactive 
)

Definition at line 89 of file device.c.

References _start_dev(), USB_DELAY_DEFAULT, and usbdevice::usbdelay.

89  {
90  // Force USB interval to 10ms during initial setup phase; return to nominal 5ms after setup completes.
91  kb->usbdelay = 10;
92  int res = _start_dev(kb, makeactive);
94  return res;
95 }
#define USB_DELAY_DEFAULT
This constant is used to initialize kb->usbdelay. It is used in many places (see macros above) but of...
Definition: usb.h:192
int _start_dev(usbdevice *kb, int makeactive)
Definition: device.c:25
char usbdelay
Definition: structures.h:243

+ Here is the call graph for this function:

int start_kb_nrgb ( usbdevice kb,
int  makeactive 
)

Definition at line 9 of file device_keyboard.c.

References usbdevice::active, NK95_HWOFF, nk95cmd, and usbdevice::pollrate.

9  {
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 }
#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
char active
Definition: structures.h:231
#define NK95_HWOFF
Hardware-specific commands for the K95 nonRGB,.
Definition: usb.h:333
char pollrate
Definition: structures.h:241

Variable Documentation

pthread_mutex_t devmutex[9]

Definition at line 12 of file device.c.

Referenced by _updateconnected(), quitWithLock(), and usb_rm_device().

pthread_mutex_t inputmutex[9]

Definition at line 13 of file device.c.

pthread_mutex_t macromutex[9]

Definition at line 14 of file device.c.

pthread_mutex_t macromutex2[9]

Definition at line 15 of file device.c.

pthread_cond_t macrovar[9]

Definition at line 16 of file device.c.