blob: 5100d07286dda62369ed4f9d79ef828e648d4aeb [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*);
45static void SemiMtSetAbsPressure(EvdevPtr, struct input_event*);
46
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
95Event_Get_Button_Pad(EvdevPtr device)
96{
97 return TestBit(INPUT_PROP_BUTTONPAD, device->info.prop_bitmask);
98}
99
100int
101Event_Get_Semi_MT(EvdevPtr device)
102{
103 return TestBit(INPUT_PROP_SEMI_MT, device->info.prop_bitmask);
104}
105
106int
107Event_Get_T5R2(EvdevPtr device)
108{
109 EventStatePtr evstate = device->evstate;
110 if (Event_Get_Semi_MT(device))
111 return 0;
112 return (Event_Get_Touch_Count_Max(device) > evstate->slot_count);
113}
114
115int
116Event_Get_Touch_Count_Max(EvdevPtr device)
117{
118
119 if (TestBit(BTN_TOOL_QUINTTAP, device->info.key_bitmask))
120 return 5;
121 if (TestBit(BTN_TOOL_QUADTAP, device->info.key_bitmask))
122 return 4;
123 if (TestBit(BTN_TOOL_TRIPLETAP, device->info.key_bitmask))
124 return 3;
125 if (TestBit(BTN_TOOL_DOUBLETAP, device->info.key_bitmask))
126 return 2;
127 return 1;
128}
129
130int
131Event_Get_Touch_Count(EvdevPtr device)
132{
133
134 if (TestBit(BTN_TOOL_QUINTTAP, device->key_state_bitmask))
135 return 5;
136 if (TestBit(BTN_TOOL_QUADTAP, device->key_state_bitmask))
137 return 4;
138 if (TestBit(BTN_TOOL_TRIPLETAP, device->key_state_bitmask))
139 return 3;
140 if (TestBit(BTN_TOOL_DOUBLETAP, device->key_state_bitmask))
141 return 2;
142 if (TestBit(BTN_TOOL_FINGER, device->key_state_bitmask))
143 return 1;
144 return 0;
145}
146
147int
148Event_Get_Slot_Count(EvdevPtr device)
149{
150 EventStatePtr evstate = device->evstate;
151 return evstate->slot_count;
152}
153
154int
155Event_Get_Button_Left(EvdevPtr device)
156{
157 return TestBit(BTN_LEFT, device->key_state_bitmask);
158}
159
160int
161Event_Get_Button_Middle(EvdevPtr device)
162{
163 return TestBit(BTN_MIDDLE, device->key_state_bitmask);
164}
165
166int
167Event_Get_Button_Right(EvdevPtr device)
168{
169 return TestBit(BTN_RIGHT, device->key_state_bitmask);
170}
171
172#define CASE_RETURN(s) \
173 case (s):\
174 return #s
175
176
177const char *
178Event_To_String(int type, int code) {
179 switch (type) {
180 case EV_SYN:
181 switch (code) {
182 CASE_RETURN(SYN_REPORT);
183 CASE_RETURN(SYN_MT_REPORT);
184 default:
185 break;
186 }
187 break;
188 case EV_ABS:
189 switch (code) {
190 CASE_RETURN(ABS_X);
191 CASE_RETURN(ABS_Y);
192 CASE_RETURN(ABS_Z);
193 CASE_RETURN(ABS_PRESSURE);
194 CASE_RETURN(ABS_TOOL_WIDTH);
195 CASE_RETURN(ABS_MT_TOUCH_MAJOR);
196 CASE_RETURN(ABS_MT_TOUCH_MINOR);
197 CASE_RETURN(ABS_MT_WIDTH_MAJOR);
198 CASE_RETURN(ABS_MT_WIDTH_MINOR);
199 CASE_RETURN(ABS_MT_ORIENTATION);
200 CASE_RETURN(ABS_MT_POSITION_X);
201 CASE_RETURN(ABS_MT_POSITION_Y);
202 CASE_RETURN(ABS_MT_TOOL_TYPE);
203 CASE_RETURN(ABS_MT_BLOB_ID);
204 CASE_RETURN(ABS_MT_TRACKING_ID);
205 CASE_RETURN(ABS_MT_PRESSURE);
206 CASE_RETURN(ABS_MT_SLOT);
207 default:
208 break;
209 }
210 break;
211 case EV_KEY:
212 switch (code) {
213 CASE_RETURN(BTN_LEFT);
214 CASE_RETURN(BTN_RIGHT);
215 CASE_RETURN(BTN_MIDDLE);
216 CASE_RETURN(BTN_TOUCH);
217 CASE_RETURN(BTN_TOOL_FINGER);
218 CASE_RETURN(BTN_TOOL_DOUBLETAP);
219 CASE_RETURN(BTN_TOOL_TRIPLETAP);
220 CASE_RETURN(BTN_TOOL_QUADTAP);
221 CASE_RETURN(BTN_TOOL_QUINTTAP);
222 default:
223 break;
224 }
225 break;
226 default:
227 break;
228 }
229 return "?";
230}
231#undef CASE_RETURN
232
233const char *
234Event_Type_To_String(int type) {
235 switch (type) {
236 case EV_SYN: return "SYN";
237 case EV_KEY: return "KEY";
238 case EV_REL: return "REL";
239 case EV_ABS: return "ABS";
240 case EV_MSC: return "MSC";
241 case EV_SW: return "SW";
242 case EV_LED: return "LED";
243 case EV_SND: return "SND";
244 case EV_REP: return "REP";
245 case EV_FF: return "FF";
246 case EV_PWR: return "PWR";
247 default: return "?";
248 }
249}
250
251
252/**
253 * Probe Device Input Event Support
254 */
255int
256Event_Init(EvdevPtr device)
257{
258 int i;
259 EventStatePtr evstate;
260
261 evstate = device->evstate;
262 if (EvdevProbe(device) != Success) {
263 return !Success;
264 }
265
266 /*
267 * TODO(djkurtz): Solve the race condition between MT slot initialization
268 * from absinfo, and incoming/lost input events.
269 * Specifically, if kernel driver sends MT_SLOT event between absinfo
270 * probe and when we start listening for input events.
271 */
272
273 for (i = ABS_X; i <= ABS_MAX; i++) {
274 if (TestBit(i, device->info.abs_bitmask)) {
275 struct input_absinfo* absinfo = &device->info.absinfo[i];
276 if (i == ABS_MT_SLOT) {
277 int rc;
278 rc = MTB_Init(device, absinfo->minimum, absinfo->maximum,
279 absinfo->value);
280 if (rc != Success)
281 return rc;
282 } else if (IS_ABS_MT(i)) {
283 evstate->mt_axes[MT_CODE(i)] = absinfo;
284 }
285 }
286 }
287
288 /* Synchronize all MT slots with kernel evdev driver */
289 Event_Sync_State(device);
290 return Success;
291}
292
293void
294Event_Free(EvdevPtr device)
295{
296 MT_Free(device);
297}
298
299void
300Event_Open(EvdevPtr device)
301{
302 /* Select monotonic input event timestamps, if supported by kernel */
303 device->info.is_monotonic = (EvdevEnableMonotonic(device) == Success);
304 /* Reset the sync time variables */
305 Event_Get_Time(&device->before_sync_time, device->info.is_monotonic);
306 Event_Get_Time(&device->after_sync_time, device->info.is_monotonic);
307 LOG_DEBUG(device, "Using %s input event time stamps\n",
308 device->info.is_monotonic ? "monotonic" : "realtime");
309}
310
311static void
312Event_Get_Time(struct timeval *t, bool use_monotonic) {
313 struct timespec now;
314 clockid_t clockid = (use_monotonic) ? CLOCK_MONOTONIC : CLOCK_REALTIME;
315
316 clock_gettime(clockid, &now);
317 t->tv_sec = now.tv_sec;
318 t->tv_usec = now.tv_nsec / 1000;
319}
320
321/**
322 * Synchronize the current state with kernel evdev driver. For cmt, there are
323 * only four components required to be synced: current touch count, the MT
324 * slots information, current slot id and physical button states. However, as
325 * pressure readings are missing in ABS_MT_PRESSURE field of MT slots for
326 * semi_mt touchpad device (e.g. Cr48), we also need need to extract it with
327 * extra EVIOCGABS query.
328 */
329void
330Event_Sync_State(EvdevPtr device)
331{
332 int i;
333
334 Event_Get_Time(&device->before_sync_time, device->info.is_monotonic);
335
336 EvdevProbeKeyState(device);
337
338 /* Get current pressure information for semi_mt device */
339 if (Event_Get_Semi_MT(device)) {
340 if (EvdevProbeAbsinfo(device, ABS_PRESSURE) == Success) {
341 struct input_event ev;
342 ev.code = ABS_PRESSURE;
343 ev.value = device->info.absinfo[ABS_PRESSURE].value;
344 SemiMtSetAbsPressure(device, &ev);
345 }
346 }
347
348 /* TODO(cywang): Sync all ABS_ states for completeness */
349
350 /* Get current MT information for each slot */
351 for (i = _ABS_MT_FIRST; i <= _ABS_MT_LAST; i++) {
352 MTSlotInfo req;
353
354 if (!TestBit(i, device->info.abs_bitmask))
355 continue;
356 /*
357 * TODO(cywang): Scale the size of slots in MTSlotInfo based on the
358 * evstate->slot_count.
359 */
360
361 req.code = i;
362 if (EvdevProbeMTSlot(device, &req) != Success) {
363 continue;
364 }
365 MT_Slot_Sync(device, &req);
366 }
367
368 /* Get current slot id */
369 if (EvdevProbeAbsinfo(device, ABS_MT_SLOT) == Success)
370 MT_Slot_Set(device, device->info.absinfo[ABS_MT_SLOT].value);
371
372 Event_Get_Time(&device->after_sync_time, device->info.is_monotonic);
373
Chung-yih Wangb709c082012-07-20 16:26:15 +0800374 LOG_WARNING(device, "Event_Sync_State: before %ld.%ld after %ld.%ld\n",
375 device->before_sync_time.tv_sec,
376 device->before_sync_time.tv_usec,
377 device->after_sync_time.tv_sec,
378 device->after_sync_time.tv_usec);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700379}
380
381static void
382Event_Print(EvdevPtr device, struct input_event* ev)
383{
384 switch (ev->type) {
385 case EV_SYN:
386 switch (ev->code) {
387 case SYN_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700388 LOG_DEBUG(device, "@ %ld.%06ld ---------- SYN_REPORT -------\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700389 ev->time.tv_sec, ev->time.tv_usec);
390 return;
391 case SYN_MT_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700392 LOG_DEBUG(device, "@ %ld.%06ld ........ SYN_MT_REPORT ......\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700393 ev->time.tv_sec, ev->time.tv_usec);
394 return;
395 case SYN_DROPPED:
Dennis Kempin85a14442012-06-25 11:24:59 -0700396 LOG_WARNING(device, "@ %ld.%06ld ++++++++ SYN_DROPPED ++++++++\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700397 ev->time.tv_sec, ev->time.tv_usec);
398 return;
399 default:
Dennis Kempin85a14442012-06-25 11:24:59 -0700400 LOG_WARNING(device, "@ %ld.%06ld ?????? SYN_UNKNOWN (%d) ?????\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700401 ev->time.tv_sec, ev->time.tv_usec, ev->code);
402 return;
403 }
404 break;
405 case EV_ABS:
406 if (ev->code == ABS_MT_SLOT) {
Dennis Kempinde0712f2012-06-11 15:13:50 -0700407 LOG_DEBUG(device, "@ %ld.%06ld .......... MT SLOT %d ........\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700408 ev->time.tv_sec, ev->time.tv_usec, ev->value);
409 return;
410 }
411 break;
412 default:
413 break;
414 }
415
Dennis Kempinde0712f2012-06-11 15:13:50 -0700416 LOG_DEBUG(device, "@ %ld.%06ld %s[%d] (%s) = %d\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700417 ev->time.tv_sec, ev->time.tv_usec, Event_Type_To_String(ev->type),
418 ev->code, Event_To_String(ev->type, ev->code), ev->value);
419}
420
421/**
422 * Process Input Events
423 */
424bool
425Event_Process(EvdevPtr device, struct input_event* ev)
426{
427 EventStatePtr evstate = device->evstate;
428
429 Event_Print(device, ev);
430 if (evstate->debug_buf) {
431 evstate->debug_buf[evstate->debug_buf_tail] = *ev;
432 evstate->debug_buf_tail =
433 (evstate->debug_buf_tail + 1) % DEBUG_BUF_SIZE;
434 }
435
436 switch (ev->type) {
437 case EV_SYN:
438 if (ev->code == SYN_DROPPED)
439 return true;
440 Event_Syn(device, ev);
441 break;
442
443 case EV_KEY:
444 Event_Key(device, ev);
445 break;
446
447 case EV_ABS:
448 Event_Abs(device, ev);
449 break;
450
451 default:
452 break;
453 }
454 return false;
455}
456
457/**
458 * Dump the log of input events to disk
459 */
460void
461Event_Dump_Debug_Log(void* vinfo)
462{
463 EvdevPtr device = (EvdevPtr) vinfo;
464 size_t i;
465 EventStatePtr evstate = device->evstate;
466
467 FILE* fp = fopen("/var/log/cmt_input_events.dat", "wb");
468 if (!fp) {
469 LOG_ERROR(device, "fopen() failed for debug log");
470 return;
471 }
472 for (i = 0; i < DEBUG_BUF_SIZE; i++) {
473 size_t rc;
474 struct input_event *ev =
475 &evstate->debug_buf[(evstate->debug_buf_tail + i) % DEBUG_BUF_SIZE];
476 if (ev->time.tv_sec == 0 && ev->time.tv_usec == 0)
477 continue;
478 rc = fprintf(fp, "E: %ld.%06ld %04x %04x %d\n",
479 ev->time.tv_sec,
480 ev->time.tv_usec,
481 ev->type,
482 ev->code,
483 ev->value);
484 if (rc == 0) {
485 LOG_ERROR(device, "fprintf() failed for debug log. Log is short");
486 break;
487 }
488 }
489 fclose(fp);
490}
491
492static void
493Event_Syn(EvdevPtr device, struct input_event* ev)
494{
495 switch (ev->code) {
496 case SYN_REPORT:
497 Event_Syn_Report(device, ev);
498 break;
499 case SYN_MT_REPORT:
500 Event_Syn_MT_Report(device, ev);
501 break;
502 }
503}
504
505static void
506Event_Syn_Report(EvdevPtr device, struct input_event* ev)
507{
508 EventStatePtr evstate = device->evstate;
509 device->syn_report(device->syn_report_udata, evstate, &ev->time);
510
511 MT_Print_Slots(device);
512}
513
514static void
515Event_Syn_MT_Report(EvdevPtr device, struct input_event* ev)
516{
517 /* TODO(djkurtz): Handle MT-A */
518}
519
520static void
521Event_Key(EvdevPtr device, struct input_event* ev)
522{
523 AssignBit(device->key_state_bitmask, ev->code, ev->value);
524}
525
526static void
527SemiMtSetAbsPressure(EvdevPtr device, struct input_event* ev)
528{
529 /*
530 * Update all active slots with the same ABS_PRESSURE value if it is a
531 * semi-mt device.
532 */
533 EventStatePtr evstate = device->evstate;
534
535 for (int i = 0; i < evstate->slot_count; i++) {
536 MtSlotPtr slot = &evstate->slots[i];
537 slot->pressure = ev->value;
538 }
539}
540
541static void
542Event_Abs(EvdevPtr device, struct input_event* ev)
543{
544 if (ev->code == ABS_MT_SLOT)
545 MT_Slot_Set(device, ev->value);
546 else if (IS_ABS_MT(ev->code))
547 Event_Abs_MT(device, ev);
548 else if ((ev->code == ABS_PRESSURE) && Event_Get_Semi_MT(device))
549 SemiMtSetAbsPressure(device, ev);
550}
551
552static void
553Event_Abs_MT(EvdevPtr device, struct input_event* ev)
554{
555 EventStatePtr evstate = device->evstate;
556 struct input_absinfo* axis = evstate->mt_axes[MT_CODE(ev->code)];
557 MtSlotPtr slot = evstate->slot_current;
558
559 if (axis == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700560 LOG_WARNING(device, "ABS_MT[%02x] was not reported by this device\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700561 ev->code);
562 return;
563 }
564
565 /* Warn about out of range data, but don't ignore */
566 if ((ev->code != ABS_MT_TRACKING_ID)
567 && ((ev->value < axis->minimum)
568 || (ev->value > axis->maximum))) {
569 LOG_WARNING(device, "ABS_MT[%02x] = %d : value out of range [%d .. %d]\n",
570 ev->code, ev->value, axis->minimum, axis->maximum);
571 }
572
573 if (slot == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700574 LOG_WARNING(device, "MT slot not set. Ignoring ABS_MT event\n");
Dennis Kempina9963ba2012-06-08 10:32:23 -0700575 return;
576 }
577
578 MT_Slot_Value_Set(slot, ev->code, ev->value);
579}