20     nanoseconds += timespec->tv_nsec;
 
   21     timespec->tv_sec += nanoseconds / 1000000000;
 
   22     timespec->tv_nsec = nanoseconds % 1000000000;
 
   43     for(
int i = 1; i < 
DEV_MAX; i++){
 
   45         if (mut) pthread_mutex_lock(
devmutex + i);
 
   52     ckb_info(
"Closing root controller\n");
 
   59     printf(
"\n[W] Ignoring signal %d (already shutting down)\n", type);
 
   66     printf(
"\n[I] Caught signal %d\n", type);
 
   71 void localecase(
char* dst, 
size_t length, 
const char* src){
 
   72     char* ldst = dst + length;
 
   88 int main(
int argc, 
char** argv){
 
   95     printf(
"    ckb: Corsair RGB driver %s\n", CKB_VERSION_STR);
 
   97     for(
int i = 1; i < argc; i++){
 
   98         if(!strcmp(argv[i], 
"--help")){
 
  101                         "Usage: ckb-daemon [--gid=<gid>] [--hwload=<always|try|never>] [--nonotify] [--nobind] [--nomouseaccel] [--nonroot]\n" 
  103                         "Usage: ckb-daemon [--gid=<gid>] [--hwload=<always|try|never>] [--nonotify] [--nobind] [--nonroot]\n" 
  106                         "See https://github.com/ccMSC/ckb/blob/master/DAEMON.md for full instructions.\n" 
  108                         "Command-line parameters:\n" 
  110                         "        Restrict access to %s* nodes to users in group <gid>.\n" 
  111                         "        (Ordinarily they are accessible to anyone)\n" 
  112                         "    --hwload=<always|try|never>\n" 
  113                         "        --hwload=always will force loading of stored hardware profiles on compatible devices. May result in long start up times.\n" 
  114                         "        --hwload=try will try to load the profiles, but give up if not immediately successful (default).\n" 
  115                         "        --hwload=never will ignore hardware profiles completely.\n" 
  117                         "        Disables key monitoring/notifications.\n" 
  118                         "        Note that this makes reactive lighting impossible.\n" 
  120                         "        Disables all key rebinding, macros, and notifications. Implies --nonotify.\n" 
  123                         "        Disables mouse acceleration, even if the system preferences enable it.\n" 
  126                         "        Allows running ckb-daemon as a non root user.\n" 
  127                         "        This will almost certainly not work. Use only if you know what you're doing.\n" 
  134     char pidpath[strlen(
devpath) + 6];
 
  135     snprintf(pidpath, 
sizeof(pidpath), 
"%s0/pid", 
devpath);
 
  136     FILE* pidfile = fopen(pidpath, 
"r");
 
  139         fscanf(pidfile, 
"%d", &pid);
 
  144                 ckb_fatal_nofile(
"ckb-daemon is already running (PID %d). Try `killall ckb-daemon`.\n", pid);
 
  145                 ckb_fatal_nofile(
"(If you're certain the process is dead, delete %s and try again)\n", pidpath);
 
  153     for(
int i = 1; i < argc; i++){
 
  154         char* argument = argv[i];
 
  157         if(sscanf(argument, 
"--gid=%u", &newgid) == 1){
 
  161         } 
else if(!strcmp(argument, 
"--nobind")){
 
  165         } 
else if(!strcmp(argument, 
"--nonotify")){
 
  169         } 
else if(sscanf(argument, 
"--hwload=%6s", hwload) == 1){
 
  170             if(!strcmp(hwload, 
"always") || !strcmp(hwload, 
"yes") || !strcmp(hwload, 
"y") || !strcmp(hwload, 
"a")){
 
  173             } 
else if(!strcmp(hwload, 
"tryonce") || !strcmp(hwload, 
"try") || !strcmp(hwload, 
"once") || !strcmp(hwload, 
"t") || !strcmp(hwload, 
"o")){
 
  176             } 
else if(!strcmp(hwload, 
"never") || !strcmp(hwload, 
"none") || !strcmp(hwload, 
"no") || !strcmp(hwload, 
"n")){
 
  180         } 
else if(!strcmp(argument, 
"--nonroot")){
 
  185         else if(!strcmp(argument, 
"--nomouseaccel")){
 
  196             ckb_fatal_nofile(
"ckb-daemon must be run as root. Try `sudo %s`\n", argv[0]);
 
  199             ckb_warn_nofile(
"Warning: not running as root, allowing anyway per command-line parameter...\n");
 
  210     sigfillset(&signals);
 
  211     sigdelset(&signals, SIGTERM);
 
  212     sigdelset(&signals, SIGINT);
 
  213     sigdelset(&signals, SIGQUIT);
 
  214     sigdelset(&signals, SIGUSR1);
 
  216     sigprocmask(SIG_SETMASK, &signals, 0);
 
  220     signal(SIGUSR1, (
void (*)())
restart);
 
  229     ckb_err(
"restart called, running quit without mutex-lock.\n");
 
static void quitWithLock(char mut)
quitWithLock 
 
void sighandler2(int type)
 
int usbmain()
Start the USB main loop. Returns program exit code when finished. 
 
int mkdevpath(usbdevice *kb)
Create a dev path for the keyboard at index. Returns 0 on success. 
 
#define ckb_err(fmt, args...)
 
usbdevice keyboard[9]
remember all usb devices. Needed for closeusb(). 
 
void sighandler(int type)
 
int hwload_mode
hwload_mode = 1 means read hardware once. should be enough 
 
pthread_mutex_t devmutex[9]
Mutex for handling the usbdevice structure. 
 
volatile int reset_stop
brief . 
 
void localecase(char *dst, size_t length, const char *src)
 
long gid
Group ID for the control nodes. -1 to give read/write access to everybody. 
 
void timespec_add(struct timespec *timespec, long nanoseconds)
 
const char *const devpath
 
#define ckb_warn_nofile(fmt, args...)
 
#define ckb_fatal_nofile(fmt, args...)
 
#define ckb_info(fmt, args...)
 
static void quit()
quit Stop working the daemon. function is called if the daemon received a sigterm In this case...
 
int closeusb(usbdevice *kb)
 
void usbkill()
Stop the USB system. 
 
int rmdevpath(usbdevice *kb)
Remove the dev path for the keyboard at index. Returns 0 on success. 
 
int main(int argc, char **argv)
 
#define ckb_info_nofile(fmt, args...)
 
int revertusb(usbdevice *kb)