blob: a633cf1328a5753b2eb51ae8f0b8ab7d3e351fa7 [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
Chung-yih Wang1359d8b2012-11-21 11:25:33 +080035/* make VCSID as version number */
36#ifndef VCSID
37#define VCSID "Unknown"
38#endif
Dennis Kempina9963ba2012-06-08 10:32:23 -070039
Che-Liang Chiouf616b122012-10-24 17:08:51 -070040static void Event_Clear_Ev_Rel_State(EvdevPtr);
Dennis Kempina9963ba2012-06-08 10:32:23 -070041
Che-Liang Chiouf616b122012-10-24 17:08:51 -070042static bool Event_Syn(EvdevPtr, struct input_event*);
Dennis Kempina9963ba2012-06-08 10:32:23 -070043static void Event_Syn_Report(EvdevPtr, struct input_event*);
44static void Event_Syn_MT_Report(EvdevPtr, struct input_event*);
45
46static void Event_Key(EvdevPtr, struct input_event*);
47
48static void Event_Abs(EvdevPtr, struct input_event*);
49static void Event_Abs_MT(EvdevPtr, struct input_event*);
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +080050static void Event_Abs_Update_Pressure(EvdevPtr, struct input_event*);
Dennis Kempina9963ba2012-06-08 10:32:23 -070051
Che-Liang Chiouf616b122012-10-24 17:08:51 -070052static void Event_Rel(EvdevPtr, struct input_event*);
53
Dennis Kempina9963ba2012-06-08 10:32:23 -070054static void Event_Get_Time(struct timeval*, bool);
55
Chung-yih Wang1359d8b2012-11-21 11:25:33 +080056const char*
57Evdev_Get_Version() {
58 return VCSID;
59}
60
Dennis Kempina9963ba2012-06-08 10:32:23 -070061/**
62 * Input Device Event Property accessors
63 */
64int
65Event_Get_Left(EvdevPtr device)
66{
Yufeng Shen86e52252012-07-05 11:44:36 -040067 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_X];
Dennis Kempina9963ba2012-06-08 10:32:23 -070068 return absinfo->minimum;
69}
70
71int
72Event_Get_Right(EvdevPtr device)
73{
Yufeng Shen86e52252012-07-05 11:44:36 -040074 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_X];
Dennis Kempina9963ba2012-06-08 10:32:23 -070075 return absinfo->maximum;
76}
77
78int
79Event_Get_Top(EvdevPtr device)
80{
Yufeng Shen86e52252012-07-05 11:44:36 -040081 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_Y];
Dennis Kempina9963ba2012-06-08 10:32:23 -070082 return absinfo->minimum;
83}
84
85int
86Event_Get_Bottom(EvdevPtr device)
87{
Yufeng Shen86e52252012-07-05 11:44:36 -040088 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_Y];
Dennis Kempina9963ba2012-06-08 10:32:23 -070089 return absinfo->maximum;
90}
91
92int
93Event_Get_Res_Y(EvdevPtr device)
94{
Yufeng Shen86e52252012-07-05 11:44:36 -040095 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_Y];
Dennis Kempina9963ba2012-06-08 10:32:23 -070096 return absinfo->resolution;
97}
98
99int
100Event_Get_Res_X(EvdevPtr device)
101{
Yufeng Shen86e52252012-07-05 11:44:36 -0400102 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_X];
Dennis Kempina9963ba2012-06-08 10:32:23 -0700103 return absinfo->resolution;
104}
105
106int
Che-Liang Chioua2563012012-10-11 11:41:06 -0700107Event_Get_Orientation_Minimum(EvdevPtr device)
108{
109 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_ORIENTATION];
110 return absinfo->minimum;
111}
112
113int
114Event_Get_Orientation_Maximum(EvdevPtr device)
115{
116 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_ORIENTATION];
117 return absinfo->maximum;
118}
119
120int
Dennis Kempina9963ba2012-06-08 10:32:23 -0700121Event_Get_Button_Pad(EvdevPtr device)
122{
123 return TestBit(INPUT_PROP_BUTTONPAD, device->info.prop_bitmask);
124}
125
126int
127Event_Get_Semi_MT(EvdevPtr device)
128{
129 return TestBit(INPUT_PROP_SEMI_MT, device->info.prop_bitmask);
130}
131
132int
133Event_Get_T5R2(EvdevPtr device)
134{
135 EventStatePtr evstate = device->evstate;
136 if (Event_Get_Semi_MT(device))
137 return 0;
138 return (Event_Get_Touch_Count_Max(device) > evstate->slot_count);
139}
140
141int
142Event_Get_Touch_Count_Max(EvdevPtr device)
143{
144
145 if (TestBit(BTN_TOOL_QUINTTAP, device->info.key_bitmask))
146 return 5;
147 if (TestBit(BTN_TOOL_QUADTAP, device->info.key_bitmask))
148 return 4;
149 if (TestBit(BTN_TOOL_TRIPLETAP, device->info.key_bitmask))
150 return 3;
151 if (TestBit(BTN_TOOL_DOUBLETAP, device->info.key_bitmask))
152 return 2;
153 return 1;
154}
155
156int
157Event_Get_Touch_Count(EvdevPtr device)
158{
159
160 if (TestBit(BTN_TOOL_QUINTTAP, device->key_state_bitmask))
161 return 5;
162 if (TestBit(BTN_TOOL_QUADTAP, device->key_state_bitmask))
163 return 4;
164 if (TestBit(BTN_TOOL_TRIPLETAP, device->key_state_bitmask))
165 return 3;
166 if (TestBit(BTN_TOOL_DOUBLETAP, device->key_state_bitmask))
167 return 2;
168 if (TestBit(BTN_TOOL_FINGER, device->key_state_bitmask))
169 return 1;
170 return 0;
171}
172
173int
174Event_Get_Slot_Count(EvdevPtr device)
175{
176 EventStatePtr evstate = device->evstate;
177 return evstate->slot_count;
178}
179
180int
181Event_Get_Button_Left(EvdevPtr device)
182{
Dennis Kempine2a65d82014-02-24 13:27:40 -0800183 return Event_Get_Button(device, BTN_LEFT);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700184}
185
186int
187Event_Get_Button_Middle(EvdevPtr device)
188{
Dennis Kempine2a65d82014-02-24 13:27:40 -0800189 return Event_Get_Button(device, BTN_MIDDLE);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700190}
191
192int
193Event_Get_Button_Right(EvdevPtr device)
194{
Dennis Kempine2a65d82014-02-24 13:27:40 -0800195 return Event_Get_Button(device, BTN_RIGHT);
196}
197
198int
199Event_Get_Button(EvdevPtr device, int button)
200{
201 return TestBit(button, device->key_state_bitmask);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700202}
203
204#define CASE_RETURN(s) \
205 case (s):\
206 return #s
207
208
209const char *
210Event_To_String(int type, int code) {
211 switch (type) {
212 case EV_SYN:
213 switch (code) {
214 CASE_RETURN(SYN_REPORT);
215 CASE_RETURN(SYN_MT_REPORT);
216 default:
217 break;
218 }
219 break;
220 case EV_ABS:
221 switch (code) {
222 CASE_RETURN(ABS_X);
223 CASE_RETURN(ABS_Y);
224 CASE_RETURN(ABS_Z);
225 CASE_RETURN(ABS_PRESSURE);
226 CASE_RETURN(ABS_TOOL_WIDTH);
227 CASE_RETURN(ABS_MT_TOUCH_MAJOR);
228 CASE_RETURN(ABS_MT_TOUCH_MINOR);
229 CASE_RETURN(ABS_MT_WIDTH_MAJOR);
230 CASE_RETURN(ABS_MT_WIDTH_MINOR);
231 CASE_RETURN(ABS_MT_ORIENTATION);
232 CASE_RETURN(ABS_MT_POSITION_X);
233 CASE_RETURN(ABS_MT_POSITION_Y);
234 CASE_RETURN(ABS_MT_TOOL_TYPE);
235 CASE_RETURN(ABS_MT_BLOB_ID);
236 CASE_RETURN(ABS_MT_TRACKING_ID);
237 CASE_RETURN(ABS_MT_PRESSURE);
238 CASE_RETURN(ABS_MT_SLOT);
239 default:
240 break;
241 }
242 break;
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700243 case EV_REL:
244 switch (code) {
245 CASE_RETURN(REL_X);
246 CASE_RETURN(REL_Y);
247 CASE_RETURN(REL_WHEEL);
248 CASE_RETURN(REL_HWHEEL);
249 default:
250 break;
251 }
252 break;
Dennis Kempina9963ba2012-06-08 10:32:23 -0700253 case EV_KEY:
254 switch (code) {
255 CASE_RETURN(BTN_LEFT);
256 CASE_RETURN(BTN_RIGHT);
257 CASE_RETURN(BTN_MIDDLE);
Dennis Kempine2a65d82014-02-24 13:27:40 -0800258 CASE_RETURN(BTN_BACK);
259 CASE_RETURN(BTN_FORWARD);
260 CASE_RETURN(BTN_EXTRA);
261 CASE_RETURN(BTN_SIDE);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700262 CASE_RETURN(BTN_TOUCH);
263 CASE_RETURN(BTN_TOOL_FINGER);
264 CASE_RETURN(BTN_TOOL_DOUBLETAP);
265 CASE_RETURN(BTN_TOOL_TRIPLETAP);
266 CASE_RETURN(BTN_TOOL_QUADTAP);
267 CASE_RETURN(BTN_TOOL_QUINTTAP);
268 default:
269 break;
270 }
271 break;
272 default:
273 break;
274 }
275 return "?";
276}
277#undef CASE_RETURN
278
279const char *
280Event_Type_To_String(int type) {
281 switch (type) {
282 case EV_SYN: return "SYN";
283 case EV_KEY: return "KEY";
284 case EV_REL: return "REL";
285 case EV_ABS: return "ABS";
286 case EV_MSC: return "MSC";
287 case EV_SW: return "SW";
288 case EV_LED: return "LED";
289 case EV_SND: return "SND";
290 case EV_REP: return "REP";
291 case EV_FF: return "FF";
292 case EV_PWR: return "PWR";
293 default: return "?";
294 }
295}
296
297
298/**
299 * Probe Device Input Event Support
300 */
301int
302Event_Init(EvdevPtr device)
303{
304 int i;
305 EventStatePtr evstate;
306
307 evstate = device->evstate;
308 if (EvdevProbe(device) != Success) {
309 return !Success;
310 }
311
Dennis Kempina9963ba2012-06-08 10:32:23 -0700312 for (i = ABS_X; i <= ABS_MAX; i++) {
313 if (TestBit(i, device->info.abs_bitmask)) {
314 struct input_absinfo* absinfo = &device->info.absinfo[i];
315 if (i == ABS_MT_SLOT) {
316 int rc;
317 rc = MTB_Init(device, absinfo->minimum, absinfo->maximum,
318 absinfo->value);
319 if (rc != Success)
320 return rc;
321 } else if (IS_ABS_MT(i)) {
322 evstate->mt_axes[MT_CODE(i)] = absinfo;
323 }
324 }
325 }
Dennis Kempina9963ba2012-06-08 10:32:23 -0700326 return Success;
327}
328
329void
330Event_Free(EvdevPtr device)
331{
332 MT_Free(device);
333}
334
335void
336Event_Open(EvdevPtr device)
337{
338 /* Select monotonic input event timestamps, if supported by kernel */
339 device->info.is_monotonic = (EvdevEnableMonotonic(device) == Success);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700340 LOG_DEBUG(device, "Using %s input event time stamps\n",
341 device->info.is_monotonic ? "monotonic" : "realtime");
Daniel Kurtz000bdff2012-09-17 15:45:29 +0800342
343 /* Synchronize all MT slots with kernel evdev driver */
344 Event_Sync_State(device);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700345}
346
347static void
348Event_Get_Time(struct timeval *t, bool use_monotonic) {
349 struct timespec now;
350 clockid_t clockid = (use_monotonic) ? CLOCK_MONOTONIC : CLOCK_REALTIME;
351
352 clock_gettime(clockid, &now);
353 t->tv_sec = now.tv_sec;
354 t->tv_usec = now.tv_nsec / 1000;
355}
356
357/**
358 * Synchronize the current state with kernel evdev driver. For cmt, there are
359 * only four components required to be synced: current touch count, the MT
360 * slots information, current slot id and physical button states. However, as
361 * pressure readings are missing in ABS_MT_PRESSURE field of MT slots for
362 * semi_mt touchpad device (e.g. Cr48), we also need need to extract it with
363 * extra EVIOCGABS query.
364 */
365void
366Event_Sync_State(EvdevPtr device)
367{
368 int i;
369
370 Event_Get_Time(&device->before_sync_time, device->info.is_monotonic);
371
372 EvdevProbeKeyState(device);
373
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800374 /* Get current pressure information for single-pressure device */
375 if (EvdevIsSinglePressureDevice(device) == Success) {
376 struct input_event ev;
377 ev.code = ABS_PRESSURE;
378 ev.value = device->info.absinfo[ABS_PRESSURE].value;
379 Event_Abs_Update_Pressure(device, &ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700380 }
381
382 /* TODO(cywang): Sync all ABS_ states for completeness */
383
384 /* Get current MT information for each slot */
385 for (i = _ABS_MT_FIRST; i <= _ABS_MT_LAST; i++) {
386 MTSlotInfo req;
387
388 if (!TestBit(i, device->info.abs_bitmask))
389 continue;
390 /*
391 * TODO(cywang): Scale the size of slots in MTSlotInfo based on the
392 * evstate->slot_count.
393 */
394
395 req.code = i;
396 if (EvdevProbeMTSlot(device, &req) != Success) {
397 continue;
398 }
399 MT_Slot_Sync(device, &req);
400 }
401
402 /* Get current slot id */
403 if (EvdevProbeAbsinfo(device, ABS_MT_SLOT) == Success)
404 MT_Slot_Set(device, device->info.absinfo[ABS_MT_SLOT].value);
405
406 Event_Get_Time(&device->after_sync_time, device->info.is_monotonic);
407
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700408 /* Initialize EV_REL event state */
409 Event_Clear_Ev_Rel_State(device);
410
Chung-yih Wangb709c082012-07-20 16:26:15 +0800411 LOG_WARNING(device, "Event_Sync_State: before %ld.%ld after %ld.%ld\n",
Mike Frysingerda3e4732012-12-23 13:00:24 -0500412 (long)device->before_sync_time.tv_sec,
413 (long)device->before_sync_time.tv_usec,
414 (long)device->after_sync_time.tv_sec,
415 (long)device->after_sync_time.tv_usec);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700416}
417
418static void
419Event_Print(EvdevPtr device, struct input_event* ev)
420{
421 switch (ev->type) {
422 case EV_SYN:
423 switch (ev->code) {
424 case SYN_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700425 LOG_DEBUG(device, "@ %ld.%06ld ---------- SYN_REPORT -------\n",
Mike Frysingerda3e4732012-12-23 13:00:24 -0500426 (long)ev->time.tv_sec, (long)ev->time.tv_usec);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700427 return;
428 case SYN_MT_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700429 LOG_DEBUG(device, "@ %ld.%06ld ........ SYN_MT_REPORT ......\n",
Mike Frysingerda3e4732012-12-23 13:00:24 -0500430 (long)ev->time.tv_sec, (long)ev->time.tv_usec);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700431 return;
432 case SYN_DROPPED:
Dennis Kempin85a14442012-06-25 11:24:59 -0700433 LOG_WARNING(device, "@ %ld.%06ld ++++++++ SYN_DROPPED ++++++++\n",
Mike Frysingerda3e4732012-12-23 13:00:24 -0500434 (long)ev->time.tv_sec, (long)ev->time.tv_usec);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700435 return;
436 default:
Dennis Kempin85a14442012-06-25 11:24:59 -0700437 LOG_WARNING(device, "@ %ld.%06ld ?????? SYN_UNKNOWN (%d) ?????\n",
Mike Frysingerda3e4732012-12-23 13:00:24 -0500438 (long)ev->time.tv_sec, (long)ev->time.tv_usec, ev->code);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700439 return;
440 }
441 break;
442 case EV_ABS:
443 if (ev->code == ABS_MT_SLOT) {
Dennis Kempinde0712f2012-06-11 15:13:50 -0700444 LOG_DEBUG(device, "@ %ld.%06ld .......... MT SLOT %d ........\n",
Mike Frysingerda3e4732012-12-23 13:00:24 -0500445 (long)ev->time.tv_sec, (long)ev->time.tv_usec, ev->value);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700446 return;
447 }
448 break;
449 default:
450 break;
451 }
452
Dennis Kempinde0712f2012-06-11 15:13:50 -0700453 LOG_DEBUG(device, "@ %ld.%06ld %s[%d] (%s) = %d\n",
Mike Frysingerda3e4732012-12-23 13:00:24 -0500454 (long)ev->time.tv_sec, (long)ev->time.tv_usec,
455 Event_Type_To_String(ev->type), ev->code,
456 Event_To_String(ev->type, ev->code), ev->value);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700457}
458
459/**
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700460 * Process Input Events. It returns TRUE if SYN_DROPPED detected.
Dennis Kempina9963ba2012-06-08 10:32:23 -0700461 */
462bool
463Event_Process(EvdevPtr device, struct input_event* ev)
464{
Dennis Kempina9963ba2012-06-08 10:32:23 -0700465 Event_Print(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700466
467 switch (ev->type) {
468 case EV_SYN:
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700469 return Event_Syn(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700470
471 case EV_KEY:
472 Event_Key(device, ev);
473 break;
474
475 case EV_ABS:
476 Event_Abs(device, ev);
477 break;
478
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700479 case EV_REL:
480 Event_Rel(device, ev);
481 break;
482
Dennis Kempina9963ba2012-06-08 10:32:23 -0700483 default:
484 break;
485 }
486 return false;
487}
488
489/**
490 * Dump the log of input events to disk
491 */
492void
Dennis Kempin328acb82014-04-10 13:58:25 -0700493Event_Dump_Debug_Log(void* vinfo) {
494 Event_Dump_Debug_Log_To(vinfo, "/var/log/xorg/cmt_input_events.dat");
495}
496
497void
498Event_Dump_Debug_Log_To(void* vinfo, const char* filename)
Dennis Kempina9963ba2012-06-08 10:32:23 -0700499{
500 EvdevPtr device = (EvdevPtr) vinfo;
501 size_t i;
Dennis Kempin69c91ed2013-02-12 14:53:10 -0800502 int ret;
Dennis Kempina9963ba2012-06-08 10:32:23 -0700503 EventStatePtr evstate = device->evstate;
504
Dennis Kempin328acb82014-04-10 13:58:25 -0700505 FILE* fp = fopen(filename, "wb");
Dennis Kempina9963ba2012-06-08 10:32:23 -0700506 if (!fp) {
507 LOG_ERROR(device, "fopen() failed for debug log");
508 return;
509 }
Dennis Kempin69c91ed2013-02-12 14:53:10 -0800510
511 ret = EvdevWriteInfoToFile(fp, &device->info);
512 if (ret <= 0) {
513 LOG_ERROR(device, "EvdevWriteInfoToFile failed. Log without info.");
514 }
515
Dennis Kempina9963ba2012-06-08 10:32:23 -0700516 for (i = 0; i < DEBUG_BUF_SIZE; i++) {
Dennis Kempina9963ba2012-06-08 10:32:23 -0700517 struct input_event *ev =
518 &evstate->debug_buf[(evstate->debug_buf_tail + i) % DEBUG_BUF_SIZE];
519 if (ev->time.tv_sec == 0 && ev->time.tv_usec == 0)
520 continue;
Dennis Kempin69c91ed2013-02-12 14:53:10 -0800521 ret = EvdevWriteEventToFile(fp, ev);
522 if (ret <= 0) {
523 LOG_ERROR(device, "EvdevWriteEventToFile failed. Log is short.");
Dennis Kempina9963ba2012-06-08 10:32:23 -0700524 break;
525 }
526 }
527 fclose(fp);
528}
529
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700530/**
Dennis Kempind6ae1672014-01-08 11:41:33 -0800531 * Clear Debug Buffer
532 */
533void
534Event_Clear_Debug_Log(void* vinfo)
535{
536 EvdevPtr device = (EvdevPtr) vinfo;
537 EventStatePtr evstate = device->evstate;
538
539 memset(evstate->debug_buf, 0, sizeof(evstate->debug_buf));
540 evstate->debug_buf_tail = 0;
541}
542
543/**
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700544 * Clear EV_REL event state. This function should be called after a EV_SYN
545 * event is processed because EV_REL event state is not accumulative.
546 */
Dennis Kempina9963ba2012-06-08 10:32:23 -0700547static void
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700548Event_Clear_Ev_Rel_State(EvdevPtr device)
549{
550 EventStatePtr evstate;
551
552 evstate = device->evstate;
553 evstate->rel_x = 0;
554 evstate->rel_y = 0;
555 evstate->rel_wheel = 0;
556 evstate->rel_hwheel = 0;
557}
558
559/**
560 * Process EV_SYN events. It returns TRUE if SYN_DROPPED detected.
561 */
562static bool
Dennis Kempina9963ba2012-06-08 10:32:23 -0700563Event_Syn(EvdevPtr device, struct input_event* ev)
564{
565 switch (ev->code) {
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700566 case SYN_DROPPED:
567 /*
568 * Technically we don't need to call Event_Clear_Ev_Rel_State() here
569 * because when SYN_DROPPED is detected, Event_Sync_State() will be
570 * called and Event_Sync_State() will call Event_Clear_Ev_Rel_State()
571 * to re-initialize EV_REL event state.
572 */
573 return true;
Dennis Kempina9963ba2012-06-08 10:32:23 -0700574 case SYN_REPORT:
575 Event_Syn_Report(device, ev);
576 break;
577 case SYN_MT_REPORT:
578 Event_Syn_MT_Report(device, ev);
579 break;
580 }
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700581 return false;
Dennis Kempina9963ba2012-06-08 10:32:23 -0700582}
583
584static void
585Event_Syn_Report(EvdevPtr device, struct input_event* ev)
586{
587 EventStatePtr evstate = device->evstate;
588 device->syn_report(device->syn_report_udata, evstate, &ev->time);
589
590 MT_Print_Slots(device);
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700591
592 Event_Clear_Ev_Rel_State(device);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700593}
594
595static void
596Event_Syn_MT_Report(EvdevPtr device, struct input_event* ev)
597{
598 /* TODO(djkurtz): Handle MT-A */
599}
600
601static void
602Event_Key(EvdevPtr device, struct input_event* ev)
603{
604 AssignBit(device->key_state_bitmask, ev->code, ev->value);
605}
606
607static void
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800608Event_Abs_Update_Pressure(EvdevPtr device, struct input_event* ev)
Dennis Kempina9963ba2012-06-08 10:32:23 -0700609{
610 /*
611 * Update all active slots with the same ABS_PRESSURE value if it is a
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800612 * single-pressure device.
Dennis Kempina9963ba2012-06-08 10:32:23 -0700613 */
614 EventStatePtr evstate = device->evstate;
615
616 for (int i = 0; i < evstate->slot_count; i++) {
617 MtSlotPtr slot = &evstate->slots[i];
618 slot->pressure = ev->value;
619 }
620}
621
622static void
623Event_Abs(EvdevPtr device, struct input_event* ev)
624{
625 if (ev->code == ABS_MT_SLOT)
626 MT_Slot_Set(device, ev->value);
627 else if (IS_ABS_MT(ev->code))
628 Event_Abs_MT(device, ev);
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800629 else if ((ev->code == ABS_PRESSURE) && EvdevIsSinglePressureDevice(device))
630 Event_Abs_Update_Pressure(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700631}
632
633static void
634Event_Abs_MT(EvdevPtr device, struct input_event* ev)
635{
636 EventStatePtr evstate = device->evstate;
637 struct input_absinfo* axis = evstate->mt_axes[MT_CODE(ev->code)];
638 MtSlotPtr slot = evstate->slot_current;
639
640 if (axis == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700641 LOG_WARNING(device, "ABS_MT[%02x] was not reported by this device\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700642 ev->code);
643 return;
644 }
645
646 /* Warn about out of range data, but don't ignore */
647 if ((ev->code != ABS_MT_TRACKING_ID)
648 && ((ev->value < axis->minimum)
649 || (ev->value > axis->maximum))) {
650 LOG_WARNING(device, "ABS_MT[%02x] = %d : value out of range [%d .. %d]\n",
651 ev->code, ev->value, axis->minimum, axis->maximum);
Chung-yih Wangf573f892013-01-04 14:29:02 +0800652 /* Update the effective boundary as we already print out the warning */
653 if (ev->value < axis->minimum)
654 axis->minimum = ev->value;
655 else if (ev->value > axis->maximum)
656 axis->maximum = ev->value;
Dennis Kempina9963ba2012-06-08 10:32:23 -0700657 }
658
659 if (slot == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700660 LOG_WARNING(device, "MT slot not set. Ignoring ABS_MT event\n");
Dennis Kempina9963ba2012-06-08 10:32:23 -0700661 return;
662 }
663
664 MT_Slot_Value_Set(slot, ev->code, ev->value);
665}
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700666
667static void
668Event_Rel(EvdevPtr device, struct input_event* ev)
669{
670 EventStatePtr evstate = device->evstate;
671
672 switch (ev->code) {
673 case REL_X:
674 evstate->rel_x = ev->value;
675 break;
676 case REL_Y:
677 evstate->rel_y = ev->value;
678 break;
679 case REL_WHEEL:
680 evstate->rel_wheel = ev->value;
681 break;
682 case REL_HWHEEL:
683 evstate->rel_hwheel = ev->value;
684 break;
685 }
686}