blob: 11576e3b228b7559763597fe9bbc37cbde4a25be [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
Che-Liang Chiouf616b122012-10-24 17:08:51 -070036static void Event_Clear_Ev_Rel_State(EvdevPtr);
Dennis Kempina9963ba2012-06-08 10:32:23 -070037
Che-Liang Chiouf616b122012-10-24 17:08:51 -070038static bool Event_Syn(EvdevPtr, struct input_event*);
Dennis Kempina9963ba2012-06-08 10:32:23 -070039static void Event_Syn_Report(EvdevPtr, struct input_event*);
40static void Event_Syn_MT_Report(EvdevPtr, struct input_event*);
41
42static void Event_Key(EvdevPtr, struct input_event*);
43
44static void Event_Abs(EvdevPtr, struct input_event*);
45static void Event_Abs_MT(EvdevPtr, struct input_event*);
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +080046static void Event_Abs_Update_Pressure(EvdevPtr, struct input_event*);
Dennis Kempina9963ba2012-06-08 10:32:23 -070047
Che-Liang Chiouf616b122012-10-24 17:08:51 -070048static void Event_Rel(EvdevPtr, struct input_event*);
49
Dennis Kempina9963ba2012-06-08 10:32:23 -070050static void Event_Get_Time(struct timeval*, bool);
51
52/**
53 * Input Device Event Property accessors
54 */
55int
56Event_Get_Left(EvdevPtr device)
57{
Yufeng Shen86e52252012-07-05 11:44:36 -040058 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_X];
Dennis Kempina9963ba2012-06-08 10:32:23 -070059 return absinfo->minimum;
60}
61
62int
63Event_Get_Right(EvdevPtr device)
64{
Yufeng Shen86e52252012-07-05 11:44:36 -040065 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_X];
Dennis Kempina9963ba2012-06-08 10:32:23 -070066 return absinfo->maximum;
67}
68
69int
70Event_Get_Top(EvdevPtr device)
71{
Yufeng Shen86e52252012-07-05 11:44:36 -040072 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_Y];
Dennis Kempina9963ba2012-06-08 10:32:23 -070073 return absinfo->minimum;
74}
75
76int
77Event_Get_Bottom(EvdevPtr device)
78{
Yufeng Shen86e52252012-07-05 11:44:36 -040079 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_Y];
Dennis Kempina9963ba2012-06-08 10:32:23 -070080 return absinfo->maximum;
81}
82
83int
84Event_Get_Res_Y(EvdevPtr device)
85{
Yufeng Shen86e52252012-07-05 11:44:36 -040086 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_Y];
Dennis Kempina9963ba2012-06-08 10:32:23 -070087 return absinfo->resolution;
88}
89
90int
91Event_Get_Res_X(EvdevPtr device)
92{
Yufeng Shen86e52252012-07-05 11:44:36 -040093 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_POSITION_X];
Dennis Kempina9963ba2012-06-08 10:32:23 -070094 return absinfo->resolution;
95}
96
97int
Che-Liang Chioua2563012012-10-11 11:41:06 -070098Event_Get_Orientation_Minimum(EvdevPtr device)
99{
100 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_ORIENTATION];
101 return absinfo->minimum;
102}
103
104int
105Event_Get_Orientation_Maximum(EvdevPtr device)
106{
107 struct input_absinfo* absinfo = &device->info.absinfo[ABS_MT_ORIENTATION];
108 return absinfo->maximum;
109}
110
111int
Dennis Kempina9963ba2012-06-08 10:32:23 -0700112Event_Get_Button_Pad(EvdevPtr device)
113{
114 return TestBit(INPUT_PROP_BUTTONPAD, device->info.prop_bitmask);
115}
116
117int
118Event_Get_Semi_MT(EvdevPtr device)
119{
120 return TestBit(INPUT_PROP_SEMI_MT, device->info.prop_bitmask);
121}
122
123int
124Event_Get_T5R2(EvdevPtr device)
125{
126 EventStatePtr evstate = device->evstate;
127 if (Event_Get_Semi_MT(device))
128 return 0;
129 return (Event_Get_Touch_Count_Max(device) > evstate->slot_count);
130}
131
132int
133Event_Get_Touch_Count_Max(EvdevPtr device)
134{
135
136 if (TestBit(BTN_TOOL_QUINTTAP, device->info.key_bitmask))
137 return 5;
138 if (TestBit(BTN_TOOL_QUADTAP, device->info.key_bitmask))
139 return 4;
140 if (TestBit(BTN_TOOL_TRIPLETAP, device->info.key_bitmask))
141 return 3;
142 if (TestBit(BTN_TOOL_DOUBLETAP, device->info.key_bitmask))
143 return 2;
144 return 1;
145}
146
147int
148Event_Get_Touch_Count(EvdevPtr device)
149{
150
151 if (TestBit(BTN_TOOL_QUINTTAP, device->key_state_bitmask))
152 return 5;
153 if (TestBit(BTN_TOOL_QUADTAP, device->key_state_bitmask))
154 return 4;
155 if (TestBit(BTN_TOOL_TRIPLETAP, device->key_state_bitmask))
156 return 3;
157 if (TestBit(BTN_TOOL_DOUBLETAP, device->key_state_bitmask))
158 return 2;
159 if (TestBit(BTN_TOOL_FINGER, device->key_state_bitmask))
160 return 1;
161 return 0;
162}
163
164int
165Event_Get_Slot_Count(EvdevPtr device)
166{
167 EventStatePtr evstate = device->evstate;
168 return evstate->slot_count;
169}
170
171int
172Event_Get_Button_Left(EvdevPtr device)
173{
174 return TestBit(BTN_LEFT, device->key_state_bitmask);
175}
176
177int
178Event_Get_Button_Middle(EvdevPtr device)
179{
180 return TestBit(BTN_MIDDLE, device->key_state_bitmask);
181}
182
183int
184Event_Get_Button_Right(EvdevPtr device)
185{
186 return TestBit(BTN_RIGHT, device->key_state_bitmask);
187}
188
189#define CASE_RETURN(s) \
190 case (s):\
191 return #s
192
193
194const char *
195Event_To_String(int type, int code) {
196 switch (type) {
197 case EV_SYN:
198 switch (code) {
199 CASE_RETURN(SYN_REPORT);
200 CASE_RETURN(SYN_MT_REPORT);
201 default:
202 break;
203 }
204 break;
205 case EV_ABS:
206 switch (code) {
207 CASE_RETURN(ABS_X);
208 CASE_RETURN(ABS_Y);
209 CASE_RETURN(ABS_Z);
210 CASE_RETURN(ABS_PRESSURE);
211 CASE_RETURN(ABS_TOOL_WIDTH);
212 CASE_RETURN(ABS_MT_TOUCH_MAJOR);
213 CASE_RETURN(ABS_MT_TOUCH_MINOR);
214 CASE_RETURN(ABS_MT_WIDTH_MAJOR);
215 CASE_RETURN(ABS_MT_WIDTH_MINOR);
216 CASE_RETURN(ABS_MT_ORIENTATION);
217 CASE_RETURN(ABS_MT_POSITION_X);
218 CASE_RETURN(ABS_MT_POSITION_Y);
219 CASE_RETURN(ABS_MT_TOOL_TYPE);
220 CASE_RETURN(ABS_MT_BLOB_ID);
221 CASE_RETURN(ABS_MT_TRACKING_ID);
222 CASE_RETURN(ABS_MT_PRESSURE);
223 CASE_RETURN(ABS_MT_SLOT);
224 default:
225 break;
226 }
227 break;
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700228 case EV_REL:
229 switch (code) {
230 CASE_RETURN(REL_X);
231 CASE_RETURN(REL_Y);
232 CASE_RETURN(REL_WHEEL);
233 CASE_RETURN(REL_HWHEEL);
234 default:
235 break;
236 }
237 break;
Dennis Kempina9963ba2012-06-08 10:32:23 -0700238 case EV_KEY:
239 switch (code) {
240 CASE_RETURN(BTN_LEFT);
241 CASE_RETURN(BTN_RIGHT);
242 CASE_RETURN(BTN_MIDDLE);
243 CASE_RETURN(BTN_TOUCH);
244 CASE_RETURN(BTN_TOOL_FINGER);
245 CASE_RETURN(BTN_TOOL_DOUBLETAP);
246 CASE_RETURN(BTN_TOOL_TRIPLETAP);
247 CASE_RETURN(BTN_TOOL_QUADTAP);
248 CASE_RETURN(BTN_TOOL_QUINTTAP);
249 default:
250 break;
251 }
252 break;
253 default:
254 break;
255 }
256 return "?";
257}
258#undef CASE_RETURN
259
260const char *
261Event_Type_To_String(int type) {
262 switch (type) {
263 case EV_SYN: return "SYN";
264 case EV_KEY: return "KEY";
265 case EV_REL: return "REL";
266 case EV_ABS: return "ABS";
267 case EV_MSC: return "MSC";
268 case EV_SW: return "SW";
269 case EV_LED: return "LED";
270 case EV_SND: return "SND";
271 case EV_REP: return "REP";
272 case EV_FF: return "FF";
273 case EV_PWR: return "PWR";
274 default: return "?";
275 }
276}
277
278
279/**
280 * Probe Device Input Event Support
281 */
282int
283Event_Init(EvdevPtr device)
284{
285 int i;
286 EventStatePtr evstate;
287
288 evstate = device->evstate;
289 if (EvdevProbe(device) != Success) {
290 return !Success;
291 }
292
Dennis Kempina9963ba2012-06-08 10:32:23 -0700293 for (i = ABS_X; i <= ABS_MAX; i++) {
294 if (TestBit(i, device->info.abs_bitmask)) {
295 struct input_absinfo* absinfo = &device->info.absinfo[i];
296 if (i == ABS_MT_SLOT) {
297 int rc;
298 rc = MTB_Init(device, absinfo->minimum, absinfo->maximum,
299 absinfo->value);
300 if (rc != Success)
301 return rc;
302 } else if (IS_ABS_MT(i)) {
303 evstate->mt_axes[MT_CODE(i)] = absinfo;
304 }
305 }
306 }
Dennis Kempina9963ba2012-06-08 10:32:23 -0700307 return Success;
308}
309
310void
311Event_Free(EvdevPtr device)
312{
313 MT_Free(device);
314}
315
316void
317Event_Open(EvdevPtr device)
318{
319 /* Select monotonic input event timestamps, if supported by kernel */
320 device->info.is_monotonic = (EvdevEnableMonotonic(device) == Success);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700321 LOG_DEBUG(device, "Using %s input event time stamps\n",
322 device->info.is_monotonic ? "monotonic" : "realtime");
Daniel Kurtz000bdff2012-09-17 15:45:29 +0800323
324 /* Synchronize all MT slots with kernel evdev driver */
325 Event_Sync_State(device);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700326}
327
328static void
329Event_Get_Time(struct timeval *t, bool use_monotonic) {
330 struct timespec now;
331 clockid_t clockid = (use_monotonic) ? CLOCK_MONOTONIC : CLOCK_REALTIME;
332
333 clock_gettime(clockid, &now);
334 t->tv_sec = now.tv_sec;
335 t->tv_usec = now.tv_nsec / 1000;
336}
337
338/**
339 * Synchronize the current state with kernel evdev driver. For cmt, there are
340 * only four components required to be synced: current touch count, the MT
341 * slots information, current slot id and physical button states. However, as
342 * pressure readings are missing in ABS_MT_PRESSURE field of MT slots for
343 * semi_mt touchpad device (e.g. Cr48), we also need need to extract it with
344 * extra EVIOCGABS query.
345 */
346void
347Event_Sync_State(EvdevPtr device)
348{
349 int i;
350
351 Event_Get_Time(&device->before_sync_time, device->info.is_monotonic);
352
353 EvdevProbeKeyState(device);
354
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800355 /* Get current pressure information for single-pressure device */
356 if (EvdevIsSinglePressureDevice(device) == Success) {
357 struct input_event ev;
358 ev.code = ABS_PRESSURE;
359 ev.value = device->info.absinfo[ABS_PRESSURE].value;
360 Event_Abs_Update_Pressure(device, &ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700361 }
362
363 /* TODO(cywang): Sync all ABS_ states for completeness */
364
365 /* Get current MT information for each slot */
366 for (i = _ABS_MT_FIRST; i <= _ABS_MT_LAST; i++) {
367 MTSlotInfo req;
368
369 if (!TestBit(i, device->info.abs_bitmask))
370 continue;
371 /*
372 * TODO(cywang): Scale the size of slots in MTSlotInfo based on the
373 * evstate->slot_count.
374 */
375
376 req.code = i;
377 if (EvdevProbeMTSlot(device, &req) != Success) {
378 continue;
379 }
380 MT_Slot_Sync(device, &req);
381 }
382
383 /* Get current slot id */
384 if (EvdevProbeAbsinfo(device, ABS_MT_SLOT) == Success)
385 MT_Slot_Set(device, device->info.absinfo[ABS_MT_SLOT].value);
386
387 Event_Get_Time(&device->after_sync_time, device->info.is_monotonic);
388
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700389 /* Initialize EV_REL event state */
390 Event_Clear_Ev_Rel_State(device);
391
Chung-yih Wangb709c082012-07-20 16:26:15 +0800392 LOG_WARNING(device, "Event_Sync_State: before %ld.%ld after %ld.%ld\n",
393 device->before_sync_time.tv_sec,
394 device->before_sync_time.tv_usec,
395 device->after_sync_time.tv_sec,
396 device->after_sync_time.tv_usec);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700397}
398
399static void
400Event_Print(EvdevPtr device, struct input_event* ev)
401{
402 switch (ev->type) {
403 case EV_SYN:
404 switch (ev->code) {
405 case SYN_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700406 LOG_DEBUG(device, "@ %ld.%06ld ---------- SYN_REPORT -------\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700407 ev->time.tv_sec, ev->time.tv_usec);
408 return;
409 case SYN_MT_REPORT:
Dennis Kempinde0712f2012-06-11 15:13:50 -0700410 LOG_DEBUG(device, "@ %ld.%06ld ........ SYN_MT_REPORT ......\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700411 ev->time.tv_sec, ev->time.tv_usec);
412 return;
413 case SYN_DROPPED:
Dennis Kempin85a14442012-06-25 11:24:59 -0700414 LOG_WARNING(device, "@ %ld.%06ld ++++++++ SYN_DROPPED ++++++++\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700415 ev->time.tv_sec, ev->time.tv_usec);
416 return;
417 default:
Dennis Kempin85a14442012-06-25 11:24:59 -0700418 LOG_WARNING(device, "@ %ld.%06ld ?????? SYN_UNKNOWN (%d) ?????\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700419 ev->time.tv_sec, ev->time.tv_usec, ev->code);
420 return;
421 }
422 break;
423 case EV_ABS:
424 if (ev->code == ABS_MT_SLOT) {
Dennis Kempinde0712f2012-06-11 15:13:50 -0700425 LOG_DEBUG(device, "@ %ld.%06ld .......... MT SLOT %d ........\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700426 ev->time.tv_sec, ev->time.tv_usec, ev->value);
427 return;
428 }
429 break;
430 default:
431 break;
432 }
433
Dennis Kempinde0712f2012-06-11 15:13:50 -0700434 LOG_DEBUG(device, "@ %ld.%06ld %s[%d] (%s) = %d\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700435 ev->time.tv_sec, ev->time.tv_usec, Event_Type_To_String(ev->type),
436 ev->code, Event_To_String(ev->type, ev->code), ev->value);
437}
438
439/**
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700440 * Process Input Events. It returns TRUE if SYN_DROPPED detected.
Dennis Kempina9963ba2012-06-08 10:32:23 -0700441 */
442bool
443Event_Process(EvdevPtr device, struct input_event* ev)
444{
Dennis Kempina9963ba2012-06-08 10:32:23 -0700445 Event_Print(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700446
447 switch (ev->type) {
448 case EV_SYN:
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700449 return Event_Syn(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700450
451 case EV_KEY:
452 Event_Key(device, ev);
453 break;
454
455 case EV_ABS:
456 Event_Abs(device, ev);
457 break;
458
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700459 case EV_REL:
460 Event_Rel(device, ev);
461 break;
462
Dennis Kempina9963ba2012-06-08 10:32:23 -0700463 default:
464 break;
465 }
466 return false;
467}
468
469/**
470 * Dump the log of input events to disk
471 */
472void
473Event_Dump_Debug_Log(void* vinfo)
474{
475 EvdevPtr device = (EvdevPtr) vinfo;
476 size_t i;
477 EventStatePtr evstate = device->evstate;
478
479 FILE* fp = fopen("/var/log/cmt_input_events.dat", "wb");
480 if (!fp) {
481 LOG_ERROR(device, "fopen() failed for debug log");
482 return;
483 }
484 for (i = 0; i < DEBUG_BUF_SIZE; i++) {
485 size_t rc;
486 struct input_event *ev =
487 &evstate->debug_buf[(evstate->debug_buf_tail + i) % DEBUG_BUF_SIZE];
488 if (ev->time.tv_sec == 0 && ev->time.tv_usec == 0)
489 continue;
490 rc = fprintf(fp, "E: %ld.%06ld %04x %04x %d\n",
491 ev->time.tv_sec,
492 ev->time.tv_usec,
493 ev->type,
494 ev->code,
495 ev->value);
496 if (rc == 0) {
497 LOG_ERROR(device, "fprintf() failed for debug log. Log is short");
498 break;
499 }
500 }
501 fclose(fp);
502}
503
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700504/**
505 * Clear EV_REL event state. This function should be called after a EV_SYN
506 * event is processed because EV_REL event state is not accumulative.
507 */
Dennis Kempina9963ba2012-06-08 10:32:23 -0700508static void
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700509Event_Clear_Ev_Rel_State(EvdevPtr device)
510{
511 EventStatePtr evstate;
512
513 evstate = device->evstate;
514 evstate->rel_x = 0;
515 evstate->rel_y = 0;
516 evstate->rel_wheel = 0;
517 evstate->rel_hwheel = 0;
518}
519
520/**
521 * Process EV_SYN events. It returns TRUE if SYN_DROPPED detected.
522 */
523static bool
Dennis Kempina9963ba2012-06-08 10:32:23 -0700524Event_Syn(EvdevPtr device, struct input_event* ev)
525{
526 switch (ev->code) {
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700527 case SYN_DROPPED:
528 /*
529 * Technically we don't need to call Event_Clear_Ev_Rel_State() here
530 * because when SYN_DROPPED is detected, Event_Sync_State() will be
531 * called and Event_Sync_State() will call Event_Clear_Ev_Rel_State()
532 * to re-initialize EV_REL event state.
533 */
534 return true;
Dennis Kempina9963ba2012-06-08 10:32:23 -0700535 case SYN_REPORT:
536 Event_Syn_Report(device, ev);
537 break;
538 case SYN_MT_REPORT:
539 Event_Syn_MT_Report(device, ev);
540 break;
541 }
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700542 return false;
Dennis Kempina9963ba2012-06-08 10:32:23 -0700543}
544
545static void
546Event_Syn_Report(EvdevPtr device, struct input_event* ev)
547{
548 EventStatePtr evstate = device->evstate;
549 device->syn_report(device->syn_report_udata, evstate, &ev->time);
550
551 MT_Print_Slots(device);
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700552
553 Event_Clear_Ev_Rel_State(device);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700554}
555
556static void
557Event_Syn_MT_Report(EvdevPtr device, struct input_event* ev)
558{
559 /* TODO(djkurtz): Handle MT-A */
560}
561
562static void
563Event_Key(EvdevPtr device, struct input_event* ev)
564{
565 AssignBit(device->key_state_bitmask, ev->code, ev->value);
566}
567
568static void
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800569Event_Abs_Update_Pressure(EvdevPtr device, struct input_event* ev)
Dennis Kempina9963ba2012-06-08 10:32:23 -0700570{
571 /*
572 * Update all active slots with the same ABS_PRESSURE value if it is a
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800573 * single-pressure device.
Dennis Kempina9963ba2012-06-08 10:32:23 -0700574 */
575 EventStatePtr evstate = device->evstate;
576
577 for (int i = 0; i < evstate->slot_count; i++) {
578 MtSlotPtr slot = &evstate->slots[i];
579 slot->pressure = ev->value;
580 }
581}
582
583static void
584Event_Abs(EvdevPtr device, struct input_event* ev)
585{
586 if (ev->code == ABS_MT_SLOT)
587 MT_Slot_Set(device, ev->value);
588 else if (IS_ABS_MT(ev->code))
589 Event_Abs_MT(device, ev);
Chung-yih Wang8b2fa0a2012-07-23 16:49:10 +0800590 else if ((ev->code == ABS_PRESSURE) && EvdevIsSinglePressureDevice(device))
591 Event_Abs_Update_Pressure(device, ev);
Dennis Kempina9963ba2012-06-08 10:32:23 -0700592}
593
594static void
595Event_Abs_MT(EvdevPtr device, struct input_event* ev)
596{
597 EventStatePtr evstate = device->evstate;
598 struct input_absinfo* axis = evstate->mt_axes[MT_CODE(ev->code)];
599 MtSlotPtr slot = evstate->slot_current;
600
601 if (axis == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700602 LOG_WARNING(device, "ABS_MT[%02x] was not reported by this device\n",
Dennis Kempina9963ba2012-06-08 10:32:23 -0700603 ev->code);
604 return;
605 }
606
607 /* Warn about out of range data, but don't ignore */
608 if ((ev->code != ABS_MT_TRACKING_ID)
609 && ((ev->value < axis->minimum)
610 || (ev->value > axis->maximum))) {
611 LOG_WARNING(device, "ABS_MT[%02x] = %d : value out of range [%d .. %d]\n",
612 ev->code, ev->value, axis->minimum, axis->maximum);
613 }
614
615 if (slot == NULL) {
Dennis Kempin85a14442012-06-25 11:24:59 -0700616 LOG_WARNING(device, "MT slot not set. Ignoring ABS_MT event\n");
Dennis Kempina9963ba2012-06-08 10:32:23 -0700617 return;
618 }
619
620 MT_Slot_Value_Set(slot, ev->code, ev->value);
621}
Che-Liang Chiouf616b122012-10-24 17:08:51 -0700622
623static void
624Event_Rel(EvdevPtr device, struct input_event* ev)
625{
626 EventStatePtr evstate = device->evstate;
627
628 switch (ev->code) {
629 case REL_X:
630 evstate->rel_x = ev->value;
631 break;
632 case REL_Y:
633 evstate->rel_y = ev->value;
634 break;
635 case REL_WHEEL:
636 evstate->rel_wheel = ev->value;
637 break;
638 case REL_HWHEEL:
639 evstate->rel_hwheel = ev->value;
640 break;
641 }
642}