2 * uterm - Linux User-Space Terminal
4 * Copyright (c) 2011 Ran Benita <ran234@gmail.com>
5 * Copyright (c) 2011-2012 David Herrmann <dh.herrmann@googlemail.com>
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:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
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.
34 #include <linux/input.h>
41 #include "shl_dlist.h"
44 #include "uterm_input.h"
46 #define LOG_SUBSYSTEM "input"
48 /* How many longs are needed to hold \n bits. */
49 #define NLONGS(n) (((n) + LONG_BIT - 1) / LONG_BIT)
52 FEATURE_HAS_KEYS = 0x01,
53 FEATURE_HAS_LEDS = 0x02,
56 static void input_free_dev(struct uterm_input_dev *dev);
58 static void notify_key(struct uterm_input_dev *dev,
66 uxkb_dev_process(dev, value, code);
69 static void input_data_dev(struct ev_fd *fd, int mask, void *data)
71 struct uterm_input_dev *dev = data;
72 struct input_event ev[16];
76 if (mask & (EV_HUP | EV_ERR)) {
77 log_debug("EOF on %s", dev->node);
83 while (len == sizeof(ev)) {
84 len = read(dev->rfd, &ev, sizeof(ev));
86 if (errno == EWOULDBLOCK)
88 log_warn("reading from %s failed (%d): %m",
91 } else if (len == 0) {
92 log_debug("EOF on %s", dev->node);
94 } else if (len % sizeof(*ev)) {
95 log_warn("invalid input_event on %s", dev->node);
97 n = len / sizeof(*ev);
98 for (i = 0; i < n; i++)
99 notify_key(dev, ev[i].type, ev[i].code,
105 static int input_wake_up_dev(struct uterm_input_dev *dev)
108 unsigned long ledbits[NLONGS(LED_CNT)] = { 0 };
113 dev->rfd = open(dev->node, O_CLOEXEC | O_NONBLOCK | O_RDONLY);
115 log_warn("cannot open device %s (%d): %m", dev->node, errno);
119 if (dev->features & FEATURE_HAS_KEYS) {
120 if (dev->features & FEATURE_HAS_LEDS) {
121 ret = ioctl(dev->rfd, EVIOCGLED(sizeof(ledbits)),
124 log_warn("cannot read LED state of %s (%d): %m",
128 /* rediscover the keyboard state if sth changed during sleep */
129 uxkb_dev_reset(dev, ledbits);
131 ret = ev_eloop_new_fd(dev->input->eloop, &dev->fd,
132 dev->rfd, EV_READABLE,
133 input_data_dev, dev);
144 static void input_sleep_dev(struct uterm_input_dev *dev)
149 ev_eloop_rm_fd(dev->fd);
155 static void input_new_dev(struct uterm_input *input,
157 unsigned int features)
159 struct uterm_input_dev *dev;
162 dev = malloc(sizeof(*dev));
165 memset(dev, 0, sizeof(*dev));
168 dev->features = features;
170 dev->node = strdup(node);
175 dev->event.keysyms = malloc(sizeof(uint32_t) * dev->num_syms);
176 if (!dev->event.keysyms)
178 dev->event.codepoints = malloc(sizeof(uint32_t) * dev->num_syms);
179 if (!dev->event.codepoints)
181 dev->repeat_event.keysyms = malloc(sizeof(uint32_t) * dev->num_syms);
182 if (!dev->repeat_event.keysyms)
184 dev->repeat_event.codepoints = malloc(sizeof(uint32_t) * dev->num_syms);
185 if (!dev->repeat_event.codepoints)
188 ret = uxkb_dev_init(dev);
190 goto err_rcodepoints;
192 if (input->awake > 0) {
193 ret = input_wake_up_dev(dev);
198 log_debug("new device %s", node);
199 shl_dlist_link(&input->devices, &dev->list);
203 uxkb_dev_destroy(dev);
205 free(dev->repeat_event.codepoints);
207 free(dev->repeat_event.keysyms);
209 free(dev->event.codepoints);
211 free(dev->event.keysyms);
218 static void input_free_dev(struct uterm_input_dev *dev)
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);
232 int uterm_input_new(struct uterm_input **out,
233 struct ev_eloop *eloop,
237 unsigned int repeat_delay,
238 unsigned int repeat_rate)
240 struct uterm_input *input;
248 if (repeat_delay >= 1000)
252 if (repeat_rate >= 1000)
255 input = malloc(sizeof(*input));
258 memset(input, 0, sizeof(*input));
260 input->eloop = eloop;
261 input->repeat_delay = repeat_delay;
262 input->repeat_rate = repeat_rate;
263 shl_dlist_init(&input->devices);
265 ret = shl_hook_new(&input->hook);
269 ret = uxkb_desc_init(input, layout, variant, options);
273 log_debug("new object %p", input);
274 ev_eloop_ref(input->eloop);
279 shl_hook_free(input->hook);
285 void uterm_input_ref(struct uterm_input *input)
287 if (!input || !input->ref)
293 void uterm_input_unref(struct uterm_input *input)
295 struct uterm_input_dev *dev;
297 if (!input || !input->ref || --input->ref)
300 log_debug("free object %p", input);
302 while (input->devices.next != &input->devices) {
303 dev = shl_dlist_entry(input->devices.next,
304 struct uterm_input_dev,
309 uxkb_desc_destroy(input);
310 shl_hook_free(input->hook);
311 ev_eloop_unref(input->eloop);
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.
319 static unsigned int probe_device_features(const char *node)
322 unsigned int features = 0;
323 unsigned long evbits[NLONGS(EV_CNT)] = { 0 };
324 unsigned long keybits[NLONGS(KEY_CNT)] = { 0 };
326 fd = open(node, O_NONBLOCK | O_CLOEXEC | O_RDONLY);
330 /* Which types of input events the device supports. */
331 ret = ioctl(fd, EVIOCGBIT(0, sizeof(evbits)), evbits);
335 /* Device supports keys/buttons. */
336 if (input_bit_is_set(evbits, EV_KEY)) {
337 ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
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.
346 for (i = KEY_RESERVED; i <= KEY_MIN_INTERESTING; i++) {
347 if (input_bit_is_set(keybits, i)) {
348 features |= FEATURE_HAS_KEYS;
354 if (input_bit_is_set(evbits, EV_LED))
355 features |= FEATURE_HAS_LEDS;
361 log_warn("cannot probe features of device %s (%d): %m", node, errno);
366 void uterm_input_add_dev(struct uterm_input *input, const char *node)
368 unsigned int features;
373 features = probe_device_features(node);
374 if (!(features & FEATURE_HAS_KEYS)) {
375 log_debug("ignoring non-useful device %s", node);
379 input_new_dev(input, node, features);
382 void uterm_input_remove_dev(struct uterm_input *input, const char *node)
384 struct shl_dlist *iter;
385 struct uterm_input_dev *dev;
390 shl_dlist_for_each(iter, &input->devices) {
391 dev = shl_dlist_entry(iter,
392 struct uterm_input_dev,
394 if (!strcmp(dev->node, node)) {
401 int uterm_input_register_cb(struct uterm_input *input,
408 return shl_hook_add_cast(input->hook, cb, data);
411 void uterm_input_unregister_cb(struct uterm_input *input,
418 shl_hook_rm_cast(input->hook, cb, data);
421 void uterm_input_sleep(struct uterm_input *input)
423 struct shl_dlist *iter;
424 struct uterm_input_dev *dev;
430 if (input->awake != 0)
433 log_debug("going to sleep");
435 shl_dlist_for_each(iter, &input->devices) {
436 dev = shl_dlist_entry(iter,
437 struct uterm_input_dev,
439 input_sleep_dev(dev);
443 void uterm_input_wake_up(struct uterm_input *input)
445 struct shl_dlist *iter, *tmp;
446 struct uterm_input_dev *dev;
453 if (input->awake != 1)
456 log_debug("wakeing up");
458 shl_dlist_for_each_safe(iter, tmp, &input->devices) {
459 dev = shl_dlist_entry(iter,
460 struct uterm_input_dev,
462 ret = input_wake_up_dev(dev);
468 bool uterm_input_is_awake(struct uterm_input *input)
473 return input->awake > 0;