2 * kmscon - udev input hotplug and evdev handling
4 * Copyright (c) 2011 Ran Benita <ran234@gmail.com>
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files
8 * (the "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * The main object kmscon_input discovers and monitors input devices, and
28 * adds/removes them accordingly from the devices linked list.
30 * The udev monitor keeps running even while the object is in INPUT_ASLEEP.
31 * We do this because we'll either lose track of the devices, or otherwise
32 * have to re-scan the devices at every wakeup.
34 * The kmscon_input_device objects hold the file descriptors for their device
35 * nodes. All events go through the input-object callback; there is currently
36 * no "routing" or any differentiation between them. When the input is put to
37 * sleep, all fd's are closed. When woken up, they are opened. There should be
38 * not spurious events delivered. The initial state depends on the
39 * kmscon_input's state.
45 #include <linux/input.h>
56 /* How many longs are needed to hold \n bits. */
57 #define NLONGS(n) (((n) + LONG_BIT - 1) / LONG_BIT)
64 /* See probe_device_features(). */
66 FEATURE_HAS_KEYS = 0x01,
67 FEATURE_HAS_LEDS = 0x02,
70 struct kmscon_input_device {
72 struct kmscon_input_device *next;
73 struct kmscon_input *input;
75 unsigned int features;
81 struct kmscon_kbd *kbd;
86 enum input_state state;
87 struct kmscon_input_device *devices;
89 struct ev_eloop *eloop;
94 struct udev_monitor *monitor;
95 struct ev_fd *monitor_fd;
97 struct kmscon_kbd_desc *desc;
100 static void remove_device(struct kmscon_input *input, const char *node);
102 static void notify_key(struct kmscon_input_device *device,
103 uint16_t type, uint16_t code, int32_t value)
106 struct kmscon_input_event ev;
107 struct kmscon_input *input;
112 input = device->input;
113 ret = kmscon_kbd_process_key(device->kbd, value, code, &ev);
115 if (ret && ret != -ENOKEY)
118 if (ret != -ENOKEY && input->cb)
119 input->cb(input, &ev, input->data);
122 static void device_data_arrived(struct ev_fd *fd, int mask, void *data)
126 struct kmscon_input_device *device = data;
127 struct kmscon_input *input = device->input;
128 struct input_event ev[16];
131 while (len == sizeof(ev)) {
132 len = read(device->rfd, &ev, sizeof(ev));
134 if (errno == EWOULDBLOCK)
137 log_warn("input: reading device %s failed %d\n",
138 device->devnode, errno);
139 remove_device(input, device->devnode);
140 } else if (len == 0) {
141 log_debug("input: EOF device %s\n", device->devnode);
142 remove_device(input, device->devnode);
143 } else if (len % sizeof(*ev)) {
144 log_warn("input: read invalid input_event\n");
146 n = len / sizeof(*ev);
147 for (i = 0; i < n; i++)
148 notify_key(device, ev[i].type, ev[i].code,
154 int kmscon_input_device_wake_up(struct kmscon_input_device *device)
157 unsigned long ledbits[NLONGS(LED_CNT)] = { 0 };
159 if (!device || !device->input || !device->input->eloop)
165 device->rfd = open(device->devnode, O_CLOEXEC | O_NONBLOCK | O_RDONLY);
166 if (device->rfd < 0) {
167 log_warn("input: cannot open input device %s: %d\n",
168 device->devnode, errno);
172 if (device->features & FEATURE_HAS_KEYS) {
173 if (device->features & FEATURE_HAS_LEDS) {
175 ioctl(device->rfd, EVIOCGLED(sizeof(ledbits)),
178 log_warn("input: cannot discover state of LEDs (%s): %m\n",
182 /* rediscover the keyboard state if sth changed during sleep */
183 kmscon_kbd_reset(device->kbd, ledbits);
185 ret = ev_eloop_new_fd(device->input->eloop, &device->fd,
186 device->rfd, EV_READABLE,
187 device_data_arrived, device);
198 void kmscon_input_device_sleep(struct kmscon_input_device *device)
206 if (device->features & FEATURE_HAS_KEYS)
207 ev_eloop_rm_fd(device->fd);
214 static int kmscon_input_device_new(struct kmscon_input_device **out,
215 struct kmscon_input *input, const char *devnode,
216 unsigned int features)
219 struct kmscon_input_device *device;
224 log_debug("input: new input device %s\n", devnode);
226 device = malloc(sizeof(*device));
230 memset(device, 0, sizeof(*device));
233 device->devnode = strdup(devnode);
234 if (!device->devnode) {
239 ret = kmscon_kbd_new(&device->kbd, input->desc);
241 free(device->devnode);
246 device->input = input;
247 device->features = features;
254 /* static void kmscon_input_device_ref(struct kmscon_input_device *device) */
262 static void kmscon_input_device_unref(struct kmscon_input_device *device)
264 if (!device || !device->ref)
270 kmscon_input_device_sleep(device);
271 kmscon_kbd_unref(device->kbd);
272 log_debug("input: destroying input device %s\n", device->devnode);
273 free(device->devnode);
277 int kmscon_input_new(struct kmscon_input **out)
280 struct kmscon_input *input;
281 static const char *layout, *variant, *options;
286 input = malloc(sizeof(*input));
290 log_debug("input: creating input object\n");
292 memset(input, 0, sizeof(*input));
294 input->state = INPUT_ASLEEP;
296 /* TODO: Make properly configurable */
297 layout = getenv("KMSCON_XKB_LAYOUT") ?: "us";
298 variant = getenv("KMSCON_XKB_VARIANT") ?: "";
299 options = getenv("KMSCON_XKB_OPTIONS") ?: "";
301 ret = kmscon_kbd_desc_new(&input->desc, layout, variant, options);
303 log_warn("input: cannot create xkb description\n");
307 input->udev = udev_new();
309 log_warn("input: cannot create udev object\n");
314 input->monitor = udev_monitor_new_from_netlink(input->udev, "udev");
315 if (!input->monitor) {
316 log_warn("input: cannot create udev monitor\n");
321 ret = udev_monitor_filter_add_match_subsystem_devtype(input->monitor,
324 log_warn("input: cannot add udev filter\n");
329 ret = udev_monitor_enable_receiving(input->monitor);
331 log_warn("input: cannot start udev monitor\n");
340 udev_monitor_unref(input->monitor);
342 udev_unref(input->udev);
344 kmscon_kbd_desc_unref(input->desc);
350 void kmscon_input_ref(struct kmscon_input *input)
358 void kmscon_input_unref(struct kmscon_input *input)
360 if (!input || !input->ref)
366 kmscon_input_disconnect_eloop(input);
367 udev_monitor_unref(input->monitor);
368 udev_unref(input->udev);
369 kmscon_kbd_desc_unref(input->desc);
371 log_debug("input: destroying input object\n");
375 * See if the device has anything useful to offer.
376 * We go over the desired features and return a mask of enum device_feature's.
378 static unsigned int probe_device_features(const char *node)
381 unsigned int features = 0;
382 unsigned long evbits[NLONGS(EV_CNT)] = { 0 };
383 unsigned long keybits[NLONGS(KEY_CNT)] = { 0 };
385 fd = open(node, O_NONBLOCK | O_CLOEXEC);
389 /* Which types of input events the device supports. */
391 ioctl(fd, EVIOCGBIT(0, sizeof(evbits)), evbits);
395 /* Device supports keys/buttons. */
396 if (kmscon_evdev_bit_is_set(evbits, EV_KEY)) {
398 ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
403 * If the device support any of the normal keyboard keys, we
404 * take it. Even if the keys are not ordinary they can be
405 * mapped to anything by the keyboard backend.
407 for (i = KEY_RESERVED; i <= KEY_MIN_INTERESTING; i++) {
408 if (kmscon_evdev_bit_is_set(keybits, i)) {
409 features |= FEATURE_HAS_KEYS;
415 if (kmscon_evdev_bit_is_set(evbits, EV_LED))
416 features |= FEATURE_HAS_LEDS;
423 log_warn("input: cannot probe features of device (%s): %m\n",
429 static void add_device(struct kmscon_input *input,
430 struct udev_device *udev_device)
433 struct kmscon_input_device *device;
435 unsigned int features;
437 if (!input || !udev_device)
440 node = udev_device_get_devnode(udev_device);
444 features = probe_device_features(node);
445 if (!(features & FEATURE_HAS_KEYS)) {
446 log_debug("input: ignoring non-useful device %s\n", node);
450 ret = kmscon_input_device_new(&device, input, node, features);
452 log_warn("input: cannot create input device for %s\n",
457 if (input->state == INPUT_AWAKE) {
458 ret = kmscon_input_device_wake_up(device);
460 log_warn("input: cannot wake up new device %s\n",
462 kmscon_input_device_unref(device);
467 device->next = input->devices;
468 input->devices = device;
469 log_debug("input: added device %s (features: %#x)\n", node, features);
472 static void remove_device(struct kmscon_input *input, const char *node)
474 struct kmscon_input_device *iter, *prev;
476 if (!input || !node || !input->devices)
479 iter = input->devices;
483 if (!strcmp(iter->devnode, node)) {
485 input->devices = iter->next;
487 prev->next = iter->next;
489 kmscon_input_device_unref(iter);
490 log_debug("input: removed device %s\n", node);
499 static void remove_device_udev(struct kmscon_input *input,
500 struct udev_device *udev_device)
507 node = udev_device_get_devnode(udev_device);
511 remove_device(input, node);
514 static void device_changed(struct ev_fd *fd, int mask, void *data)
516 struct kmscon_input *input = data;
517 struct udev_device *udev_device;
520 udev_device = udev_monitor_receive_device(input->monitor);
524 action = udev_device_get_action(udev_device);
526 log_warn("input: cannot get action field of new device\n");
530 if (!strcmp(action, "add"))
531 add_device(input, udev_device);
532 else if (!strcmp(action, "remove"))
533 remove_device_udev(input, udev_device);
536 udev_device_unref(udev_device);
539 static void add_initial_devices(struct kmscon_input *input)
542 struct udev_enumerate *e;
543 struct udev_list_entry *first;
544 struct udev_list_entry *item;
545 struct udev_device *udev_device;
548 e = udev_enumerate_new(input->udev);
550 log_warn("input: cannot create udev enumeration\n");
554 ret = udev_enumerate_add_match_subsystem(e, "input");
556 log_warn("input: cannot add match to udev enumeration\n");
560 ret = udev_enumerate_scan_devices(e);
562 log_warn("input: cannot scan udev enumeration\n");
566 first = udev_enumerate_get_list_entry(e);
567 udev_list_entry_foreach(item, first) {
568 syspath = udev_list_entry_get_name(item);
572 udev_device = udev_device_new_from_syspath(input->udev, syspath);
574 log_warn("input: cannot create device "
579 add_device(input, udev_device);
580 udev_device_unref(udev_device);
584 udev_enumerate_unref(e);
587 int kmscon_input_connect_eloop(struct kmscon_input *input,
588 struct ev_eloop *eloop, kmscon_input_cb cb, void *data)
593 if (!input || !eloop || !cb)
599 fd = udev_monitor_get_fd(input->monitor);
600 ret = ev_eloop_new_fd(eloop, &input->monitor_fd, fd,
601 EV_READABLE, device_changed, input);
606 input->eloop = eloop;
610 add_initial_devices(input);
615 void kmscon_input_disconnect_eloop(struct kmscon_input *input)
617 struct kmscon_input_device *tmp;
619 if (!input || !input->eloop)
622 while (input->devices) {
623 tmp = input->devices;
624 input->devices = tmp->next;
625 kmscon_input_device_unref(tmp);
628 ev_eloop_rm_fd(input->monitor_fd);
629 input->monitor_fd = NULL;
630 ev_eloop_unref(input->eloop);
636 void kmscon_input_sleep(struct kmscon_input *input)
638 struct kmscon_input_device *iter;
643 for (iter = input->devices; iter; iter = iter->next)
644 kmscon_input_device_sleep(iter);
646 input->state = INPUT_ASLEEP;
649 void kmscon_input_wake_up(struct kmscon_input *input)
651 struct kmscon_input_device *iter, *prev, *tmp;
658 iter = input->devices;
661 ret = kmscon_input_device_wake_up(iter);
664 input->devices = iter->next;
666 prev->next = iter->next;
671 log_warn("input: device %s does not wake up, "
672 "removing device\n", tmp->devnode);
673 kmscon_input_device_unref(tmp);
680 input->state = INPUT_AWAKE;
683 bool kmscon_input_is_asleep(struct kmscon_input *input)
688 return input->state == INPUT_ASLEEP;