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

Go to the source code of this file.

Functions

int updatergb_kb (usbdevice *kb, int force)
 
int updatergb_mouse (usbdevice *kb, int force)
 
int savergb_kb (usbdevice *kb, lighting *light, int mode)
 
int savergb_mouse (usbdevice *kb, lighting *light, int mode)
 
int loadrgb_kb (usbdevice *kb, lighting *light, int mode)
 
int loadrgb_mouse (usbdevice *kb, lighting *light, int mode)
 
char * printrgb (const lighting *light, const usbdevice *kb)
 
void cmd_rgb (usbdevice *kb, usbmode *mode, int dummy, int keyindex, const char *code)
 
void cmd_ioff (usbdevice *kb, usbmode *mode, int dummy1, int dummy2, const char *led)
 
void cmd_ion (usbdevice *kb, usbmode *mode, int dummy1, int dummy2, const char *led)
 
void cmd_iauto (usbdevice *kb, usbmode *mode, int dummy1, int dummy2, const char *led)
 
void cmd_inotify (usbdevice *kb, usbmode *mode, int nnumber, int dummy, const char *led)
 

Function Documentation

void cmd_iauto ( usbdevice kb,
usbmode mode,
int  dummy1,
int  dummy2,
const char *  led 
)

Definition at line 63 of file led.c.

References usbmode::ioff, usbmode::ion, iselect(), and usbdevice::vtable.

63  {
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 }
uchar ion
Definition: structures.h:93
uchar ioff
Definition: structures.h:93
unsigned char uchar
Definition: includes.h:24
const union devcmd * vtable
Definition: structures.h:180
static uchar iselect(const char *led)
Definition: led.c:28

+ Here is the call graph for this function:

void cmd_inotify ( usbdevice kb,
usbmode mode,
int  nnumber,
int  dummy,
const char *  led 
)

Definition at line 74 of file led.c.

References usbmode::inotify, and iselect().

74  {
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 }
unsigned char uchar
Definition: includes.h:24
uchar inotify[10]
Definition: structures.h:95
static uchar iselect(const char *led)
Definition: led.c:28

+ Here is the call graph for this function:

void cmd_ioff ( usbdevice kb,
usbmode mode,
int  dummy1,
int  dummy2,
const char *  led 
)

Definition at line 41 of file led.c.

References usbmode::ioff, usbmode::ion, iselect(), and usbdevice::vtable.

41  {
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 }
uchar ion
Definition: structures.h:93
uchar ioff
Definition: structures.h:93
unsigned char uchar
Definition: includes.h:24
const union devcmd * vtable
Definition: structures.h:180
static uchar iselect(const char *led)
Definition: led.c:28

+ Here is the call graph for this function:

void cmd_ion ( usbdevice kb,
usbmode mode,
int  dummy1,
int  dummy2,
const char *  led 
)

Definition at line 52 of file led.c.

References usbmode::ioff, usbmode::ion, iselect(), and usbdevice::vtable.

52  {
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 }
uchar ion
Definition: structures.h:93
uchar ioff
Definition: structures.h:93
unsigned char uchar
Definition: includes.h:24
const union devcmd * vtable
Definition: structures.h:180
static uchar iselect(const char *led)
Definition: led.c:28

+ Here is the call graph for this function:

void cmd_rgb ( usbdevice kb,
usbmode mode,
int  dummy,
int  keyindex,
const char *  code 
)

Definition at line 6 of file led.c.

References lighting::b, lighting::g, keymap, key::led, usbmode::light, lighting::r, and lighting::sidelight.

6  {
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 }
uchar sidelight
Definition: structures.h:78
const key keymap[(((152+22+12)+25)+12)]
Definition: keymap.c:5
short led
Definition: keymap.h:51
lighting light
Definition: structures.h:84
unsigned char uchar
Definition: includes.h:24
uchar g[152+12]
Definition: structures.h:75
uchar b[152+12]
Definition: structures.h:76
uchar r[152+12]
Definition: structures.h:74
int loadrgb_kb ( usbdevice kb,
lighting light,
int  mode 
)

Since Firmware Version 2.05 for K95RGB the answers for getting the stored color-maps from the hardware has changed a bit. So comparing for the correct answer cannot validate against the cmd, and has to be done against a third map. Up to now we know, that K70RGB Pro and K70 Lux RGB have firmware version 2.04 and having the problem also. So we have to determine in the most inner loop the firmware version and type of KB to select the correct compare-table.

Read colors

                                              < That is the old comparison method: you get back what you sent.

Normally a firmware version >= 2.05 runs with the new compare array. Up to now there is a 2.04 running in K70 RGB Lux with the same behavior. It seems that K70RGB has the same problem

Definition at line 190 of file led_keyboard.c.

References lighting::b, ckb_err, usbdevice::fwversion, lighting::g, IS_V2_OVERRIDE, MSG_SIZE, N_KEYS_HW, P_K70_LUX, P_K70_LUX_NRGB, usbdevice::product, lighting::r, usbrecv, and usbsend.

Referenced by hwloadmode().

190  {
191  if(kb->fwversion >= 0x0120 || IS_V2_OVERRIDE(kb)){
192  uchar data_pkt[12][MSG_SIZE] = {
193  { 0x0e, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x01 },
194  { 0xff, 0x01, 60, 0 },
195  { 0xff, 0x02, 60, 0 },
196  { 0xff, 0x03, 24, 0 },
197  { 0x0e, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x02 },
198  { 0xff, 0x01, 60, 0 },
199  { 0xff, 0x02, 60, 0 },
200  { 0xff, 0x03, 24, 0 },
201  { 0x0e, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x03 },
202  { 0xff, 0x01, 60, 0 },
203  { 0xff, 0x02, 60, 0 },
204  { 0xff, 0x03, 24, 0 },
205  };
206  uchar in_pkt[4][MSG_SIZE] = {
207  { 0x0e, 0x14, 0x03, 0x01 },
208  { 0xff, 0x01, 60, 0 },
209  { 0xff, 0x02, 60, 0 },
210  { 0xff, 0x03, 24, 0 },
211  };
212 
218 
219  uchar cmp_pkt[4][4] = {
220  { 0x0e, 0x14, 0x03, 0x01 },
221  { 0x0e, 0xff, 0x01, 60 },
222  { 0x0e, 0xff, 0x02, 60 },
223  { 0x0e, 0xff, 0x03, 24 },
224  };
226  uchar* colors[3] = { light->r, light->g, light->b };
227  for(int clr = 0; clr < 3; clr++){
228  for(int i = 0; i < 4; i++){
229  if(!usbrecv(kb, data_pkt[i + clr * 4], in_pkt[i]))
230  return -1;
231 
232  uchar* comparePacket = data_pkt[i + clr * 4];
233  if ((kb->fwversion >= 0x205)
237  || ((kb->fwversion >= 0x204)
238  && ((kb->product == P_K70_LUX_NRGB) || (kb->product == P_K70_LUX)))) {
239  comparePacket = cmp_pkt[i];
240  }
241 
242  if (memcmp(in_pkt[i], comparePacket, 4)) {
243  ckb_err("Bad input header\n");
244  ckb_err("color = %d, i = %d, mode = %d\nOutput (Request): %2.2x %2.2x %2.2x %2.2x\nInput(Reply): %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", clr, i, mode,
245  comparePacket[0], comparePacket[1], comparePacket[2], comparePacket[3],
246  in_pkt[i][0], in_pkt[i][1], in_pkt[i][2], in_pkt[i][3], in_pkt[i][4], in_pkt[i][5], in_pkt[i][6], in_pkt[i][7]);
247  in_pkt[2][0] = 0x99;
248  in_pkt[2][1] = 0x99;
249  in_pkt[2][2] = 0x99;
250  in_pkt[2][3] = 0x99;
251  usbrecv(kb, in_pkt[2], in_pkt[2]); // just to find it in the wireshark log
252  return -1;
253  }
254  }
255  // Copy colors to lighting. in_pkt[0] is irrelevant.
256  memcpy(colors[clr], in_pkt[1] + 4, 60);
257  memcpy(colors[clr] + 60, in_pkt[2] + 4, 60);
258  memcpy(colors[clr] + 120, in_pkt[3] + 4, 24);
259  }
260  } else {
261  uchar data_pkt[5][MSG_SIZE] = {
262  { 0x0e, 0x14, 0x02, 0x01, 0x01, mode + 1, 0 },
263  { 0xff, 0x01, 60, 0 },
264  { 0xff, 0x02, 60, 0 },
265  { 0xff, 0x03, 60, 0 },
266  { 0xff, 0x04, 36, 0 },
267  };
268  uchar in_pkt[4][MSG_SIZE] = {
269  { 0xff, 0x01, 60, 0 },
270  { 0xff, 0x02, 60, 0 },
271  { 0xff, 0x03, 60, 0 },
272  { 0xff, 0x04, 36, 0 },
273  };
274  // Write initial packet
275  if(!usbsend(kb, data_pkt[0], 1))
276  return -1;
277  // Read colors
278  for(int i = 1; i < 5; i++){
279  if(!usbrecv(kb, data_pkt[i],in_pkt[i - 1]))
280  return -1;
281  if(memcmp(in_pkt[i - 1], data_pkt[i], 4)){
282  ckb_err("Bad input header\n");
283  return -1;
284  }
285  }
286  // Copy the data back to the mode
287  uint8_t mr[N_KEYS_HW / 2], mg[N_KEYS_HW / 2], mb[N_KEYS_HW / 2];
288  memcpy(mr, in_pkt[0] + 4, 60);
289  memcpy(mr + 60, in_pkt[1] + 4, 12);
290  memcpy(mg, in_pkt[1] + 16, 48);
291  memcpy(mg + 48, in_pkt[2] + 4, 24);
292  memcpy(mb, in_pkt[2] + 28, 36);
293  memcpy(mb + 36, in_pkt[3] + 4, 36);
294  // Unpack LED data to 8bpc format
295  for(int i = 0; i < N_KEYS_HW; i++){
296  int i_2 = i / 2;
297  uint8_t r, g, b;
298 
299  // 3-bit intensities stored in alternate nybbles.
300  if (i & 1) {
301  r = 7 - (mr[i_2] >> 4);
302  g = 7 - (mg[i_2] >> 4);
303  b = 7 - (mb[i_2] >> 4);
304  } else {
305  r = 7 - (mr[i_2] & 0x0F);
306  g = 7 - (mg[i_2] & 0x0F);
307  b = 7 - (mb[i_2] & 0x0F);
308  }
309  // Scale 3-bit values up to 8 bits.
310  light->r[i] = r << 5 | r << 2 | r >> 1;
311  light->g[i] = g << 5 | g << 2 | g >> 1;
312  light->b[i] = b << 5 | b << 2 | b >> 1;
313  }
314  }
315  return 0;
316 }
#define MSG_SIZE
Definition: structures.h:176
#define ckb_err(fmt, args...)
Definition: includes.h:49
ushort fwversion
Definition: structures.h:239
unsigned char uchar
Definition: includes.h:24
#define N_KEYS_HW
Definition: keymap.h:24
short product
Definition: structures.h:237
uchar g[152+12]
Definition: structures.h:75
#define usbrecv(kb, out_msg, in_msg)
usbrecv macro is used to wrap _usbrecv() with debugging information (file and lineno) ...
Definition: usb.h:288
#define P_K70_LUX
Definition: usb.h:67
#define P_K70_LUX_NRGB
Definition: usb.h:69
uchar b[152+12]
Definition: structures.h:76
#define usbsend(kb, messages, count)
usbsend macro is used to wrap _usbsend() with debugging information (file and lineno) ...
Definition: usb.h:271
#define IS_V2_OVERRIDE(kb)
Used when a device has a firmware with a low version number that uses the new protocol.
Definition: usb.h:172
uchar r[152+12]
Definition: structures.h:74

+ Here is the caller graph for this function:

int loadrgb_mouse ( usbdevice kb,
lighting light,
int  mode 
)

Definition at line 87 of file led_mouse.c.

References lighting::b, ckb_err, lighting::g, IS_SABRE, IS_SCIMITAR, LED_DPI, LED_MOUSE, MSG_SIZE, lighting::r, and usbrecv.

Referenced by cmd_hwload_mouse().

87  {
88  (void)mode;
89 
90  uchar data_pkt[MSG_SIZE] = { 0x0e, 0x13, 0x10, 1, 0 };
91  uchar in_pkt[MSG_SIZE] = { 0 };
92  // Load each RGB zone
93  int zonecount = IS_SCIMITAR(kb) ? 4 : IS_SABRE(kb) ? 3 : 2;
94  for(int i = 0; i < zonecount; i++){
95  if(!usbrecv(kb, data_pkt, in_pkt))
96  return -1;
97  if(memcmp(in_pkt, data_pkt, 4)){
98  ckb_err("Bad input header\n");
99  return -2;
100  }
101  // Copy data
102  int led = LED_MOUSE + i;
103  if(led >= LED_DPI)
104  led++; // Skip DPI light
105  light->r[led] = in_pkt[4];
106  light->g[led] = in_pkt[5];
107  light->b[led] = in_pkt[6];
108  // Set packet for next zone
109  data_pkt[2]++;
110  }
111  return 0;
112 }
#define MSG_SIZE
Definition: structures.h:176
#define LED_MOUSE
Definition: keymap.h:39
#define IS_SCIMITAR(kb)
Definition: usb.h:113
#define ckb_err(fmt, args...)
Definition: includes.h:49
#define IS_SABRE(kb)
Definition: usb.h:107
#define LED_DPI
Definition: keymap.h:43
unsigned char uchar
Definition: includes.h:24
uchar g[152+12]
Definition: structures.h:75
#define usbrecv(kb, out_msg, in_msg)
usbrecv macro is used to wrap _usbrecv() with debugging information (file and lineno) ...
Definition: usb.h:288
uchar b[152+12]
Definition: structures.h:76
uchar r[152+12]
Definition: structures.h:74

+ Here is the caller graph for this function:

char* printrgb ( const lighting light,
const usbdevice kb 
)

Definition at line 120 of file led.c.

References lighting::b, lighting::g, has_key(), keymap, key::led, N_KEYS_EXTENDED, key::name, and lighting::r.

Referenced by _cmd_get().

120  {
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 }
static int has_key(const char *name, const usbdevice *kb)
Definition: led.c:88
const key keymap[(((152+22+12)+25)+12)]
Definition: keymap.c:5
short led
Definition: keymap.h:51
unsigned char uchar
Definition: includes.h:24
const char * name
Definition: keymap.h:50
uchar g[152+12]
Definition: structures.h:75
#define N_KEYS_EXTENDED
Definition: keymap.h:45
uchar b[152+12]
Definition: structures.h:76
uchar r[152+12]
Definition: structures.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int savergb_kb ( usbdevice kb,
lighting light,
int  mode 
)

Definition at line 148 of file led_keyboard.c.

References usbdevice::dither, usbdevice::fwversion, IS_STRAFE, IS_V2_OVERRIDE, makergb_512(), makergb_full(), MSG_SIZE, ordered8to3(), quantize8to3(), and usbsend.

Referenced by cmd_hwsave_kb().

148  {
149  if(kb->fwversion >= 0x0120 || IS_V2_OVERRIDE(kb)){
150  uchar data_pkt[12][MSG_SIZE] = {
151  // Red
152  { 0x7f, 0x01, 60, 0 },
153  { 0x7f, 0x02, 60, 0 },
154  { 0x7f, 0x03, 24, 0 },
155  { 0x07, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x01 },
156  // Green
157  { 0x7f, 0x01, 60, 0 },
158  { 0x7f, 0x02, 60, 0 },
159  { 0x7f, 0x03, 24, 0 },
160  { 0x07, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x02 },
161  // Blue
162  { 0x7f, 0x01, 60, 0 },
163  { 0x7f, 0x02, 60, 0 },
164  { 0x7f, 0x03, 24, 0 },
165  { 0x07, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x03 }
166  };
167  makergb_full(light, data_pkt);
168  if(!usbsend(kb, data_pkt[0], 12))
169  return -1;
170  if (IS_STRAFE(kb)){ // end save
171  uchar save_end_pkt[MSG_SIZE] = { 0x07, 0x14, 0x04, 0x01, 0x01 };
172  if(!usbsend(kb, save_end_pkt, 1))
173  return -1;
174  }
175  } else {
176  uchar data_pkt[5][MSG_SIZE] = {
177  { 0x7f, 0x01, 60, 0 },
178  { 0x7f, 0x02, 60, 0 },
179  { 0x7f, 0x03, 60, 0 },
180  { 0x7f, 0x04, 36, 0 },
181  { 0x07, 0x14, 0x02, 0x00, 0x01, mode + 1 }
182  };
183  makergb_512(light, data_pkt, kb->dither ? ordered8to3 : quantize8to3);
184  if(!usbsend(kb, data_pkt[0], 5))
185  return -1;
186  }
187  return 0;
188 }
#define MSG_SIZE
Definition: structures.h:176
static uchar quantize8to3(int index, uchar value)
Definition: led_keyboard.c:32
ushort fwversion
Definition: structures.h:239
char dither
Definition: structures.h:249
static void makergb_full(const lighting *light, uchar data_pkt[12][64])
Definition: led_keyboard.c:58
unsigned char uchar
Definition: includes.h:24
static uchar ordered8to3(int index, uchar value)
Definition: led_keyboard.c:24
#define IS_STRAFE(kb)
Definition: usb.h:91
static void makergb_512(const lighting *light, uchar data_pkt[5][64], uchar(*ditherfn)(int, uchar))
Definition: led_keyboard.c:38
#define usbsend(kb, messages, count)
usbsend macro is used to wrap _usbsend() with debugging information (file and lineno) ...
Definition: usb.h:271
#define IS_V2_OVERRIDE(kb)
Used when a device has a firmware with a low version number that uses the new protocol.
Definition: usb.h:172

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int savergb_mouse ( usbdevice kb,
lighting light,
int  mode 
)

Definition at line 66 of file led_mouse.c.

References lighting::b, lighting::g, IS_SABRE, IS_SCIMITAR, LED_DPI, LED_MOUSE, MSG_SIZE, lighting::r, and usbsend.

Referenced by cmd_hwsave_mouse().

66  {
67  (void)mode;
68 
69  uchar data_pkt[MSG_SIZE] = { 0x07, 0x13, 0x10, 1, 0 };
70  // Save each RGB zone, minus the DPI light which is sent in the DPI packets
71  int zonecount = IS_SCIMITAR(kb) ? 4 : IS_SABRE(kb) ? 3 : 2;
72  for(int i = 0; i < zonecount; i++){
73  int led = LED_MOUSE + i;
74  if(led >= LED_DPI)
75  led++; // Skip DPI light
76  data_pkt[4] = light->r[led];
77  data_pkt[5] = light->g[led];
78  data_pkt[6] = light->b[led];
79  if(!usbsend(kb, data_pkt, 1))
80  return -1;
81  // Set packet for next zone
82  data_pkt[2]++;
83  }
84  return 0;
85 }
#define MSG_SIZE
Definition: structures.h:176
#define LED_MOUSE
Definition: keymap.h:39
#define IS_SCIMITAR(kb)
Definition: usb.h:113
#define IS_SABRE(kb)
Definition: usb.h:107
#define LED_DPI
Definition: keymap.h:43
unsigned char uchar
Definition: includes.h:24
uchar g[152+12]
Definition: structures.h:75
uchar b[152+12]
Definition: structures.h:76
#define usbsend(kb, messages, count)
usbsend macro is used to wrap _usbsend() with debugging information (file and lineno) ...
Definition: usb.h:271
uchar r[152+12]
Definition: structures.h:74

+ Here is the caller graph for this function:

int updatergb_kb ( usbdevice kb,
int  force 
)

Definition at line 79 of file led_keyboard.c.

References usbdevice::active, usbprofile::currentmode, usbdevice::dither, lighting::forceupdate, IS_FULLRANGE, usbprofile::lastlight, usbmode::light, makergb_512(), makergb_full(), MSG_SIZE, ordered8to3(), P_K95_PLATINUM, usbdevice::product, usbdevice::profile, quantize8to3(), rgbcmp(), lighting::sidelight, and usbsend.

79  {
80  if(!kb->active)
81  return 0;
82  lighting* lastlight = &kb->profile->lastlight;
83  lighting* newlight = &kb->profile->currentmode->light;
84  // Don't do anything if the lighting hasn't changed
85  if(!force && !lastlight->forceupdate && !newlight->forceupdate
86  && !rgbcmp(lastlight, newlight) && lastlight->sidelight == newlight->sidelight) // strafe sidelights
87  return 0;
88  lastlight->forceupdate = newlight->forceupdate = 0;
89 
90  if(IS_FULLRANGE(kb)){
91  // Update strafe sidelights if necessary
92  if(lastlight->sidelight != newlight->sidelight) {
93  uchar data_pkt[2][MSG_SIZE] = {
94  { 0x07, 0x05, 0x08, 0x00, 0x00 },
95  { 0x07, 0x05, 0x02, 0, 0x03 }
96  };
97  if (newlight->sidelight)
98  data_pkt[0][4]=1; // turn on
99  if(!usbsend(kb, data_pkt[0], 2))
100  return -1;
101  }
102  // 16.8M color lighting works fine on strafe and is the only way it actually works
103  uchar data_pkt[12][MSG_SIZE] = {
104  // Red
105  { 0x7f, 0x01, 0x3c, 0 },
106  { 0x7f, 0x02, 0x3c, 0 },
107  { 0x7f, 0x03, 0x18, 0 },
108  { 0x07, 0x28, 0x01, 0x03, 0x01, 0},
109  // Green
110  { 0x7f, 0x01, 0x3c, 0 },
111  { 0x7f, 0x02, 0x3c, 0 },
112  { 0x7f, 0x03, 0x18, 0 },
113  { 0x07, 0x28, 0x02, 0x03, 0x01, 0},
114  // Blue
115  { 0x7f, 0x01, 0x3c, 0 },
116  { 0x7f, 0x02, 0x3c, 0 },
117  { 0x7f, 0x03, 0x18, 0 },
118  { 0x07, 0x28, 0x03, 0x03, 0x02, 0}
119  };
120  // The K95 Platinum needs 0x30 for the lightbar to work, due to the length of the packet.
121  // A way to dynamically calculate the length would be preferred, based on the device.
122  if(kb->product == P_K95_PLATINUM){
123  data_pkt[2][2] = 0x30;
124  data_pkt[6][2] = 0x30;
125  data_pkt[10][2] = 0x30;
126  }
127  makergb_full(newlight, data_pkt);
128  if(!usbsend(kb, data_pkt[0], 12))
129  return -1;
130  } else {
131  // On older keyboards it looks flickery and causes lighting glitches, so we don't use it.
132  uchar data_pkt[5][MSG_SIZE] = {
133  { 0x7f, 0x01, 60, 0 },
134  { 0x7f, 0x02, 60, 0 },
135  { 0x7f, 0x03, 60, 0 },
136  { 0x7f, 0x04, 36, 0 },
137  { 0x07, 0x27, 0x00, 0x00, 0xD8 }
138  };
139  makergb_512(newlight, data_pkt, kb->dither ? ordered8to3 : quantize8to3);
140  if(!usbsend(kb, data_pkt[0], 5))
141  return -1;
142  }
143 
144  memcpy(lastlight, newlight, sizeof(lighting));
145  return 0;
146 }
#define IS_FULLRANGE(kb)
Full color range (16.8M) vs partial color range (512)
Definition: usb.h:160
#define MSG_SIZE
Definition: structures.h:176
uchar sidelight
Definition: structures.h:78
lighting lastlight
Definition: structures.h:107
#define P_K95_PLATINUM
Definition: usb.h:81
usbprofile * profile
Definition: structures.h:221
usbmode * currentmode
Definition: structures.h:105
static uchar quantize8to3(int index, uchar value)
Definition: led_keyboard.c:32
char dither
Definition: structures.h:249
char active
Definition: structures.h:231
lighting light
Definition: structures.h:84
static void makergb_full(const lighting *light, uchar data_pkt[12][64])
Definition: led_keyboard.c:58
unsigned char uchar
Definition: includes.h:24
static int rgbcmp(const lighting *lhs, const lighting *rhs)
Definition: led_keyboard.c:74
uchar forceupdate
Definition: structures.h:77
short product
Definition: structures.h:237
static uchar ordered8to3(int index, uchar value)
Definition: led_keyboard.c:24
static void makergb_512(const lighting *light, uchar data_pkt[5][64], uchar(*ditherfn)(int, uchar))
Definition: led_keyboard.c:38
#define usbsend(kb, messages, count)
usbsend macro is used to wrap _usbsend() with debugging information (file and lineno) ...
Definition: usb.h:271

+ Here is the call graph for this function:

int updatergb_mouse ( usbdevice kb,
int  force 
)

Definition at line 20 of file led_mouse.c.

References usbdevice::active, lighting::b, usbprofile::currentmode, lighting::forceupdate, lighting::g, IS_GLAIVE, isblack(), usbprofile::lastlight, LED_MOUSE, usbmode::light, MSG_SIZE, N_MOUSE_ZONES, usbdevice::profile, lighting::r, rgbcmp(), and usbsend.

20  {
21  if(!kb->active)
22  return 0;
23  lighting* lastlight = &kb->profile->lastlight;
24  lighting* newlight = &kb->profile->currentmode->light;
25  // Don't do anything if the lighting hasn't changed
26  if(!force && !lastlight->forceupdate && !newlight->forceupdate
27  && !rgbcmp(lastlight, newlight))
28  return 0;
29  lastlight->forceupdate = newlight->forceupdate = 0;
30 
31  // Prevent writing to DPI LEDs or non-existent LED zones for the Glaive.
32  int num_zones = IS_GLAIVE(kb) ? 3 : N_MOUSE_ZONES;
33  // Send the RGB values for each zone to the mouse
34  uchar data_pkt[2][MSG_SIZE] = {
35  { 0x07, 0x22, num_zones, 0x01, 0 }, // RGB colors
36  { 0x07, 0x05, 0x02, 0 } // Lighting on/off
37  };
38  uchar* rgb_data = &data_pkt[0][4];
39  for(int i = 0; i < N_MOUSE_ZONES; i++){
40  if (IS_GLAIVE(kb) && i != 0 && i != 1 && i != 5)
41  continue;
42  *rgb_data++ = i + 1;
43  *rgb_data++ = newlight->r[LED_MOUSE + i];
44  *rgb_data++ = newlight->g[LED_MOUSE + i];
45  *rgb_data++ = newlight->b[LED_MOUSE + i];
46  }
47  // Send RGB data
48  if(!usbsend(kb, data_pkt[0], 1))
49  return -1;
50  int was_black = isblack(kb, lastlight), is_black = isblack(kb, newlight);
51  if(is_black){
52  // If the lighting is black, send the deactivation packet (M65 only)
53  if(!usbsend(kb, data_pkt[1], 1))
54  return -1;
55  } else if(was_black || force){
56  // If the lighting WAS black, or if we're on forced update, send the activation packet
57  data_pkt[1][4] = 1;
58  if(!usbsend(kb, data_pkt[1], 1))
59  return -1;
60  }
61 
62  memcpy(lastlight, newlight, sizeof(lighting));
63  return 0;
64 }
#define MSG_SIZE
Definition: structures.h:176
lighting lastlight
Definition: structures.h:107
static int isblack(const usbdevice *kb, const lighting *light)
Definition: led_mouse.c:13
usbprofile * profile
Definition: structures.h:221
#define LED_MOUSE
Definition: keymap.h:39
usbmode * currentmode
Definition: structures.h:105
#define N_MOUSE_ZONES
Definition: keymap.h:40
char active
Definition: structures.h:231
lighting light
Definition: structures.h:84
static int rgbcmp(const lighting *lhs, const lighting *rhs)
Definition: led_mouse.c:7
unsigned char uchar
Definition: includes.h:24
uchar forceupdate
Definition: structures.h:77
uchar g[152+12]
Definition: structures.h:75
uchar b[152+12]
Definition: structures.h:76
#define usbsend(kb, messages, count)
usbsend macro is used to wrap _usbsend() with debugging information (file and lineno) ...
Definition: usb.h:271
#define IS_GLAIVE(kb)
Definition: usb.h:121
uchar r[152+12]
Definition: structures.h:74

+ Here is the call graph for this function: