blob: 8b10cd6456b3747cac90669565c6a35b60ab0190 [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
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 }
Dennis Kempina9963ba2012-06-08 10:32:23 -0700287 return Success;
288}
289
290void
291Event_Free(EvdevPtr device)
292{
293 MT_Free(device);
294}
295
296void
297Event_Open(EvdevPtr device)
298{
299 /* Select monotonic input event timestamps, if supported by kernel */
300 device->info.is_monotonic = (EvdevEnableMonotonic(device) == Success);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700301 LOG_DEBUG(device, "Using %s input event time stamps\n",
302 device->info.is_monotonic ? "monotonic" : "realtime");
Daniel Kurtz000bdff2012-09-17 15:45:29 +0800303
304 /* Synchronize all MT slots with kernel evdev driver */
305 Event_Sync_State(device);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700306}
307
308static void
309Event_Get_Time(struct timeval *t, bool use_monotonic) {
310 struct timespec now;
311 clockid_t clockid = (use_monotonic) ? CLOCK_MONOTONIC : CLOCK_REALTIME;
312
313 clock_gettime(clockid, &now);
314 t->tv_sec = now.tv_sec;
315 t->tv_usec = now.tv_nsec / 1000;
316}
317
318/**
319 * Synchronize the current state with kernel evdev driver. For cmt, there are
320 * only four components required to be synced: current touch count, the MT
321 * slots information, current slot id and physical button states. However, as
322 * pressure readings are missing in ABS_MT_PRESSURE field of MT slots for
323 * semi_mt touchpad device (e.g. Cr48), we also need need to extract it with
324 * extra EVIOCGABS query.
325 */
326void
327Event_Sync_State(EvdevPtr device)
328{
329 int i;
330
331 Event_Get_Time(&device->before_sync_time, device->info.is_monotonic);
332
333 EvdevProbeKeyState(device);
334
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800335 /* Get current pressure information for single-pressure device */
336 if (EvdevIsSinglePressureDevice(device) == Success) {
337 struct input_event ev;
338 ev.code = ABS_PRESSURE;
339 ev.value = device->info.absinfo[ABS_PRESSURE].value;
340 Event_Abs_Update_Pressure(device, &ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700341 }
342
343 /* TODO(cywang): Sync all ABS_ states for completeness */
344
345 /* Get current MT information for each slot */
346 for (i = _ABS_MT_FIRST; i <= _ABS_MT_LAST; i++) {
347 MTSlotInfo req;
348
349 if (!TestBit(i, device->info.abs_bitmask))
350 continue;
351 /*
352 * TODO(cywang): Scale the size of slots in MTSlotInfo based on the
353 * evstate->slot_count.
354 */
355
356 req.code = i;
357 if (EvdevProbeMTSlot(device, &req) != Success) {
358 continue;
359 }
360 MT_Slot_Sync(device, &req);
361 }
362
363 /* Get current slot id */
364 if (EvdevProbeAbsinfo(device, ABS_MT_SLOT) == Success)
365 MT_Slot_Set(device, device->info.absinfo[ABS_MT_SLOT].value);
366
367 Event_Get_Time(&device->after_sync_time, device->info.is_monotonic);
368
Chung-yih Wangb709c082012-07-20 16:26:15 +0800369 LOG_WARNING(device, "Event_Sync_State: before %ld.%ld after %ld.%ld\n",
370 device->before_sync_time.tv_sec,
371 device->before_sync_time.tv_usec,
372 device->after_sync_time.tv_sec,
373 device->after_sync_time.tv_usec);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700374}
375
376static void
377Event_Print(EvdevPtr device, struct input_event* ev)
378{
379 switch (ev->type) {
380 case EV_SYN:
381 switch (ev->code) {
382 case SYN_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700383 LOG_DEBUG(device, "@ %ld.%06ld ---------- SYN_REPORT -------\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700384 ev->time.tv_sec, ev->time.tv_usec);
385 return;
386 case SYN_MT_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700387 LOG_DEBUG(device, "@ %ld.%06ld ........ SYN_MT_REPORT ......\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700388 ev->time.tv_sec, ev->time.tv_usec);
389 return;
390 case SYN_DROPPED:
Dennis Kempin85a14442012-06-25 11:24:59 -0700391 LOG_WARNING(device, "@ %ld.%06ld ++++++++ SYN_DROPPED ++++++++\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700392 ev->time.tv_sec, ev->time.tv_usec);
393 return;
394 default:
Dennis Kempin85a14442012-06-25 11:24:59 -0700395 LOG_WARNING(device, "@ %ld.%06ld ?????? SYN_UNKNOWN (%d) ?????\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700396 ev->time.tv_sec, ev->time.tv_usec, ev->code);
397 return;
398 }
399 break;
400 case EV_ABS:
401 if (ev->code == ABS_MT_SLOT) {
Dennis Kempinde0712f2012-06-11 15:13:50 -0700402 LOG_DEBUG(device, "@ %ld.%06ld .......... MT SLOT %d ........\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700403 ev->time.tv_sec, ev->time.tv_usec, ev->value);
404 return;
405 }
406 break;
407 default:
408 break;
409 }
410
Dennis Kempinde0712f2012-06-11 15:13:50 -0700411 LOG_DEBUG(device, "@ %ld.%06ld %s[%d] (%s) = %d\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700412 ev->time.tv_sec, ev->time.tv_usec, Event_Type_To_String(ev->type),
413 ev->code, Event_To_String(ev->type, ev->code), ev->value);
414}
415
416/**
417 * Process Input Events
418 */
419bool
420Event_Process(EvdevPtr device, struct input_event* ev)
421{
Dennis Kempina9963ba2012-06-08 10:32:23 -0700422 Event_Print(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700423
424 switch (ev->type) {
425 case EV_SYN:
426 if (ev->code == SYN_DROPPED)
427 return true;
428 Event_Syn(device, ev);
429 break;
430
431 case EV_KEY:
432 Event_Key(device, ev);
433 break;
434
435 case EV_ABS:
436 Event_Abs(device, ev);
437 break;
438
439 default:
440 break;
441 }
442 return false;
443}
444
445/**
446 * Dump the log of input events to disk
447 */
448void
449Event_Dump_Debug_Log(void* vinfo)
450{
451 EvdevPtr device = (EvdevPtr) vinfo;
452 size_t i;
453 EventStatePtr evstate = device->evstate;
454
455 FILE* fp = fopen("/var/log/cmt_input_events.dat", "wb");
456 if (!fp) {
457 LOG_ERROR(device, "fopen() failed for debug log");
458 return;
459 }
460 for (i = 0; i < DEBUG_BUF_SIZE; i++) {
461 size_t rc;
462 struct input_event *ev =
463 &evstate->debug_buf[(evstate->debug_buf_tail + i) % DEBUG_BUF_SIZE];
464 if (ev->time.tv_sec == 0 && ev->time.tv_usec == 0)
465 continue;
466 rc = fprintf(fp, "E: %ld.%06ld %04x %04x %d\n",
467 ev->time.tv_sec,
468 ev->time.tv_usec,
469 ev->type,
470 ev->code,
471 ev->value);
472 if (rc == 0) {
473 LOG_ERROR(device, "fprintf() failed for debug log. Log is short");
474 break;
475 }
476 }
477 fclose(fp);
478}
479
480static void
481Event_Syn(EvdevPtr device, struct input_event* ev)
482{
483 switch (ev->code) {
484 case SYN_REPORT:
485 Event_Syn_Report(device, ev);
486 break;
487 case SYN_MT_REPORT:
488 Event_Syn_MT_Report(device, ev);
489 break;
490 }
491}
492
493static void
494Event_Syn_Report(EvdevPtr device, struct input_event* ev)
495{
496 EventStatePtr evstate = device->evstate;
497 device->syn_report(device->syn_report_udata, evstate, &ev->time);
498
499 MT_Print_Slots(device);
500}
501
502static void
503Event_Syn_MT_Report(EvdevPtr device, struct input_event* ev)
504{
505 /* TODO(djkurtz): Handle MT-A */
506}
507
508static void
509Event_Key(EvdevPtr device, struct input_event* ev)
510{
511 AssignBit(device->key_state_bitmask, ev->code, ev->value);
512}
513
514static void
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800515Event_Abs_Update_Pressure(EvdevPtr device, struct input_event* ev)
Dennis Kempina9963ba2012-06-08 10:32:23 -0700516{
517 /*
518 * Update all active slots with the same ABS_PRESSURE value if it is a
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800519 * single-pressure device.
Dennis Kempina9963ba2012-06-08 10:32:23 -0700520 */
521 EventStatePtr evstate = device->evstate;
522
523 for (int i = 0; i < evstate->slot_count; i++) {
524 MtSlotPtr slot = &evstate->slots[i];
525 slot->pressure = ev->value;
526 }
527}
528
529static void
530Event_Abs(EvdevPtr device, struct input_event* ev)
531{
532 if (ev->code == ABS_MT_SLOT)
533 MT_Slot_Set(device, ev->value);
534 else if (IS_ABS_MT(ev->code))
535 Event_Abs_MT(device, ev);
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800536 else if ((ev->code == ABS_PRESSURE) && EvdevIsSinglePressureDevice(device))
537 Event_Abs_Update_Pressure(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700538}
539
540static void
541Event_Abs_MT(EvdevPtr device, struct input_event* ev)
542{
543 EventStatePtr evstate = device->evstate;
544 struct input_absinfo* axis = evstate->mt_axes[MT_CODE(ev->code)];
545 MtSlotPtr slot = evstate->slot_current;
546
547 if (axis == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700548 LOG_WARNING(device, "ABS_MT[%02x] was not reported by this device\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700549 ev->code);
550 return;
551 }
552
553 /* Warn about out of range data, but don't ignore */
554 if ((ev->code != ABS_MT_TRACKING_ID)
555 && ((ev->value < axis->minimum)
556 || (ev->value > axis->maximum))) {
557 LOG_WARNING(device, "ABS_MT[%02x] = %d : value out of range [%d .. %d]\n",
558 ev->code, ev->value, axis->minimum, axis->maximum);
559 }
560
561 if (slot == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700562 LOG_WARNING(device, "MT slot not set. Ignoring ABS_MT event\n");
Dennis Kempina9963ba2012-06-08 10:32:23 -0700563 return;
564 }
565
566 MT_Slot_Value_Set(slot, ev->code, ev->value);
567}