shl: move log.[ch] to shl_log.[ch]
[platform/upstream/kmscon.git] / src / uterm_input_uxkb.c
1 /*
2  * uterm - Linux User-Space Terminal
3  *
4  * Copyright (c) 2011 Ran Benita <ran234@gmail.com>
5  * Copyright (c) 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 #include <errno.h>
28 #include <inttypes.h>
29 #include <linux/input.h>
30 #include <stdbool.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <xkbcommon/xkbcommon.h>
35 #include "shl_hook.h"
36 #include "shl_log.h"
37 #include "shl_misc.h"
38 #include "uterm_input.h"
39 #include "uterm_input_internal.h"
40
41 #define LOG_SUBSYSTEM "input_uxkb"
42
43 int uxkb_desc_init(struct uterm_input *input,
44                    const char *model,
45                    const char *layout,
46                    const char *variant,
47                    const char *options)
48 {
49         int ret;
50         struct xkb_rule_names rmlvo = {
51                 .rules = "evdev",
52                 .model = model,
53                 .layout = layout,
54                 .variant = variant,
55                 .options = options,
56         };
57
58         input->ctx = xkb_context_new(0);
59         if (!input->ctx) {
60                 log_error("cannot create XKB context");
61                 return -ENOMEM;
62         }
63
64         input->keymap = xkb_keymap_new_from_names(input->ctx, &rmlvo, 0);
65         if (!input->keymap) {
66                 log_warn("failed to create keymap (%s, %s, %s, %s), "
67                          "reverting to default system keymap",
68                          model, layout, variant, options);
69
70                 rmlvo.model = "";
71                 rmlvo.layout = "";
72                 rmlvo.variant = "";
73                 rmlvo.options = "";
74
75                 input->keymap = xkb_keymap_new_from_names(input->ctx,
76                                                           &rmlvo, 0);
77                 if (!input->keymap) {
78                         log_warn("failed to create XKB keymap");
79                         ret = -EFAULT;
80                         goto err_ctx;
81                 }
82         }
83
84         log_debug("new keyboard description (%s, %s, %s, %s)",
85                   model, layout, variant, options);
86         return 0;
87
88 err_ctx:
89         xkb_context_unref(input->ctx);
90         return ret;
91 }
92
93 void uxkb_desc_destroy(struct uterm_input *input)
94 {
95         xkb_keymap_unref(input->keymap);
96         xkb_context_unref(input->ctx);
97 }
98
99 static void timer_event(struct ev_timer *timer, uint64_t num, void *data)
100 {
101         struct uterm_input_dev *dev = data;
102
103         dev->repeat_event.handled = false;
104         shl_hook_call(dev->input->hook, dev->input, &dev->repeat_event);
105 }
106
107 int uxkb_dev_init(struct uterm_input_dev *dev)
108 {
109         int ret;
110
111         ret = ev_eloop_new_timer(dev->input->eloop, &dev->repeat_timer, NULL,
112                                  timer_event, dev);
113         if (ret)
114                 return ret;
115
116         dev->state = xkb_state_new(dev->input->keymap);
117         if (!dev->state) {
118                 log_error("cannot create XKB state");
119                 ret = -ENOMEM;
120                 goto err_timer;
121         }
122
123         return 0;
124
125 err_timer:
126         ev_eloop_rm_timer(dev->repeat_timer);
127         return ret;
128 }
129
130 void uxkb_dev_destroy(struct uterm_input_dev *dev)
131 {
132         xkb_state_unref(dev->state);
133         ev_eloop_rm_timer(dev->repeat_timer);
134 }
135
136 #define EVDEV_KEYCODE_OFFSET 8
137 enum {
138         KEY_RELEASED = 0,
139         KEY_PRESSED = 1,
140         KEY_REPEATED = 2,
141 };
142
143 static void uxkb_dev_update_keyboard_leds(struct uterm_input_dev *dev)
144 {
145         static const struct {
146                 int evdev_led;
147                 const char *xkb_led;
148         } leds[] = {
149                 { LED_NUML, XKB_LED_NAME_NUM },
150                 { LED_CAPSL, XKB_LED_NAME_CAPS },
151                 { LED_SCROLLL, XKB_LED_NAME_SCROLL },
152         };
153         struct input_event events[sizeof(leds) / sizeof(*leds)];
154         int i, ret;
155
156         if (!(dev->capabilities & UTERM_DEVICE_HAS_LEDS))
157                 return;
158
159         memset(events, 0, sizeof(events));
160
161         for (i = 0; i < sizeof(leds) / sizeof(*leds); i++) {
162                 events[i].type = EV_LED;
163                 events[i].code = leds[i].evdev_led;
164                 if (xkb_state_led_name_is_active(dev->state,
165                                                 leds[i].xkb_led) > 0)
166                         events[i].value = 1;
167         }
168
169         ret = write(dev->rfd, events, sizeof(events));
170         if (ret != sizeof(events))
171                 log_warning("cannot update LED state (%d): %m", errno);
172 }
173
174 static inline int uxkb_dev_resize_event(struct uterm_input_dev *dev, size_t s)
175 {
176         uint32_t *tmp;
177
178         if (s > dev->num_syms) {
179                 tmp = realloc(dev->event.keysyms,
180                               sizeof(uint32_t) * s);
181                 if (!tmp) {
182                         log_warning("cannot reallocate keysym buffer");
183                         return -ENOKEY;
184                 }
185                 dev->event.keysyms = tmp;
186
187                 tmp = realloc(dev->event.codepoints,
188                               sizeof(uint32_t) * s);
189                 if (!tmp) {
190                         log_warning("cannot reallocate codepoints buffer");
191                         return -ENOKEY;
192                 }
193                 dev->event.codepoints = tmp;
194
195                 tmp = realloc(dev->repeat_event.keysyms,
196                               sizeof(uint32_t) * s);
197                 if (!tmp) {
198                         log_warning("cannot reallocate keysym buffer");
199                         return -ENOKEY;
200                 }
201                 dev->repeat_event.keysyms = tmp;
202
203                 tmp = realloc(dev->repeat_event.codepoints,
204                               sizeof(uint32_t) * s);
205                 if (!tmp) {
206                         log_warning("cannot reallocate codepoints buffer");
207                         return -ENOKEY;
208                 }
209                 dev->repeat_event.codepoints = tmp;
210
211                 dev->num_syms = s;
212         }
213
214         return 0;
215 }
216
217 static int uxkb_dev_fill_event(struct uterm_input_dev *dev,
218                                struct uterm_input_event *ev,
219                                xkb_keycode_t code,
220                                int num_syms,
221                                const xkb_keysym_t *syms)
222 {
223         int ret, i;
224
225         ret = uxkb_dev_resize_event(dev, num_syms);
226         if (ret)
227                 return ret;
228
229         ev->keycode = code;
230         ev->ascii = shl_get_ascii(dev->state, code, syms, num_syms);
231         ev->mods = shl_get_xkb_mods(dev->state);
232         ev->num_syms = num_syms;
233         memcpy(ev->keysyms, syms, sizeof(uint32_t) * num_syms);
234
235         for (i = 0; i < num_syms; ++i) {
236                 ev->codepoints[i] = xkb_keysym_to_utf32(syms[i]);
237                 if (!ev->codepoints[i])
238                         ev->codepoints[i] = UTERM_INPUT_INVALID;
239         }
240
241         return 0;
242 }
243
244 static void uxkb_dev_repeat(struct uterm_input_dev *dev, unsigned int state)
245 {
246         struct xkb_keymap *keymap = xkb_state_get_keymap(dev->state);
247         unsigned int i;
248         int num_keysyms, ret;
249         const uint32_t *keysyms;
250         struct itimerspec spec;
251
252         if (dev->repeating && dev->repeat_event.keycode == dev->event.keycode) {
253                 if (state == KEY_RELEASED) {
254                         dev->repeating = false;
255                         ev_timer_update(dev->repeat_timer, NULL);
256                 }
257                 return;
258         }
259
260         if (state == KEY_PRESSED &&
261             xkb_keymap_key_repeats(keymap, dev->event.keycode)) {
262                 dev->repeat_event.keycode = dev->event.keycode;
263                 dev->repeat_event.ascii = dev->event.ascii;
264                 dev->repeat_event.mods = dev->event.mods;
265                 dev->repeat_event.num_syms = dev->event.num_syms;
266
267                 for (i = 0; i < dev->event.num_syms; ++i) {
268                         dev->repeat_event.keysyms[i] = dev->event.keysyms[i];
269                         dev->repeat_event.codepoints[i] =
270                                                 dev->event.codepoints[i];
271                 }
272         } else if (dev->repeating &&
273                    !xkb_keymap_key_repeats(keymap, dev->event.keycode)) {
274                 num_keysyms = xkb_state_key_get_syms(dev->state,
275                                                      dev->repeat_event.keycode,
276                                                      &keysyms);
277                 if (num_keysyms <= 0)
278                         return;
279
280                 ret = uxkb_dev_fill_event(dev, &dev->repeat_event,
281                                           dev->repeat_event.keycode,
282                                           num_keysyms, keysyms);
283                 if (ret)
284                         return;
285
286                 return;
287         } else {
288                 return;
289         }
290
291         dev->repeating = true;
292         spec.it_interval.tv_sec = 0;
293         spec.it_interval.tv_nsec = dev->input->repeat_rate * 1000000;
294         spec.it_value.tv_sec = 0;
295         spec.it_value.tv_nsec = dev->input->repeat_delay * 1000000;
296         ev_timer_update(dev->repeat_timer, &spec);
297 }
298
299 int uxkb_dev_process(struct uterm_input_dev *dev,
300                      uint16_t key_state, uint16_t code)
301 {
302         struct xkb_state *state;
303         xkb_keycode_t keycode;
304         const xkb_keysym_t *keysyms;
305         int num_keysyms, ret;
306         enum xkb_state_component changed;
307
308         if (key_state == KEY_REPEATED)
309                 return -ENOKEY;
310
311         state = dev->state;
312         keycode = code + EVDEV_KEYCODE_OFFSET;
313
314         num_keysyms = xkb_state_key_get_syms(state, keycode, &keysyms);
315
316         changed = 0;
317         if (key_state == KEY_PRESSED)
318                 changed = xkb_state_update_key(state, keycode, XKB_KEY_DOWN);
319         else if (key_state == KEY_RELEASED)
320                 changed = xkb_state_update_key(state, keycode, XKB_KEY_UP);
321
322         if (changed & XKB_STATE_LEDS)
323                 uxkb_dev_update_keyboard_leds(dev);
324
325         if (num_keysyms <= 0)
326                 return -ENOKEY;
327
328         ret = uxkb_dev_fill_event(dev, &dev->event, keycode, num_keysyms,
329                                   keysyms);
330         if (ret)
331                 return -ENOKEY;
332
333         uxkb_dev_repeat(dev, key_state);
334
335         if (key_state == KEY_RELEASED)
336                 return -ENOKEY;
337
338         dev->event.handled = false;
339         shl_hook_call(dev->input->hook, dev->input, &dev->event);
340
341         return 0;
342 }
343
344 void uxkb_dev_sleep(struct uterm_input_dev *dev)
345 {
346         /*
347          * While the device is asleep, we don't receive key events. This
348          * means that when we wake up, the keyboard state may be different
349          * (e.g. some key is pressed but we don't know about it). This can
350          * cause various problems, like stuck modifiers: consider if we
351          * miss a release of the left Shift key. When the user presses it
352          * again, xkb_state_update_key() will think there is *another* left
353          * Shift key that was pressed. When the key is released, it's as if
354          * this "second" key was released, but the "first" is still left
355          * pressed.
356          * To handle this, when the device goes to sleep, we save our
357          * current knowledge of the keyboard's press/release state. On wake
358          * up, we compare the states before and after, and just feed
359          * xkb_state_update_key() the deltas.
360          */
361         memset(dev->key_state_bits, 0, sizeof(dev->key_state_bits));
362         errno = 0;
363         ioctl(dev->rfd, EVIOCGKEY(sizeof(dev->key_state_bits)),
364               dev->key_state_bits);
365         if (errno)
366                 log_warn("failed to save keyboard state (%d): %m", errno);
367 }
368
369 void uxkb_dev_wake_up(struct uterm_input_dev *dev)
370 {
371         uint32_t code;
372         char *old_bits, cur_bits[sizeof(dev->key_state_bits)];
373         char old_bit, cur_bit;
374
375         old_bits = dev->key_state_bits;
376
377         memset(cur_bits, 0, sizeof(cur_bits));
378         errno = 0;
379         ioctl(dev->rfd, EVIOCGKEY(sizeof(cur_bits)), cur_bits);
380         if (errno) {
381                 log_warn("failed to get current keyboard state (%d): %m",
382                          errno);
383                 return;
384         }
385
386         for (code = 0; code < KEY_CNT; code++) {
387                 old_bit = (old_bits[code / 8] & (1 << (code % 8)));
388                 cur_bit = (cur_bits[code / 8] & (1 << (code % 8)));
389
390                 if (old_bit == cur_bit)
391                         continue;
392
393                 xkb_state_update_key(dev->state, code + EVDEV_KEYCODE_OFFSET,
394                                      cur_bit ? XKB_KEY_DOWN : XKB_KEY_UP);
395         }
396
397         uxkb_dev_update_keyboard_leds(dev);
398 }