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)