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;
60 struct l4input l4event;
63 /** l4evdev device structure */
69 struct input_handle handle;
72 unsigned int pkt_count;
73 int old_x[4], old_y[4];
78 struct l4evdev *pcspkr;
80 /** all known devices */
81 static struct l4evdev l4evdev_devices[L4EVDEV_DEVICES];
82 /** global event list */
83 static struct l4evdev_event l4evdev_buffer[L4EVDEV_BUFFER];
84 static int l4evdev_buffer_head = 0;
85 static int l4evdev_buffer_tail = 0;
86 #define DEVS l4evdev_devices
87 #define BUFFER l4evdev_buffer
88 #define HEAD l4evdev_buffer_head /**< next event slot */
89 #define TAIL l4evdev_buffer_tail /**< first-in event if !(HEAD==TAIL) */
90 #define INC(x) (x) = ((x) + 1) % L4EVDEV_BUFFER
92 static pthread_mutex_t l4evdev_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
94 /*************************
95 *** TOUCHPAD HANDLING ***
96 *************************/
97 /* convert absolute to relative events for inappropriate devices like touchpads
98 * (taken from input/mousedev.c) */
99 static unsigned int tpad_touch(struct l4evdev *mousedev, int value)
102 /* FIXME tap support */
104 if (mousedev->touch &&
105 time_before(jiffies, mousedev->touch + msecs_to_jiffies(tap_time))) {
107 * Toggle left button to emulate tap.
108 * We rely on the fact that mousedev_mix always has 0
109 * motion packet so we won't mess current position.
111 set_bit(0, &mousedev->packet.buttons);
112 set_bit(0, &mousedev_mix.packet.buttons);
113 mousedev_notify_readers(mousedev, &mousedev_mix.packet);
114 mousedev_notify_readers(&mousedev_mix, &mousedev_mix.packet);
115 clear_bit(0, &mousedev->packet.buttons);
116 clear_bit(0, &mousedev_mix.packet.buttons);
119 mousedev->touch = mousedev->pkt_count = 0;
120 mousedev->frac_dx = 0;
121 mousedev->frac_dy = 0;
124 if (!mousedev->touch)
125 mousedev->touch = jiffies;
127 /* FIXME tap support */
131 static unsigned int tpad_trans_key(unsigned int code)
164 /* abort per default */
166 button = KEY_RESERVED;
172 #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
173 #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
175 /* check event and convert if appropriate
176 * returns 1 if event should be ignored */
177 static int tpad_event(struct input_dev *dev, struct l4evdev *mousedev,
178 unsigned int *type0, unsigned int *code0, int *value0)
181 unsigned int type = *type0;
182 unsigned int code = *code0;
184 enum { FRACTION_DENOM = 128 };
186 /* is it really a touchpad ? */
187 if (!test_bit(BTN_TOOL_FINGER, dev->keybit))
193 /* from input/mousedev.c:315 */
196 if (value == 2) return 1;
198 if (code == BTN_TOUCH)
199 code = tpad_touch(mousedev, value);
201 code = tpad_trans_key(code);
203 /* ignore some unhandled codes */
204 if (code == KEY_RESERVED) return 1;
209 /* from input/mousedev.c:324 */
211 if (code == SYN_REPORT) {
212 if (mousedev->touch) {
213 mousedev->pkt_count++;
214 /* Input system eats duplicate events, but we need all of them
215 * to do correct averaging so apply present one forward
226 /* from input/mousedev.c:119 */
228 /* ignore if pad was not touched */
229 if (!mousedev->touch) return 1;
231 size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
232 if (size == 0) size = 256 * 2;
236 /* ignore events with insufficient state */
237 if (mousedev->pkt_count < 2) return 1;
239 tmp = ((value - fx(2)) * (256 * FRACTION_DENOM)) / size;
240 tmp += mousedev->frac_dx;
241 value = tmp / FRACTION_DENOM;
242 mousedev->frac_dx = tmp - value * FRACTION_DENOM;
249 /* ignore events with insufficient state */
250 if (mousedev->pkt_count < 2) return 1;
252 tmp = ((value - fy(2)) * (256 * FRACTION_DENOM)) / size;
253 tmp += mousedev->frac_dy;
254 value = tmp / FRACTION_DENOM;
255 mousedev->frac_dy = tmp - value * FRACTION_DENOM;
260 default: /* ignore this event */
266 /* ignore unknown events */
268 printf("l4evdev.c: tpad ignored. D: %s, T: %d, C: %d, V: %d\n",
269 mousedev->handle.dev->phys, type, code, value);
274 /* propagate handled events */
281 /** SOME EVENTS ARE FILTERED OUT **/
282 static inline int filter_event(struct input_handle *handle, unsigned int type,
283 unsigned int code, int value)
285 /* filter sound driver events */
286 if (test_bit(EV_SND, handle->dev->evbit))
289 /* filter misc event: scancode -- no handlers yet */
290 if ((type == EV_MSC) && (code == MSC_SCAN))
298 /** HANDLE INCOMING EVENTS (CALLBACK VARIANT) **/
299 static L4_CV void(*callback)(struct l4input *) = NULL;
301 static void l4evdev_event_cb(struct input_handle *handle, unsigned int type,
302 unsigned int code, int value)
305 static unsigned long count = 0;
307 static struct l4input ev;
309 /* handle touchpads */
311 if (tpad_event(handle->dev, (struct l4evdev *)handle->private,
312 &type, &code, &value))
316 if (filter_event(handle, type, code, value)) return;
318 ev.time = l4_kip_clock(l4re_kip());
322 ev.stream_id = (l4_umword_t)handle->dev;
328 printf("l4evdev.c: Ev[%ld]. D: %s, T: %d, C: %d, V: %d\n",
329 count++, handle->dev->phys, type, code, value);
333 /** HANDLE INCOMING EVENTS (BUFFER AND PULL VARIANT) **/
334 static void l4evdev_event(struct input_handle *handle, unsigned int type,
335 unsigned int code, int value)
338 static unsigned long count = 0;
340 struct l4evdev *evdev = handle->private;
341 l4_kernel_clock_t clk = l4_kip_clock(l4re_kip());
343 /* handle touchpads */
345 if (tpad_event(handle->dev, (struct l4evdev *)handle->private,
346 &type, &code, &value))
350 if (filter_event(handle, type, code, value)) return;
352 pthread_mutex_lock(&l4evdev_lock);
354 BUFFER[HEAD].evdev = evdev;
355 BUFFER[HEAD].l4event.time = clk;
356 BUFFER[HEAD].l4event.type = type;
357 BUFFER[HEAD].l4event.code = code;
358 BUFFER[HEAD].l4event.value = value;
359 BUFFER[HEAD].l4event.stream_id = (l4_umword_t)handle->dev;
363 /* check head and tail */
365 /* clear oldest event struct in buffer */
366 //memset(&BUFFER[TAIL], 0, sizeof(struct l4evdev_event));
370 pthread_mutex_unlock(&l4evdev_lock);
373 printf("l4evdev.c: Ev[%ld]. D: %s, T: %d, C: %d, V: %d\n",
374 count++, handle->dev->phys, type, code, value);
378 struct l4evdev *get_next_evdev(int *devnp)
382 for (devn = 0; (devn < L4EVDEV_DEVICES) && (DEVS[devn].exists); devn++)
385 if (devn == L4EVDEV_DEVICES) {
386 printf("l4evdev.c: no more free l4evdev devices\n");
395 /* XXX had connect/disconnect to be locked? */
397 static struct input_handle * l4evdev_connect(struct input_handler *handler,
398 struct input_dev *dev,
399 struct input_device_id *id)
402 struct l4evdev *evdev = get_next_evdev(&devn);
407 memset(evdev, 0, sizeof (struct l4evdev));
412 sprintf(evdev->name, "event%d", devn);
414 evdev->handle.dev = dev;
415 evdev->handle.name = evdev->name;
416 evdev->handle.handler = handler;
417 evdev->handle.private = evdev;
419 input_open_device(&evdev->handle);
421 printf("connect \"%s\", %s\n", dev->name, dev->phys);
423 if (test_bit(EV_SND, dev->evbit))
426 return &evdev->handle;
429 static void l4evdev_disconnect(struct input_handle *handle)
431 struct l4evdev *evdev = handle->private;
436 input_close_device(handle);
437 if (test_bit(EV_SND, handle->dev->evbit))
439 else /* XXX what about pending events? */
440 memset(&DEVS[evdev->devn], 0, sizeof(struct l4evdev));
443 static struct input_device_id l4evdev_ids[] = {
444 { .driver_info = 1 }, /* Matches all devices */
445 { }, /* Terminating zero entry */
448 static struct input_handler l4evdev_handler = {
449 .event = NULL, /* fill it on init() */
450 .connect = l4evdev_connect,
451 .disconnect = l4evdev_disconnect,
452 .fops = NULL, /* not used */
453 .minor = 0, /* not used */
455 .id_table = l4evdev_ids
458 /*****************************************************************************/
460 static int l4evdev_ispending(void)
462 return !(HEAD==TAIL);
465 static int l4evdev_flush(void *buf, int count)
468 struct l4input *buffer = buf;
470 pthread_mutex_lock(&l4evdev_lock);
472 while ((TAIL!=HEAD) && count) {
473 /* flush event buffer */
474 *buffer = BUFFER[TAIL].l4event;
476 //memset(&BUFFER[TAIL], 0, sizeof(struct l4evdev_event));
483 pthread_mutex_unlock(&l4evdev_lock);
488 static void l4_input_fill_info(struct input_dev *dev, l4re_event_stream_info_t *info)
490 memset(info, 0, sizeof(*info));
491 info->stream_id = (l4_umword_t)dev;
493 info->id.bustype = dev->id.bustype;
494 info->id.vendor = dev->id.vendor;
495 info->id.product = dev->id.product;
496 info->id.version = dev->id.version;
497 #define COPY_BITS(n) memcpy(info->n ##s, dev->n, min(sizeof(info->n ##s), sizeof(dev->n)))
508 l4evdev_stream_info_for_id(l4_umword_t id, l4re_event_stream_info_t *si)
511 for (devn = 0; devn < L4EVDEV_DEVICES; devn++) {
512 if (!DEVS[devn].exists)
514 if ((l4_umword_t)DEVS[devn].handle.dev == id) {
515 l4_input_fill_info(DEVS[devn].handle.dev, si);
524 l4evdev_absinfo(l4_umword_t id, unsigned naxes, unsigned const *axes,
525 l4re_event_absinfo_t *infos)
528 struct input_dev *dev;
529 for (devn = 0; devn < L4EVDEV_DEVICES; devn++) {
530 if (!DEVS[devn].exists)
532 if ((l4_umword_t)DEVS[devn].handle.dev == id) {
537 if (devn == L4EVDEV_DEVICES)
540 dev = DEVS[devn].handle.dev;
541 for (idx = 0; idx < naxes; idx++) {
542 unsigned a = axes[idx];
546 infos[idx].value = 0;
547 infos[idx].min = dev->absmin[a];
548 infos[idx].max = dev->absmax[a];
549 infos[idx].fuzz = dev->absfuzz[a];
550 infos[idx].flat = dev->absflat[a];
551 infos[idx].resolution = 0;
556 static int l4evdev_pcspkr(int tone)
561 input_event(pcspkr->handle.dev, EV_SND, SND_TONE, tone);
566 static struct l4input_ops ops = {
567 l4evdev_ispending, l4evdev_flush, l4evdev_pcspkr
570 struct l4input_ops * l4input_internal_l4evdev_init(L4_CV void (*cb)(struct l4input *))
575 l4evdev_handler.event = l4evdev_event_cb;
577 /* buffer events in ring buffer */
578 l4evdev_handler.event = l4evdev_event;
581 input_register_handler(&l4evdev_handler);
586 void l4input_internal_register_ux(struct input_dev *dev)
589 struct l4evdev *evdev = get_next_evdev(&devn);
594 printf("EVDEV-NR: %d\n", devn);
599 sprintf(evdev->name, "event%d", devn);
601 evdev->handle.dev = dev;
602 evdev->handle.name = evdev->name;
603 evdev->handle.handler = 0;
604 evdev->handle.private = evdev;
607 void l4input_internal_l4evdev_exit(void)
609 input_unregister_handler(&l4evdev_handler);