diff --git a/src/daemon.c b/src/daemon.c index 3fb13c4..f74ee06 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -1,7 +1,5 @@ #include "keyd.h" -#define VKBD_NAME "keyd virtual keyboard" - struct config_ent { struct config config; struct keyboard *kbd; @@ -188,7 +186,7 @@ static void manage_device(struct device *dev) uint8_t flags = 0; struct config_ent *ent; - if (!strcmp(dev->name, VKBD_NAME)) + if (dev->is_virtual) return; if (dev->capabilities & CAP_KEYBOARD) @@ -425,6 +423,7 @@ static int event_handler(struct event *ev) struct keyboard *kbd = ev->dev->data; timeout_kbd = ev->dev->data; switch (ev->devev->type) { + size_t i; case DEV_KEY: dbg("input %s %s", KEY_NAME(ev->devev->code), ev->devev->pressed ? "down" : "up"); @@ -479,6 +478,18 @@ static int event_handler(struct event *ev) vkbd_mouse_scroll(vkbd, ev->devev->x, ev->devev->y); break; } + } else if (ev->dev->is_virtual && ev->devev->type == DEV_LED) { + size_t i; + + /* + * Propagate LED events received by the virtual device from userspace + * to all grabbed devices. + * + * NOTE/TODO: Account for potential layer_indicator interference + */ + for (i = 0; i < device_table_sz; i++) + if (device_table[i].data) + device_set_led(&device_table[i], ev->devev->code, ev->devev->pressed); } break; diff --git a/src/device.c b/src/device.c index a8503a9..e189c78 100644 --- a/src/device.c +++ b/src/device.c @@ -138,6 +138,7 @@ static int device_init(const char *path, struct device *dev) dev->data = NULL; dev->grabbed = 0; + dev->is_virtual = !strcmp(dev->name, VKBD_NAME); return 0; } else { close(fd); @@ -453,6 +454,12 @@ struct device_event *device_read_event(struct device *dev) dbg2("key %s %s", KEY_NAME(devev.code), devev.pressed ? "down" : "up"); + break; + case EV_LED: + devev.type = DEV_LED; + devev.code = ev.code; + devev.pressed = ev.value; + break; default: if (ev.type) diff --git a/src/device.h b/src/device.h index 83b54fe..6a8718b 100644 --- a/src/device.h +++ b/src/device.h @@ -25,6 +25,7 @@ struct device { uint8_t capabilities; uint16_t product_id; uint16_t vendor_id; + uint8_t is_virtual; char name[64]; char path[256]; @@ -42,6 +43,7 @@ struct device { struct device_event { enum { DEV_KEY, + DEV_LED, DEV_MOUSE_MOVE, /* All absolute values are relative to a resolution of 1024x1024. */ diff --git a/src/keyd.h b/src/keyd.h index 8cf63bd..6318939 100644 --- a/src/keyd.h +++ b/src/keyd.h @@ -49,6 +49,7 @@ #define MAX_IPC_MESSAGE_SIZE 4096 #define ARRAY_SIZE(x) (int)(sizeof(x)/sizeof(x[0])) +#define VKBD_NAME "keyd virtual keyboard" enum event_type { EV_DEV_ADD, diff --git a/src/vkbd/uinput.c b/src/vkbd/uinput.c index 715f828..6c5f974 100644 --- a/src/vkbd/uinput.c +++ b/src/vkbd/uinput.c @@ -33,6 +33,7 @@ struct vkbd { static int create_virtual_keyboard(const char *name) { + int i; int ret; size_t code; struct uinput_user_dev udev = {0}; @@ -53,6 +54,11 @@ static int create_virtual_keyboard(const char *name) exit(-1); } + if (ioctl(fd, UI_SET_EVBIT, EV_LED)) { + perror("ioctl set_evbit"); + exit(-1); + } + if (ioctl(fd, UI_SET_EVBIT, EV_SYN)) { perror("ioctl set_evbit"); exit(-1); @@ -67,6 +73,12 @@ static int create_virtual_keyboard(const char *name) } } + for (i = LED_NUML; i <= LED_MISC; i++) + if (ioctl(fd, UI_SET_LEDBIT, i)) { + perror("ioctl set_ledbit"); + exit(-1); + } + if (ioctl(fd, UI_SET_KEYBIT, KEY_ZOOM)) { perror("ioctl set_keybit"); exit(-1);