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_mouse.c
Go to the documentation of this file.
1 #include "led.h"
2 #include "notify.h"
3 #include "profile.h"
4 #include "usb.h"
5 
6 // Compare two light structures, ignore keys
7 static int rgbcmp(const lighting* lhs, const lighting* rhs){
8  return memcmp(lhs->r + LED_MOUSE, rhs->r + LED_MOUSE, N_MOUSE_ZONES) || memcmp(lhs->g + LED_MOUSE, rhs->g + LED_MOUSE, N_MOUSE_ZONES) || memcmp(lhs->b + LED_MOUSE, rhs->b + LED_MOUSE, N_MOUSE_ZONES);
9 }
10 
11 // Return true if all mouse zones are black
12 // Automatically returns false for all devices except M65, because they don't like this packet
13 static int isblack(const usbdevice* kb, const lighting* light){
14  if(!IS_M65(kb))
15  return 0;
16  uchar black[N_MOUSE_ZONES] = { 0 };
17  return !memcmp(light->r + LED_MOUSE, black, sizeof(black)) && !memcmp(light->g + LED_MOUSE, black, sizeof(black)) && !memcmp(light->b + LED_MOUSE, black, sizeof(black));
18 }
19 
20 int updatergb_mouse(usbdevice* kb, int force){
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 }
61 
62 int savergb_mouse(usbdevice* kb, lighting* light, int mode){
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 }
80 
81 int loadrgb_mouse(usbdevice* kb, lighting* light, int mode){
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
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
int savergb_mouse(usbdevice *kb, lighting *light, int mode)
Definition: led_mouse.c:62
int loadrgb_mouse(usbdevice *kb, lighting *light, int mode)
Definition: led_mouse.c:81
usbmode * currentmode
Definition: structures.h:105
#define IS_SCIMITAR(kb)
Definition: usb.h:99
#define IS_M65(kb)
Definition: usb.h:83
#define ckb_err(fmt, args...)
Definition: includes.h:49
int updatergb_mouse(usbdevice *kb, int force)
Definition: led_mouse.c:20
#define IS_SABRE(kb)
Definition: usb.h:93
#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
#define usbrecv(kb, out_msg, in_msg)
usbrecv macro is used to wrap _usbrecv() with debugging information (file and lineno) ...
Definition: usb.h:256
Definitions for using USB interface.
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