blob: 9e8841c58fab87de4f74ae737671dd21ebd77bac [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 */
6
Dennis Kempin320aef12012-06-11 15:26:52 -07007#include <libevdev/libevdev_event.h>
Dennis Kempina9963ba2012-06-08 10:32:23 -07008
9#include <errno.h>
10#include <linux/input.h>
11#include <stdbool.h>
12#include <time.h>
13
Dennis Kempin320aef12012-06-11 15:26:52 -070014#include <libevdev/libevdev.h>
15#include <libevdev/libevdev_util.h>
Dennis Kempina9963ba2012-06-08 10:32:23 -070016
17#ifndef BTN_TOOL_QUINTTAP
18#define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */
19#endif
20
21/* Set clockid to be used for timestamps */
22#ifndef EVIOCSCLOCKID
23#define EVIOCSCLOCKID _IOW('E', 0xa0, int)
24#endif
25
26#ifndef EVIOCGMTSLOTS
27#define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len)
28#endif
29
30/* SYN_DROPPED added in kernel v2.6.38-rc4 */
31#ifndef SYN_DROPPED
32#define SYN_DROPPED 3
33#endif
34
35
36
37static void Event_Syn(EvdevPtr, struct input_event*);
38static void Event_Syn_Report(EvdevPtr, struct input_event*);
39static void Event_Syn_MT_Report(EvdevPtr, struct input_event*);
40
41static void Event_Key(EvdevPtr, struct input_event*);
42
43static void Event_Abs(EvdevPtr, struct input_event*);
44static void Event_Abs_MT(EvdevPtr, struct input_event*);
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +080045static void Event_Abs_Update_Pressure(EvdevPtr, struct input_event*);
Dennis Kempina9963ba2012-06-08 10:32:23 -070046
47static void Event_Get_Time(struct timeval*, bool);
48
49/**
50 * Input Device Event Property accessors
51 */
52int
53Event_Get_Left(EvdevPtr device)
54{
Yufeng Shen86e52252012-07-05 11:44:36 -040055 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_X];
Dennis Kempina9963ba2012-06-08 10:32:23 -070056 return absinfo->minimum;
57}
58
59int
60Event_Get_Right(EvdevPtr device)
61{
Yufeng Shen86e52252012-07-05 11:44:36 -040062 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_X];
Dennis Kempina9963ba2012-06-08 10:32:23 -070063 return absinfo->maximum;
64}
65
66int
67Event_Get_Top(EvdevPtr device)
68{
Yufeng Shen86e52252012-07-05 11:44:36 -040069 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_Y];
Dennis Kempina9963ba2012-06-08 10:32:23 -070070 return absinfo->minimum;
71}
72
73int
74Event_Get_Bottom(EvdevPtr device)
75{
Yufeng Shen86e52252012-07-05 11:44:36 -040076 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_Y];
Dennis Kempina9963ba2012-06-08 10:32:23 -070077 return absinfo->maximum;
78}
79
80int
81Event_Get_Res_Y(EvdevPtr device)
82{
Yufeng Shen86e52252012-07-05 11:44:36 -040083 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_Y];
Dennis Kempina9963ba2012-06-08 10:32:23 -070084 return absinfo->resolution;
85}
86
87int
88Event_Get_Res_X(EvdevPtr device)
89{
Yufeng Shen86e52252012-07-05 11:44:36 -040090 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_X];
Dennis Kempina9963ba2012-06-08 10:32:23 -070091 return absinfo->resolution;
92}
93
94int
Che-Liang Chioua2563012012-10-11 11:41:06 -070095Event_Get_Orientation_Minimum(EvdevPtr device)
96{
97 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_ORIENTATION];
98 return absinfo->minimum;
99}
100
101int
102Event_Get_Orientation_Maximum(EvdevPtr device)
103{
104 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_ORIENTATION];
105 return absinfo->maximum;
106}
107
108int
Dennis Kempina9963ba2012-06-08 10:32:23 -0700109Event_Get_Button_Pad(EvdevPtr device)
110{
111 return TestBit(INPUT_PROP_BUTTONPAD, device->info.prop_bitmask);
112}
113
114int
115Event_Get_Semi_MT(EvdevPtr device)
116{
117 return TestBit(INPUT_PROP_SEMI_MT, device->info.prop_bitmask);
118}
119
120int
121Event_Get_T5R2(EvdevPtr device)
122{
123 EventStatePtr evstate = device->evstate;
124 if (Event_Get_Semi_MT(device))
125 return 0;
126 return (Event_Get_Touch_Count_Max(device) > evstate->slot_count);
127}
128
129int
130Event_Get_Touch_Count_Max(EvdevPtr device)
131{
132
133 if (TestBit(BTN_TOOL_QUINTTAP, device->info.key_bitmask))
134 return 5;
135 if (TestBit(BTN_TOOL_QUADTAP, device->info.key_bitmask))
136 return 4;
137 if (TestBit(BTN_TOOL_TRIPLETAP, device->info.key_bitmask))
138 return 3;
139 if (TestBit(BTN_TOOL_DOUBLETAP, device->info.key_bitmask))
140 return 2;
141 return 1;
142}
143
144int
145Event_Get_Touch_Count(EvdevPtr device)
146{
147
148 if (TestBit(BTN_TOOL_QUINTTAP, device->key_state_bitmask))
149 return 5;
150 if (TestBit(BTN_TOOL_QUADTAP, device->key_state_bitmask))
151 return 4;
152 if (TestBit(BTN_TOOL_TRIPLETAP, device->key_state_bitmask))
153 return 3;
154 if (TestBit(BTN_TOOL_DOUBLETAP, device->key_state_bitmask))
155 return 2;
156 if (TestBit(BTN_TOOL_FINGER, device->key_state_bitmask))
157 return 1;
158 return 0;
159}
160
161int
162Event_Get_Slot_Count(EvdevPtr device)
163{
164 EventStatePtr evstate = device->evstate;
165 return evstate->slot_count;
166}
167
168int
169Event_Get_Button_Left(EvdevPtr device)
170{
171 return TestBit(BTN_LEFT, device->key_state_bitmask);
172}
173
174int
175Event_Get_Button_Middle(EvdevPtr device)
176{
177 return TestBit(BTN_MIDDLE, device->key_state_bitmask);
178}
179
180int
181Event_Get_Button_Right(EvdevPtr device)
182{
183 return TestBit(BTN_RIGHT, device->key_state_bitmask);
184}
185
186#define CASE_RETURN(s) \
187 case (s):\
188 return #s
189
190
191const char *
192Event_To_String(int type, int code) {
193 switch (type) {
194 case EV_SYN:
195 switch (code) {
196 CASE_RETURN(SYN_REPORT);
197 CASE_RETURN(SYN_MT_REPORT);
198 default:
199 break;
200 }
201 break;
202 case EV_ABS:
203 switch (code) {
204 CASE_RETURN(ABS_X);
205 CASE_RETURN(ABS_Y);
206 CASE_RETURN(ABS_Z);
207 CASE_RETURN(ABS_PRESSURE);
208 CASE_RETURN(ABS_TOOL_WIDTH);
209 CASE_RETURN(ABS_MT_TOUCH_MAJOR);
210 CASE_RETURN(ABS_MT_TOUCH_MINOR);
211 CASE_RETURN(ABS_MT_WIDTH_MAJOR);
212 CASE_RETURN(ABS_MT_WIDTH_MINOR);
213 CASE_RETURN(ABS_MT_ORIENTATION);
214 CASE_RETURN(ABS_MT_POSITION_X);
215 CASE_RETURN(ABS_MT_POSITION_Y);
216 CASE_RETURN(ABS_MT_TOOL_TYPE);
217 CASE_RETURN(ABS_MT_BLOB_ID);
218 CASE_RETURN(ABS_MT_TRACKING_ID);
219 CASE_RETURN(ABS_MT_PRESSURE);
220 CASE_RETURN(ABS_MT_SLOT);
221 default:
222 break;
223 }
224 break;
225 case EV_KEY:
226 switch (code) {
227 CASE_RETURN(BTN_LEFT);
228 CASE_RETURN(BTN_RIGHT);
229 CASE_RETURN(BTN_MIDDLE);
230 CASE_RETURN(BTN_TOUCH);
231 CASE_RETURN(BTN_TOOL_FINGER);
232 CASE_RETURN(BTN_TOOL_DOUBLETAP);
233 CASE_RETURN(BTN_TOOL_TRIPLETAP);
234 CASE_RETURN(BTN_TOOL_QUADTAP);
235 CASE_RETURN(BTN_TOOL_QUINTTAP);
236 default:
237 break;
238 }
239 break;
240 default:
241 break;
242 }
243 return "?";
244}
245#undef CASE_RETURN
246
247const char *
248Event_Type_To_String(int type) {
249 switch (type) {
250 case EV_SYN: return "SYN";
251 case EV_KEY: return "KEY";
252 case EV_REL: return "REL";
253 case EV_ABS: return "ABS";
254 case EV_MSC: return "MSC";
255 case EV_SW: return "SW";
256 case EV_LED: return "LED";
257 case EV_SND: return "SND";
258 case EV_REP: return "REP";
259 case EV_FF: return "FF";
260 case EV_PWR: return "PWR";
261 default: return "?";
262 }
263}
264
265
266/**
267 * Probe Device Input Event Support
268 */
269int
270Event_Init(EvdevPtr device)
271{
272 int i;
273 EventStatePtr evstate;
274
275 evstate = device->evstate;
276 if (EvdevProbe(device) != Success) {
277 return !Success;
278 }
279
Dennis Kempina9963ba2012-06-08 10:32:23 -0700280 for (i = ABS_X; i <= ABS_MAX; i++) {
281 if (TestBit(i, device->info.abs_bitmask)) {
282 struct input_absinfo* absinfo = &device->info.absinfo[i];
283 if (i == ABS_MT_SLOT) {
284 int rc;
285 rc = MTB_Init(device, absinfo->minimum, absinfo->maximum,
286 absinfo->value);
287 if (rc != Success)
288 return rc;
289 } else if (IS_ABS_MT(i)) {
290 evstate->mt_axes[MT_CODE(i)] = absinfo;
291 }
292 }
293 }
Dennis Kempina9963ba2012-06-08 10:32:23 -0700294 return Success;
295}
296
297void
298Event_Free(EvdevPtr device)
299{
300 MT_Free(device);
301}
302
303void
304Event_Open(EvdevPtr device)
305{
306 /* Select monotonic input event timestamps, if supported by kernel */
307 device->info.is_monotonic = (EvdevEnableMonotonic(device) == Success);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700308 LOG_DEBUG(device, "Using %s input event time stamps\n",
309 device->info.is_monotonic ? "monotonic" : "realtime");
Daniel Kurtz000bdff2012-09-17 15:45:29 +0800310
311 /* Synchronize all MT slots with kernel evdev driver */
312 Event_Sync_State(device);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700313}
314
315static void
316Event_Get_Time(struct timeval *t, bool use_monotonic) {
317 struct timespec now;
318 clockid_t clockid = (use_monotonic) ? CLOCK_MONOTONIC : CLOCK_REALTIME;
319
320 clock_gettime(clockid, &now);
321 t->tv_sec = now.tv_sec;
322 t->tv_usec = now.tv_nsec / 1000;
323}
324
325/**
326 * Synchronize the current state with kernel evdev driver. For cmt, there are
327 * only four components required to be synced: current touch count, the MT
328 * slots information, current slot id and physical button states. However, as
329 * pressure readings are missing in ABS_MT_PRESSURE field of MT slots for
330 * semi_mt touchpad device (e.g. Cr48), we also need need to extract it with
331 * extra EVIOCGABS query.
332 */
333void
334Event_Sync_State(EvdevPtr device)
335{
336 int i;
337
338 Event_Get_Time(&device->before_sync_time, device->info.is_monotonic);
339
340 EvdevProbeKeyState(device);
341
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800342 /* Get current pressure information for single-pressure device */
343 if (EvdevIsSinglePressureDevice(device) == Success) {
344 struct input_event ev;
345 ev.code = ABS_PRESSURE;
346 ev.value = device->info.absinfo[ABS_PRESSURE].value;
347 Event_Abs_Update_Pressure(device, &ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700348 }
349
350 /* TODO(cywang): Sync all ABS_ states for completeness */
351
352 /* Get current MT information for each slot */
353 for (i = _ABS_MT_FIRST; i <= _ABS_MT_LAST; i++) {
354 MTSlotInfo req;
355
356 if (!TestBit(i, device->info.abs_bitmask))
357 continue;
358 /*
359 * TODO(cywang): Scale the size of slots in MTSlotInfo based on the
360 * evstate->slot_count.
361 */
362
363 req.code = i;
364 if (EvdevProbeMTSlot(device, &req) != Success) {
365 continue;
366 }
367 MT_Slot_Sync(device, &req);
368 }
369
370 /* Get current slot id */
371 if (EvdevProbeAbsinfo(device, ABS_MT_SLOT) == Success)
372 MT_Slot_Set(device, device->info.absinfo[ABS_MT_SLOT].value);
373
374 Event_Get_Time(&device->after_sync_time, device->info.is_monotonic);
375
Chung-yih Wangb709c082012-07-20 16:26:15 +0800376 LOG_WARNING(device, "Event_Sync_State: before %ld.%ld after %ld.%ld\n",
377 device->before_sync_time.tv_sec,
378 device->before_sync_time.tv_usec,
379 device->after_sync_time.tv_sec,
380 device->after_sync_time.tv_usec);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700381}
382
383static void
384Event_Print(EvdevPtr device, struct input_event* ev)
385{
386 switch (ev->type) {
387 case EV_SYN:
388 switch (ev->code) {
389 case SYN_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700390 LOG_DEBUG(device, "@ %ld.%06ld ---------- SYN_REPORT -------\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700391 ev->time.tv_sec, ev->time.tv_usec);
392 return;
393 case SYN_MT_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700394 LOG_DEBUG(device, "@ %ld.%06ld ........ SYN_MT_REPORT ......\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700395 ev->time.tv_sec, ev->time.tv_usec);
396 return;
397 case SYN_DROPPED:
Dennis Kempin85a14442012-06-25 11:24:59 -0700398 LOG_WARNING(device, "@ %ld.%06ld ++++++++ SYN_DROPPED ++++++++\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700399 ev->time.tv_sec, ev->time.tv_usec);
400 return;
401 default:
Dennis Kempin85a14442012-06-25 11:24:59 -0700402 LOG_WARNING(device, "@ %ld.%06ld ?????? SYN_UNKNOWN (%d) ?????\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700403 ev->time.tv_sec, ev->time.tv_usec, ev->code);
404 return;
405 }
406 break;
407 case EV_ABS:
408 if (ev->code == ABS_MT_SLOT) {
Dennis Kempinde0712f2012-06-11 15:13:50 -0700409 LOG_DEBUG(device, "@ %ld.%06ld .......... MT SLOT %d ........\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700410 ev->time.tv_sec, ev->time.tv_usec, ev->value);
411 return;
412 }
413 break;
414 default:
415 break;
416 }
417
Dennis Kempinde0712f2012-06-11 15:13:50 -0700418 LOG_DEBUG(device, "@ %ld.%06ld %s[%d] (%s) = %d\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700419 ev->time.tv_sec, ev->time.tv_usec, Event_Type_To_String(ev->type),
420 ev->code, Event_To_String(ev->type, ev->code), ev->value);
421}
422
423/**
424 * Process Input Events
425 */
426bool
427Event_Process(EvdevPtr device, struct input_event* ev)
428{
Dennis Kempina9963ba2012-06-08 10:32:23 -0700429 Event_Print(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700430
431 switch (ev->type) {
432 case EV_SYN:
433 if (ev->code == SYN_DROPPED)
434 return true;
435 Event_Syn(device, ev);
436 break;
437
438 case EV_KEY:
439 Event_Key(device, ev);
440 break;
441
442 case EV_ABS:
443 Event_Abs(device, ev);
444 break;
445
446 default:
447 break;
448 }
449 return false;
450}
451
452/**
453 * Dump the log of input events to disk
454 */
455void
456Event_Dump_Debug_Log(void* vinfo)
457{
458 EvdevPtr device = (EvdevPtr) vinfo;
459 size_t i;
460 EventStatePtr evstate = device->evstate;
461
462 FILE* fp = fopen("/var/log/cmt_input_events.dat", "wb");
463 if (!fp) {
464 LOG_ERROR(device, "fopen() failed for debug log");
465 return;
466 }
467 for (i = 0; i < DEBUG_BUF_SIZE; i++) {
468 size_t rc;
469 struct input_event *ev =
470 &evstate->debug_buf[(evstate->debug_buf_tail + i) % DEBUG_BUF_SIZE];
471 if (ev->time.tv_sec == 0 && ev->time.tv_usec == 0)
472 continue;
473 rc = fprintf(fp, "E: %ld.%06ld %04x %04x %d\n",
474 ev->time.tv_sec,
475 ev->time.tv_usec,
476 ev->type,
477 ev->code,
478 ev->value);
479 if (rc == 0) {
480 LOG_ERROR(device, "fprintf() failed for debug log. Log is short");
481 break;
482 }
483 }
484 fclose(fp);
485}
486
487static void
488Event_Syn(EvdevPtr device, struct input_event* ev)
489{
490 switch (ev->code) {
491 case SYN_REPORT:
492 Event_Syn_Report(device, ev);
493 break;
494 case SYN_MT_REPORT:
495 Event_Syn_MT_Report(device, ev);
496 break;
497 }
498}
499
500static void
501Event_Syn_Report(EvdevPtr device, struct input_event* ev)
502{
503 EventStatePtr evstate = device->evstate;
504 device->syn_report(device->syn_report_udata, evstate, &ev->time);
505
506 MT_Print_Slots(device);
507}
508
509static void
510Event_Syn_MT_Report(EvdevPtr device, struct input_event* ev)
511{
512 /* TODO(djkurtz): Handle MT-A */
513}
514
515static void
516Event_Key(EvdevPtr device, struct input_event* ev)
517{
518 AssignBit(device->key_state_bitmask, ev->code, ev->value);
519}
520
521static void
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800522Event_Abs_Update_Pressure(EvdevPtr device, struct input_event* ev)
Dennis Kempina9963ba2012-06-08 10:32:23 -0700523{
524 /*
525 * Update all active slots with the same ABS_PRESSURE value if it is a
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800526 * single-pressure device.
Dennis Kempina9963ba2012-06-08 10:32:23 -0700527 */
528 EventStatePtr evstate = device->evstate;
529
530 for (int i = 0; i < evstate->slot_count; i++) {
531 MtSlotPtr slot = &evstate->slots[i];
532 slot->pressure = ev->value;
533 }
534}
535
536static void
537Event_Abs(EvdevPtr device, struct input_event* ev)
538{
539 if (ev->code == ABS_MT_SLOT)
540 MT_Slot_Set(device, ev->value);
541 else if (IS_ABS_MT(ev->code))
542 Event_Abs_MT(device, ev);
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800543 else if ((ev->code == ABS_PRESSURE) && EvdevIsSinglePressureDevice(device))
544 Event_Abs_Update_Pressure(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700545}
546
547static void
548Event_Abs_MT(EvdevPtr device, struct input_event* ev)
549{
550 EventStatePtr evstate = device->evstate;
551 struct input_absinfo* axis = evstate->mt_axes[MT_CODE(ev->code)];
552 MtSlotPtr slot = evstate->slot_current;
553
554 if (axis == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700555 LOG_WARNING(device, "ABS_MT[%02x] was not reported by this device\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700556 ev->code);
557 return;
558 }
559
560 /* Warn about out of range data, but don't ignore */
561 if ((ev->code != ABS_MT_TRACKING_ID)
562 && ((ev->value < axis->minimum)
563 || (ev->value > axis->maximum))) {
564 LOG_WARNING(device, "ABS_MT[%02x] = %d : value out of range [%d .. %d]\n",
565 ev->code, ev->value, axis->minimum, axis->maximum);
566 }
567
568 if (slot == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700569 LOG_WARNING(device, "MT slot not set. Ignoring ABS_MT event\n");
Dennis Kempina9963ba2012-06-08 10:32:23 -0700570 return;
571 }
572
573 MT_Slot_Value_Set(slot, ev->code, ev->value);
574}