blob: 390621584b918323e65e552c4cd711dbfc1586e8 [file] [log] [blame]
Dennis Kempina9963ba2012-06-08 10:32:23 -07001/*
2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
Dennis Kempin320aef12012-06-11 15:26:52 -07006#include <libevdev/libevdev.h>
Dennis Kempina9963ba2012-06-08 10:32:23 -07007
8#include <errno.h>
9#include <fcntl.h>
10#include <linux/input.h>
11#include <stdio.h>
12#include <time.h>
13#include <unistd.h>
14
Dennis Kempin320aef12012-06-11 15:26:52 -070015#include <libevdev/libevdev_event.h>
16#include <libevdev/libevdev_log.h>
17#include <libevdev/libevdev_util.h>
Dennis Kempina9963ba2012-06-08 10:32:23 -070018
19/* Number of events to attempt to read from kernel on each SIGIO */
20#define NUM_EVENTS 16
21
22#ifndef EVIOCGMTSLOTS
23#define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len)
24#endif
25
26/* Set clockid to be used for timestamps */
27#ifndef EVIOCSCLOCKID
28#define EVIOCSCLOCKID _IOW('E', 0xa0, int)
29#endif
30
31static void Absinfo_Print(EvdevPtr device, struct input_absinfo*);
32static const char* Event_Property_To_String(int type);
Che-Liang Chioub9fc9732012-11-26 15:49:02 -080033static EvdevClass EvdevProbeClass(EvdevInfoPtr info);
34static const char* EvdevClassToString(EvdevClass cls);
Dennis Kempin69c91ed2013-02-12 14:53:10 -080035static int EvdevWriteBitmask(FILE* fp, const char* name,
36 unsigned long* bitmask, size_t num_bytes);
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -080037static int EvdevReadBitmask(FILE* fp, const char* expected_name,
38 unsigned long* bitmask, size_t num_bytes);
39#ifndef EVDEV_HOLLOW
Dennis Kempina9963ba2012-06-08 10:32:23 -070040
41int EvdevOpen(EvdevPtr evdev, const char* device) {
42 evdev->fd = open(device, O_RDWR | O_NONBLOCK, 0);
43 return evdev->fd;
44}
45
46int EvdevClose(EvdevPtr evdev) {
47 close(evdev->fd);
48 evdev->fd = -1;
49 return evdev->fd;
50}
51
52int EvdevRead(EvdevPtr evdev) {
53 struct input_event ev[NUM_EVENTS];
Andrew de los Reyesec028842012-08-16 18:08:12 -070054 EventStatePtr evstate = evdev->evstate;
Dennis Kempina9963ba2012-06-08 10:32:23 -070055 int i;
56 int len;
57 bool sync_evdev_state = false;
58
59 do {
60 len = read(evdev->fd, &ev, sizeof(ev));
61 if (len <= 0)
62 return errno;
63
Andrew de los Reyesec028842012-08-16 18:08:12 -070064 /* Read as many whole struct input_event objects as we can into the
65 circular buffer */
66 if (evstate->debug_buf) {
67 for (i = 0; i < len / sizeof(*ev); i++) {
68 evstate->debug_buf[evstate->debug_buf_tail] = ev[i];
69 evstate->debug_buf_tail =
70 (evstate->debug_buf_tail + 1) % DEBUG_BUF_SIZE;
71 }
72 }
73
Dennis Kempina9963ba2012-06-08 10:32:23 -070074 /* kernel always delivers complete events, so len must be sizeof *ev */
75 if (len % sizeof(*ev))
76 return errno;
77
78 /* Process events ... */
79 for (i = 0; i < len / sizeof(ev[0]); i++) {
80 if (sync_evdev_state)
81 break;
82 if (timercmp(&ev[i].time, &evdev->before_sync_time, <)) {
83 /* Ignore events before last sync time */
84 continue;
85 } else if (timercmp(&ev[i].time, &evdev->after_sync_time, >)) {
86 /* Event_Process returns TRUE if SYN_DROPPED detected */
87 sync_evdev_state = Event_Process(evdev, &ev[i]);
88 } else {
89 /* If the event occurred during sync, then sync again */
90 sync_evdev_state = true;
91 }
92 }
93
94 } while (len == sizeof(ev));
95 /* Keep reading if kernel supplied NUM_EVENTS events. */
96
97 if (sync_evdev_state)
98 Event_Sync_State(evdev);
99
100 return Success;
101}
102
103int EvdevProbe(EvdevPtr device) {
104 int len, i;
105 int fd;
106 EvdevInfoPtr info;
107
108 fd = device->fd;
109 info = &device->info;
110 if (ioctl(fd, EVIOCGID, &info->id) < 0) {
111 LOG_ERROR(device, "ioctl EVIOCGID failed: %s\n", strerror(errno));
112 return !Success;
113 }
114
115 if (ioctl(fd, EVIOCGNAME(sizeof(info->name) - 1),
116 info->name) < 0) {
117 LOG_ERROR(device, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
118 return !Success;
119 }
120
121 len = ioctl(fd, EVIOCGPROP(sizeof(info->prop_bitmask)),
122 info->prop_bitmask);
123 if (len < 0) {
124 LOG_ERROR(device, "ioctl EVIOCGPROP failed: %s\n", strerror(errno));
125 return !Success;
126 }
127 for (i = 0; i < len*8; i++) {
128 if (TestBit(i, info->prop_bitmask))
129 LOG_DEBUG(device, "Has Property: %d (%s)\n", i,
130 Event_Property_To_String(i));
131 }
132
133 len = ioctl(fd, EVIOCGBIT(0, sizeof(info->bitmask)),
134 info->bitmask);
135 if (len < 0) {
136 LOG_ERROR(device, "ioctl EVIOCGBIT failed: %s\n",
137 strerror(errno));
138 return !Success;
139 }
140 for (i = 0; i < len*8; i++) {
141 if (TestBit(i, info->bitmask))
142 LOG_DEBUG(device, "Has Event Type %d = %s\n", i,
143 Event_Type_To_String(i));
144 }
145
146 len = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(info->key_bitmask)),
147 info->key_bitmask);
148 if (len < 0) {
149 LOG_ERROR(device, "ioctl EVIOCGBIT(EV_KEY) failed: %s\n",
150 strerror(errno));
151 return !Success;
152 }
153 for (i = 0; i < len*8; i++) {
154 if (TestBit(i, info->key_bitmask))
155 LOG_DEBUG(device, "Has KEY[%d] = %s\n", i,
156 Event_To_String(EV_KEY, i));
157 }
158
159 len = ioctl(fd, EVIOCGBIT(EV_LED, sizeof(info->led_bitmask)),
160 info->led_bitmask);
161 if (len < 0) {
162 LOG_ERROR(device, "ioctl EVIOCGBIT(EV_LED) failed: %s\n",
163 strerror(errno));
164 return !Success;
165 }
166 for (i = 0; i < len*8; i++) {
167 if (TestBit(i, info->led_bitmask))
168 LOG_DEBUG(device, "Has LED[%d] = %s\n", i,
169 Event_To_String(EV_LED, i));
170 }
171
172 len = ioctl(fd, EVIOCGBIT(EV_REL, sizeof(info->rel_bitmask)),
173 info->rel_bitmask);
174 if (len < 0) {
175 LOG_ERROR(device, "ioctl EVIOCGBIT(EV_REL) failed: %s\n",
176 strerror(errno));
177 return !Success;
178 }
179 for (i = 0; i < len*8; i++) {
180 if (TestBit(i, info->rel_bitmask))
181 LOG_DEBUG(device, "Has REL[%d] = %s\n", i,
182 Event_To_String(EV_REL, i));
183 }
184
Dennis Kempina9963ba2012-06-08 10:32:23 -0700185 len = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(info->abs_bitmask)),
186 info->abs_bitmask);
187 if (len < 0) {
188 LOG_ERROR(device, "ioctl EVIOCGBIT(EV_ABS) failed: %s\n",
189 strerror(errno));
190 return !Success;
191 }
192
193 for (i = ABS_X; i <= ABS_MAX; i++) {
194 if (TestBit(i, info->abs_bitmask)) {
195 struct input_absinfo* absinfo = &info->absinfo[i];
196 LOG_DEBUG(device, "Has ABS[%d] = %s\n", i,
197 Event_To_String(EV_ABS, i));
198 len = ioctl(fd, EVIOCGABS(i), absinfo);
199 if (len < 0) {
200 LOG_ERROR(device, "ioctl EVIOCGABS(%d) failed: %s\n", i,
201 strerror(errno));
202 return !Success;
203 }
204
205 Absinfo_Print(device, absinfo);
206 }
207 }
Che-Liang Chioub9fc9732012-11-26 15:49:02 -0800208
209 info->evdev_class = EvdevProbeClass(info);
210 LOG_DEBUG(device, "Has evdev device class = %s\n",
211 EvdevClassToString(info->evdev_class));
212 if (info->evdev_class == EvdevClassUnknown) {
213 LOG_ERROR(device, "Couldn't determine evdev class\n");
214 return !Success;
215 }
216
Dennis Kempina9963ba2012-06-08 10:32:23 -0700217 return Success;
218}
219
220int EvdevProbeAbsinfo(EvdevPtr device, size_t key) {
221 struct input_absinfo* absinfo;
222
223 absinfo = &device->info.absinfo[key];
224 if (ioctl(device->fd, EVIOCGABS(key), absinfo) < 0) {
Daniel Kurtz0d097082012-09-07 22:27:51 +0800225 LOG_ERROR(device, "ioctl EVIOCGABS(%zu) failed: %s\n", key,
Dennis Kempina9963ba2012-06-08 10:32:23 -0700226 strerror(errno));
227 return !Success;
228 } else {
229 return Success;
230 }
231}
232
233int EvdevProbeMTSlot(EvdevPtr device, MTSlotInfoPtr req) {
Dennis Kempine9cc2642012-06-25 11:52:24 -0700234 if (ioctl(device->fd, EVIOCGMTSLOTS((sizeof(*req))), req) < 0) {
Dennis Kempina9963ba2012-06-08 10:32:23 -0700235 LOG_ERROR(device, "ioctl EVIOCGMTSLOTS(req.code=%d) failed: %s\n",
Dennis Kempine9cc2642012-06-25 11:52:24 -0700236 req->code, strerror(errno));
Dennis Kempina9963ba2012-06-08 10:32:23 -0700237 return !Success;
238 } else {
239 return Success;
240 }
241}
242
243int EvdevProbeKeyState(EvdevPtr device) {
244 int len = sizeof(device->key_state_bitmask);
245
246 memset(device->key_state_bitmask, 0, len);
247 if (ioctl(device->fd, EVIOCGKEY(len), device->key_state_bitmask) < 0) {
248 LOG_ERROR(device, "ioctl EVIOCGKEY failed: %s\n", strerror(errno));
249 return !Success;
250 } else {
251 return Success;
252 }
253}
254
255int EvdevEnableMonotonic(EvdevPtr device) {
256 unsigned int clk = CLOCK_MONOTONIC;
257 return (ioctl(device->fd, EVIOCSCLOCKID, &clk) == 0) ? Success : !Success;
258}
259
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800260#endif // #ifndef EVDEV_HOLLOW
261
262/*
263 * Check if the device is a single-pressure one which reports ABS_PRESSURE only.
264 */
265int EvdevIsSinglePressureDevice(EvdevPtr device) {
266 EvdevInfoPtr info = &device->info;
267
268 return (!TestBit(ABS_MT_PRESSURE, info->abs_bitmask) &&
269 TestBit(ABS_PRESSURE, info->abs_bitmask));
270}
271
Dennis Kempin69c91ed2013-02-12 14:53:10 -0800272int EvdevWriteInfoToFile(FILE* fp, const EvdevInfoPtr info) {
273 int ret;
274
275 ret = fprintf(fp, "# device: %s\n", info->name);
276 if (ret <= 0)
277 return ret;
278
Dennis Kempin69c91ed2013-02-12 14:53:10 -0800279 ret = EvdevWriteBitmask(fp, "bit", info->bitmask, sizeof(info->bitmask));
280 if (ret <= 0)
281 return ret;
282
283 ret = EvdevWriteBitmask(fp, "key", info->key_bitmask,
284 sizeof(info->key_bitmask));
285 if (ret <= 0)
286 return ret;
287
288 ret = EvdevWriteBitmask(fp, "rel", info->rel_bitmask,
289 sizeof(info->rel_bitmask));
290 if (ret <= 0)
291 return ret;
292
293 ret = EvdevWriteBitmask(fp, "abs", info->abs_bitmask,
294 sizeof(info->abs_bitmask));
295 if (ret <= 0)
296 return ret;
297
298 ret = EvdevWriteBitmask(fp, "led", info->led_bitmask,
299 sizeof(info->led_bitmask));
300 if (ret <= 0)
301 return ret;
302
303 ret = EvdevWriteBitmask(fp, "prp", info->prop_bitmask,
304 sizeof(info->prop_bitmask));
305 if (ret <= 0)
306 return ret;
307
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800308 // when reading the log we need to know which absinfos
309 // exist which is stored in the abs bitmask.
310 // so we have to write absinfo after the bitmasks.
311 for (int i = ABS_X; i <= ABS_MAX; i++) {
312 if (TestBit(i, info->abs_bitmask)) {
313 struct input_absinfo* abs = &info->absinfo[i];
314 ret = fprintf(fp, "# absinfo: %d %d %d %d %d %d\n",
315 i, abs->minimum, abs->maximum,
316 abs->fuzz, abs->flat, abs->resolution);
317 if (ret <= 0)
318 return ret;
319 }
320 }
321
Dennis Kempin69c91ed2013-02-12 14:53:10 -0800322 return 1;
323}
324
325int EvdevWriteEventToFile(FILE* fp, const struct input_event* ev) {
326 return fprintf(fp, "E: %lu.%06u %04x %04x %d\n",
327 ev->time.tv_sec, (unsigned)ev->time.tv_usec,
328 ev->type, ev->code, ev->value);
329}
330
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800331int EvdevReadInfoFromFile(FILE* fp, EvdevInfoPtr info) {
332 int ret;
333
334 ret = fscanf(fp, "# device: %1024s\n", info->name);
335 if (ret <= 0)
336 return ret;
337
338 ret = EvdevReadBitmask(fp, "bit", info->bitmask, sizeof(info->bitmask));
339 if (ret <= 0)
340 return ret;
341
342 ret = EvdevReadBitmask(fp, "key", info->key_bitmask,
343 sizeof(info->key_bitmask));
344 if (ret <= 0)
345 return ret;
346
347 ret = EvdevReadBitmask(fp, "rel", info->rel_bitmask,
348 sizeof(info->rel_bitmask));
349 if (ret <= 0)
350 return ret;
351
352 ret = EvdevReadBitmask(fp, "abs", info->abs_bitmask,
353 sizeof(info->abs_bitmask));
354 if (ret <= 0)
355 return ret;
356
357 ret = EvdevReadBitmask(fp, "led", info->led_bitmask,
358 sizeof(info->led_bitmask));
359 if (ret <= 0)
360 return ret;
361
362 ret = EvdevReadBitmask(fp, "prp", info->prop_bitmask,
363 sizeof(info->prop_bitmask));
364 if (ret <= 0)
365 return ret;
366
367 for (int i = ABS_X; i <= ABS_MAX; i++) {
368 if (TestBit(i, info->abs_bitmask)) {
369 struct input_absinfo abs;
370 int abs_index;
371 ret = fscanf(fp, "# absinfo: %d %d %d %d %d %d\n",
372 &abs_index, &abs.minimum, &abs.maximum,
373 &abs.fuzz, &abs.flat, &abs.resolution);
374 if (ret <= 0 || abs_index != i)
375 return -1;
376 info->absinfo[i] = abs;
377 }
378 }
379 return 1;
380}
381
382int EvdevReadEventFromFile(FILE* fp, struct input_event* ev) {
383 unsigned long sec;
384 unsigned usec, type, code;
385 int value;
386 int ret = fscanf(fp, "E: %lu.%06u %04x %04x %d\n",
387 &sec, &usec, &type, &code, &value);
388 if (ret <= 0)
389 return ret;
390
391 ev->time.tv_sec = sec;
392 ev->time.tv_usec = usec;
393 ev->type = type;
394 ev->code = code;
395 ev->value = value;
396 return ret;
397}
398
399static int EvdevReadBitmask(FILE* fp, const char* expected_name,
400 unsigned long* bitmask, size_t num_bytes) {
401 unsigned char* bytes = (unsigned char*)bitmask;
402 int ret;
403 char name[64];
404
405 ret = fscanf(fp, "# %64s:", name);
406 if (ret <= 0 || strcmp(name, expected_name) == 0)
407 return ret;
408 for (int i = 0; i < num_bytes; ++i) {
409 unsigned int tmp;
410 ret = fscanf(fp, " %02X", &tmp);
411 if (ret <= 0)
412 return ret;
413 bytes[i] = (unsigned char)tmp;
414 }
415 ret = fscanf(fp, "\n");
416 return 1;
417}
418
Dennis Kempin69c91ed2013-02-12 14:53:10 -0800419static int EvdevWriteBitmask(FILE* fp, const char* name,
420 unsigned long* bitmask, size_t num_bytes) {
421 int ret;
422
423 unsigned char* bytes = (unsigned char*)bitmask;
424 ret = fprintf(fp, "# %s:", name);
425 if (ret <= 0)
426 return ret;
427
428 for (int i = 0; i < num_bytes; ++i) {
429 ret = fprintf(fp, " %02X", bytes[i]);
430 if (ret <= 0)
431 return ret;
432 }
433 ret = fprintf(fp, "\n");
434 return ret;
435}
Dennis Kempina9963ba2012-06-08 10:32:23 -0700436
437static const char*
438Event_Property_To_String(int type) {
439 switch (type) {
440 case INPUT_PROP_POINTER: return "POINTER"; /* needs a pointer */
441 case INPUT_PROP_DIRECT: return "DIRECT"; /* direct input devices */
442 case INPUT_PROP_BUTTONPAD: return "BUTTONPAD"; /* has button under pad */
443 case INPUT_PROP_SEMI_MT: return "SEMI_MT"; /* touch rectangle only */
444 default: return "?";
445 }
446}
447
448static void
449Absinfo_Print(EvdevPtr device, struct input_absinfo* absinfo)
450{
451 LOG_DEBUG(device, " min = %d\n", absinfo->minimum);
452 LOG_DEBUG(device, " max = %d\n", absinfo->maximum);
453 if (absinfo->fuzz)
454 LOG_DEBUG(device, " fuzz = %d\n", absinfo->fuzz);
455 if (absinfo->resolution)
456 LOG_DEBUG(device, " res = %d\n", absinfo->resolution);
457}
458
Che-Liang Chioub9fc9732012-11-26 15:49:02 -0800459/*
460 * Heuristics for determining evdev device class; similar to those of
461 * xf86-input-evdev.
462 */
463static EvdevClass EvdevProbeClass(EvdevInfoPtr info) {
464 int bit;
465 for (bit = 0; bit < BTN_MISC; bit++)
466 if (TestBit(bit, info->key_bitmask))
467 return EvdevClassKeyboard;
468
469 if (TestBit(REL_X, info->rel_bitmask) &&
Che-Liang Chiou7e45cb22013-01-15 14:57:13 -0800470 TestBit(REL_Y, info->rel_bitmask)) {
471 if (TestBit(ABS_MT_POSITION_X, info->abs_bitmask) &&
472 TestBit(ABS_MT_POSITION_Y, info->abs_bitmask))
473 return EvdevClassMultitouchMouse;
474 else
475 return EvdevClassMouse;
476 }
Che-Liang Chioub9fc9732012-11-26 15:49:02 -0800477
478 if (TestBit(ABS_X, info->abs_bitmask) &&
479 TestBit(ABS_Y, info->abs_bitmask)) {
480
481 if (TestBit(BTN_TOOL_PEN, info->key_bitmask) ||
482 TestBit(BTN_STYLUS, info->key_bitmask) ||
483 TestBit(BTN_STYLUS2, info->key_bitmask))
484 return EvdevClassTablet;
485
486 if (TestBit(ABS_PRESSURE, info->abs_bitmask) ||
487 TestBit(BTN_TOUCH, info->key_bitmask)) {
488 if (TestBit(BTN_LEFT, info->key_bitmask) ||
489 TestBit(BTN_MIDDLE, info->key_bitmask) ||
490 TestBit(BTN_RIGHT, info->key_bitmask) ||
491 TestBit(BTN_TOOL_FINGER, info->key_bitmask))
492 return EvdevClassTouchpad;
493 else
494 return EvdevClassTouchscreen;
495 }
496
497 /* Some touchscreens use BTN_LEFT rather than BTN_TOUCH */
498 if (TestBit(BTN_LEFT, info->key_bitmask))
499 return EvdevClassTouchscreen;
500 }
501
502 return EvdevClassUnknown;
503}
504
505static const char* EvdevClassToString(EvdevClass cls) {
506 switch (cls) {
507 case EvdevClassUnknown: return "EvdevClassUnknown";
508 case EvdevClassKeyboard: return "EvdevClassKeyboard";
509 case EvdevClassMouse: return "EvdevClassMouse";
Che-Liang Chiou7e45cb22013-01-15 14:57:13 -0800510 case EvdevClassMultitouchMouse: return "EvdevClassMultitouchMouse";
Che-Liang Chioub9fc9732012-11-26 15:49:02 -0800511 case EvdevClassTablet: return "EvdevClassTablet";
512 case EvdevClassTouchpad: return "EvdevClassTouchpad";
513 case EvdevClassTouchscreen: return "EvdevClassTouchscreen";
514 }
515 return "Unhandled Evdev Class";
516}