11 const char *
const devpath = 
"/dev/input/ckb";
 
   13 const char *
const devpath = 
"/var/run/ckb";
 
   17 #define S_GID_READ  (gid >= 0 ? S_CUSTOM_R : S_READ) 
   20     DIR* dir = opendir(path);
 
   24     while((file = readdir(dir)))
 
   26         if(!strcmp(file->d_name, 
".") || !strcmp(file->d_name, 
".."))
 
   28         char path2[FILENAME_MAX];
 
   29         snprintf(path2, FILENAME_MAX, 
"%s/%s", path, file->d_name);
 
   57     char cpath[strlen(
devpath) + 12];
 
   58     snprintf(cpath, 
sizeof(cpath), 
"%s0/connected", 
devpath);
 
   59     FILE* cfile = fopen(cpath, 
"w");
 
   61         ckb_warn(
"Unable to update %s: %s\n", cpath, strerror(errno));
 
   66     for(
int i = 1; i < 
DEV_MAX; i++){
 
   94     char outpath[strlen(
devpath) + 10];
 
   95     snprintf(outpath, 
sizeof(outpath), 
"%s%d/notify%d", 
devpath, index, notify);
 
   96     if(mkfifo(outpath, 
S_GID_READ) != 0 || (kb->
outfifo[notify] = open(outpath, O_RDWR | O_NONBLOCK) + 1) == 0){
 
   98         ckb_warn(
"Unable to create %s: %s\n", outpath, strerror(errno));
 
  119     char outpath[strlen(
devpath) + 10];
 
  120     snprintf(outpath, 
sizeof(outpath), 
"%s%d/notify%d", 
devpath, index, notify);
 
  122     close(kb->
outfifo[notify] - 1);
 
  125     int res = 
remove(outpath);
 
  139     char path[strlen(
devpath) + 2];
 
  140     snprintf(path, 
sizeof(path), 
"%s%d", 
devpath, index);
 
  142         ckb_err(
"Unable to delete %s: %s\n", path, strerror(errno));
 
  146         ckb_err(
"Unable to create %s: %s\n", path, strerror(errno));
 
  157         char vpath[
sizeof(path) + 8];
 
  158         snprintf(vpath, 
sizeof(vpath), 
"%s/version", path);
 
  159         FILE* vfile = fopen(vpath, 
"w");
 
  161             fprintf(vfile, 
"%s\n", CKB_VERSION_STR);
 
  165                 chown(vpath, 0, 
gid);
 
  167             ckb_warn(
"Unable to create %s: %s\n", vpath, strerror(errno));
 
  171         char ppath[
sizeof(path) + 4];
 
  172         snprintf(ppath, 
sizeof(ppath), 
"%s/pid", path);
 
  173         FILE* pfile = fopen(ppath, 
"w");
 
  175             fprintf(pfile, 
"%u\n", getpid());
 
  179                 chown(vpath, 0, 
gid);
 
  181             ckb_warn(
"Unable to create %s: %s\n", ppath, strerror(errno));
 
  186         char inpath[
sizeof(path) + 4];
 
  187         snprintf(inpath, 
sizeof(inpath), 
"%s/cmd", path);
 
  190                 || (kb->
infifo = open(inpath, O_RDWR) + 1) == 0){
 
  192             ckb_err(
"Unable to create %s: %s\n", inpath, strerror(errno));
 
  204         char mpath[
sizeof(path) + 6], spath[
sizeof(path) + 7];
 
  205         snprintf(mpath, 
sizeof(mpath), 
"%s/model", path);
 
  206         snprintf(spath, 
sizeof(spath), 
"%s/serial", path);
 
  207         FILE* mfile = fopen(mpath, 
"w");
 
  209             fputs(kb->
name, mfile);
 
  214                 chown(mpath, 0, 
gid);
 
  216             ckb_warn(
"Unable to create %s: %s\n", mpath, strerror(errno));
 
  219         FILE* sfile = fopen(spath, 
"w");
 
  226                 chown(spath, 0, 
gid);
 
  228             ckb_warn(
"Unable to create %s: %s\n", spath, strerror(errno));
 
  232         char fpath[
sizeof(path) + 9];
 
  233         snprintf(fpath, 
sizeof(fpath), 
"%s/features", path);
 
  234         FILE* ffile = fopen(fpath, 
"w");
 
  238                 fputs(
" monochrome", ffile);
 
  240                 fputs(
" rgb", ffile);
 
  242                 fputs(
" pollrate", ffile);
 
  244                 fputs(
" adjrate", ffile);
 
  246                 fputs(
" bind", ffile);
 
  248                 fputs(
" notify", ffile);
 
  250                 fputs(
" fwversion", ffile);
 
  252                 fputs(
" fwupdate", ffile);
 
  257                 chown(fpath, 0, 
gid);
 
  259             ckb_warn(
"Unable to create %s: %s\n", fpath, strerror(errno));
 
  280         write(kb->
infifo - 1, 
"\n", 1); 
 
  287     char path[strlen(
devpath) + 2];
 
  288     snprintf(path, 
sizeof(path), 
"%s%d", 
devpath, index);
 
  290         ckb_warn(
"Unable to delete %s: %s\n", path, strerror(errno));
 
  294     ckb_info(
"Removed device path %s\n", path);
 
  301     char fwpath[strlen(
devpath) + 12];
 
  302     snprintf(fwpath, 
sizeof(fwpath), 
"%s%d/fwversion", 
devpath, index);
 
  303     FILE* fwfile = fopen(fwpath, 
"w");
 
  310             chown(fwpath, 0, 
gid);
 
  312         ckb_warn(
"Unable to create %s: %s\n", fwpath, strerror(errno));
 
  316     char ppath[strlen(
devpath) + 11];
 
  317     snprintf(ppath, 
sizeof(ppath), 
"%s%d/pollrate", 
devpath, index);
 
  318     FILE* pfile = fopen(ppath, 
"w");
 
  320         fprintf(pfile, 
"%d ms", kb->
pollrate);
 
  325             chown(ppath, 0, 
gid);
 
  327         ckb_warn(
"Unable to create %s: %s\n", fwpath, strerror(errno));
 
  334 #define MAX_BUFFER (1024 * 1024 - 1) 
  344     int buffersize = (*ctx)->buffersize = 4095;
 
  345     (*ctx)->buffer = malloc(buffersize + 1);
 
  355     char* buffer = ctx->
buffer;
 
  358     memcpy(buffer, buffer + leftover, leftoverlen);
 
  360     ssize_t length = read(fd, buffer + leftoverlen, buffersize - leftoverlen);
 
  361     length = (length < 0 ? 0 : length) + leftoverlen;
 
  368     while(length == buffersize){
 
  371         int oldsize = buffersize;
 
  374         buffer = ctx->
buffer = realloc(buffer, buffersize + 1);
 
  375         ssize_t length2 = read(fd, buffer + oldsize, buffersize - oldsize);
 
  382     char* lastline = memrchr(buffer, 
'\n', length);
 
  383     if(lastline == buffer + length - 1){
 
  390         leftover = ctx->
leftover = lastline + 1 - buffer;
 
  391         leftoverlen = ctx->
leftoverlen = length - leftover;
 
  399             ckb_warn(
"Too much input (1MB). Dropping.\n");
 
const char * vendor_str(short vendor)
brief . 
 
unsigned readlines(int fd, readlines_ctx ctx, const char **input)
 
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(). 
 
pthread_mutex_t devmutex[9]
Mutex for handling the usbdevice structure. 
 
int mkfwnode(usbdevice *kb)
Writes a keyboard's firmware version and poll rate to its device node. 
 
long gid
Group ID for the control nodes. -1 to give read/write access to everybody. 
 
void readlines_ctx_init(readlines_ctx *ctx)
 
#define ckb_warn(fmt, args...)
 
const char *const devpath
 
#define ckb_info(fmt, args...)
 
#define INDEX_OF(entry, array)
 
const char * product_str(short product)
brief . 
 
int _mknotifynode(usbdevice *kb, int notify)
 
#define HAS_FEATURES(kb, feat)
 
int rmnotifynode(usbdevice *kb, int notify)
Removes a notification node for the specified keyboard. 
 
int mknotifynode(usbdevice *kb, int notify)
Creates a notification node for the specified keyboard. 
 
static int _mkdevpath(usbdevice *kb)
 
void readlines_ctx_free(readlines_ctx ctx)
 
int rmdevpath(usbdevice *kb)
Remove the dev path for the keyboard at index. Returns 0 on success. 
 
void _updateconnected()
_updateconnected Update the list of connected devices. 
 
int rm_recursive(const char *path)
 
void updateconnected()
Update the list of connected devices. 
 
int _rmnotifynode(usbdevice *kb, int notify)