ckb-next  beta-v0.2.8 at branch testing
ckb-next driver for corsair devices
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator 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 54 of file led.c.

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

54  {
55  uchar bits = iselect(led);
56  // Remove the bits from both ioff and ion
57  mode->ioff &= ~bits;
58  mode->ion &= ~bits;
59  kb->vtable->updateindicators(kb, 0);
60 }
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:25

+ 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 62 of file led.c.

References usbmode::inotify, and iselect().

62  {
63  uchar bits = iselect(led);
64  if(strstr(led, ":off"))
65  // Turn notifications for these bits off
66  mode->inotify[nnumber] &= ~bits;
67  else
68  // Turn notifications for these bits on
69  mode->inotify[nnumber] |= bits;
70 }
unsigned char uchar
Definition: includes.h:24
uchar inotify[10]
Definition: structures.h:95
static uchar iselect(const char *led)
Definition: led.c:25

+ 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 38 of file led.c.

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

38  {
39  uchar bits = iselect(led);
40  // Add the bits to ioff, remove them from ion
41  mode->ioff |= bits;
42  mode->ion &= ~bits;
43  kb->vtable->updateindicators(kb, 0);
44 }
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:25

+ 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 46 of file led.c.

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

46  {
47  uchar bits = iselect(led);
48  // Remove the bits from ioff, add them to ion
49  mode->ioff &= ~bits;
50  mode->ion |= bits;
51  kb->vtable->updateindicators(kb, 0);
52 }
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:25

+ 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  int index = keymap[keyindex].led;
8  if(index < 0) {
9  if (index == -2){ // Process strafe sidelights
10  uchar sideshine;
11  if (sscanf(code, "%2hhx",&sideshine)) // monochromatic
12  mode->light.sidelight = sideshine;
13  }
14  return;
15  }
16  uchar r, g, b;
17  if(sscanf(code, "%2hhx%2hhx%2hhx", &r, &g, &b) == 3){
18  mode->light.r[index] = r;
19  mode->light.g[index] = g;
20  mode->light.b[index] = b;
21  }
22 }
uchar sidelight
Definition: structures.h:78
uchar b[152+11]
Definition: structures.h:76
lighting light
Definition: structures.h:84
unsigned char uchar
Definition: includes.h:24
short led
Definition: keymap.h:51
uchar g[152+11]
Definition: structures.h:75
uchar r[152+11]
Definition: structures.h:74
const key keymap[(((152+3+12)+25)+11)]
Definition: keymap.c:5
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 181 of file led_keyboard.c.

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

Referenced by hwloadmode().

181  {
182  if(kb->fwversion >= 0x0120){
183  uchar data_pkt[12][MSG_SIZE] = {
184  { 0x0e, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x01 },
185  { 0xff, 0x01, 60, 0 },
186  { 0xff, 0x02, 60, 0 },
187  { 0xff, 0x03, 24, 0 },
188  { 0x0e, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x02 },
189  { 0xff, 0x01, 60, 0 },
190  { 0xff, 0x02, 60, 0 },
191  { 0xff, 0x03, 24, 0 },
192  { 0x0e, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x03 },
193  { 0xff, 0x01, 60, 0 },
194  { 0xff, 0x02, 60, 0 },
195  { 0xff, 0x03, 24, 0 },
196  };
197  uchar in_pkt[4][MSG_SIZE] = {
198  { 0x0e, 0x14, 0x03, 0x01 },
199  { 0xff, 0x01, 60, 0 },
200  { 0xff, 0x02, 60, 0 },
201  { 0xff, 0x03, 24, 0 },
202  };
203 
209 
210  uchar cmp_pkt[4][4] = {
211  { 0x0e, 0x14, 0x03, 0x01 },
212  { 0x0e, 0xff, 0x01, 60 },
213  { 0x0e, 0xff, 0x02, 60 },
214  { 0x0e, 0xff, 0x03, 24 },
215  };
217  uchar* colors[3] = { light->r, light->g, light->b };
218  for(int clr = 0; clr < 3; clr++){
219  for(int i = 0; i < 4; i++){
220  if(!usbrecv(kb, data_pkt[i + clr * 4], in_pkt[i]))
221  return -1;
222 
223  uchar* comparePacket = data_pkt[i + clr * 4];
224  if ((kb->fwversion >= 0x205)
228  || ((kb->fwversion >= 0x204)
229  && ((kb->product == P_K70_LUX_NRGB) || (kb->product == P_K70_LUX)))) {
230  comparePacket = cmp_pkt[i];
231  }
232 
233  if (memcmp(in_pkt[i], comparePacket, 4)) {
234  ckb_err("Bad input header\n");
235  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,
236  comparePacket[0], comparePacket[1], comparePacket[2], comparePacket[3],
237  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]);
238  in_pkt[2][0] = 0x99;
239  in_pkt[2][1] = 0x99;
240  in_pkt[2][2] = 0x99;
241  in_pkt[2][3] = 0x99;
242  usbrecv(kb, in_pkt[2], in_pkt[2]); // just to find it in the wireshark log
243  return -1;
244  }
245  }
246  // Copy colors to lighting. in_pkt[0] is irrelevant.
247  memcpy(colors[clr], in_pkt[1] + 4, 60);
248  memcpy(colors[clr] + 60, in_pkt[2] + 4, 60);
249  memcpy(colors[clr] + 120, in_pkt[3] + 4, 24);
250  }
251  } else {
252  uchar data_pkt[5][MSG_SIZE] = {
253  { 0x0e, 0x14, 0x02, 0x01, 0x01, mode + 1, 0 },
254  { 0xff, 0x01, 60, 0 },
255  { 0xff, 0x02, 60, 0 },
256  { 0xff, 0x03, 60, 0 },
257  { 0xff, 0x04, 36, 0 },
258  };
259  uchar in_pkt[4][MSG_SIZE] = {
260  { 0xff, 0x01, 60, 0 },
261  { 0xff, 0x02, 60, 0 },
262  { 0xff, 0x03, 60, 0 },
263  { 0xff, 0x04, 36, 0 },
264  };
265  // Write initial packet
266  if(!usbsend(kb, data_pkt[0], 1))
267  return -1;
268  // Read colors
269  for(int i = 1; i < 5; i++){
270  if(!usbrecv(kb, data_pkt[i],in_pkt[i - 1]))
271  return -1;
272  if(memcmp(in_pkt[i - 1], data_pkt[i], 4)){
273  ckb_err("Bad input header\n");
274  return -1;
275  }
276  }
277  // Copy the data back to the mode
278  uint8_t mr[N_KEYS_HW / 2], mg[N_KEYS_HW / 2], mb[N_KEYS_HW / 2];
279  memcpy(mr, in_pkt[0] + 4, 60);
280  memcpy(mr + 60, in_pkt[1] + 4, 12);
281  memcpy(mg, in_pkt[1] + 16, 48);
282  memcpy(mg + 48, in_pkt[2] + 4, 24);
283  memcpy(mb, in_pkt[2] + 28, 36);
284  memcpy(mb + 36, in_pkt[3] + 4, 36);
285  // Unpack LED data to 8bpc format
286  for(int i = 0; i < N_KEYS_HW; i++){
287  int i_2 = i / 2;
288  uint8_t r, g, b;
289 
290  // 3-bit intensities stored in alternate nybbles.
291  if (i & 1) {
292  r = 7 - (mr[i_2] >> 4);
293  g = 7 - (mg[i_2] >> 4);
294  b = 7 - (mb[i_2] >> 4);
295  } else {
296  r = 7 - (mr[i_2] & 0x0F);
297  g = 7 - (mg[i_2] & 0x0F);
298  b = 7 - (mb[i_2] & 0x0F);
299  }
300  // Scale 3-bit values up to 8 bits.
301  light->r[i] = r << 5 | r << 2 | r >> 1;
302  light->g[i] = g << 5 | g << 2 | g >> 1;
303  light->b[i] = b << 5 | b << 2 | b >> 1;
304  }
305  }
306  return 0;
307 }
#define MSG_SIZE
Definition: structures.h:176
uchar b[152+11]
Definition: structures.h:76
#define ckb_err(fmt, args...)
Definition: includes.h:49
ushort fwversion
Definition: structures.h:239
#define N_KEYS_HW
Definition: keymap.h:24
unsigned char uchar
Definition: includes.h:24
short product
Definition: structures.h:237
uchar g[152+11]
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:256
uchar r[152+11]
Definition: structures.h:74
#define P_K70_LUX
Definition: usb.h:55
#define P_K70_LUX_NRGB
Definition: usb.h:57
#define usbsend(kb, messages, count)
usbsend macro is used to wrap _usbsend() with debugging information (file and lineno) ...
Definition: usb.h:239

+ Here is the caller graph for this function:

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

Definition at line 81 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().

81  {
82  uchar data_pkt[MSG_SIZE] = { 0x0e, 0x13, 0x10, 1, 0 };
83  uchar in_pkt[MSG_SIZE] = { 0 };
84  // Load each RGB zone
85  int zonecount = IS_SCIMITAR(kb) ? 4 : IS_SABRE(kb) ? 3 : 2;
86  for(int i = 0; i < zonecount; i++){
87  if(!usbrecv(kb, data_pkt, in_pkt))
88  return -1;
89  if(memcmp(in_pkt, data_pkt, 4)){
90  ckb_err("Bad input header\n");
91  return -2;
92  }
93  // Copy data
94  int led = LED_MOUSE + i;
95  if(led >= LED_DPI)
96  led++; // Skip DPI light
97  light->r[led] = in_pkt[4];
98  light->g[led] = in_pkt[5];
99  light->b[led] = in_pkt[6];
100  // Set packet for next zone
101  data_pkt[2]++;
102  }
103  return 0;
104 }
#define MSG_SIZE
Definition: structures.h:176
uchar b[152+11]
Definition: structures.h:76
#define IS_SCIMITAR(kb)
Definition: usb.h:99
#define ckb_err(fmt, args...)
Definition: includes.h:49
#define IS_SABRE(kb)
Definition: usb.h:93
unsigned char uchar
Definition: includes.h:24
uchar g[152+11]
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:256
uchar r[152+11]
Definition: structures.h:74
#define LED_DPI
Definition: keymap.h:43
#define LED_MOUSE
Definition: keymap.h:39

+ Here is the caller graph for this function:

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

Definition at line 102 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().

102  {
104  const uchar* mr = light->r;
105  const uchar* mg = light->g;
106  const uchar* mb = light->b;
107  for(int i = 0; i < N_KEYS_EXTENDED; i++){
108  // Translate the key index to an RGB index using the key map
109  int k = keymap[i].led;
110  if(k < 0)
111  continue;
112  r[i] = mr[k];
113  g[i] = mg[k];
114  b[i] = mb[k];
115  }
116  // Make a buffer to track key names and to filter out duplicates
117  char names[N_KEYS_EXTENDED][11];
118  for(int i = 0; i < N_KEYS_EXTENDED; i++){
119  const char* name = keymap[i].name;
120  if(keymap[i].led < 0 || !has_key(name, kb))
121  names[i][0] = 0;
122  else
123  strncpy(names[i], name, 11);
124  }
125  // Check to make sure these aren't all the same color
126  int same = 1;
127  for(int i = 1; i < N_KEYS_EXTENDED; i++){
128  if(!names[i][0])
129  continue;
130  if(r[i] != r[0] || g[i] != g[0] || b[i] != b[0]){
131  same = 0;
132  break;
133  }
134  }
135  // If they are, just output that color
136  if(same){
137  char* buffer = malloc(7);
138  snprintf(buffer, 7, "%02x%02x%02x", r[0], g[0], b[0]);
139  return buffer;
140  }
141  const int BUFFER_LEN = 4096; // Should be more than enough to fit all keys
142  char* buffer = malloc(BUFFER_LEN);
143  int length = 0;
144  for(int i = 0; i < N_KEYS_EXTENDED; i++){
145  if(!names[i][0])
146  continue;
147  // Print the key name
148  int newlen = 0;
149  snprintf(buffer + length, BUFFER_LEN - length, length == 0 ? "%s%n" : " %s%n", names[i], &newlen);
150  length += newlen;
151  // Look ahead to see if any other keys have this color. If so, print them here as well.
152  uchar kr = r[i], kg = g[i], kb = b[i];
153  for(int j = i + 1; j < N_KEYS_EXTENDED; j++){
154  if(!names[j][0])
155  continue;
156  if(r[j] != kr || g[j] != kg || b[j] != kb)
157  continue;
158  snprintf(buffer + length, BUFFER_LEN - length, ",%s%n", names[j], &newlen);
159  length += newlen;
160  // Erase the key's name so it won't get printed later
161  names[j][0] = 0;
162  }
163  // Print the color
164  snprintf(buffer + length, BUFFER_LEN - length, ":%02x%02x%02x%n", kr, kg, kb, &newlen);
165  length += newlen;
166  }
167  return buffer;
168 }
static int has_key(const char *name, const usbdevice *kb)
Definition: led.c:73
uchar b[152+11]
Definition: structures.h:76
#define N_KEYS_EXTENDED
Definition: keymap.h:45
const char * name
Definition: keymap.h:50
unsigned char uchar
Definition: includes.h:24
short led
Definition: keymap.h:51
uchar g[152+11]
Definition: structures.h:75
uchar r[152+11]
Definition: structures.h:74
const key keymap[(((152+3+12)+25)+11)]
Definition: keymap.c:5

+ 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 139 of file led_keyboard.c.

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

Referenced by cmd_hwsave_kb().

139  {
140  if(kb->fwversion >= 0x0120){
141  uchar data_pkt[12][MSG_SIZE] = {
142  // Red
143  { 0x7f, 0x01, 60, 0 },
144  { 0x7f, 0x02, 60, 0 },
145  { 0x7f, 0x03, 24, 0 },
146  { 0x07, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x01 },
147  // Green
148  { 0x7f, 0x01, 60, 0 },
149  { 0x7f, 0x02, 60, 0 },
150  { 0x7f, 0x03, 24, 0 },
151  { 0x07, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x02 },
152  // Blue
153  { 0x7f, 0x01, 60, 0 },
154  { 0x7f, 0x02, 60, 0 },
155  { 0x7f, 0x03, 24, 0 },
156  { 0x07, 0x14, 0x03, 0x01, 0x01, mode + 1, 0x03 }
157  };
158  makergb_full(light, data_pkt);
159  if(!usbsend(kb, data_pkt[0], 12))
160  return -1;
161  if (IS_STRAFE(kb)){ // end save
162  uchar save_end_pkt[MSG_SIZE] = { 0x07, 0x14, 0x04, 0x01, 0x01 };
163  if(!usbsend(kb, save_end_pkt, 1))
164  return -1;
165  }
166  } else {
167  uchar data_pkt[5][MSG_SIZE] = {
168  { 0x7f, 0x01, 60, 0 },
169  { 0x7f, 0x02, 60, 0 },
170  { 0x7f, 0x03, 60, 0 },
171  { 0x7f, 0x04, 36, 0 },
172  { 0x07, 0x14, 0x02, 0x00, 0x01, mode + 1 }
173  };
174  makergb_512(light, data_pkt, kb->dither ? ordered8to3 : quantize8to3);
175  if(!usbsend(kb, data_pkt[0], 5))
176  return -1;
177  }
178  return 0;
179 }
#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:56
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:77
static void makergb_512(const lighting *light, uchar data_pkt[5][64], uchar(*ditherfn)(int, uchar))
Definition: led_keyboard.c:36
#define usbsend(kb, messages, count)
usbsend macro is used to wrap _usbsend() with debugging information (file and lineno) ...
Definition: usb.h:239

+ 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 62 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().

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

+ Here is the caller graph for this function:

int updatergb_kb ( usbdevice kb,
int  force 
)

Definition at line 77 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(), usbdevice::profile, quantize8to3(), rgbcmp(), lighting::sidelight, and usbsend.

77  {
78  if(!kb->active)
79  return 0;
80  lighting* lastlight = &kb->profile->lastlight;
81  lighting* newlight = &kb->profile->currentmode->light;
82  // Don't do anything if the lighting hasn't changed
83  if(!force && !lastlight->forceupdate && !newlight->forceupdate
84  && !rgbcmp(lastlight, newlight) && lastlight->sidelight == newlight->sidelight) // strafe sidelights
85  return 0;
86  lastlight->forceupdate = newlight->forceupdate = 0;
87 
88  if(IS_FULLRANGE(kb)){
89  // Update strafe sidelights if necessary
90  if(lastlight->sidelight != newlight->sidelight) {
91  uchar data_pkt[2][MSG_SIZE] = {
92  { 0x07, 0x05, 0x08, 0x00, 0x00 },
93  { 0x07, 0x05, 0x02, 0, 0x03 }
94  };
95  if (newlight->sidelight)
96  data_pkt[0][4]=1; // turn on
97  if(!usbsend(kb, data_pkt[0], 2))
98  return -1;
99  }
100  // 16.8M color lighting works fine on strafe and is the only way it actually works
101  uchar data_pkt[12][MSG_SIZE] = {
102  // Red
103  { 0x7f, 0x01, 0x3c, 0 },
104  { 0x7f, 0x02, 0x3c, 0 },
105  { 0x7f, 0x03, 0x18, 0 },
106  { 0x07, 0x28, 0x01, 0x03, 0x01, 0},
107  // Green
108  { 0x7f, 0x01, 0x3c, 0 },
109  { 0x7f, 0x02, 0x3c, 0 },
110  { 0x7f, 0x03, 0x18, 0 },
111  { 0x07, 0x28, 0x02, 0x03, 0x01, 0},
112  // Blue
113  { 0x7f, 0x01, 0x3c, 0 },
114  { 0x7f, 0x02, 0x3c, 0 },
115  { 0x7f, 0x03, 0x18, 0 },
116  { 0x07, 0x28, 0x03, 0x03, 0x02, 0}
117  };
118  makergb_full(newlight, data_pkt);
119  if(!usbsend(kb, data_pkt[0], 12))
120  return -1;
121  } else {
122  // On older keyboards it looks flickery and causes lighting glitches, so we don't use it.
123  uchar data_pkt[5][MSG_SIZE] = {
124  { 0x7f, 0x01, 60, 0 },
125  { 0x7f, 0x02, 60, 0 },
126  { 0x7f, 0x03, 60, 0 },
127  { 0x7f, 0x04, 36, 0 },
128  { 0x07, 0x27, 0x00, 0x00, 0xD8 }
129  };
130  makergb_512(newlight, data_pkt, kb->dither ? ordered8to3 : quantize8to3);
131  if(!usbsend(kb, data_pkt[0], 5))
132  return -1;
133  }
134 
135  memcpy(lastlight, newlight, sizeof(lighting));
136  return 0;
137 }
#define IS_FULLRANGE(kb)
Full color range (16.8M) vs partial color range (512)
Definition: usb.h:138
#define MSG_SIZE
Definition: structures.h:176
uchar sidelight
Definition: structures.h:78
lighting lastlight
Definition: structures.h:107
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:56
unsigned char uchar
Definition: includes.h:24
static int rgbcmp(const lighting *lhs, const lighting *rhs)
Definition: led_keyboard.c:72
uchar forceupdate
Definition: structures.h:77
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:36
#define usbsend(kb, messages, count)
usbsend macro is used to wrap _usbsend() with debugging information (file and lineno) ...
Definition: usb.h:239

+ 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, 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  // Send the RGB values for each zone to the mouse
32  uchar data_pkt[2][MSG_SIZE] = {
33  { 0x07, 0x22, N_MOUSE_ZONES, 0x01, 0 }, // RGB colors
34  { 0x07, 0x05, 0x02, 0 } // Lighting on/off
35  };
36  uchar* rgb_data = &data_pkt[0][4];
37  for(int i = 0; i < N_MOUSE_ZONES; i++){
38  *rgb_data++ = i + 1;
39  *rgb_data++ = newlight->r[LED_MOUSE + i];
40  *rgb_data++ = newlight->g[LED_MOUSE + i];
41  *rgb_data++ = newlight->b[LED_MOUSE + i];
42  }
43  // Send RGB data
44  if(!usbsend(kb, data_pkt[0], 1))
45  return -1;
46  int was_black = isblack(kb, lastlight), is_black = isblack(kb, newlight);
47  if(is_black){
48  // If the lighting is black, send the deactivation packet (M65 only)
49  if(!usbsend(kb, data_pkt[1], 1))
50  return -1;
51  } else if(was_black || force){
52  // If the lighting WAS black, or if we're on forced update, send the activation packet
53  data_pkt[1][4] = 1;
54  if(!usbsend(kb, data_pkt[1], 1))
55  return -1;
56  }
57 
58  memcpy(lastlight, newlight, sizeof(lighting));
59  return 0;
60 }
#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
uchar b[152+11]
Definition: structures.h:76
usbprofile * profile
Definition: structures.h:221
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+11]
Definition: structures.h:75
uchar r[152+11]
Definition: structures.h:74
#define usbsend(kb, messages, count)
usbsend macro is used to wrap _usbsend() with debugging information (file and lineno) ...
Definition: usb.h:239
#define LED_MOUSE
Definition: keymap.h:39

+ Here is the call graph for this function: