kmscon: add --xkb-repeat-rate/delay command-line arguments
[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 "log.h"
41 #include "shl_dlist.h"
42 #include "shl_hook.h"
43 #include "uterm.h"
44 #include "uterm_input.h"
45
46 #define LOG_SUBSYSTEM "input"
47
48 /* How many longs are needed to hold \n bits. */
49 #define NLONGS(n) (((n) + LONG_BIT - 1) / LONG_BIT)
50
51 enum device_feature {
52         FEATURE_HAS_KEYS = 0x01,
53         FEATURE_HAS_LEDS = 0x02,
54 };
55
56 static void input_free_dev(struct uterm_input_dev *dev);
57
58 static void notify_key(struct uterm_input_dev *dev,
59                         uint16_t type,
60                         uint16_t code,
61                         int32_t value)
62 {
63         if (type != EV_KEY)
64                 return;
65
66         uxkb_dev_process(dev, value, code);
67 }
68
69 static void input_data_dev(struct ev_fd *fd, int mask, void *data)
70 {
71         struct uterm_input_dev *dev = data;
72         struct input_event ev[16];
73         ssize_t len, n;
74         int i;
75
76         if (mask & (EV_HUP | EV_ERR)) {
77                 log_debug("EOF on %s", dev->node);
78                 input_free_dev(dev);
79                 return;
80         }
81
82         len = sizeof(ev);
83         while (len == sizeof(ev)) {
84                 len = read(dev->rfd, &ev, sizeof(ev));
85                 if (len < 0) {
86                         if (errno == EWOULDBLOCK)
87                                 break;
88                         log_warn("reading from %s failed (%d): %m",
89                                                 dev->node, errno);
90                         input_free_dev(dev);
91                 } else if (len == 0) {
92                         log_debug("EOF on %s", dev->node);
93                         input_free_dev(dev);
94                 } else if (len % sizeof(*ev)) {
95                         log_warn("invalid input_event on %s", dev->node);
96                 } else {
97                         n = len / sizeof(*ev);
98                         for (i = 0; i < n; i++)
99                                 notify_key(dev, ev[i].type, ev[i].code,
100                                                                 ev[i].value);
101                 }
102         }
103 }
104
105 static int input_wake_up_dev(struct uterm_input_dev *dev)
106 {
107         int ret;
108         unsigned long ledbits[NLONGS(LED_CNT)] = { 0 };
109
110         if (dev->rfd >= 0)
111                 return 0;
112
113         dev->rfd = open(dev->node, O_CLOEXEC | O_NONBLOCK | O_RDONLY);
114         if (dev->rfd < 0) {
115                 log_warn("cannot open device %s (%d): %m", dev->node, errno);
116                 return -EFAULT;
117         }
118
119         if (dev->features & FEATURE_HAS_KEYS) {
120                 if (dev->features & FEATURE_HAS_LEDS) {
121                         ret = ioctl(dev->rfd, EVIOCGLED(sizeof(ledbits)),
122                                                                 &ledbits);
123                         if (ret == -1)
124                                 log_warn("cannot read LED state of %s (%d): %m",
125                                          dev->node, errno);
126                 }
127
128                 /* rediscover the keyboard state if sth changed during sleep */
129                 uxkb_dev_reset(dev, ledbits);
130
131                 ret = ev_eloop_new_fd(dev->input->eloop, &dev->fd,
132                                                 dev->rfd, EV_READABLE,
133                                                 input_data_dev, dev);
134                 if (ret) {
135                         close(dev->rfd);
136                         dev->rfd = -1;
137                         return ret;
138                 }
139         }
140
141         return 0;
142 }
143
144 static void input_sleep_dev(struct uterm_input_dev *dev)
145 {
146         if (dev->rfd < 0)
147                 return;
148
149         ev_eloop_rm_fd(dev->fd);
150         dev->fd = NULL;
151         close(dev->rfd);
152         dev->rfd = -1;
153 }
154
155 static void input_new_dev(struct uterm_input *input,
156                                 const char *node,
157                                 unsigned int features)
158 {
159         struct uterm_input_dev *dev;
160         int ret;
161
162         dev = malloc(sizeof(*dev));
163         if (!dev)
164                 return;
165         memset(dev, 0, sizeof(*dev));
166         dev->input = input;
167         dev->rfd = -1;
168         dev->features = features;
169
170         dev->node = strdup(node);
171         if (!dev->node)
172                 goto err_free;
173
174         dev->num_syms = 1;
175         dev->event.keysyms = malloc(sizeof(uint32_t) * dev->num_syms);
176         if (!dev->event.keysyms)
177                 goto err_node;
178         dev->event.codepoints = malloc(sizeof(uint32_t) * dev->num_syms);
179         if (!dev->event.codepoints)
180                 goto err_syms;
181         dev->repeat_event.keysyms = malloc(sizeof(uint32_t) * dev->num_syms);
182         if (!dev->repeat_event.keysyms)
183                 goto err_codepoints;
184         dev->repeat_event.codepoints = malloc(sizeof(uint32_t) * dev->num_syms);
185         if (!dev->repeat_event.codepoints)
186                 goto err_rsyms;
187
188         ret = uxkb_dev_init(dev);
189         if (ret)
190                 goto err_rcodepoints;
191
192         if (input->awake > 0) {
193                 ret = input_wake_up_dev(dev);
194                 if (ret)
195                         goto err_kbd;
196         }
197
198         log_debug("new device %s", node);
199         shl_dlist_link(&input->devices, &dev->list);
200         return;
201
202 err_kbd:
203         uxkb_dev_destroy(dev);
204 err_rcodepoints:
205         free(dev->repeat_event.codepoints);
206 err_rsyms:
207         free(dev->repeat_event.keysyms);
208 err_codepoints:
209         free(dev->event.codepoints);
210 err_syms:
211         free(dev->event.keysyms);
212 err_node:
213         free(dev->node);
214 err_free:
215         free(dev);
216 }
217
218 static void input_free_dev(struct uterm_input_dev *dev)
219 {
220         log_debug("free device %s", dev->node);
221         input_sleep_dev(dev);
222         shl_dlist_unlink(&dev->list);
223         uxkb_dev_destroy(dev);
224         free(dev->repeat_event.codepoints);
225         free(dev->repeat_event.keysyms);
226         free(dev->event.codepoints);
227         free(dev->event.keysyms);
228         free(dev->node);
229         free(dev);
230 }
231
232 int uterm_input_new(struct uterm_input **out,
233                     struct ev_eloop *eloop,
234                     const char *layout,
235                     const char *variant,
236                     const char *options,
237                     unsigned int repeat_delay,
238                     unsigned int repeat_rate)
239 {
240         struct uterm_input *input;
241         int ret;
242
243         if (!out || !eloop)
244                 return -EINVAL;
245
246         if (!repeat_delay)
247                 repeat_delay = 250;
248         if (repeat_delay >= 1000)
249                 repeat_delay = 999;
250         if (!repeat_rate)
251                 repeat_rate = 25;
252         if (repeat_rate >= 1000)
253                 repeat_rate = 999;
254
255         input = malloc(sizeof(*input));
256         if (!input)
257                 return -ENOMEM;
258         memset(input, 0, sizeof(*input));
259         input->ref = 1;
260         input->eloop = eloop;
261         input->repeat_delay = repeat_delay;
262         input->repeat_rate = repeat_rate;
263         shl_dlist_init(&input->devices);
264
265         ret = shl_hook_new(&input->hook);
266         if (ret)
267                 goto err_free;
268
269         ret = uxkb_desc_init(input, layout, variant, options);
270         if (ret)
271                 goto err_hook;
272
273         log_debug("new object %p", input);
274         ev_eloop_ref(input->eloop);
275         *out = input;
276         return 0;
277
278 err_hook:
279         shl_hook_free(input->hook);
280 err_free:
281         free(input);
282         return ret;
283 }
284
285 void uterm_input_ref(struct uterm_input *input)
286 {
287         if (!input || !input->ref)
288                 return;
289
290         ++input->ref;
291 }
292
293 void uterm_input_unref(struct uterm_input *input)
294 {
295         struct uterm_input_dev *dev;
296
297         if (!input || !input->ref || --input->ref)
298                 return;
299
300         log_debug("free object %p", input);
301
302         while (input->devices.next != &input->devices) {
303                 dev = shl_dlist_entry(input->devices.next,
304                                         struct uterm_input_dev,
305                                         list);
306                 input_free_dev(dev);
307         }
308
309         uxkb_desc_destroy(input);
310         shl_hook_free(input->hook);
311         ev_eloop_unref(input->eloop);
312         free(input);
313 }
314
315 /*
316  * See if the device has anything useful to offer.
317  * We go over the desired features and return a mask of enum device_feature's.
318  */
319 static unsigned int probe_device_features(const char *node)
320 {
321         int i, fd, ret;
322         unsigned int features = 0;
323         unsigned long evbits[NLONGS(EV_CNT)] = { 0 };
324         unsigned long keybits[NLONGS(KEY_CNT)] = { 0 };
325
326         fd = open(node, O_NONBLOCK | O_CLOEXEC | O_RDONLY);
327         if (fd < 0)
328                 return 0;
329
330         /* Which types of input events the device supports. */
331         ret = ioctl(fd, EVIOCGBIT(0, sizeof(evbits)), evbits);
332         if (ret == -1)
333                 goto err_ioctl;
334
335         /* Device supports keys/buttons. */
336         if (input_bit_is_set(evbits, EV_KEY)) {
337                 ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
338                 if (ret == -1)
339                         goto err_ioctl;
340
341                 /*
342                  * If the device support any of the normal keyboard keys, we
343                  * take it. Even if the keys are not ordinary they can be
344                  * mapped to anything by the keyboard backend.
345                  */
346                 for (i = KEY_RESERVED; i <= KEY_MIN_INTERESTING; i++) {
347                         if (input_bit_is_set(keybits, i)) {
348                                 features |= FEATURE_HAS_KEYS;
349                                 break;
350                         }
351                 }
352         }
353
354         if (input_bit_is_set(evbits, EV_LED))
355                 features |= FEATURE_HAS_LEDS;
356
357         close(fd);
358         return features;
359
360 err_ioctl:
361         log_warn("cannot probe features of device %s (%d): %m", node, errno);
362         close(fd);
363         return 0;
364 }
365
366 void uterm_input_add_dev(struct uterm_input *input, const char *node)
367 {
368         unsigned int features;
369
370         if (!input || !node)
371                 return;
372
373         features = probe_device_features(node);
374         if (!(features & FEATURE_HAS_KEYS)) {
375                 log_debug("ignoring non-useful device %s", node);
376                 return;
377         }
378
379         input_new_dev(input, node, features);
380 }
381
382 void uterm_input_remove_dev(struct uterm_input *input, const char *node)
383 {
384         struct shl_dlist *iter;
385         struct uterm_input_dev *dev;
386
387         if (!input || !node)
388                 return;
389
390         shl_dlist_for_each(iter, &input->devices) {
391                 dev = shl_dlist_entry(iter,
392                                         struct uterm_input_dev,
393                                         list);
394                 if (!strcmp(dev->node, node)) {
395                         input_free_dev(dev);
396                         break;
397                 }
398         }
399 }
400
401 int uterm_input_register_cb(struct uterm_input *input,
402                                 uterm_input_cb cb,
403                                 void *data)
404 {
405         if (!input || !cb)
406                 return -EINVAL;
407
408         return shl_hook_add_cast(input->hook, cb, data);
409 }
410
411 void uterm_input_unregister_cb(struct uterm_input *input,
412                                 uterm_input_cb cb,
413                                 void *data)
414 {
415         if (!input || !cb)
416                 return;
417
418         shl_hook_rm_cast(input->hook, cb, data);
419 }
420
421 void uterm_input_sleep(struct uterm_input *input)
422 {
423         struct shl_dlist *iter;
424         struct uterm_input_dev *dev;
425
426         if (!input)
427                 return;
428
429         --input->awake;
430         if (input->awake != 0)
431                 return;
432
433         log_debug("going to sleep");
434
435         shl_dlist_for_each(iter, &input->devices) {
436                 dev = shl_dlist_entry(iter,
437                                         struct uterm_input_dev,
438                                         list);
439                 input_sleep_dev(dev);
440         }
441 }
442
443 void uterm_input_wake_up(struct uterm_input *input)
444 {
445         struct shl_dlist *iter, *tmp;
446         struct uterm_input_dev *dev;
447         int ret;
448
449         if (!input)
450                 return;
451
452         ++input->awake;
453         if (input->awake != 1)
454                 return;
455
456         log_debug("wakeing up");
457
458         shl_dlist_for_each_safe(iter, tmp, &input->devices) {
459                 dev = shl_dlist_entry(iter,
460                                         struct uterm_input_dev,
461                                         list);
462                 ret = input_wake_up_dev(dev);
463                 if (ret)
464                         input_free_dev(dev);
465         }
466 }
467
468 bool uterm_input_is_awake(struct uterm_input *input)
469 {
470         if (!input)
471                 return false;
472
473         return input->awake > 0;
474 }