shl: move log.[ch] to shl_log.[ch]
[platform/upstream/kmscon.git] / src / uterm_input.c
1 /*
2  * uterm - Linux User-Space Terminal
3  *
4  * Copyright (c) 2011 Ran Benita <ran234@gmail.com>
5  * Copyright (c) 2011-2012 David Herrmann <dh.herrmann@googlemail.com>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files
9  * (the "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included
16  * in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26
27 /*
28  * Input Devices
29  */
30
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <limits.h>
34 #include <linux/input.h>
35 #include <stdbool.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unistd.h>
39 #include "eloop.h"
40 #include "shl_dlist.h"
41 #include "shl_hook.h"
42 #include "shl_log.h"
43 #include "shl_misc.h"
44 #include "uterm_input.h"
45 #include "uterm_input_internal.h"
46
47 #define LOG_SUBSYSTEM "input"
48
49 /* How many longs are needed to hold \n bits. */
50 #define NLONGS(n) (((n) + LONG_BIT - 1) / LONG_BIT)
51
52 static void input_free_dev(struct uterm_input_dev *dev);
53
54 static void notify_key(struct uterm_input_dev *dev,
55                         uint16_t type,
56                         uint16_t code,
57                         int32_t value)
58 {
59         if (type != EV_KEY)
60                 return;
61
62         uxkb_dev_process(dev, value, code);
63 }
64
65 static void input_data_dev(struct ev_fd *fd, int mask, void *data)
66 {
67         struct uterm_input_dev *dev = data;
68         struct input_event ev[16];
69         ssize_t len, n;
70         int i;
71
72         if (mask & (EV_HUP | EV_ERR)) {
73                 log_debug("EOF on %s", dev->node);
74                 input_free_dev(dev);
75                 return;
76         }
77
78         len = sizeof(ev);
79         while (len == sizeof(ev)) {
80                 len = read(dev->rfd, &ev, sizeof(ev));
81                 if (len < 0) {
82                         if (errno == EWOULDBLOCK)
83                                 break;
84                         log_warn("reading from %s failed (%d): %m",
85                                                 dev->node, errno);
86                         input_free_dev(dev);
87                 } else if (len == 0) {
88                         log_debug("EOF on %s", dev->node);
89                         input_free_dev(dev);
90                 } else if (len % sizeof(*ev)) {
91                         log_warn("invalid input_event on %s", dev->node);
92                 } else {
93                         n = len / sizeof(*ev);
94                         for (i = 0; i < n; i++)
95                                 notify_key(dev, ev[i].type, ev[i].code,
96                                                                 ev[i].value);
97                 }
98         }
99 }
100
101 static int input_wake_up_dev(struct uterm_input_dev *dev)
102 {
103         int ret;
104
105         if (dev->rfd >= 0)
106                 return 0;
107
108         dev->rfd = open(dev->node, O_CLOEXEC | O_NONBLOCK | O_RDWR);
109         if (dev->rfd < 0) {
110                 log_warn("cannot open device %s (%d): %m", dev->node, errno);
111                 return -EFAULT;
112         }
113
114         uxkb_dev_wake_up(dev);
115
116         ret = ev_eloop_new_fd(dev->input->eloop, &dev->fd, dev->rfd,
117                               EV_READABLE, input_data_dev, dev);
118         if (ret) {
119                 close(dev->rfd);
120                 dev->rfd = -1;
121                 return ret;
122         }
123
124         return 0;
125 }
126
127 static void input_sleep_dev(struct uterm_input_dev *dev)
128 {
129         if (dev->rfd < 0)
130                 return;
131
132         uxkb_dev_sleep(dev);
133
134         dev->repeating = false;
135         ev_timer_update(dev->repeat_timer, NULL);
136         ev_eloop_rm_fd(dev->fd);
137         dev->fd = NULL;
138         close(dev->rfd);
139         dev->rfd = -1;
140 }
141
142 static void input_new_dev(struct uterm_input *input,
143                                 const char *node,
144                                 unsigned int capabilities)
145 {
146         struct uterm_input_dev *dev;
147         int ret;
148
149         dev = malloc(sizeof(*dev));
150         if (!dev)
151                 return;
152         memset(dev, 0, sizeof(*dev));
153         dev->input = input;
154         dev->rfd = -1;
155         dev->capabilities = capabilities;
156
157         dev->node = strdup(node);
158         if (!dev->node)
159                 goto err_free;
160
161         dev->num_syms = 1;
162         dev->event.keysyms = malloc(sizeof(uint32_t) * dev->num_syms);
163         if (!dev->event.keysyms)
164                 goto err_node;
165         dev->event.codepoints = malloc(sizeof(uint32_t) * dev->num_syms);
166         if (!dev->event.codepoints)
167                 goto err_syms;
168         dev->repeat_event.keysyms = malloc(sizeof(uint32_t) * dev->num_syms);
169         if (!dev->repeat_event.keysyms)
170                 goto err_codepoints;
171         dev->repeat_event.codepoints = malloc(sizeof(uint32_t) * dev->num_syms);
172         if (!dev->repeat_event.codepoints)
173                 goto err_rsyms;
174
175         ret = uxkb_dev_init(dev);
176         if (ret)
177                 goto err_rcodepoints;
178
179         if (input->awake > 0) {
180                 ret = input_wake_up_dev(dev);
181                 if (ret)
182                         goto err_kbd;
183         }
184
185         log_debug("new device %s", node);
186         shl_dlist_link(&input->devices, &dev->list);
187         return;
188
189 err_kbd:
190         uxkb_dev_destroy(dev);
191 err_rcodepoints:
192         free(dev->repeat_event.codepoints);
193 err_rsyms:
194         free(dev->repeat_event.keysyms);
195 err_codepoints:
196         free(dev->event.codepoints);
197 err_syms:
198         free(dev->event.keysyms);
199 err_node:
200         free(dev->node);
201 err_free:
202         free(dev);
203 }
204
205 static void input_free_dev(struct uterm_input_dev *dev)
206 {
207         log_debug("free device %s", dev->node);
208         input_sleep_dev(dev);
209         shl_dlist_unlink(&dev->list);
210         uxkb_dev_destroy(dev);
211         free(dev->repeat_event.codepoints);
212         free(dev->repeat_event.keysyms);
213         free(dev->event.codepoints);
214         free(dev->event.keysyms);
215         free(dev->node);
216         free(dev);
217 }
218
219 SHL_EXPORT
220 int uterm_input_new(struct uterm_input **out,
221                     struct ev_eloop *eloop,
222                     const char *model,
223                     const char *layout,
224                     const char *variant,
225                     const char *options,
226                     unsigned int repeat_delay,
227                     unsigned int repeat_rate)
228 {
229         struct uterm_input *input;
230         int ret;
231
232         if (!out || !eloop)
233                 return -EINVAL;
234
235         if (!repeat_delay)
236                 repeat_delay = 250;
237         if (repeat_delay >= 1000)
238                 repeat_delay = 999;
239         if (!repeat_rate)
240                 repeat_rate = 50;
241         if (repeat_rate >= 1000)
242                 repeat_rate = 999;
243
244         input = malloc(sizeof(*input));
245         if (!input)
246                 return -ENOMEM;
247         memset(input, 0, sizeof(*input));
248         input->ref = 1;
249         input->eloop = eloop;
250         input->repeat_delay = repeat_delay;
251         input->repeat_rate = repeat_rate;
252         shl_dlist_init(&input->devices);
253
254         ret = shl_hook_new(&input->hook);
255         if (ret)
256                 goto err_free;
257
258         ret = uxkb_desc_init(input, model, layout, variant, options);
259         if (ret)
260                 goto err_hook;
261
262         log_debug("new object %p", input);
263         ev_eloop_ref(input->eloop);
264         *out = input;
265         return 0;
266
267 err_hook:
268         shl_hook_free(input->hook);
269 err_free:
270         free(input);
271         return ret;
272 }
273
274 SHL_EXPORT
275 void uterm_input_ref(struct uterm_input *input)
276 {
277         if (!input || !input->ref)
278                 return;
279
280         ++input->ref;
281 }
282
283 SHL_EXPORT
284 void uterm_input_unref(struct uterm_input *input)
285 {
286         struct uterm_input_dev *dev;
287
288         if (!input || !input->ref || --input->ref)
289                 return;
290
291         log_debug("free object %p", input);
292
293         while (input->devices.next != &input->devices) {
294                 dev = shl_dlist_entry(input->devices.next,
295                                         struct uterm_input_dev,
296                                         list);
297                 input_free_dev(dev);
298         }
299
300         uxkb_desc_destroy(input);
301         shl_hook_free(input->hook);
302         ev_eloop_unref(input->eloop);
303         free(input);
304 }
305
306 /*
307  * See if the device has anything useful to offer.
308  * We go over the possible capabilities and return a mask of enum
309  * uterm_input_device_capability's.
310  */
311 static unsigned int probe_device_capabilities(const char *node)
312 {
313         int i, fd, ret;
314         unsigned int capabilities = 0;
315         unsigned long evbits[NLONGS(EV_CNT)] = { 0 };
316         unsigned long keybits[NLONGS(KEY_CNT)] = { 0 };
317
318         fd = open(node, O_NONBLOCK | O_CLOEXEC | O_RDONLY);
319         if (fd < 0)
320                 return 0;
321
322         /* Which types of input events the device supports. */
323         ret = ioctl(fd, EVIOCGBIT(0, sizeof(evbits)), evbits);
324         if (ret == -1)
325                 goto err_ioctl;
326
327         /* Device supports keys/buttons. */
328         if (input_bit_is_set(evbits, EV_KEY)) {
329                 ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
330                 if (ret == -1)
331                         goto err_ioctl;
332
333                 /*
334                  * If the device support any of the normal keyboard keys, we
335                  * take it. Even if the keys are not ordinary they can be
336                  * mapped to anything by the keyboard backend.
337                  */
338                 for (i = KEY_RESERVED; i <= KEY_MIN_INTERESTING; i++) {
339                         if (input_bit_is_set(keybits, i)) {
340                                 capabilities |= UTERM_DEVICE_HAS_KEYS;
341                                 break;
342                         }
343                 }
344         }
345
346         if (input_bit_is_set(evbits, EV_LED))
347                 capabilities |= UTERM_DEVICE_HAS_LEDS;
348
349         close(fd);
350         return capabilities;
351
352 err_ioctl:
353         log_warn("cannot probe capabilities of device %s (%d): %m",
354                                                         node, errno);
355         close(fd);
356         return 0;
357 }
358
359 SHL_EXPORT
360 void uterm_input_add_dev(struct uterm_input *input, const char *node)
361 {
362         unsigned int capabilities;
363
364         if (!input || !node)
365                 return;
366
367         capabilities = probe_device_capabilities(node);
368         if (!(capabilities & UTERM_DEVICE_HAS_KEYS)) {
369                 log_debug("ignoring non-useful device %s", node);
370                 return;
371         }
372
373         input_new_dev(input, node, capabilities);
374 }
375
376 SHL_EXPORT
377 void uterm_input_remove_dev(struct uterm_input *input, const char *node)
378 {
379         struct shl_dlist *iter;
380         struct uterm_input_dev *dev;
381
382         if (!input || !node)
383                 return;
384
385         shl_dlist_for_each(iter, &input->devices) {
386                 dev = shl_dlist_entry(iter,
387                                         struct uterm_input_dev,
388                                         list);
389                 if (!strcmp(dev->node, node)) {
390                         input_free_dev(dev);
391                         break;
392                 }
393         }
394 }
395
396 SHL_EXPORT
397 int uterm_input_register_cb(struct uterm_input *input,
398                                 uterm_input_cb cb,
399                                 void *data)
400 {
401         if (!input || !cb)
402                 return -EINVAL;
403
404         return shl_hook_add_cast(input->hook, cb, data, false);
405 }
406
407 SHL_EXPORT
408 void uterm_input_unregister_cb(struct uterm_input *input,
409                                 uterm_input_cb cb,
410                                 void *data)
411 {
412         if (!input || !cb)
413                 return;
414
415         shl_hook_rm_cast(input->hook, cb, data);
416 }
417
418 SHL_EXPORT
419 void uterm_input_sleep(struct uterm_input *input)
420 {
421         struct shl_dlist *iter;
422         struct uterm_input_dev *dev;
423
424         if (!input)
425                 return;
426
427         --input->awake;
428         if (input->awake != 0)
429                 return;
430
431         log_debug("going to sleep");
432
433         shl_dlist_for_each(iter, &input->devices) {
434                 dev = shl_dlist_entry(iter,
435                                         struct uterm_input_dev,
436                                         list);
437                 input_sleep_dev(dev);
438         }
439 }
440
441 SHL_EXPORT
442 void uterm_input_wake_up(struct uterm_input *input)
443 {
444         struct shl_dlist *iter, *tmp;
445         struct uterm_input_dev *dev;
446         int ret;
447
448         if (!input)
449                 return;
450
451         ++input->awake;
452         if (input->awake != 1)
453                 return;
454
455         log_debug("wakeing up");
456
457         shl_dlist_for_each_safe(iter, tmp, &input->devices) {
458                 dev = shl_dlist_entry(iter,
459                                         struct uterm_input_dev,
460                                         list);
461                 ret = input_wake_up_dev(dev);
462                 if (ret)
463                         input_free_dev(dev);
464         }
465 }
466
467 SHL_EXPORT
468 bool uterm_input_is_awake(struct uterm_input *input)
469 {
470         if (!input)
471                 return false;
472
473         return input->awake > 0;
474 }