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
led.c
Go to the documentation of this file.
1 #include "command.h"
2 #include "led.h"
3 #include "profile.h"
4 #include "usb.h"
5 
6 void cmd_rgb(usbdevice* kb, usbmode* mode, int dummy, int keyindex, const char* code){
7  (void)kb;
8  (void)dummy;
9 
10  int index = keymap[keyindex].led;
11  if(index < 0) {
12  if (index == -2){ // Process strafe sidelights
13  uchar sideshine;
14  if (sscanf(code, "%2hhx",&sideshine)) // monochromatic
15  mode->light.sidelight = sideshine;
16  }
17  return;
18  }
19  uchar r, g, b;
20  if(sscanf(code, "%2hhx%2hhx%2hhx", &r, &g, &b) == 3){
21  mode->light.r[index] = r;
22  mode->light.g[index] = g;
23  mode->light.b[index] = b;
24  }
25 }
26 
27 // Indicator bitfield from string
28 static uchar iselect(const char* led){
29  int result = 0;
30  if(!strncmp(led, "num", 3) || strstr(led, ",num"))
31  result |= I_NUM;
32  if(!strncmp(led, "caps", 4) || strstr(led, ",caps"))
33  result |= I_CAPS;
34  if(!strncmp(led, "scroll", 6) || strstr(led, ",scroll"))
35  result |= I_SCROLL;
36  if(!strncmp(led, "all", 3) || strstr(led, ",all"))
37  result |= I_NUM | I_CAPS | I_SCROLL;
38  return result;
39 }
40 
41 void cmd_ioff(usbdevice* kb, usbmode* mode, int dummy1, int dummy2, const char* led){
42  (void)dummy1;
43  (void)dummy2;
44 
45  uchar bits = iselect(led);
46  // Add the bits to ioff, remove them from ion
47  mode->ioff |= bits;
48  mode->ion &= ~bits;
49  kb->vtable->updateindicators(kb, 0);
50 }
51 
52 void cmd_ion(usbdevice* kb, usbmode* mode, int dummy1, int dummy2, const char* led){
53  (void)dummy1;
54  (void)dummy2;
55 
56  uchar bits = iselect(led);
57  // Remove the bits from ioff, add them to ion
58  mode->ioff &= ~bits;
59  mode->ion |= bits;
60  kb->vtable->updateindicators(kb, 0);
61 }
62 
63 void cmd_iauto(usbdevice* kb, usbmode* mode, int dummy1, int dummy2, const char* led){
64  (void)dummy1;
65  (void)dummy2;
66 
67  uchar bits = iselect(led);
68  // Remove the bits from both ioff and ion
69  mode->ioff &= ~bits;
70  mode->ion &= ~bits;
71  kb->vtable->updateindicators(kb, 0);
72 }
73 
74 void cmd_inotify(usbdevice* kb, usbmode* mode, int nnumber, int dummy, const char* led){
75  (void)kb;
76  (void)dummy;
77 
78  uchar bits = iselect(led);
79  if(strstr(led, ":off"))
80  // Turn notifications for these bits off
81  mode->inotify[nnumber] &= ~bits;
82  else
83  // Turn notifications for these bits on
84  mode->inotify[nnumber] |= bits;
85 }
86 
87 // Does a key exist in the current LED layout?
88 static int has_key(const char* name, const usbdevice* kb){
89  if(!name)
90  return 0;
91  if(IS_MOUSE(kb->vendor, kb->product)){
92  // Mice only have the RGB zones
93  if((IS_SABRE(kb) || IS_SCIMITAR(kb)) && !strcmp(name, "wheel"))
94  return 1;
95  if(IS_SCIMITAR(kb) && !strcmp(name, "thumb"))
96  return 1;
97  if(strstr(name, "dpi") == name || !strcmp(name, "front") || !strcmp(name, "back"))
98  return 1;
99  return 0;
100  } else {
101  // But keyboards don't have them at all
102  if(strstr(name, "dpi") == name || !strcmp(name, "front") || !strcmp(name, "back") || !strcmp(name, "wheel") || !strcmp(name, "thumb"))
103  return 0;
104  // Only K95 has G keys and M keys (G1 - G18, MR, M1 - M3)
105  if(!IS_K95(kb) && ((name[0] == 'g' && name[1] >= '1' && name[1] <= '9') || (name[0] == 'm' && (name[1] == 'r' || name[1] == '1' || name[1] == '2' || name[1] == '3'))))
106  return 0;
107  // K65 and K63 have lights on VolUp/VolDn
108  if((!IS_K65(kb) && !IS_K63(kb)) && (!strcmp(name, "volup") || !strcmp(name, "voldn")))
109  return 0;
110  // K65 lacks numpad and media buttons
111  if(IS_K65(kb) && (strstr(name, "num") == name || !strcmp(name, "stop") || !strcmp(name, "prev") || !strcmp(name, "play") || !strcmp(name, "next")))
112  return 0;
113  // K63 lacks numpad
114  if(IS_K63(kb) && strstr(name, "num") == name)
115  return 0;
116  }
117  return 1;
118 }
119 
120 char* printrgb(const lighting* light, const usbdevice* kb){
122  const uchar* mr = light->r;
123  const uchar* mg = light->g;
124  const uchar* mb = light->b;
125  for(int i = 0; i < N_KEYS_EXTENDED; i++){
126  // Translate the key index to an RGB index using the key map
127  int k = keymap[i].led;
128  if(k < 0)
129  continue;
130  r[i] = mr[k];
131  g[i] = mg[k];
132  b[i] = mb[k];
133  }
134  // Make a buffer to track key names and to filter out duplicates
135  char names[N_KEYS_EXTENDED][11];
136  for(int i = 0; i < N_KEYS_EXTENDED; i++){
137  const char* name = keymap[i].name;
138  if(keymap[i].led < 0 || !has_key(name, kb))
139  names[i][0] = 0;
140  else
141  strncpy(names[i], name, 11);
142  }
143  // Check to make sure these aren't all the same color
144  int same = 1;
145  for(int i = 1; i < N_KEYS_EXTENDED; i++){
146  if(!names[i][0])
147  continue;
148  if(r[i] != r[0] || g[i] != g[0] || b[i] != b[0]){
149  same = 0;
150  break;
151  }
152  }
153  // If they are, just output that color
154  if(same){
155  char* buffer = malloc(7);
156  snprintf(buffer, 7, "%02x%02x%02x", r[0], g[0], b[0]);
157  return buffer;
158  }
159  const int BUFFER_LEN = 4096; // Should be more than enough to fit all keys
160  char* buffer = malloc(BUFFER_LEN);
161  int length = 0;
162  for(int i = 0; i < N_KEYS_EXTENDED; i++){
163  if(!names[i][0])
164  continue;
165  // Print the key name
166  int newlen = 0;
167  snprintf(buffer + length, BUFFER_LEN - length, length == 0 ? "%s%n" : " %s%n", names[i], &newlen);
168  length += newlen;
169  // Look ahead to see if any other keys have this color. If so, print them here as well.
170  uchar kr = r[i], kg = g[i], kb = b[i];
171  for(int j = i + 1; j < N_KEYS_EXTENDED; j++){
172  if(!names[j][0])
173  continue;
174  if(r[j] != kr || g[j] != kg || b[j] != kb)
175  continue;
176  snprintf(buffer + length, BUFFER_LEN - length, ",%s%n", names[j], &newlen);
177  length += newlen;
178  // Erase the key's name so it won't get printed later
179  names[j][0] = 0;
180  }
181  // Print the color
182  snprintf(buffer + length, BUFFER_LEN - length, ":%02x%02x%02x%n", kr, kg, kb, &newlen);
183  length += newlen;
184  }
185  return buffer;
186 }
void cmd_ioff(usbdevice *kb, usbmode *mode, int dummy1, int dummy2, const char *led)
Definition: led.c:41
static int has_key(const char *name, const usbdevice *kb)
Definition: led.c:88
uchar sidelight
Definition: structures.h:78
#define IS_K63(kb)
Definition: usb.h:47
uchar ion
Definition: structures.h:93
#define IS_SCIMITAR(kb)
Definition: usb.h:113
const key keymap[(((152+22+12)+25)+12)]
Definition: keymap.c:5
short led
Definition: keymap.h:51
void cmd_rgb(usbdevice *kb, usbmode *mode, int dummy, int keyindex, const char *code)
Definition: led.c:6
#define IS_SABRE(kb)
Definition: usb.h:107
lighting light
Definition: structures.h:84
void cmd_inotify(usbdevice *kb, usbmode *mode, int nnumber, int dummy, const char *led)
Definition: led.c:74
#define IS_K65(kb)
Definition: usb.h:57
#define IS_MOUSE(vendor, product)
Mouse vs keyboard test.
Definition: usb.h:163
uchar ioff
Definition: structures.h:93
unsigned char uchar
Definition: includes.h:24
short product
Definition: structures.h:237
const char * name
Definition: keymap.h:50
const union devcmd * vtable
Definition: structures.h:180
#define I_NUM
Definition: structures.h:19
char * printrgb(const lighting *light, const usbdevice *kb)
Definition: led.c:120
uchar g[152+12]
Definition: structures.h:75
uchar inotify[10]
Definition: structures.h:95
Definitions for using USB interface.
#define N_KEYS_EXTENDED
Definition: keymap.h:45
#define IS_K95(kb)
Definition: usb.h:83
uchar b[152+12]
Definition: structures.h:76
#define I_CAPS
Definition: structures.h:20
static uchar iselect(const char *led)
Definition: led.c:28
void cmd_iauto(usbdevice *kb, usbmode *mode, int dummy1, int dummy2, const char *led)
Definition: led.c:63
#define I_SCROLL
Definition: structures.h:21
short vendor
Definition: structures.h:237
void cmd_ion(usbdevice *kb, usbmode *mode, int dummy1, int dummy2, const char *led)
Definition: led.c:52
uchar r[152+12]
Definition: structures.h:74