blob: c43abc1318c606c06cd74b1e7e96142809750772 [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
Dennis Kempina9963ba2012-06-08 10:32:23 -0700266 for (i = ABS_X; i <= ABS_MAX; i++) {
267 if (TestBit(i, device->info.abs_bitmask)) {
268 struct input_absinfo* absinfo = &device->info.absinfo[i];
269 if (i == ABS_MT_SLOT) {
270 int rc;
271 rc = MTB_Init(device, absinfo->minimum, absinfo->maximum,
272 absinfo->value);
273 if (rc != Success)
274 return rc;
275 } else if (IS_ABS_MT(i)) {
276 evstate->mt_axes[MT_CODE(i)] = absinfo;
277 }
278 }
279 }
Dennis Kempina9963ba2012-06-08 10:32:23 -0700280 return Success;
281}
282
283void
284Event_Free(EvdevPtr device)
285{
286 MT_Free(device);
287}
288
289void
290Event_Open(EvdevPtr device)
291{
292 /* Select monotonic input event timestamps, if supported by kernel */
293 device->info.is_monotonic = (EvdevEnableMonotonic(device) == Success);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700294 LOG_DEBUG(device, "Using %s input event time stamps\n",
295 device->info.is_monotonic ? "monotonic" : "realtime");
Daniel Kurtz000bdff2012-09-17 15:45:29 +0800296
297 /* Synchronize all MT slots with kernel evdev driver */
298 Event_Sync_State(device);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700299}
300
301static void
302Event_Get_Time(struct timeval *t, bool use_monotonic) {
303 struct timespec now;
304 clockid_t clockid = (use_monotonic) ? CLOCK_MONOTONIC : CLOCK_REALTIME;
305
306 clock_gettime(clockid, &now);
307 t->tv_sec = now.tv_sec;
308 t->tv_usec = now.tv_nsec / 1000;
309}
310
311/**
312 * Synchronize the current state with kernel evdev driver. For cmt, there are
313 * only four components required to be synced: current touch count, the MT
314 * slots information, current slot id and physical button states. However, as
315 * pressure readings are missing in ABS_MT_PRESSURE field of MT slots for
316 * semi_mt touchpad device (e.g. Cr48), we also need need to extract it with
317 * extra EVIOCGABS query.
318 */
319void
320Event_Sync_State(EvdevPtr device)
321{
322 int i;
323
324 Event_Get_Time(&device->before_sync_time, device->info.is_monotonic);
325
326 EvdevProbeKeyState(device);
327
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800328 /* Get current pressure information for single-pressure device */
329 if (EvdevIsSinglePressureDevice(device) == Success) {
330 struct input_event ev;
331 ev.code = ABS_PRESSURE;
332 ev.value = device->info.absinfo[ABS_PRESSURE].value;
333 Event_Abs_Update_Pressure(device, &ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700334 }
335
336 /* TODO(cywang): Sync all ABS_ states for completeness */
337
338 /* Get current MT information for each slot */
339 for (i = _ABS_MT_FIRST; i <= _ABS_MT_LAST; i++) {
340 MTSlotInfo req;
341
342 if (!TestBit(i, device->info.abs_bitmask))
343 continue;
344 /*
345 * TODO(cywang): Scale the size of slots in MTSlotInfo based on the
346 * evstate->slot_count.
347 */
348
349 req.code = i;
350 if (EvdevProbeMTSlot(device, &req) != Success) {
351 continue;
352 }
353 MT_Slot_Sync(device, &req);
354 }
355
356 /* Get current slot id */
357 if (EvdevProbeAbsinfo(device, ABS_MT_SLOT) == Success)
358 MT_Slot_Set(device, device->info.absinfo[ABS_MT_SLOT].value);
359
360 Event_Get_Time(&device->after_sync_time, device->info.is_monotonic);
361
Chung-yih Wangb709c082012-07-20 16:26:15 +0800362 LOG_WARNING(device, "Event_Sync_State: before %ld.%ld after %ld.%ld\n",
363 device->before_sync_time.tv_sec,
364 device->before_sync_time.tv_usec,
365 device->after_sync_time.tv_sec,
366 device->after_sync_time.tv_usec);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700367}
368
369static void
370Event_Print(EvdevPtr device, struct input_event* ev)
371{
372 switch (ev->type) {
373 case EV_SYN:
374 switch (ev->code) {
375 case SYN_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700376 LOG_DEBUG(device, "@ %ld.%06ld ---------- SYN_REPORT -------\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700377 ev->time.tv_sec, ev->time.tv_usec);
378 return;
379 case SYN_MT_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700380 LOG_DEBUG(device, "@ %ld.%06ld ........ SYN_MT_REPORT ......\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700381 ev->time.tv_sec, ev->time.tv_usec);
382 return;
383 case SYN_DROPPED:
Dennis Kempin85a14442012-06-25 11:24:59 -0700384 LOG_WARNING(device, "@ %ld.%06ld ++++++++ SYN_DROPPED ++++++++\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700385 ev->time.tv_sec, ev->time.tv_usec);
386 return;
387 default:
Dennis Kempin85a14442012-06-25 11:24:59 -0700388 LOG_WARNING(device, "@ %ld.%06ld ?????? SYN_UNKNOWN (%d) ?????\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700389 ev->time.tv_sec, ev->time.tv_usec, ev->code);
390 return;
391 }
392 break;
393 case EV_ABS:
394 if (ev->code == ABS_MT_SLOT) {
Dennis Kempinde0712f2012-06-11 15:13:50 -0700395 LOG_DEBUG(device, "@ %ld.%06ld .......... MT SLOT %d ........\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700396 ev->time.tv_sec, ev->time.tv_usec, ev->value);
397 return;
398 }
399 break;
400 default:
401 break;
402 }
403
Dennis Kempinde0712f2012-06-11 15:13:50 -0700404 LOG_DEBUG(device, "@ %ld.%06ld %s[%d] (%s) = %d\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700405 ev->time.tv_sec, ev->time.tv_usec, Event_Type_To_String(ev->type),
406 ev->code, Event_To_String(ev->type, ev->code), ev->value);
407}
408
409/**
410 * Process Input Events
411 */
412bool
413Event_Process(EvdevPtr device, struct input_event* ev)
414{
Dennis Kempina9963ba2012-06-08 10:32:23 -0700415 Event_Print(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700416
417 switch (ev->type) {
418 case EV_SYN:
419 if (ev->code == SYN_DROPPED)
420 return true;
421 Event_Syn(device, ev);
422 break;
423
424 case EV_KEY:
425 Event_Key(device, ev);
426 break;
427
428 case EV_ABS:
429 Event_Abs(device, ev);
430 break;
431
432 default:
433 break;
434 }
435 return false;
436}
437
438/**
439 * Dump the log of input events to disk
440 */
441void
442Event_Dump_Debug_Log(void* vinfo)
443{
444 EvdevPtr device = (EvdevPtr) vinfo;
445 size_t i;
446 EventStatePtr evstate = device->evstate;
447
448 FILE* fp = fopen("/var/log/cmt_input_events.dat", "wb");
449 if (!fp) {
450 LOG_ERROR(device, "fopen() failed for debug log");
451 return;
452 }
453 for (i = 0; i < DEBUG_BUF_SIZE; i++) {
454 size_t rc;
455 struct input_event *ev =
456 &evstate->debug_buf[(evstate->debug_buf_tail + i) % DEBUG_BUF_SIZE];
457 if (ev->time.tv_sec == 0 && ev->time.tv_usec == 0)
458 continue;
459 rc = fprintf(fp, "E: %ld.%06ld %04x %04x %d\n",
460 ev->time.tv_sec,
461 ev->time.tv_usec,
462 ev->type,
463 ev->code,
464 ev->value);
465 if (rc == 0) {
466 LOG_ERROR(device, "fprintf() failed for debug log. Log is short");
467 break;
468 }
469 }
470 fclose(fp);
471}
472
473static void
474Event_Syn(EvdevPtr device, struct input_event* ev)
475{
476 switch (ev->code) {
477 case SYN_REPORT:
478 Event_Syn_Report(device, ev);
479 break;
480 case SYN_MT_REPORT:
481 Event_Syn_MT_Report(device, ev);
482 break;
483 }
484}
485
486static void
487Event_Syn_Report(EvdevPtr device, struct input_event* ev)
488{
489 EventStatePtr evstate = device->evstate;
490 device->syn_report(device->syn_report_udata, evstate, &ev->time);
491
492 MT_Print_Slots(device);
493}
494
495static void
496Event_Syn_MT_Report(EvdevPtr device, struct input_event* ev)
497{
498 /* TODO(djkurtz): Handle MT-A */
499}
500
501static void
502Event_Key(EvdevPtr device, struct input_event* ev)
503{
504 AssignBit(device->key_state_bitmask, ev->code, ev->value);
505}
506
507static void
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800508Event_Abs_Update_Pressure(EvdevPtr device, struct input_event* ev)
Dennis Kempina9963ba2012-06-08 10:32:23 -0700509{
510 /*
511 * Update all active slots with the same ABS_PRESSURE value if it is a
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800512 * single-pressure device.
Dennis Kempina9963ba2012-06-08 10:32:23 -0700513 */
514 EventStatePtr evstate = device->evstate;
515
516 for (int i = 0; i < evstate->slot_count; i++) {
517 MtSlotPtr slot = &evstate->slots[i];
518 slot->pressure = ev->value;
519 }
520}
521
522static void
523Event_Abs(EvdevPtr device, struct input_event* ev)
524{
525 if (ev->code == ABS_MT_SLOT)
526 MT_Slot_Set(device, ev->value);
527 else if (IS_ABS_MT(ev->code))
528 Event_Abs_MT(device, ev);
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800529 else if ((ev->code == ABS_PRESSURE) && EvdevIsSinglePressureDevice(device))
530 Event_Abs_Update_Pressure(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700531}
532
533static void
534Event_Abs_MT(EvdevPtr device, struct input_event* ev)
535{
536 EventStatePtr evstate = device->evstate;
537 struct input_absinfo* axis = evstate->mt_axes[MT_CODE(ev->code)];
538 MtSlotPtr slot = evstate->slot_current;
539
540 if (axis == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700541 LOG_WARNING(device, "ABS_MT[%02x] was not reported by this device\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700542 ev->code);
543 return;
544 }
545
546 /* Warn about out of range data, but don't ignore */
547 if ((ev->code != ABS_MT_TRACKING_ID)
548 && ((ev->value < axis->minimum)
549 || (ev->value > axis->maximum))) {
550 LOG_WARNING(device, "ABS_MT[%02x] = %d : value out of range [%d .. %d]\n",
551 ev->code, ev->value, axis->minimum, axis->maximum);
552 }
553
554 if (slot == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700555 LOG_WARNING(device, "MT slot not set. Ignoring ABS_MT event\n");
Dennis Kempina9963ba2012-06-08 10:32:23 -0700556 return;
557 }
558
559 MT_Slot_Value_Set(slot, ev->code, ev->value);
560}