2 * tslib/plugins/input-raw.c
5 * Copyright (C) 2001 Russell King.
7 * Rewritten for the Linux input device API:
8 * Copyright (C) 2002 Nicolas Pitre
10 * This file is placed under the LGPL. Please see the file
11 * COPYING for more details.
14 * Read raw pressure, x, y, and timestamp from a touchscreen device.
27 #include <sys/types.h>
29 #include <linux/input.h>
30 #ifndef EV_SYN /* 2.4 kernel headers */
34 # define EV_CNT (EV_MAX+1)
37 # define ABS_CNT (ABS_MAX+1)
40 # define KEY_CNT (KEY_MAX+1)
43 #include "tslib-private.h"
45 #define GRAB_EVENTS_WANTED 1
46 #define GRAB_EVENTS_ACTIVE 2
49 struct tslib_module_info module;
60 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
61 #define BIT(nr) (1UL << (nr))
62 #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
63 #define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
64 #define BITS_PER_BYTE 8
65 #define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE)
66 #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
68 static int check_fd(struct tslib_input *i)
70 struct tsdev *ts = i->module.dev;
72 long evbit[BITS_TO_LONGS(EV_CNT)];
73 long absbit[BITS_TO_LONGS(ABS_CNT)];
74 long keybit[BITS_TO_LONGS(KEY_CNT)];
76 if (ioctl(ts->fd, EVIOCGVERSION, &version) < 0) {
77 fprintf(stderr, "tslib: Selected device is not a Linux input event device\n");
81 if (version < EV_VERSION) {
82 fprintf(stderr, "tslib: Selected device uses a different version of the event protocol than tslib was compiled for\n");
86 if ( (ioctl(ts->fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
87 !(evbit[BIT_WORD(EV_ABS)] & BIT_MASK(EV_ABS)) ||
88 !(evbit[BIT_WORD(EV_KEY)] & BIT_MASK(EV_KEY)) ) {
89 fprintf(stderr, "tslib: Selected device is not a touchscreen (must support ABS and KEY event types)\n");
93 if ((ioctl(ts->fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit)) < 0 ||
94 !(absbit[BIT_WORD(ABS_X)] & BIT_MASK(ABS_X)) ||
95 !(absbit[BIT_WORD(ABS_Y)] & BIT_MASK(ABS_Y))) {
96 fprintf(stderr, "tslib: Selected device is not a touchscreen (must support ABS_X and ABS_Y events)\n");
100 /* Since some touchscreens (eg. infrared) physically can't measure pressure,
101 the input system doesn't report it on those. Tslib relies on pressure, thus
102 we set it to constant 255. It's still controlled by BTN_TOUCH - when not
103 touched, the pressure is forced to 0. */
105 if (!(absbit[BIT_WORD(ABS_PRESSURE)] & BIT_MASK(ABS_PRESSURE))) {
108 if ((ioctl(ts->fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
109 !(keybit[BIT_WORD(BTN_TOUCH)] & BIT_MASK(BTN_TOUCH)) ) {
110 fprintf(stderr, "tslib: Selected device is not a touchscreen (must support BTN_TOUCH events)\n");
115 if (evbit[BIT_WORD(EV_SYN)] & BIT_MASK(EV_SYN))
118 if (i->grab_events == GRAB_EVENTS_WANTED) {
119 if (ioctl(ts->fd, EVIOCGRAB, (void *)1)) {
120 fprintf(stderr, "tslib: Unable to grab selected input device\n");
123 i->grab_events = GRAB_EVENTS_ACTIVE;
129 static int ts_input_read(struct tslib_module_info *inf,
130 struct ts_sample *samp, int nr)
132 struct tslib_input *i = (struct tslib_input *)inf;
133 struct tsdev *ts = inf->dev;
134 struct input_event ev;
140 i->sane_fd = check_fd(i);
142 if (i->sane_fd == -1)
147 ret = read(ts->fd, &ev, sizeof(struct input_event));
148 if (ret < (int)sizeof(struct input_event)) {
163 /* Fill out a new complete event */
170 samp->x = i->current_x;
171 samp->y = i->current_y;
172 samp->pressure = i->current_p;
176 fprintf(stderr, "RAW---------------------> %d %d %d %d.%d\n",
177 samp->x, samp->y, samp->pressure, samp->tv.tv_sec,
186 i->current_x = ev.value;
189 i->current_y = ev.value;
192 i->current_p = ev.value;
200 unsigned char *p = (unsigned char *) &ev;
201 int len = sizeof(struct input_event);
204 ret = read(ts->fd, p, len);
206 if (errno == EINTR) {
212 if (ret < (int)sizeof(struct input_event)) {
214 * restart read to get the rest of the event
220 /* successful read of a whole event */
222 if (ev.type == EV_ABS) {
226 samp->x = i->current_x = ev.value;
227 samp->y = i->current_y;
228 samp->pressure = i->current_p;
230 fprintf(stderr, "tslib: dropped x = 0\n");
236 samp->x = i->current_x;
237 samp->y = i->current_y = ev.value;
238 samp->pressure = i->current_p;
240 fprintf(stderr, "tslib: dropped y = 0\n");
245 samp->x = i->current_x;
246 samp->y = i->current_y;
247 samp->pressure = i->current_p = ev.value;
252 fprintf(stderr, "RAW---------------------------> %d %d %d\n",
253 samp->x, samp->y, samp->pressure);
257 } else if (ev.type == EV_KEY) {
272 fprintf(stderr, "tslib: Unknown event type %d\n", ev.type);
274 p = (unsigned char *) &ev;
282 static int ts_input_fini(struct tslib_module_info *inf)
284 struct tslib_input *i = (struct tslib_input *)inf;
285 struct tsdev *ts = inf->dev;
287 if (i->grab_events == GRAB_EVENTS_ACTIVE) {
288 if (ioctl(ts->fd, EVIOCGRAB, (void *)0)) {
289 fprintf(stderr, "tslib: Unable to un-grab selected input device\n");
297 static const struct tslib_ops __ts_input_ops = {
298 .read = ts_input_read,
299 .fini = ts_input_fini,
302 static int parse_raw_grab(struct tslib_module_info *inf, char *str, void *data)
304 struct tslib_input *i = (struct tslib_input *)inf;
308 v = strtoul(str, NULL, 0);
310 if (v == ULONG_MAX && errno == ERANGE)
317 i->grab_events = GRAB_EVENTS_WANTED;
325 static const struct tslib_vars raw_vars[] =
327 { "grab_events", (void *)1, parse_raw_grab },
330 #define NR_VARS (sizeof(raw_vars) / sizeof(raw_vars[0]))
332 TSAPI struct tslib_module_info *input_mod_init(struct tsdev *dev, const char *params)
334 struct tslib_input *i;
336 i = malloc(sizeof(struct tslib_input));
340 i->module.ops = &__ts_input_ops;
348 if (tslib_parse_vars(&i->module, raw_vars, NR_VARS, params)) {
356 #ifndef TSLIB_STATIC_INPUT_MODULE
357 TSLIB_MODULE_INIT(input_mod_init);