1 /*****************************************************************************/
3 * \file input/lib/src/l4evdev.c
4 * \brief L4INPUT Event Device
7 * \author Christian Helmuth <ch12@os.inf.tu-dresden.de>
8 * \author Frank Mehnert <fm3@os.inf.tu-dresden.de>
10 * This is roughly a Linux /dev/event implementation adopted from evdev.
12 * Original copyright notice from drivers/input/evdev.c follows...
15 * Event char devices, giving access to raw input device events.
17 * Copyright (c) 1999-2002 Vojtech Pavlik
19 * This program is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License version 2 as published by
21 * the Free Software Foundation.
26 #include <l4/sys/err.h>
27 #include <l4/input/libinput.h>
28 #include <l4/re/c/util/cap_alloc.h>
29 #include <l4/re/env.h>
30 #include <linux/kernel.h>
37 #include <linux/input.h>
38 #include <linux/jiffies.h>
44 There can be up to L4EVDEV_DEVICES managed.
46 So we _don't_ need one event queue/list per device to support dedicated
47 event handlers per device -> we use one general event queue (for DOpE) with
48 up to L4EVDEV_BUFFER l4evdev_event structures. CON uses callbacks and
49 therefore needs no ring buffer.
52 #define L4EVDEV_DEVICES 16
53 #define L4EVDEV_BUFFER 512
55 #define DEBUG_L4EVDEV 0
57 /** l4evdev event structure */
58 struct l4evdev_event {
59 struct l4evdev *evdev;
61 struct input_event event;
62 struct l4input l4event;
66 /** l4evdev device structure */
72 struct input_handle handle;
75 unsigned int pkt_count;
76 int old_x[4], old_y[4];
81 struct l4evdev *pcspkr;
83 /** all known devices */
84 static struct l4evdev l4evdev_devices[L4EVDEV_DEVICES];
85 /** global event list */
86 static struct l4evdev_event l4evdev_buffer[L4EVDEV_BUFFER];
87 static int l4evdev_buffer_head = 0;
88 static int l4evdev_buffer_tail = 0;
89 #define DEVS l4evdev_devices
90 #define BUFFER l4evdev_buffer
91 #define HEAD l4evdev_buffer_head /**< next event slot */
92 #define TAIL l4evdev_buffer_tail /**< first-in event if !(HEAD==TAIL) */
93 #define INC(x) (x) = ((x) + 1) % L4EVDEV_BUFFER
95 static pthread_mutex_t l4evdev_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
97 /*************************
98 *** TOUCHPAD HANDLING ***
99 *************************/
100 /* convert absolute to relative events for inappropriate devices like touchpads
101 * (taken from input/mousedev.c) */
102 static unsigned int tpad_touch(struct l4evdev *mousedev, int value)
105 /* FIXME tap support */
107 if (mousedev->touch &&
108 time_before(jiffies, mousedev->touch + msecs_to_jiffies(tap_time))) {
110 * Toggle left button to emulate tap.
111 * We rely on the fact that mousedev_mix always has 0
112 * motion packet so we won't mess current position.
114 set_bit(0, &mousedev->packet.buttons);
115 set_bit(0, &mousedev_mix.packet.buttons);
116 mousedev_notify_readers(mousedev, &mousedev_mix.packet);
117 mousedev_notify_readers(&mousedev_mix, &mousedev_mix.packet);
118 clear_bit(0, &mousedev->packet.buttons);
119 clear_bit(0, &mousedev_mix.packet.buttons);
122 mousedev->touch = mousedev->pkt_count = 0;
123 mousedev->frac_dx = 0;
124 mousedev->frac_dy = 0;
127 if (!mousedev->touch)
128 mousedev->touch = jiffies;
130 /* FIXME tap support */
134 static unsigned int tpad_trans_key(unsigned int code)
167 /* abort per default */
169 button = KEY_RESERVED;
175 #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
176 #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
178 /* check event and convert if appropriate
179 * returns 1 if event should be ignored */
180 static int tpad_event(struct input_dev *dev, struct l4evdev *mousedev,
181 unsigned int *type0, unsigned int *code0, int *value0)
184 unsigned int type = *type0;
185 unsigned int code = *code0;
187 enum { FRACTION_DENOM = 128 };
189 /* is it really a touchpad ? */
190 if (!test_bit(BTN_TOOL_FINGER, dev->keybit))
196 /* from input/mousedev.c:315 */
199 if (value == 2) return 1;
201 if (code == BTN_TOUCH)
202 code = tpad_touch(mousedev, value);
204 code = tpad_trans_key(code);
206 /* ignore some unhandled codes */
207 if (code == KEY_RESERVED) return 1;
212 /* from input/mousedev.c:324 */
214 if (code == SYN_REPORT) {
215 if (mousedev->touch) {
216 mousedev->pkt_count++;
217 /* Input system eats duplicate events, but we need all of them
218 * to do correct averaging so apply present one forward
229 /* from input/mousedev.c:119 */
231 /* ignore if pad was not touched */
232 if (!mousedev->touch) return 1;
234 size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
235 if (size == 0) size = 256 * 2;
239 /* ignore events with insufficient state */
240 if (mousedev->pkt_count < 2) return 1;
242 tmp = ((value - fx(2)) * (256 * FRACTION_DENOM)) / size;
243 tmp += mousedev->frac_dx;
244 value = tmp / FRACTION_DENOM;
245 mousedev->frac_dx = tmp - value * FRACTION_DENOM;
252 /* ignore events with insufficient state */
253 if (mousedev->pkt_count < 2) return 1;
255 tmp = ((value - fy(2)) * (256 * FRACTION_DENOM)) / size;
256 tmp += mousedev->frac_dy;
257 value = tmp / FRACTION_DENOM;
258 mousedev->frac_dy = tmp - value * FRACTION_DENOM;
263 default: /* ignore this event */
269 /* ignore unknown events */
271 printf("l4evdev.c: tpad ignored. D: %s, T: %d, C: %d, V: %d\n",
272 mousedev->handle.dev->phys, type, code, value);
277 /* propagate handled events */
284 /** SOME EVENTS ARE FILTERED OUT **/
285 static inline int filter_event(struct input_handle *handle, unsigned int type,
286 unsigned int code, int value)
288 /* filter sound driver events */
289 if (test_bit(EV_SND, handle->dev->evbit))
292 /* filter misc event: scancode -- no handlers yet */
293 if ((type == EV_MSC) && (code == MSC_SCAN))
301 /** HANDLE INCOMING EVENTS (CALLBACK VARIANT) **/
302 static L4_CV void(*callback)(struct l4input *) = NULL;
304 static void l4evdev_event_cb(struct input_handle *handle, unsigned int type,
305 unsigned int code, int value)
308 static unsigned long count = 0;
310 static struct l4input ev;
312 /* handle touchpads */
314 if (tpad_event(handle->dev, (struct l4evdev *)handle->private,
315 &type, &code, &value))
319 if (filter_event(handle, type, code, value)) return;
321 ev.time = l4_kip_clock(l4re_kip());
325 ev.stream_id = (l4_umword_t)handle->dev;
331 printf("l4evdev.c: Ev[%ld]. D: %s, T: %d, C: %d, V: %d\n",
332 count++, handle->dev->phys, type, code, value);
336 /** HANDLE INCOMING EVENTS (BUFFER AND PULL VARIANT) **/
337 static void l4evdev_event(struct input_handle *handle, unsigned int type,
338 unsigned int code, int value)
341 static unsigned long count = 0;
343 struct l4evdev *evdev = handle->private;
344 l4_kernel_clock_t clk = l4_kip_clock(l4re_kip());
346 /* handle touchpads */
348 if (tpad_event(handle->dev, (struct l4evdev *)handle->private,
349 &type, &code, &value))
353 if (filter_event(handle, type, code, value)) return;
355 pthread_mutex_lock(&l4evdev_lock);
357 BUFFER[HEAD].evdev = evdev;
358 BUFFER[HEAD].l4event.time = clk;
359 BUFFER[HEAD].event.type = type;
360 BUFFER[HEAD].event.code = code;
361 BUFFER[HEAD].event.value = value;
362 BUFFER[HEAD].l4event.stream_id = (l4_umword_t)handle->dev;
366 /* check head and tail */
368 /* clear oldest event struct in buffer */
369 //memset(&BUFFER[TAIL], 0, sizeof(struct l4evdev_event));
373 pthread_mutex_unlock(&l4evdev_lock);
376 printf("l4evdev.c: Ev[%ld]. D: %s, T: %d, C: %d, V: %d\n",
377 count++, handle->dev->phys, type, code, value);
381 struct l4evdev *get_next_evdev(int *devnp)
385 for (devn = 0; (devn < L4EVDEV_DEVICES) && (DEVS[devn].exists); devn++)
388 if (devn == L4EVDEV_DEVICES) {
389 printf("l4evdev.c: no more free l4evdev devices\n");
398 /* XXX had connect/disconnect to be locked? */
400 static struct input_handle * l4evdev_connect(struct input_handler *handler,
401 struct input_dev *dev,
402 struct input_device_id *id)
405 struct l4evdev *evdev = get_next_evdev(&devn);
410 memset(evdev, 0, sizeof (struct l4evdev));
415 sprintf(evdev->name, "event%d", devn);
417 evdev->handle.dev = dev;
418 evdev->handle.name = evdev->name;
419 evdev->handle.handler = handler;
420 evdev->handle.private = evdev;
422 input_open_device(&evdev->handle);
424 printf("connect \"%s\", %s\n", dev->name, dev->phys);
426 if (test_bit(EV_SND, dev->evbit))
429 return &evdev->handle;
432 static void l4evdev_disconnect(struct input_handle *handle)
434 struct l4evdev *evdev = handle->private;
439 input_close_device(handle);
440 if (test_bit(EV_SND, handle->dev->evbit))
442 else /* XXX what about pending events? */
443 memset(&DEVS[evdev->devn], 0, sizeof(struct l4evdev));
446 static struct input_device_id l4evdev_ids[] = {
447 { .driver_info = 1 }, /* Matches all devices */
448 { }, /* Terminating zero entry */
451 static struct input_handler l4evdev_handler = {
452 .event = NULL, /* fill it on init() */
453 .connect = l4evdev_connect,
454 .disconnect = l4evdev_disconnect,
455 .fops = NULL, /* not used */
456 .minor = 0, /* not used */
458 .id_table = l4evdev_ids
461 /*****************************************************************************/
463 static int l4evdev_ispending(void)
465 return !(HEAD==TAIL);
468 static int l4evdev_flush(void *buf, int count)
471 struct l4input *buffer = buf;
473 pthread_mutex_lock(&l4evdev_lock);
475 while ((TAIL!=HEAD) && count) {
476 /* flush event buffer */
477 /* XXX if sizeof(struct l4input) and sizeof(struct input_event) differ
478 memcpy is not enough */
481 buffer->time = BUFFER[TAIL].l4event.time;
482 buffer->type = BUFFER[TAIL].event.type;
483 buffer->code = BUFFER[TAIL].event.code;
484 buffer->value = BUFFER[TAIL].event.value;
485 buffer->stream_id = BUFFER[TAIL].l4event.stream_id;
487 //memset(&BUFFER[TAIL], 0, sizeof(struct l4evdev_event));
494 pthread_mutex_unlock(&l4evdev_lock);
499 static void l4_input_fill_info(struct input_dev *dev, l4re_event_stream_info_t *info)
501 info->stream_id = (l4_umword_t)dev;
503 info->id.bustype = dev->id.bustype;
504 info->id.vendor = dev->id.vendor;
505 info->id.product = dev->id.product;
506 info->id.version = dev->id.version;
507 #define COPY_BITS(n) memcpy(info->n ##s, dev->n, min(sizeof(info->n ##s), sizeof(dev->n)))
518 l4evdev_stream_info_for_id(l4_umword_t id, l4re_event_stream_info_t *si)
521 for (devn = 0; devn < L4EVDEV_DEVICES; devn++) {
522 if (!DEVS[devn].exists)
524 if ((l4_umword_t)DEVS[devn].handle.dev == id) {
525 l4_input_fill_info(DEVS[devn].handle.dev, si);
534 l4evdev_absinfo(l4_umword_t id, unsigned naxes, unsigned *axes,
535 l4re_event_absinfo_t *infos)
538 struct input_dev *dev;
539 for (devn = 0; devn < L4EVDEV_DEVICES; devn++) {
540 if (!DEVS[devn].exists)
542 if ((l4_umword_t)DEVS[devn].handle.dev == id) {
547 if (devn == L4EVDEV_DEVICES)
550 dev = DEVS[devn].handle.dev;
551 for (idx = 0; idx < naxes; idx++) {
552 unsigned a = axes[idx];
556 infos[idx].value = 0;
557 infos[idx].min = dev->absmin[a];
558 infos[idx].max = dev->absmax[a];
559 infos[idx].fuzz = dev->absfuzz[a];
560 infos[idx].flat = dev->absflat[a];
561 infos[idx].resolution = 0;
566 static int l4evdev_pcspkr(int tone)
571 input_event(pcspkr->handle.dev, EV_SND, SND_TONE, tone);
576 static struct l4input_ops ops = {
577 l4evdev_ispending, l4evdev_flush, l4evdev_pcspkr
580 struct l4input_ops * l4input_internal_l4evdev_init(L4_CV void (*cb)(struct l4input *))
585 l4evdev_handler.event = l4evdev_event_cb;
587 /* buffer events in ring buffer */
588 l4evdev_handler.event = l4evdev_event;
591 input_register_handler(&l4evdev_handler);
596 void l4input_internal_register_ux(struct input_dev *dev)
599 struct l4evdev *evdev = get_next_evdev(&devn);
604 printf("EVDEV-NR: %d\n", devn);
609 sprintf(evdev->name, "event%d", devn);
611 evdev->handle.dev = dev;
612 evdev->handle.name = evdev->name;
613 evdev->handle.handler = 0;
614 evdev->handle.private = evdev;
617 void l4input_internal_l4evdev_exit(void)
619 input_unregister_handler(&l4evdev_handler);