blob: 1b4d52e24832d55ce18aac1d653439e2b70c1cb6 [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
Dennis Kempin0e265392013-02-22 12:59:03 -080031static int EvdevWriteBitmask(FILE* fp, const char* name,
32 unsigned long* bitmask, size_t num_bytes);
33static int EvdevReadBitmask(FILE* fp, const char* expected_name,
34 unsigned long* bitmask, size_t num_bytes);
35
36#ifndef EVDEV_HOLLOW
37
Dennis Kempina9963ba2012-06-08 10:32:23 -070038static void Absinfo_Print(EvdevPtr device, struct input_absinfo*);
39static const char* Event_Property_To_String(int type);
Che-Liang Chioub9fc9732012-11-26 15:49:02 -080040static EvdevClass EvdevProbeClass(EvdevInfoPtr info);
41static const char* EvdevClassToString(EvdevClass cls);
Dennis Kempina9963ba2012-06-08 10:32:23 -070042
43int EvdevOpen(EvdevPtr evdev, const char* device) {
44 evdev->fd = open(device, O_RDWR | O_NONBLOCK, 0);
45 return evdev->fd;
46}
47
48int EvdevClose(EvdevPtr evdev) {
49 close(evdev->fd);
50 evdev->fd = -1;
51 return evdev->fd;
52}
53
54int EvdevRead(EvdevPtr evdev) {
55 struct input_event ev[NUM_EVENTS];
Andrew de los Reyesec028842012-08-16 18:08:12 -070056 EventStatePtr evstate = evdev->evstate;
Dennis Kempina9963ba2012-06-08 10:32:23 -070057 int i;
58 int len;
Michael Spang61f882f2015-04-09 11:07:40 -040059 int status = Success;
Dennis Kempina9963ba2012-06-08 10:32:23 -070060 bool sync_evdev_state = false;
61
62 do {
63 len = read(evdev->fd, &ev, sizeof(ev));
Michael Spang61f882f2015-04-09 11:07:40 -040064 if (len < 0) {
65 if (errno != EINTR && errno != EAGAIN)
66 status = errno;
Chung-yih Wang53af0892013-06-27 18:13:37 +080067 break;
Michael Spang61f882f2015-04-09 11:07:40 -040068 }
Dennis Kempina9963ba2012-06-08 10:32:23 -070069
Andrew de los Reyesec028842012-08-16 18:08:12 -070070 /* Read as many whole struct input_event objects as we can into the
71 circular buffer */
Yunlian Jiang4f5d5052015-01-20 14:27:40 -080072 for (i = 0; i < len / sizeof(*ev); i++) {
73 evstate->debug_buf[evstate->debug_buf_tail] = ev[i];
74 evstate->debug_buf_tail =
75 (evstate->debug_buf_tail + 1) % DEBUG_BUF_SIZE;
Andrew de los Reyesec028842012-08-16 18:08:12 -070076 }
77
Dennis Kempina9963ba2012-06-08 10:32:23 -070078 /* kernel always delivers complete events, so len must be sizeof *ev */
79 if (len % sizeof(*ev))
Chung-yih Wang53af0892013-06-27 18:13:37 +080080 break;
Dennis Kempina9963ba2012-06-08 10:32:23 -070081
82 /* Process events ... */
83 for (i = 0; i < len / sizeof(ev[0]); i++) {
84 if (sync_evdev_state)
85 break;
86 if (timercmp(&ev[i].time, &evdev->before_sync_time, <)) {
87 /* Ignore events before last sync time */
88 continue;
89 } else if (timercmp(&ev[i].time, &evdev->after_sync_time, >)) {
90 /* Event_Process returns TRUE if SYN_DROPPED detected */
Chung-yih Wang53af0892013-06-27 18:13:37 +080091 sync_evdev_state |= Event_Process(evdev, &ev[i]);
Dennis Kempina9963ba2012-06-08 10:32:23 -070092 } else {
93 /* If the event occurred during sync, then sync again */
94 sync_evdev_state = true;
95 }
96 }
97
98 } while (len == sizeof(ev));
99 /* Keep reading if kernel supplied NUM_EVENTS events. */
100
101 if (sync_evdev_state)
102 Event_Sync_State(evdev);
103
Michael Spang61f882f2015-04-09 11:07:40 -0400104 return status;
Dennis Kempina9963ba2012-06-08 10:32:23 -0700105}
106
107int EvdevProbe(EvdevPtr device) {
108 int len, i;
109 int fd;
110 EvdevInfoPtr info;
111
112 fd = device->fd;
113 info = &device->info;
114 if (ioctl(fd, EVIOCGID, &info->id) < 0) {
115 LOG_ERROR(device, "ioctl EVIOCGID failed: %s\n", strerror(errno));
116 return !Success;
117 }
118
119 if (ioctl(fd, EVIOCGNAME(sizeof(info->name) - 1),
120 info->name) < 0) {
121 LOG_ERROR(device, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
122 return !Success;
123 }
124
125 len = ioctl(fd, EVIOCGPROP(sizeof(info->prop_bitmask)),
126 info->prop_bitmask);
127 if (len < 0) {
128 LOG_ERROR(device, "ioctl EVIOCGPROP failed: %s\n", strerror(errno));
129 return !Success;
130 }
131 for (i = 0; i < len*8; i++) {
132 if (TestBit(i, info->prop_bitmask))
133 LOG_DEBUG(device, "Has Property: %d (%s)\n", i,
134 Event_Property_To_String(i));
135 }
136
137 len = ioctl(fd, EVIOCGBIT(0, sizeof(info->bitmask)),
138 info->bitmask);
139 if (len < 0) {
140 LOG_ERROR(device, "ioctl EVIOCGBIT failed: %s\n",
141 strerror(errno));
142 return !Success;
143 }
144 for (i = 0; i < len*8; i++) {
145 if (TestBit(i, info->bitmask))
146 LOG_DEBUG(device, "Has Event Type %d = %s\n", i,
147 Event_Type_To_String(i));
148 }
149
150 len = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(info->key_bitmask)),
151 info->key_bitmask);
152 if (len < 0) {
153 LOG_ERROR(device, "ioctl EVIOCGBIT(EV_KEY) failed: %s\n",
154 strerror(errno));
155 return !Success;
156 }
157 for (i = 0; i < len*8; i++) {
158 if (TestBit(i, info->key_bitmask))
159 LOG_DEBUG(device, "Has KEY[%d] = %s\n", i,
160 Event_To_String(EV_KEY, i));
161 }
162
Sean O'Brien23f8ea72018-02-28 08:16:49 -0800163 len = ioctl(fd, EVIOCGBIT(EV_MSC, sizeof(info->msc_bitmask)),
164 info->msc_bitmask);
165 if (len < 0) {
166 LOG_ERROR(device, "ioctl EVIOCGBIT(EV_MSC) failed: %s\n",
167 strerror(errno));
168 return !Success;
169 }
170 for (i = 0; i < len*8; i++) {
171 if (TestBit(i, info->msc_bitmask)) {
172 LOG_DEBUG(device, "Has MSC[%d] = %s\n", i,
173 Event_To_String(EV_MSC, i));
174 }
175 }
176
Dennis Kempina9963ba2012-06-08 10:32:23 -0700177 len = ioctl(fd, EVIOCGBIT(EV_LED, sizeof(info->led_bitmask)),
178 info->led_bitmask);
179 if (len < 0) {
180 LOG_ERROR(device, "ioctl EVIOCGBIT(EV_LED) failed: %s\n",
181 strerror(errno));
182 return !Success;
183 }
184 for (i = 0; i < len*8; i++) {
185 if (TestBit(i, info->led_bitmask))
186 LOG_DEBUG(device, "Has LED[%d] = %s\n", i,
187 Event_To_String(EV_LED, i));
188 }
189
190 len = ioctl(fd, EVIOCGBIT(EV_REL, sizeof(info->rel_bitmask)),
191 info->rel_bitmask);
192 if (len < 0) {
193 LOG_ERROR(device, "ioctl EVIOCGBIT(EV_REL) failed: %s\n",
194 strerror(errno));
195 return !Success;
196 }
197 for (i = 0; i < len*8; i++) {
198 if (TestBit(i, info->rel_bitmask))
199 LOG_DEBUG(device, "Has REL[%d] = %s\n", i,
200 Event_To_String(EV_REL, i));
201 }
202
Dennis Kempina9963ba2012-06-08 10:32:23 -0700203 len = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(info->abs_bitmask)),
204 info->abs_bitmask);
205 if (len < 0) {
206 LOG_ERROR(device, "ioctl EVIOCGBIT(EV_ABS) failed: %s\n",
207 strerror(errno));
208 return !Success;
209 }
210
211 for (i = ABS_X; i <= ABS_MAX; i++) {
212 if (TestBit(i, info->abs_bitmask)) {
213 struct input_absinfo* absinfo = &info->absinfo[i];
214 LOG_DEBUG(device, "Has ABS[%d] = %s\n", i,
215 Event_To_String(EV_ABS, i));
216 len = ioctl(fd, EVIOCGABS(i), absinfo);
217 if (len < 0) {
218 LOG_ERROR(device, "ioctl EVIOCGABS(%d) failed: %s\n", i,
219 strerror(errno));
220 return !Success;
221 }
222
223 Absinfo_Print(device, absinfo);
224 }
225 }
Che-Liang Chioub9fc9732012-11-26 15:49:02 -0800226
227 info->evdev_class = EvdevProbeClass(info);
228 LOG_DEBUG(device, "Has evdev device class = %s\n",
229 EvdevClassToString(info->evdev_class));
230 if (info->evdev_class == EvdevClassUnknown) {
231 LOG_ERROR(device, "Couldn't determine evdev class\n");
232 return !Success;
233 }
234
Dennis Kempina9963ba2012-06-08 10:32:23 -0700235 return Success;
236}
237
238int EvdevProbeAbsinfo(EvdevPtr device, size_t key) {
239 struct input_absinfo* absinfo;
240
241 absinfo = &device->info.absinfo[key];
242 if (ioctl(device->fd, EVIOCGABS(key), absinfo) < 0) {
Daniel Kurtz0d097082012-09-07 22:27:51 +0800243 LOG_ERROR(device, "ioctl EVIOCGABS(%zu) failed: %s\n", key,
Dennis Kempina9963ba2012-06-08 10:32:23 -0700244 strerror(errno));
245 return !Success;
246 } else {
247 return Success;
248 }
249}
250
251int EvdevProbeMTSlot(EvdevPtr device, MTSlotInfoPtr req) {
Dennis Kempine9cc2642012-06-25 11:52:24 -0700252 if (ioctl(device->fd, EVIOCGMTSLOTS((sizeof(*req))), req) < 0) {
Dennis Kempina9963ba2012-06-08 10:32:23 -0700253 LOG_ERROR(device, "ioctl EVIOCGMTSLOTS(req.code=%d) failed: %s\n",
Dennis Kempine9cc2642012-06-25 11:52:24 -0700254 req->code, strerror(errno));
Dennis Kempina9963ba2012-06-08 10:32:23 -0700255 return !Success;
256 } else {
257 return Success;
258 }
259}
260
261int EvdevProbeKeyState(EvdevPtr device) {
262 int len = sizeof(device->key_state_bitmask);
263
264 memset(device->key_state_bitmask, 0, len);
265 if (ioctl(device->fd, EVIOCGKEY(len), device->key_state_bitmask) < 0) {
266 LOG_ERROR(device, "ioctl EVIOCGKEY failed: %s\n", strerror(errno));
267 return !Success;
268 } else {
269 return Success;
270 }
271}
272
273int EvdevEnableMonotonic(EvdevPtr device) {
274 unsigned int clk = CLOCK_MONOTONIC;
275 return (ioctl(device->fd, EVIOCSCLOCKID, &clk) == 0) ? Success : !Success;
276}
277
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800278#endif // #ifndef EVDEV_HOLLOW
279
280/*
281 * Check if the device is a single-pressure one which reports ABS_PRESSURE only.
282 */
283int EvdevIsSinglePressureDevice(EvdevPtr device) {
284 EvdevInfoPtr info = &device->info;
285
286 return (!TestBit(ABS_MT_PRESSURE, info->abs_bitmask) &&
287 TestBit(ABS_PRESSURE, info->abs_bitmask));
288}
289
Dennis Kempin69c91ed2013-02-12 14:53:10 -0800290int EvdevWriteInfoToFile(FILE* fp, const EvdevInfoPtr info) {
291 int ret;
292
293 ret = fprintf(fp, "# device: %s\n", info->name);
294 if (ret <= 0)
295 return ret;
296
Dennis Kempin69c91ed2013-02-12 14:53:10 -0800297 ret = EvdevWriteBitmask(fp, "bit", info->bitmask, sizeof(info->bitmask));
298 if (ret <= 0)
299 return ret;
300
301 ret = EvdevWriteBitmask(fp, "key", info->key_bitmask,
302 sizeof(info->key_bitmask));
303 if (ret <= 0)
304 return ret;
305
306 ret = EvdevWriteBitmask(fp, "rel", info->rel_bitmask,
307 sizeof(info->rel_bitmask));
308 if (ret <= 0)
309 return ret;
310
311 ret = EvdevWriteBitmask(fp, "abs", info->abs_bitmask,
312 sizeof(info->abs_bitmask));
313 if (ret <= 0)
314 return ret;
315
316 ret = EvdevWriteBitmask(fp, "led", info->led_bitmask,
317 sizeof(info->led_bitmask));
318 if (ret <= 0)
319 return ret;
320
321 ret = EvdevWriteBitmask(fp, "prp", info->prop_bitmask,
322 sizeof(info->prop_bitmask));
323 if (ret <= 0)
324 return ret;
325
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800326 // when reading the log we need to know which absinfos
327 // exist which is stored in the abs bitmask.
328 // so we have to write absinfo after the bitmasks.
329 for (int i = ABS_X; i <= ABS_MAX; i++) {
330 if (TestBit(i, info->abs_bitmask)) {
331 struct input_absinfo* abs = &info->absinfo[i];
332 ret = fprintf(fp, "# absinfo: %d %d %d %d %d %d\n",
333 i, abs->minimum, abs->maximum,
334 abs->fuzz, abs->flat, abs->resolution);
335 if (ret <= 0)
336 return ret;
337 }
338 }
339
Dennis Kempin69c91ed2013-02-12 14:53:10 -0800340 return 1;
341}
342
343int EvdevWriteEventToFile(FILE* fp, const struct input_event* ev) {
Mike Frysinger7abec9e2012-12-23 13:00:24 -0500344 return fprintf(fp, "E: %ld.%06u %04x %04x %d\n",
345 (long)ev->time.tv_sec, (unsigned)ev->time.tv_usec,
Dennis Kempin69c91ed2013-02-12 14:53:10 -0800346 ev->type, ev->code, ev->value);
347}
348
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800349int EvdevReadInfoFromFile(FILE* fp, EvdevInfoPtr info) {
350 int ret;
351
Dennis Kempinbb4375b2013-03-28 12:02:54 -0700352 ret = fscanf(fp, "# device: %1024[^\n]\n", info->name);
Dennis Kempin690b3b42013-05-29 11:45:32 -0700353 if (ret <= 0)
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800354 return ret;
355
356 ret = EvdevReadBitmask(fp, "bit", info->bitmask, sizeof(info->bitmask));
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700357 if (ret <= 0) {
358 fprintf(stderr, "Parse device bit failed\n");
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800359 return ret;
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700360 }
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800361
362 ret = EvdevReadBitmask(fp, "key", info->key_bitmask,
363 sizeof(info->key_bitmask));
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700364 if (ret <= 0) {
365 fprintf(stderr, "Parse device key failed\n");
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800366 return ret;
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700367 }
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800368
369 ret = EvdevReadBitmask(fp, "rel", info->rel_bitmask,
370 sizeof(info->rel_bitmask));
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700371 if (ret <= 0) {
372 fprintf(stderr, "Parse device rel failed\n");
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800373 return ret;
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700374 }
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800375
376 ret = EvdevReadBitmask(fp, "abs", info->abs_bitmask,
377 sizeof(info->abs_bitmask));
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700378 if (ret <= 0) {
379 fprintf(stderr, "Parse device abs failed\n");
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800380 return ret;
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700381 }
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800382
383 ret = EvdevReadBitmask(fp, "led", info->led_bitmask,
384 sizeof(info->led_bitmask));
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700385 if (ret <= 0) {
386 fprintf(stderr, "Parse device led failed\n");
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800387 return ret;
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700388 }
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800389
390 ret = EvdevReadBitmask(fp, "prp", info->prop_bitmask,
391 sizeof(info->prop_bitmask));
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700392 if (ret <= 0) {
393 fprintf(stderr, "Parse device prp failed\n");
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800394 return ret;
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700395 }
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800396
397 for (int i = ABS_X; i <= ABS_MAX; i++) {
398 if (TestBit(i, info->abs_bitmask)) {
399 struct input_absinfo abs;
400 int abs_index;
401 ret = fscanf(fp, "# absinfo: %d %d %d %d %d %d\n",
402 &abs_index, &abs.minimum, &abs.maximum,
403 &abs.fuzz, &abs.flat, &abs.resolution);
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700404 if (ret <= 0 || abs_index != i) {
405 fprintf(stderr, "Parse device absinfo failed on %d\n", i);
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800406 return -1;
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700407 }
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800408 info->absinfo[i] = abs;
409 }
410 }
411 return 1;
412}
413
414int EvdevReadEventFromFile(FILE* fp, struct input_event* ev) {
415 unsigned long sec;
416 unsigned usec, type, code;
417 int value;
418 int ret = fscanf(fp, "E: %lu.%06u %04x %04x %d\n",
419 &sec, &usec, &type, &code, &value);
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700420 if (ret == EOF)
421 return -1;
422 if (ret <= 0) {
423 int err = errno;
424 fprintf(stderr, "EvdevReadEventFromFile failed: %d, errno: %d\n", ret, err);
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800425 return ret;
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700426 }
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800427
428 ev->time.tv_sec = sec;
429 ev->time.tv_usec = usec;
430 ev->type = type;
431 ev->code = code;
432 ev->value = value;
433 return ret;
434}
435
436static int EvdevReadBitmask(FILE* fp, const char* expected_name,
437 unsigned long* bitmask, size_t num_bytes) {
438 unsigned char* bytes = (unsigned char*)bitmask;
439 int ret;
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700440 char name[64] = { 0 };
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800441
Chung-yih Wang2eeae932013-04-29 12:50:46 +0800442 ret = fscanf(fp, "# %63[^:]:", name);
Andrew de los Reyes8fbd3c12013-05-08 09:30:50 -0700443 if (ret <= 0 || strcmp(name, expected_name)) {
444 fprintf(stderr, "EvdevReadBitmask: %d <= 0 or [%s]!=[%s]\n",
445 ret, name, expected_name);
446 return -1;
447 }
448 memset(bitmask, 0, num_bytes);
449 for (size_t i = 0; i < num_bytes; ++i) {
450 // Make sure we don't go off the end of the line
451 int next_char = fgetc(fp);
452 if (next_char != EOF)
453 ungetc(next_char, fp);
454 if (next_char == '\n' || next_char == EOF)
455 break;
456
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800457 unsigned int tmp;
458 ret = fscanf(fp, " %02X", &tmp);
459 if (ret <= 0)
Dennis Kempin1ecc7e92013-03-29 16:58:08 -0700460 bytes[i] = 0;
461 else
462 bytes[i] = (unsigned char)tmp;
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800463 }
Chung-yih Wang2eeae932013-04-29 12:50:46 +0800464 // size(in bytes) of bitmask array may differs per platform, try to read
465 // remaining bytes if exists
466 do {
467 if (fgets(name, sizeof(name), fp) == NULL)
468 return -1;
469 } while (name[strlen(name) - 1] != '\n');
Dennis Kempin9ec1b7c2013-02-19 14:28:48 -0800470 return 1;
471}
472
Dennis Kempin69c91ed2013-02-12 14:53:10 -0800473static int EvdevWriteBitmask(FILE* fp, const char* name,
474 unsigned long* bitmask, size_t num_bytes) {
475 int ret;
476
477 unsigned char* bytes = (unsigned char*)bitmask;
478 ret = fprintf(fp, "# %s:", name);
479 if (ret <= 0)
480 return ret;
481
482 for (int i = 0; i < num_bytes; ++i) {
483 ret = fprintf(fp, " %02X", bytes[i]);
484 if (ret <= 0)
485 return ret;
486 }
487 ret = fprintf(fp, "\n");
488 return ret;
489}
Dennis Kempina9963ba2012-06-08 10:32:23 -0700490
Dennis Kempin0e265392013-02-22 12:59:03 -0800491#ifndef EVDEV_HOLLOW
492
Dennis Kempina9963ba2012-06-08 10:32:23 -0700493static const char*
494Event_Property_To_String(int type) {
495 switch (type) {
496 case INPUT_PROP_POINTER: return "POINTER"; /* needs a pointer */
497 case INPUT_PROP_DIRECT: return "DIRECT"; /* direct input devices */
498 case INPUT_PROP_BUTTONPAD: return "BUTTONPAD"; /* has button under pad */
499 case INPUT_PROP_SEMI_MT: return "SEMI_MT"; /* touch rectangle only */
500 default: return "?";
501 }
502}
503
504static void
505Absinfo_Print(EvdevPtr device, struct input_absinfo* absinfo)
506{
507 LOG_DEBUG(device, " min = %d\n", absinfo->minimum);
508 LOG_DEBUG(device, " max = %d\n", absinfo->maximum);
509 if (absinfo->fuzz)
510 LOG_DEBUG(device, " fuzz = %d\n", absinfo->fuzz);
511 if (absinfo->resolution)
512 LOG_DEBUG(device, " res = %d\n", absinfo->resolution);
513}
514
Che-Liang Chioub9fc9732012-11-26 15:49:02 -0800515/*
516 * Heuristics for determining evdev device class; similar to those of
517 * xf86-input-evdev.
518 */
519static EvdevClass EvdevProbeClass(EvdevInfoPtr info) {
520 int bit;
Che-Liang Chioub9fc9732012-11-26 15:49:02 -0800521
522 if (TestBit(REL_X, info->rel_bitmask) &&
Che-Liang Chiou7e45cb22013-01-15 14:57:13 -0800523 TestBit(REL_Y, info->rel_bitmask)) {
524 if (TestBit(ABS_MT_POSITION_X, info->abs_bitmask) &&
525 TestBit(ABS_MT_POSITION_Y, info->abs_bitmask))
526 return EvdevClassMultitouchMouse;
527 else
528 return EvdevClassMouse;
529 }
Che-Liang Chioub9fc9732012-11-26 15:49:02 -0800530
531 if (TestBit(ABS_X, info->abs_bitmask) &&
532 TestBit(ABS_Y, info->abs_bitmask)) {
533
534 if (TestBit(BTN_TOOL_PEN, info->key_bitmask) ||
535 TestBit(BTN_STYLUS, info->key_bitmask) ||
536 TestBit(BTN_STYLUS2, info->key_bitmask))
537 return EvdevClassTablet;
538
539 if (TestBit(ABS_PRESSURE, info->abs_bitmask) ||
540 TestBit(BTN_TOUCH, info->key_bitmask)) {
541 if (TestBit(BTN_LEFT, info->key_bitmask) ||
542 TestBit(BTN_MIDDLE, info->key_bitmask) ||
543 TestBit(BTN_RIGHT, info->key_bitmask) ||
544 TestBit(BTN_TOOL_FINGER, info->key_bitmask))
545 return EvdevClassTouchpad;
546 else
547 return EvdevClassTouchscreen;
548 }
549
550 /* Some touchscreens use BTN_LEFT rather than BTN_TOUCH */
551 if (TestBit(BTN_LEFT, info->key_bitmask))
552 return EvdevClassTouchscreen;
553 }
554
Andrew de los Reyesa63c82a2014-04-03 16:11:26 -0700555 for (bit = 0; bit < BTN_MISC; bit++)
556 if (TestBit(bit, info->key_bitmask))
557 return EvdevClassKeyboard;
558
Che-Liang Chioub9fc9732012-11-26 15:49:02 -0800559 return EvdevClassUnknown;
560}
561
562static const char* EvdevClassToString(EvdevClass cls) {
563 switch (cls) {
564 case EvdevClassUnknown: return "EvdevClassUnknown";
565 case EvdevClassKeyboard: return "EvdevClassKeyboard";
566 case EvdevClassMouse: return "EvdevClassMouse";
Che-Liang Chiou7e45cb22013-01-15 14:57:13 -0800567 case EvdevClassMultitouchMouse: return "EvdevClassMultitouchMouse";
Che-Liang Chioub9fc9732012-11-26 15:49:02 -0800568 case EvdevClassTablet: return "EvdevClassTablet";
569 case EvdevClassTouchpad: return "EvdevClassTouchpad";
570 case EvdevClassTouchscreen: return "EvdevClassTouchscreen";
571 }
572 return "Unhandled Evdev Class";
573}
Dennis Kempin0e265392013-02-22 12:59:03 -0800574
575#endif // #ifndef EVDEV_HOLLOW