blob: 50290127ee915056e85999ffcebf989274fc3fc1 [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 }
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
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800338 /* Get current pressure information for single-pressure device */
339 if (EvdevIsSinglePressureDevice(device) == Success) {
340 struct input_event ev;
341 ev.code = ABS_PRESSURE;
342 ev.value = device->info.absinfo[ABS_PRESSURE].value;
343 Event_Abs_Update_Pressure(device, &ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700344 }
345
346 /* TODO(cywang): Sync all ABS_ states for completeness */
347
348 /* Get current MT information for each slot */
349 for (i = _ABS_MT_FIRST; i <= _ABS_MT_LAST; i++) {
350 MTSlotInfo req;
351
352 if (!TestBit(i, device->info.abs_bitmask))
353 continue;
354 /*
355 * TODO(cywang): Scale the size of slots in MTSlotInfo based on the
356 * evstate->slot_count.
357 */
358
359 req.code = i;
360 if (EvdevProbeMTSlot(device, &req) != Success) {
361 continue;
362 }
363 MT_Slot_Sync(device, &req);
364 }
365
366 /* Get current slot id */
367 if (EvdevProbeAbsinfo(device, ABS_MT_SLOT) == Success)
368 MT_Slot_Set(device, device->info.absinfo[ABS_MT_SLOT].value);
369
370 Event_Get_Time(&device->after_sync_time, device->info.is_monotonic);
371
Chung-yih Wangb709c082012-07-20 16:26:15 +0800372 LOG_WARNING(device, "Event_Sync_State: before %ld.%ld after %ld.%ld\n",
373 device->before_sync_time.tv_sec,
374 device->before_sync_time.tv_usec,
375 device->after_sync_time.tv_sec,
376 device->after_sync_time.tv_usec);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700377}
378
379static void
380Event_Print(EvdevPtr device, struct input_event* ev)
381{
382 switch (ev->type) {
383 case EV_SYN:
384 switch (ev->code) {
385 case SYN_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700386 LOG_DEBUG(device, "@ %ld.%06ld ---------- SYN_REPORT -------\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700387 ev->time.tv_sec, ev->time.tv_usec);
388 return;
389 case SYN_MT_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700390 LOG_DEBUG(device, "@ %ld.%06ld ........ SYN_MT_REPORT ......\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700391 ev->time.tv_sec, ev->time.tv_usec);
392 return;
393 case SYN_DROPPED:
Dennis Kempin85a14442012-06-25 11:24:59 -0700394 LOG_WARNING(device, "@ %ld.%06ld ++++++++ SYN_DROPPED ++++++++\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700395 ev->time.tv_sec, ev->time.tv_usec);
396 return;
397 default:
Dennis Kempin85a14442012-06-25 11:24:59 -0700398 LOG_WARNING(device, "@ %ld.%06ld ?????? SYN_UNKNOWN (%d) ?????\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700399 ev->time.tv_sec, ev->time.tv_usec, ev->code);
400 return;
401 }
402 break;
403 case EV_ABS:
404 if (ev->code == ABS_MT_SLOT) {
Dennis Kempinde0712f2012-06-11 15:13:50 -0700405 LOG_DEBUG(device, "@ %ld.%06ld .......... MT SLOT %d ........\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700406 ev->time.tv_sec, ev->time.tv_usec, ev->value);
407 return;
408 }
409 break;
410 default:
411 break;
412 }
413
Dennis Kempinde0712f2012-06-11 15:13:50 -0700414 LOG_DEBUG(device, "@ %ld.%06ld %s[%d] (%s) = %d\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700415 ev->time.tv_sec, ev->time.tv_usec, Event_Type_To_String(ev->type),
416 ev->code, Event_To_String(ev->type, ev->code), ev->value);
417}
418
419/**
420 * Process Input Events
421 */
422bool
423Event_Process(EvdevPtr device, struct input_event* ev)
424{
Dennis Kempina9963ba2012-06-08 10:32:23 -0700425 Event_Print(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700426
427 switch (ev->type) {
428 case EV_SYN:
429 if (ev->code == SYN_DROPPED)
430 return true;
431 Event_Syn(device, ev);
432 break;
433
434 case EV_KEY:
435 Event_Key(device, ev);
436 break;
437
438 case EV_ABS:
439 Event_Abs(device, ev);
440 break;
441
442 default:
443 break;
444 }
445 return false;
446}
447
448/**
449 * Dump the log of input events to disk
450 */
451void
452Event_Dump_Debug_Log(void* vinfo)
453{
454 EvdevPtr device = (EvdevPtr) vinfo;
455 size_t i;
456 EventStatePtr evstate = device->evstate;
457
458 FILE* fp = fopen("/var/log/cmt_input_events.dat", "wb");
459 if (!fp) {
460 LOG_ERROR(device, "fopen() failed for debug log");
461 return;
462 }
463 for (i = 0; i < DEBUG_BUF_SIZE; i++) {
464 size_t rc;
465 struct input_event *ev =
466 &evstate->debug_buf[(evstate->debug_buf_tail + i) % DEBUG_BUF_SIZE];
467 if (ev->time.tv_sec == 0 && ev->time.tv_usec == 0)
468 continue;
469 rc = fprintf(fp, "E: %ld.%06ld %04x %04x %d\n",
470 ev->time.tv_sec,
471 ev->time.tv_usec,
472 ev->type,
473 ev->code,
474 ev->value);
475 if (rc == 0) {
476 LOG_ERROR(device, "fprintf() failed for debug log. Log is short");
477 break;
478 }
479 }
480 fclose(fp);
481}
482
483static void
484Event_Syn(EvdevPtr device, struct input_event* ev)
485{
486 switch (ev->code) {
487 case SYN_REPORT:
488 Event_Syn_Report(device, ev);
489 break;
490 case SYN_MT_REPORT:
491 Event_Syn_MT_Report(device, ev);
492 break;
493 }
494}
495
496static void
497Event_Syn_Report(EvdevPtr device, struct input_event* ev)
498{
499 EventStatePtr evstate = device->evstate;
500 device->syn_report(device->syn_report_udata, evstate, &ev->time);
501
502 MT_Print_Slots(device);
503}
504
505static void
506Event_Syn_MT_Report(EvdevPtr device, struct input_event* ev)
507{
508 /* TODO(djkurtz): Handle MT-A */
509}
510
511static void
512Event_Key(EvdevPtr device, struct input_event* ev)
513{
514 AssignBit(device->key_state_bitmask, ev->code, ev->value);
515}
516
517static void
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800518Event_Abs_Update_Pressure(EvdevPtr device, struct input_event* ev)
Dennis Kempina9963ba2012-06-08 10:32:23 -0700519{
520 /*
521 * Update all active slots with the same ABS_PRESSURE value if it is a
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800522 * single-pressure device.
Dennis Kempina9963ba2012-06-08 10:32:23 -0700523 */
524 EventStatePtr evstate = device->evstate;
525
526 for (int i = 0; i < evstate->slot_count; i++) {
527 MtSlotPtr slot = &evstate->slots[i];
528 slot->pressure = ev->value;
529 }
530}
531
532static void
533Event_Abs(EvdevPtr device, struct input_event* ev)
534{
535 if (ev->code == ABS_MT_SLOT)
536 MT_Slot_Set(device, ev->value);
537 else if (IS_ABS_MT(ev->code))
538 Event_Abs_MT(device, ev);
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800539 else if ((ev->code == ABS_PRESSURE) && EvdevIsSinglePressureDevice(device))
540 Event_Abs_Update_Pressure(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700541}
542
543static void
544Event_Abs_MT(EvdevPtr device, struct input_event* ev)
545{
546 EventStatePtr evstate = device->evstate;
547 struct input_absinfo* axis = evstate->mt_axes[MT_CODE(ev->code)];
548 MtSlotPtr slot = evstate->slot_current;
549
550 if (axis == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700551 LOG_WARNING(device, "ABS_MT[%02x] was not reported by this device\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700552 ev->code);
553 return;
554 }
555
556 /* Warn about out of range data, but don't ignore */
557 if ((ev->code != ABS_MT_TRACKING_ID)
558 && ((ev->value < axis->minimum)
559 || (ev->value > axis->maximum))) {
560 LOG_WARNING(device, "ABS_MT[%02x] = %d : value out of range [%d .. %d]\n",
561 ev->code, ev->value, axis->minimum, axis->maximum);
562 }
563
564 if (slot == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700565 LOG_WARNING(device, "MT slot not set. Ignoring ABS_MT event\n");
Dennis Kempina9963ba2012-06-08 10:32:23 -0700566 return;
567 }
568
569 MT_Slot_Value_Set(slot, ev->code, ev->value);
570}