eloop: move prefix to "ev_" instead of "kmscon_"
[platform/upstream/kmscon.git] / src / input.c
1 /*
2  * kmscon - udev input hotplug and evdev handling
3  *
4  * Copyright (c) 2011 Ran Benita <ran234@gmail.com>
5  *
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:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
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.
24  */
25
26 /*
27  * The main object kmscon_input discovers and monitors input devices, and
28  * adds/removes them accordingly from the devices linked list.
29  *
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.
33  *
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.
40  */
41
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <libudev.h>
45 #include <linux/input.h>
46 #include <stdbool.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <unistd.h>
50
51 #include "eloop.h"
52 #include "input.h"
53 #include "kbd.h"
54 #include "log.h"
55
56 /* How many longs are needed to hold \n bits. */
57 #define NLONGS(n) (((n) + LONG_BIT - 1) / LONG_BIT)
58
59 enum input_state {
60         INPUT_ASLEEP,
61         INPUT_AWAKE,
62 };
63
64 /* See probe_device_features(). */
65 enum device_feature {
66         FEATURE_HAS_KEYS = 0x01,
67         FEATURE_HAS_LEDS = 0x02,
68 };
69
70 struct kmscon_input_device {
71         size_t ref;
72         struct kmscon_input_device *next;
73         struct kmscon_input *input;
74
75         unsigned int features;
76
77         int rfd;
78         char *devnode;
79         struct ev_fd *fd;
80
81         struct kmscon_kbd *kbd;
82 };
83
84 struct kmscon_input {
85         size_t ref;
86         enum input_state state;
87         struct kmscon_input_device *devices;
88
89         struct ev_eloop *eloop;
90         kmscon_input_cb cb;
91         void *data;
92
93         struct udev *udev;
94         struct udev_monitor *monitor;
95         struct ev_fd *monitor_fd;
96
97         struct kmscon_kbd_desc *desc;
98 };
99
100 static void remove_device(struct kmscon_input *input, const char *node);
101
102 static void notify_key(struct kmscon_input_device *device,
103                                 uint16_t type, uint16_t code, int32_t value)
104 {
105         int ret;
106         struct kmscon_input_event ev;
107         struct kmscon_input *input;
108
109         if (type != EV_KEY)
110                 return;
111
112         input = device->input;
113         ret = kmscon_kbd_process_key(device->kbd, value, code, &ev);
114
115         if (ret && ret != -ENOKEY)
116                 return;
117
118         if (ret != -ENOKEY && input->cb)
119                 input->cb(input, &ev, input->data);
120 }
121
122 static void device_data_arrived(struct ev_fd *fd, int mask, void *data)
123 {
124         int i;
125         ssize_t len, n;
126         struct kmscon_input_device *device = data;
127         struct kmscon_input *input = device->input;
128         struct input_event ev[16];
129
130         len = sizeof(ev);
131         while (len == sizeof(ev)) {
132                 len = read(device->rfd, &ev, sizeof(ev));
133                 if (len < 0) {
134                         if (errno == EWOULDBLOCK)
135                                 break;
136
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");
145                 } else {
146                         n = len / sizeof(*ev);
147                         for (i = 0; i < n; i++)
148                                 notify_key(device, ev[i].type, ev[i].code,
149                                                                 ev[i].value);
150                 }
151         }
152 }
153
154 int kmscon_input_device_wake_up(struct kmscon_input_device *device)
155 {
156         int ret;
157         unsigned long ledbits[NLONGS(LED_CNT)] = { 0 };
158
159         if (!device || !device->input || !device->input->eloop)
160                 return -EINVAL;
161
162         if (device->fd)
163                 return 0;
164
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);
169                 return -errno;
170         }
171
172         if (device->features & FEATURE_HAS_KEYS) {
173                 if (device->features & FEATURE_HAS_LEDS) {
174                         errno = 0;
175                         ioctl(device->rfd, EVIOCGLED(sizeof(ledbits)),
176                                                                 &ledbits);
177                         if (errno)
178                                 log_warn("input: cannot discover state of LEDs (%s): %m\n",
179                                                         device->devnode);
180                 }
181
182                 /* rediscover the keyboard state if sth changed during sleep */
183                 kmscon_kbd_reset(device->kbd, ledbits);
184
185                 ret = ev_eloop_new_fd(device->input->eloop, &device->fd,
186                                                 device->rfd, EV_READABLE,
187                                                 device_data_arrived, device);
188                 if (ret) {
189                         close(device->rfd);
190                         device->rfd = -1;
191                         return ret;
192                 }
193         }
194
195         return 0;
196 }
197
198 void kmscon_input_device_sleep(struct kmscon_input_device *device)
199 {
200         if (!device)
201                 return;
202
203         if (device->rfd < 0)
204                 return;
205
206         if (device->features & FEATURE_HAS_KEYS)
207                 ev_eloop_rm_fd(device->fd);
208
209         device->fd = NULL;
210         close(device->rfd);
211         device->rfd = -1;
212 }
213
214 static int kmscon_input_device_new(struct kmscon_input_device **out,
215                         struct kmscon_input *input, const char *devnode,
216                                                 unsigned int features)
217 {
218         int ret;
219         struct kmscon_input_device *device;
220
221         if (!out || !input)
222                 return -EINVAL;
223
224         log_debug("input: new input device %s\n", devnode);
225
226         device = malloc(sizeof(*device));
227         if (!device)
228                 return -ENOMEM;
229
230         memset(device, 0, sizeof(*device));
231         device->ref = 1;
232
233         device->devnode = strdup(devnode);
234         if (!device->devnode) {
235                 free(device);
236                 return -ENOMEM;
237         }
238
239         ret = kmscon_kbd_new(&device->kbd, input->desc);
240         if (ret) {
241                 free(device->devnode);
242                 free(device);
243                 return ret;
244         }
245
246         device->input = input;
247         device->features = features;
248         device->rfd = -1;
249
250         *out = device;
251         return 0;
252 }
253
254 /* static void kmscon_input_device_ref(struct kmscon_input_device *device) */
255 /* { */
256 /*      if (!device) */
257 /*              return; */
258
259 /*      ++device->ref; */
260 /* } */
261
262 static void kmscon_input_device_unref(struct kmscon_input_device *device)
263 {
264         if (!device || !device->ref)
265                 return;
266
267         if (--device->ref)
268                 return;
269
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);
274         free(device);
275 }
276
277 int kmscon_input_new(struct kmscon_input **out)
278 {
279         int ret;
280         struct kmscon_input *input;
281         static const char *layout, *variant, *options;
282
283         if (!out)
284                 return -EINVAL;
285
286         input = malloc(sizeof(*input));
287         if (!input)
288                 return -ENOMEM;
289
290         log_debug("input: creating input object\n");
291
292         memset(input, 0, sizeof(*input));
293         input->ref = 1;
294         input->state = INPUT_ASLEEP;
295
296         /* TODO: Make properly configurable */
297         layout = getenv("KMSCON_XKB_LAYOUT") ?: "us";
298         variant = getenv("KMSCON_XKB_VARIANT") ?: "";
299         options = getenv("KMSCON_XKB_OPTIONS") ?: "";
300
301         ret = kmscon_kbd_desc_new(&input->desc, layout, variant, options);
302         if (ret) {
303                 log_warn("input: cannot create xkb description\n");
304                 goto err_free;
305         }
306
307         input->udev = udev_new();
308         if (!input->udev) {
309                 log_warn("input: cannot create udev object\n");
310                 ret = -EFAULT;
311                 goto err_xkb;
312         }
313
314         input->monitor = udev_monitor_new_from_netlink(input->udev, "udev");
315         if (!input->monitor) {
316                 log_warn("input: cannot create udev monitor\n");
317                 ret = -EFAULT;
318                 goto err_udev;
319         }
320
321         ret = udev_monitor_filter_add_match_subsystem_devtype(input->monitor,
322                                                                 "input", NULL);
323         if (ret) {
324                 log_warn("input: cannot add udev filter\n");
325                 ret = -EFAULT;
326                 goto err_monitor;
327         }
328
329         ret = udev_monitor_enable_receiving(input->monitor);
330         if (ret) {
331                 log_warn("input: cannot start udev monitor\n");
332                 ret = -EFAULT;
333                 goto err_monitor;
334         }
335
336         *out = input;
337         return 0;
338
339 err_monitor:
340         udev_monitor_unref(input->monitor);
341 err_udev:
342         udev_unref(input->udev);
343 err_xkb:
344         kmscon_kbd_desc_unref(input->desc);
345 err_free:
346         free(input);
347         return ret;
348 }
349
350 void kmscon_input_ref(struct kmscon_input *input)
351 {
352         if (!input)
353                 return;
354
355         ++input->ref;
356 }
357
358 void kmscon_input_unref(struct kmscon_input *input)
359 {
360         if (!input || !input->ref)
361                 return;
362
363         if (--input->ref)
364                 return;
365
366         kmscon_input_disconnect_eloop(input);
367         udev_monitor_unref(input->monitor);
368         udev_unref(input->udev);
369         kmscon_kbd_desc_unref(input->desc);
370         free(input);
371         log_debug("input: destroying input object\n");
372 }
373
374 /*
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.
377  * */
378 static unsigned int probe_device_features(const char *node)
379 {
380         int i, fd;
381         unsigned int features = 0;
382         unsigned long evbits[NLONGS(EV_CNT)] = { 0 };
383         unsigned long keybits[NLONGS(KEY_CNT)] = { 0 };
384
385         fd = open(node, O_NONBLOCK | O_CLOEXEC);
386         if (fd < 0)
387                 return 0;
388
389         /* Which types of input events the device supports. */
390         errno = 0;
391         ioctl(fd, EVIOCGBIT(0, sizeof(evbits)), evbits);
392         if (errno)
393                 goto err_ioctl;
394
395         /* Device supports keys/buttons. */
396         if (kmscon_evdev_bit_is_set(evbits, EV_KEY)) {
397                 errno = 0;
398                 ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
399                 if (errno)
400                         goto err_ioctl;
401
402                 /*
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.
406                  */
407                 for (i = KEY_RESERVED; i <= KEY_MIN_INTERESTING; i++) {
408                         if (kmscon_evdev_bit_is_set(keybits, i)) {
409                                 features |= FEATURE_HAS_KEYS;
410                                 break;
411                         }
412                 }
413         }
414
415         if (kmscon_evdev_bit_is_set(evbits, EV_LED))
416                 features |= FEATURE_HAS_LEDS;
417
418         close(fd);
419         return features;
420
421 err_ioctl:
422         if (errno != ENOTTY)
423                 log_warn("input: cannot probe features of device (%s): %m\n",
424                                                                         node);
425         close(fd);
426         return 0;
427 }
428
429 static void add_device(struct kmscon_input *input,
430                                         struct udev_device *udev_device)
431 {
432         int ret;
433         struct kmscon_input_device *device;
434         const char *node;
435         unsigned int features;
436
437         if (!input || !udev_device)
438                 return;
439
440         node = udev_device_get_devnode(udev_device);
441         if (!node)
442                 return;
443
444         features = probe_device_features(node);
445         if (!(features & FEATURE_HAS_KEYS)) {
446                 log_debug("input: ignoring non-useful device %s\n", node);
447                 return;
448         }
449
450         ret = kmscon_input_device_new(&device, input, node, features);
451         if (ret) {
452                 log_warn("input: cannot create input device for %s\n",
453                                                                         node);
454                 return;
455         }
456
457         if (input->state == INPUT_AWAKE) {
458                 ret = kmscon_input_device_wake_up(device);
459                 if (ret) {
460                         log_warn("input: cannot wake up new device %s\n",
461                                                                         node);
462                         kmscon_input_device_unref(device);
463                         return;
464                 }
465         }
466
467         device->next = input->devices;
468         input->devices = device;
469         log_debug("input: added device %s (features: %#x)\n", node, features);
470 }
471
472 static void remove_device(struct kmscon_input *input, const char *node)
473 {
474         struct kmscon_input_device *iter, *prev;
475
476         if (!input || !node || !input->devices)
477                 return;
478
479         iter = input->devices;
480         prev = NULL;
481
482         while (iter) {
483                 if (!strcmp(iter->devnode, node)) {
484                         if (prev == NULL)
485                                 input->devices = iter->next;
486                         else
487                                 prev->next = iter->next;
488
489                         kmscon_input_device_unref(iter);
490                         log_debug("input: removed device %s\n", node);
491                         break;
492                 }
493
494                 prev = iter;
495                 iter = iter->next;
496         }
497 }
498
499 static void remove_device_udev(struct kmscon_input *input,
500                                         struct udev_device *udev_device)
501 {
502         const char *node;
503
504         if (!udev_device)
505                 return;
506
507         node = udev_device_get_devnode(udev_device);
508         if (!node)
509                 return;
510
511         remove_device(input, node);
512 }
513
514 static void device_changed(struct ev_fd *fd, int mask, void *data)
515 {
516         struct kmscon_input *input = data;
517         struct udev_device *udev_device;
518         const char *action;
519
520         udev_device = udev_monitor_receive_device(input->monitor);
521         if (!udev_device)
522                 return;
523
524         action = udev_device_get_action(udev_device);
525         if (!action) {
526                 log_warn("input: cannot get action field of new device\n");
527                 goto err_device;
528         }
529
530         if (!strcmp(action, "add"))
531                 add_device(input, udev_device);
532         else if (!strcmp(action, "remove"))
533                 remove_device_udev(input, udev_device);
534
535 err_device:
536         udev_device_unref(udev_device);
537 }
538
539 static void add_initial_devices(struct kmscon_input *input)
540 {
541         int ret;
542         struct udev_enumerate *e;
543         struct udev_list_entry *first;
544         struct udev_list_entry *item;
545         struct udev_device *udev_device;
546         const char *syspath;
547
548         e = udev_enumerate_new(input->udev);
549         if (!e) {
550                 log_warn("input: cannot create udev enumeration\n");
551                 return;
552         }
553
554         ret = udev_enumerate_add_match_subsystem(e, "input");
555         if (ret) {
556                 log_warn("input: cannot add match to udev enumeration\n");
557                 goto err_enum;
558         }
559
560         ret = udev_enumerate_scan_devices(e);
561         if (ret) {
562                 log_warn("input: cannot scan udev enumeration\n");
563                 goto err_enum;
564         }
565
566         first = udev_enumerate_get_list_entry(e);
567         udev_list_entry_foreach(item, first) {
568                 syspath = udev_list_entry_get_name(item);
569                 if (!syspath)
570                         continue;
571
572                 udev_device = udev_device_new_from_syspath(input->udev, syspath);
573                 if (!udev_device) {
574                         log_warn("input: cannot create device "
575                                                         "from udev path\n");
576                         continue;
577                 }
578
579                 add_device(input, udev_device);
580                 udev_device_unref(udev_device);
581         }
582
583 err_enum:
584         udev_enumerate_unref(e);
585 }
586
587 int kmscon_input_connect_eloop(struct kmscon_input *input,
588                 struct ev_eloop *eloop, kmscon_input_cb cb, void *data)
589 {
590         int ret;
591         int fd;
592
593         if (!input || !eloop || !cb)
594                 return -EINVAL;
595
596         if (input->eloop)
597                 return -EALREADY;
598
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);
602         if (ret)
603                 return ret;
604
605         ev_eloop_ref(eloop);
606         input->eloop = eloop;
607         input->cb = cb;
608         input->data = data;
609
610         add_initial_devices(input);
611
612         return 0;
613 }
614
615 void kmscon_input_disconnect_eloop(struct kmscon_input *input)
616 {
617         struct kmscon_input_device *tmp;
618
619         if (!input || !input->eloop)
620                 return;
621
622         while (input->devices) {
623                 tmp = input->devices;
624                 input->devices = tmp->next;
625                 kmscon_input_device_unref(tmp);
626         }
627
628         ev_eloop_rm_fd(input->monitor_fd);
629         input->monitor_fd = NULL;
630         ev_eloop_unref(input->eloop);
631         input->eloop = NULL;
632         input->cb = NULL;
633         input->data = NULL;
634 }
635
636 void kmscon_input_sleep(struct kmscon_input *input)
637 {
638         struct kmscon_input_device *iter;
639
640         if (!input)
641                 return;
642
643         for (iter = input->devices; iter; iter = iter->next)
644                 kmscon_input_device_sleep(iter);
645
646         input->state = INPUT_ASLEEP;
647 }
648
649 void kmscon_input_wake_up(struct kmscon_input *input)
650 {
651         struct kmscon_input_device *iter, *prev, *tmp;
652         int ret;
653
654         if (!input)
655                 return;
656
657         prev = NULL;
658         iter = input->devices;
659
660         while (iter) {
661                 ret = kmscon_input_device_wake_up(iter);
662                 if (ret) {
663                         if (!prev)
664                                 input->devices = iter->next;
665                         else
666                                 prev->next = iter->next;
667
668                         tmp = iter;
669                         iter = iter->next;
670
671                         log_warn("input: device %s does not wake up, "
672                                         "removing device\n", tmp->devnode);
673                         kmscon_input_device_unref(tmp);
674                 } else {
675                         prev = iter;
676                         iter = iter->next;
677                 }
678         }
679
680         input->state = INPUT_AWAKE;
681 }
682
683 bool kmscon_input_is_asleep(struct kmscon_input *input)
684 {
685         if (!input)
686                 return false;
687
688         return input->state == INPUT_ASLEEP;
689 }