tizen 2.4 release
[adaptation/xorg/driver/xserver-xorg-input-evdev.git] / src / evdev.c
1 /*
2  *
3  * xserver-xorg-input-evdev
4  *
5  * Contact: Sung-Jin Park <sj76.park@samsung.com>
6  *          Sangjin LEE <lsj119@samsung.com>
7  *
8  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
9  * Copyright © 2004-2008 Red Hat, Inc.
10  *
11  * Permission to use, copy, modify, distribute, and sell this software
12  * and its documentation for any purpose is hereby granted without
13  * fee, provided that the above copyright notice appear in all copies
14  * and that both that copyright notice and this permission notice
15  * appear in supporting documentation, and that the name of Red Hat
16  * not be used in advertising or publicity pertaining to distribution
17  * of the software without specific, written prior permission.  Red
18  * Hat makes no representations about the suitability of this software
19  * for any purpose.  It is provided "as is" without express or implied
20  * warranty.
21  *
22  * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
23  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
24  * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
25  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
26  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
27  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
28  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29  *
30  * Authors:
31  *      Kristian Høgsberg (krh@redhat.com)
32  *      Adam Jackson (ajax@redhat.com)
33  *      Peter Hutterer (peter.hutterer@redhat.com)
34  *      Oliver McFadden (oliver.mcfadden@nokia.com)
35  */
36
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40
41 #include "evdev.h"
42
43 #include <X11/keysym.h>
44 #include <X11/extensions/XI.h>
45
46 #include <linux/version.h>
47 #include <sys/stat.h>
48 #include <libudev.h>
49 #include <unistd.h>
50 #include <errno.h>
51 #include <fcntl.h>
52
53 #include <xf86.h>
54 #include <xf86Xinput.h>
55 #ifdef _F_PROXY_DEVICE_ENABLED_
56 #include <xorg/optionstr.h>
57 #endif //_F_PROXY_DEVICE_ENABLED_
58 #include <exevents.h>
59 #include <xorgVersion.h>
60 #include <xkbsrv.h>
61
62 #include <X11/Xatom.h>
63 #include <evdev-properties.h>
64 #include <xserver-properties.h>
65
66 #ifdef _F_EVDEV_CONFINE_REGION_
67 #include <xorg/mipointrst.h>
68
69 #define MIPOINTER(dev) \
70     ((!IsMaster(dev) && !dev->master) ? \
71         (miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \
72         (miPointerPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miPointerPrivKey))
73
74 #endif /* _F_EVDEV_CONFINE_REGION_ */
75
76 #ifndef XI_PROP_PRODUCT_ID
77 #define XI_PROP_PRODUCT_ID "Device Product ID"
78 #endif
79
80 #ifndef XI_PROP_VIRTUAL_DEVICE
81 #define XI_PROP_VIRTUAL_DEVICE "Virtual Device"
82 #endif
83
84 #ifndef XI_PROP_DEVICE_TYPE
85 #define XI_PROP_DEVICE_TYPE "Device Type"
86 #endif
87
88 /* removed from server, purge when dropping support for server 1.10 */
89 #define XI86_SEND_DRAG_EVENTS   0x08
90
91 #ifndef MAXDEVICES
92 #include <inputstr.h> /* for MAX_DEVICES */
93 #define MAXDEVICES MAX_DEVICES
94 #endif
95
96 #ifdef _F_PICTURE_OFF_MODE_ENABLE_
97 #define XI_PROP_PICTURE_OFF_MODE "PICTURE_OFF_MODE"
98 static Atom atomPictureOffMode;
99 #endif //_F_PICTURE_OFF_MODE_ENABLE_
100
101 #define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
102
103 #define MIN_KEYCODE 8
104 #define GLYPHS_PER_KEY 2
105 #define AltMask         Mod1Mask
106 #define NumLockMask     Mod2Mask
107 #define AltLangMask     Mod3Mask
108 #define KanaMask        Mod4Mask
109 #define ScrollLockMask  Mod5Mask
110
111 #define CAPSFLAG        1
112 #define NUMFLAG         2
113 #define SCROLLFLAG      4
114 #define MODEFLAG        8
115 #define COMPOSEFLAG     16
116
117 #ifndef ABS_MT_SLOT
118 #define ABS_MT_SLOT 0x2f
119 #endif
120
121 #ifndef ABS_MT_TRACKING_ID
122 #define ABS_MT_TRACKING_ID 0x39
123 #endif
124
125 static char *evdevDefaults[] = {
126     "XkbRules",     "evdev",
127     "XkbModel",     "evdev",
128     "XkbLayout",    "us",
129     NULL
130 };
131
132 /* Any of those triggers a proximity event */
133 static int proximity_bits[] = {
134         BTN_TOOL_PEN,
135         BTN_TOOL_RUBBER,
136         BTN_TOOL_BRUSH,
137         BTN_TOOL_PENCIL,
138         BTN_TOOL_AIRBRUSH,
139         BTN_TOOL_FINGER,
140         BTN_TOOL_MOUSE,
141         BTN_TOOL_LENS,
142 };
143
144 extern char * strcasestr(const char *haystack, const char *needle);
145
146 static int EvdevOn(DeviceIntPtr);
147 static int EvdevCache(InputInfoPtr pInfo);
148 static void EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl);
149 static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode);
150 static BOOL EvdevGrabDevice(InputInfoPtr pInfo, int grab, int ungrab);
151 static void EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4]);
152 static int EvdevOpenDevice(InputInfoPtr pInfo);
153 static void EvdevCloseDevice(InputInfoPtr pInfo);
154
155 static void EvdevInitAxesLabels(EvdevPtr pEvdev, int mode, int natoms, Atom *atoms);
156 static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
157 static void EvdevInitProperty(DeviceIntPtr dev);
158 static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
159                             XIPropertyValuePtr val, BOOL checkonly);
160 #ifdef _F_GESTURE_EXTENSION_
161 extern void mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e);
162 static void EvdevMTSync(InputInfoPtr pInfo, MTSyncType sync);
163 static BOOL EvdevMTStatusGet(InputInfoPtr pInfo, MTSyncType sync);
164 #endif /* #ifdef _F_GESTURE_EXTENSION_ */
165 #ifdef _F_TOUCH_TRANSFORM_MATRIX_
166 static void EvdevSetTransformMatrix(InputInfoPtr pInfo, int num_transform, float *tmatrix);
167 #endif /* #ifdef _F_TOUCH_TRANSFORM_MATRIX_ */
168 #ifdef _F_SUPPORT_ROTATION_ANGLE_
169 static void EvdevSetRotationAngle(EvdevPtr pEvdev, int angle);
170 #endif /* _F_SUPPORT_ROTATION_ANGLE_ */
171 #ifdef _F_EVDEV_CONFINE_REGION_
172 Bool IsMaster(DeviceIntPtr dev);
173 DeviceIntPtr GetPairedDevice(DeviceIntPtr dev);
174 DeviceIntPtr GetMaster(DeviceIntPtr dev, int which);
175 DeviceIntPtr GetMasterPointerFromId(int deviceid);
176 static void EvdevHookPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, BoxPtr pHotBox, BoxPtr pTopLeftBox);
177 static void EvdevHookPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox);
178 static void EvdevSetCursorLimits(InputInfoPtr pInfo, int region[6], int isSet);
179 static void EvdevSetConfineRegion(InputInfoPtr pInfo, int num_item, int region[6]);
180
181 #ifdef MULTITOUCH
182 static int num_slots(EvdevPtr pEvdev);
183 #endif
184
185 static Atom prop_confine_region = 0;
186 #endif /* _F_EVDEV_CONFINE_REGION_ */
187 #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_
188 static CARD32 EvdevRelativeMoveTimer(OsTimerPtr timer, CARD32 time, pointer arg);
189 #endif /* #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_ */
190 #ifdef _F_DONOT_SEND_RMA_BTN_RELEASE_
191 static BOOL isButtonPressed = FALSE;
192 #endif //_F_DONOT_SEND_RMA_BTN_RELEASE_
193
194 static Atom prop_product_id;
195 static Atom prop_invert;
196 static Atom prop_calibration;
197 static Atom prop_swap;
198 static Atom prop_axis_label;
199 static Atom prop_btn_label;
200 static Atom prop_device;
201 static Atom prop_virtual;
202 #ifdef _F_ENABLE_DEVICE_TYPE_PROP_
203 static Atom prop_device_type;
204 #endif /* #ifdef _F_ENABLE_DEVICE_TYPE_PROP_ */
205 #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_
206 static Atom prop_relative_move_status;
207 static Atom prop_relative_move_ack;
208 #endif /* #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_ */
209
210 #ifdef _F_BLOCK_MOTION_DEVICE_
211 static Atom prop_block_motion_status; /* Atom to block motion device */
212 int block_motion_device = 0;   /* Variable to set/unset of motion device */
213 #endif //_F_BLOCK_MOTION_DEVICE_
214 #ifdef _F_PICTURE_OFF_MODE_ENABLE_
215 int pictureOffMode;
216 #endif //_F_PICTURE_OFF_MODE_ENABLE_
217 #ifdef _F_BOOST_PULSE_
218 static int fd_boostpulse = 0;
219 #endif //_F_BOOST_PULSE_
220
221 #ifdef _F_TOUCH_TRANSFORM_MATRIX_
222 static Atom prop_transform;
223 #endif /* #ifdef _F_TOUCH_TRANSFORM_MATRIX_ */
224
225 #ifdef _F_USE_DEFAULT_XKB_RULES_
226 static Atom prop_xkb_rules = None;
227 #endif //_F_USE_DEFAULT_XKB_RULES_
228
229 #ifdef _F_SUPPORT_ROTATION_ANGLE_
230 static Atom prop_rotation_angle = 0;
231 static Atom prop_rotation_node = 0;
232 #endif //_F_SUPPORT_ROTATION_ANGLE_
233
234 #ifdef _F_PROXY_DEVICE_ENABLED_
235 static Atom prop_use_proxy_slave_device;
236 static InputInfoPtr pCreatorInfo = NULL;
237 static InputInfoPtr pProxyDeviceInfo = NULL;
238 #define PROXY_DEV_NAME  "HWKeys"
239 #define OPT_TYPE_VAL "ProxyDev"
240
241 static int EvdevSetProxyDevice(DeviceIntPtr dev, int val);
242 static InputOption *EvdevOptionDupConvert(pointer original);
243 static void EvdevFreeInputOpts(InputOption* opts);
244 static void EvdevReplaceOption(InputOption *opts,const char* key, char * value);
245 static InputInfoPtr EvdevCreateProxyDevice(InputInfoPtr pInfo);
246 static void EvdevProxydevReadInput(InputInfoPtr pInfo);
247 static void MakeClassesChangedEvent(DeviceChangedEvent *dce, DeviceIntPtr master, DeviceIntPtr slave, int flags);
248 #ifndef _F_PROXY_DEVICE_CHANGE_SOURCE_ID
249 static void EvdevPostDevChangeEvent(InputInfoPtr pInfo);
250 #else /* _F_PROXY_DEVICE_CHANGE_SOURCE_ID */
251 static void EvdevCheckDevChange(EvdevPtr pEvdev, int deviceid);
252 #endif /* _F_PROXY_DEVICE_CHANGE_SOURCE_ID */
253 #endif /* #ifdef _F_PROXY_DEVICE_ENABLED_ */
254
255 /* All devices the evdev driver has allocated and knows about.
256  * MAXDEVICES is safe as null-terminated array, as two devices (VCP and VCK)
257  * cannot be used by evdev, leaving us with a space of 2 at the end. */
258 static EvdevPtr evdev_devices[MAXDEVICES] = {NULL};
259
260 #ifdef _F_REMAP_KEYS_
261 static uint16_t
262 remapKey(EvdevPtr ev, uint16_t code)
263 {
264     uint8_t slice=code/256;
265     uint8_t offs=code%256;
266
267     if (!ev->keyremap) return code;
268     if (!(ev->keyremap->sl[slice])) return code;
269     if (!(ev->keyremap->sl[slice]->cd[offs])) return code;
270     return ev->keyremap->sl[slice]->cd[offs];
271 }
272
273 static void
274 addRemap(EvdevPtr ev,uint16_t code,uint8_t value)
275 {
276     uint8_t slice=code/256;
277     uint8_t offs=code%256;
278
279     if (!ev->keyremap) {
280         ev->keyremap=(EvdevKeyRemapPtr)calloc(sizeof(EvdevKeyRemap),1);
281         if (!ev->keyremap) return;
282     }
283     if (!ev->keyremap->sl[slice]) {
284         ev->keyremap->sl[slice]=(EvdevKeyRemapSlice*)calloc(sizeof(EvdevKeyRemapSlice),1);
285         if (!ev->keyremap->sl[slice]) return;
286      }
287      ev->keyremap->sl[slice]->cd[offs]=value;
288 }
289
290 static void
291 freeRemap(EvdevPtr ev)
292 {
293     uint16_t slice;
294     if (!ev->keyremap) return;
295     for (slice=0;slice<256;++slice) {
296         if (!ev->keyremap->sl[slice]) continue;
297         free(ev->keyremap->sl[slice]);
298     }
299     free(ev->keyremap);
300     ev->keyremap=0;
301 }
302 #endif //_F_REMAP_KEYS_
303
304 static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode)
305 {
306     InputInfoPtr pInfo;
307     EvdevPtr pEvdev;
308
309     pInfo = device->public.devicePrivate;
310     pEvdev = pInfo->private;
311
312     if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
313     {
314         if (mode == Relative)
315             return Success;
316         else
317             return XI_BadMode;
318     }
319
320     switch (mode) {
321         case Absolute:
322             pEvdev->flags &= ~EVDEV_RELATIVE_MODE;
323             break;
324
325         case Relative:
326             pEvdev->flags |= EVDEV_RELATIVE_MODE;
327             break;
328
329         default:
330             return XI_BadMode;
331     }
332
333     return Success;
334 }
335
336 static size_t EvdevCountBits(unsigned long *array, size_t nlongs)
337 {
338     unsigned int i;
339     size_t count = 0;
340
341     for (i = 0; i < nlongs; i++) {
342         unsigned long x = array[i];
343
344         while (x > 0)
345         {
346             count += (x & 0x1);
347             x >>= 1;
348         }
349     }
350     return count;
351 }
352
353 static inline int EvdevBitIsSet(const unsigned long *array, int bit)
354 {
355     return !!(array[bit / LONG_BITS] & (1LL << (bit % LONG_BITS)));
356 }
357
358 static inline void EvdevSetBit(unsigned long *array, int bit)
359 {
360     array[bit / LONG_BITS] |= (1LL << (bit % LONG_BITS));
361 }
362
363 static int
364 EvdevGetMajorMinor(InputInfoPtr pInfo)
365 {
366     struct stat st;
367
368     if (fstat(pInfo->fd, &st) == -1)
369     {
370         xf86IDrvMsg(pInfo, X_ERROR, "stat failed (%s). cannot check for duplicates.\n",
371                     strerror(errno));
372         return 0;
373     }
374
375     return st.st_rdev;
376 }
377
378 /**
379  * Return TRUE if one of the devices we know about has the same min/maj
380  * number.
381  */
382 static BOOL
383 EvdevIsDuplicate(InputInfoPtr pInfo)
384 {
385     EvdevPtr pEvdev = pInfo->private;
386     EvdevPtr* dev   = evdev_devices;
387
388     if (pEvdev->min_maj)
389     {
390         while(*dev)
391         {
392             if ((*dev) != pEvdev &&
393                 (*dev)->min_maj &&
394                 (*dev)->min_maj == pEvdev->min_maj)
395                 return TRUE;
396             dev++;
397         }
398     }
399     return FALSE;
400 }
401
402 /**
403  * Add to internal device list.
404  */
405 static void
406 EvdevAddDevice(InputInfoPtr pInfo)
407 {
408     EvdevPtr pEvdev = pInfo->private;
409     EvdevPtr* dev = evdev_devices;
410
411     while(*dev)
412         dev++;
413
414     *dev = pEvdev;
415 }
416
417 /**
418  * Remove from internal device list.
419  */
420 static void
421 EvdevRemoveDevice(InputInfoPtr pInfo)
422 {
423     EvdevPtr pEvdev = pInfo->private;
424     EvdevPtr *dev   = evdev_devices;
425     int count       = 0;
426
427     while(*dev)
428     {
429         count++;
430         if (*dev == pEvdev)
431         {
432             memmove(dev, dev + 1,
433                     sizeof(evdev_devices) - (count * sizeof(EvdevPtr)));
434             break;
435         }
436         dev++;
437     }
438 }
439
440
441 static void
442 SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
443 {
444     char *s;
445
446     if ((s = xf86SetStrOption(pInfo->options, name, NULL))) {
447         if (!s[0]) {
448             free(s);
449             *option = NULL;
450         } else {
451             *option = s;
452         }
453     }
454 }
455
456 static BOOL
457 EvdevDeviceIsVirtual(const char* devicenode)
458 {
459     struct udev *udev = NULL;
460     struct udev_device *device = NULL;
461     struct stat st;
462     int rc = FALSE;
463     const char *devpath;
464
465     udev = udev_new();
466     if (!udev)
467         goto out;
468
469     if (stat(devicenode, &st) < 0) {
470         ErrorF("Failed to get (%s)'s status (stat)\n", devicenode);
471         goto out;
472     }
473     device = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
474
475     if (!device)
476         goto out;
477
478
479     devpath = udev_device_get_devpath(device);
480     if (!devpath)
481         goto out;
482
483     if (strstr(devpath, "LNXSYSTM"))
484         rc = TRUE;
485
486 out:
487     udev_device_unref(device);
488     udev_unref(udev);
489     return rc;
490 }
491
492 #ifndef HAVE_SMOOTH_SCROLLING
493 static int wheel_up_button = 4;
494 static int wheel_down_button = 5;
495 static int wheel_left_button = 6;
496 static int wheel_right_button = 7;
497 #endif
498
499 #ifdef _F_REMAP_KEYS_
500 static void
501 SetRemapOption(InputInfoPtr pInfo,const char* name)
502 {
503     char *s,*c;
504     unsigned long int code,value;
505     int consumed;
506     EvdevPtr ev = pInfo->private;
507
508     s = xf86SetStrOption(pInfo->options, name, NULL);
509     if (!s) return;
510     if (!s[0]) {
511         free(s);
512         return;
513     }
514
515     c=s;
516     while (sscanf(c," %li = %li %n",&code,&value,&consumed) > 1) {
517         c+=consumed;
518         if (code > 65535L) {
519             xf86Msg(X_ERROR,"%s: input code %ld out of range for option \"event_key_remap\", ignoring.\n",pInfo->name,code);
520             continue;
521         }
522         if (value < MIN_KEYCODE || value > 255) {
523             xf86Msg(X_ERROR,"%s: output value %ld out of range for option \"event_key_remap\", ignoring.\n",pInfo->name,value);
524             continue;
525         }
526         xf86Msg(X_INFO,"%s: remapping %ld into %ld.\n",pInfo->name,code,value);
527         addRemap(ev,code,value-MIN_KEYCODE);
528     }
529
530     if (*c!='\0') {
531         xf86Msg(X_ERROR, "%s: invalid input for option \"event_key_remap\" starting at '%s', ignoring.\n",
532                 pInfo->name, c);
533     }
534     free(s);
535 }
536 #endif //_F_REMAP_KEYS_
537
538 static EvdevEventQueuePtr
539 EvdevNextInQueue(InputInfoPtr pInfo)
540 {
541     EvdevPtr pEvdev = pInfo->private;
542
543     if (pEvdev->num_queue >= EVDEV_MAXQUEUE)
544     {
545         xf86IDrvMsg(pInfo, X_NONE, "dropping event due to full queue!\n");
546         return NULL;
547     }
548
549     pEvdev->num_queue++;
550     return &pEvdev->queue[pEvdev->num_queue - 1];
551 }
552
553 void
554 EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
555 {
556 #ifdef _F_REMAP_KEYS_
557     int code = remapKey((EvdevPtr)(pInfo->private),ev->code) + MIN_KEYCODE;
558 #else //_F_REMAP_KEYS_
559     int code = ev->code + MIN_KEYCODE;
560 #endif //_F_REMAP_KEYS_
561     EvdevEventQueuePtr pQueue;
562
563     /* Filter all repeated events from device.
564        We'll do softrepeat in the server, but only since 1.6 */
565     if (value == 2)
566         return;
567
568 #ifdef _F_BOOST_PULSE_
569     if (fd_boostpulse && value == 1)
570        write(fd_boostpulse, (void *) "1", 1);
571 #endif //_F_BOOST_PULSE_
572
573     if ((pQueue = EvdevNextInQueue(pInfo)))
574     {
575         pQueue->type = EV_QUEUE_KEY;
576         pQueue->detail.key = code;
577         pQueue->val = value;
578     }
579 }
580
581 void
582 EvdevQueueButtonEvent(InputInfoPtr pInfo, int button, int value)
583 {
584     EvdevEventQueuePtr pQueue;
585
586 #ifdef _F_BOOST_PULSE_
587    if (fd_boostpulse && value == 1)
588       write(fd_boostpulse, (void *) "1", 1);
589 #endif //_F_BOOST_PULSE_
590
591     if ((pQueue = EvdevNextInQueue(pInfo)))
592     {
593         pQueue->type = EV_QUEUE_BTN;
594         pQueue->detail.key = button;
595         pQueue->val = value;
596     }
597 }
598
599 void
600 EvdevQueueProximityEvent(InputInfoPtr pInfo, int value)
601 {
602     EvdevEventQueuePtr pQueue;
603     if ((pQueue = EvdevNextInQueue(pInfo)))
604     {
605         pQueue->type = EV_QUEUE_PROXIMITY;
606         pQueue->detail.key = 0;
607         pQueue->val = value;
608     }
609 }
610
611 #ifdef MULTITOUCH
612 void
613 EvdevQueueTouchEvent(InputInfoPtr pInfo, unsigned int touch, ValuatorMask *mask,
614                      uint16_t evtype)
615 {
616     EvdevEventQueuePtr pQueue;
617     if ((pQueue = EvdevNextInQueue(pInfo)))
618     {
619         pQueue->type = EV_QUEUE_TOUCH;
620         pQueue->detail.touch = touch;
621         valuator_mask_copy(pQueue->touchMask, mask);
622         pQueue->val = evtype;
623     }
624 }
625 #endif
626
627 /**
628  * Post button event right here, right now.
629  * Interface for MB emulation since these need to post immediately.
630  */
631 void
632 EvdevPostButtonEvent(InputInfoPtr pInfo, int button, enum ButtonAction act)
633 {
634     xf86PostButtonEvent(pInfo->dev, Relative, button,
635                         (act == BUTTON_PRESS) ? 1 : 0, 0, 0);
636 }
637
638 void
639 EvdevQueueButtonClicks(InputInfoPtr pInfo, int button, int count)
640 {
641     int i;
642
643     for (i = 0; i < count; i++) {
644         EvdevQueueButtonEvent(pInfo, button, 1);
645         EvdevQueueButtonEvent(pInfo, button, 0);
646     }
647 }
648
649 #ifdef _F_EVDEV_SUPPORT_GAMEPAD
650 static void
651 EvdevMappingGamepadAbsToKey(InputInfoPtr pInfo,  struct input_event *ev)
652 {
653     EvdevPtr pEvdev = pInfo->private;
654
655     if (pEvdev->support_directional_key == FALSE)
656         return;
657
658     if (ev->type != EV_ABS)
659     {
660         ErrorF("[EvdevMappingGamepadAbsToKey] Invalid evtype(%d)\n", ev->type);
661         return;
662     }
663
664     if (ev->code == ABS_HAT0X)
665     {
666         switch(ev->value)
667         {
668             case 1:
669                 ev->type = EV_KEY;
670                 ev->code = KEY_RIGHT;
671                 ev->value = EVDEV_PRESS;
672                 pEvdev->pre_hatx = 1;
673                 EvdevProcessEvent(pInfo, ev);
674                 break;
675             case -1:
676                 ev->type = EV_KEY;
677                 ev->code = KEY_LEFT;
678                 ev->value = EVDEV_PRESS;
679                 pEvdev->pre_hatx = -1;
680                 EvdevProcessEvent(pInfo, ev);
681                 break;
682             case 0:
683                 ev->type = EV_KEY;
684                 ev->code = ( (pEvdev->pre_hatx == 1)? KEY_RIGHT : KEY_LEFT);
685                 ev->value = EVDEV_RELEASE;
686                 pEvdev->pre_hatx = 0;
687                 EvdevProcessEvent(pInfo, ev);
688                 break;
689             default:
690                 ErrorF("[EvdevMappingGamepadAbsToKey] Invalid value\n");
691                 return;
692                 break;
693         }
694     }
695     else if(ev->code == ABS_HAT0Y)
696     {
697         switch(ev->value)
698         {
699             case 1:
700                 ev->type = EV_KEY;
701                 ev->code = KEY_DOWN;
702                 ev->value = EVDEV_PRESS;
703                 pEvdev->pre_haty = 1;
704                 EvdevProcessEvent(pInfo, ev);
705                 break;
706             case -1:
707                 ev->type = EV_KEY;
708                 ev->code = KEY_UP;
709                 ev->value = EVDEV_PRESS;
710                 pEvdev->pre_haty = -1;
711                 EvdevProcessEvent(pInfo, ev);
712                 break;
713             case 0:
714                 ev->type = EV_KEY;
715                 ev->code = ( (pEvdev->pre_haty == 1)? KEY_DOWN : KEY_UP);
716                 ev->value = EVDEV_RELEASE;
717                 pEvdev->pre_haty = 0;
718                 EvdevProcessEvent(pInfo, ev);
719                 break;
720             default:
721                 ErrorF("[EvdevMappingGamepadAbsToKey] Invalid value\n");
722                 return;
723                 break;
724         }
725     }
726     else if(ev->code == ABS_X)
727     {
728         switch(ev->value)
729         {
730             case 0:
731                 ev->type = EV_KEY;
732                 ev->code = KEY_LEFT;
733                 ev->value = EVDEV_PRESS;
734                 pEvdev->pre_x = 0;
735                 EvdevProcessEvent(pInfo, ev);
736                 break;
737             case 1 ... 254:
738                 if( pEvdev->pre_x == 255 || pEvdev->pre_x == 0 )
739                 {
740                     ev->type = EV_KEY;
741                     ev->code = ( (pEvdev->pre_x == 255)? KEY_RIGHT : KEY_LEFT);
742                     ev->value = EVDEV_RELEASE;
743                     pEvdev->pre_x = 128;
744                     EvdevProcessEvent(pInfo, ev);
745                 }
746                 break;
747             case 255:
748                 ev->type = EV_KEY;
749                 ev->code = KEY_RIGHT;
750                 ev->value = EVDEV_PRESS;
751                 pEvdev->pre_x = 255;
752                 EvdevProcessEvent(pInfo, ev);
753                 break;
754             default:
755                 ErrorF("[EvdevMappingGamepadAbsToKey] Invalid value\n");
756                 return;
757                 break;
758         }
759     }
760     else if(ev->code == ABS_Y)
761     {
762         switch(ev->value)
763         {
764             case 0:
765                 ev->type = EV_KEY;
766                 ev->code = KEY_UP;
767                 ev->value = EVDEV_PRESS;
768                 pEvdev->pre_y = 0;
769                 EvdevProcessEvent(pInfo, ev);
770                 break;
771             case 1 ... 254:
772                 if( pEvdev->pre_y == 255 || pEvdev->pre_y == 0 )
773                 {
774                     ev->type = EV_KEY;
775                     ev->code = ( (pEvdev->pre_y == 255)? KEY_DOWN : KEY_UP);
776                     ev->value = EVDEV_RELEASE;
777                     pEvdev->pre_y = 128;
778                     EvdevProcessEvent(pInfo, ev);
779                 }
780                 break;
781             case 255:
782                 ev->type = EV_KEY;
783                 ev->code = KEY_DOWN;
784                 ev->value = EVDEV_PRESS;
785                 pEvdev->pre_y = 255;
786                 EvdevProcessEvent(pInfo, ev);
787                 break;
788             default:
789                 ErrorF("[EvdevMappingGamepadAbsToKey] Invalid value\n");
790                 return;
791                 break;
792         }
793     }
794 }
795
796 static void
797 EvdevMappingGamepadKeyToKey(InputInfoPtr pInfo,  struct input_event *ev)
798 {
799     EvdevPtr pEvdev = pInfo->private;
800     if(ev->type != EV_KEY)
801     {
802         ErrorF("[EvdevMappingGamepadKeyToKey] Invalid type (%d)\n", ev->type);
803         return;
804     }
805     if(ev->code == BTN_A)
806     {
807         if (pEvdev->keycode_btnA == 0)
808         {
809             ev->code = pEvdev->keycode_btnA;
810             return;
811         }
812         switch(ev->value)
813         {
814             case 1:
815                 ev->type = EV_KEY;
816                 ev->code = pEvdev->keycode_btnA;
817                 ev->value = EVDEV_PRESS;
818                 break;
819             case 0:
820                 ev->type = EV_KEY;
821                 ev->code = pEvdev->keycode_btnA;
822                 ev->value = EVDEV_RELEASE;
823                 break;
824             default:
825                 ErrorF("[EvdevMappingGamepadKeyToKey] Invalid value\n");
826                 return;
827                 break;
828         }
829     }
830     else if(ev->code == BTN_B)
831     {
832         if (pEvdev->keycode_btnB == 0)
833         {
834             ev->code = pEvdev->keycode_btnB;
835             return;
836         }
837         switch(ev->value)
838         {
839             case 1:
840                 ev->type = EV_KEY;
841                 ev->code = pEvdev->keycode_btnB;
842                 ev->value = EVDEV_PRESS;
843                 break;
844             case 0:
845                 ev->type = EV_KEY;
846                 ev->code = pEvdev->keycode_btnB;
847                 ev->value = EVDEV_RELEASE;
848                 break;
849             default:
850                 ErrorF("[EvdevMappingGamepadKeyToKey] Invalid value\n");
851                 return;
852                 break;
853         }
854     }
855     else if(ev->code == BTN_SELECT)
856     {
857         if (pEvdev->keycode_btnSelect == 0)
858         {
859             ev->code = pEvdev->keycode_btnSelect;
860             return;
861         }
862         switch(ev->value)
863         {
864             case 1:
865                 ev->type = EV_KEY;
866                 ev->code = pEvdev->keycode_btnSelect;
867                 ev->value = EVDEV_PRESS;
868                 break;
869             case 0:
870                 ev->type = EV_KEY;
871                 ev->code = pEvdev->keycode_btnSelect;
872                 ev->value = EVDEV_RELEASE;
873                 break;
874             default:
875                 ErrorF("[EvdevMappingGamepadKeyToKey] Invalid value\n");
876                 return;
877                 break;
878         }
879     }
880     else if(ev->code == BTN_START)
881     {
882         if (pEvdev->keycode_btnStart == 0)
883         {
884             ev->code = pEvdev->keycode_btnStart;
885             return;
886         }
887         switch(ev->value)
888         {
889             case 1:
890                 ev->type = EV_KEY;
891                 ev->code = pEvdev->keycode_btnStart;
892                 ev->value = EVDEV_PRESS;
893                 break;
894             case 0:
895                 ev->type = EV_KEY;
896                 ev->code = pEvdev->keycode_btnStart;
897                 ev->value = EVDEV_RELEASE;
898                 break;
899             default:
900                 ErrorF("[EvdevMappingGamepadKeyToKey] Invalid value\n");
901                 return;
902                 break;
903         }
904     }
905     else if(ev->code == 319)
906     {
907         if (pEvdev->keycode_btnPlay== 0)
908         {
909             ev->code = pEvdev->keycode_btnPlay;
910             return;
911         }
912         switch(ev->value)
913         {
914             case 1:
915                 ev->type = EV_KEY;
916                 ev->code = pEvdev->keycode_btnPlay;
917                 ev->value = EVDEV_PRESS;
918                 break;
919             case 0:
920                 ev->type = EV_KEY;
921                 ev->code = pEvdev->keycode_btnPlay;
922                 ev->value = EVDEV_RELEASE;
923                 break;
924             default:
925                 ErrorF("[EvdevMappingGamepadKeyToKey] Invalid value\n");
926                 return;
927                 break;
928         }
929     }
930     else if(ev->code == BTN_X)
931     {
932        if (pEvdev->keycode_btnX == 0)
933       {
934           ev->code = pEvdev->keycode_btnX;
935           return;
936       }
937         switch(ev->value)
938         {
939             case 1:
940                 ev->type = EV_KEY;
941                 ev->code = pEvdev->keycode_btnX;
942                 ev->value = EVDEV_PRESS;
943                 break;
944             case 0:
945                 ev->type = EV_KEY;
946                 ev->code = pEvdev->keycode_btnX;
947                 ev->value = EVDEV_RELEASE;
948                 break;
949             default:
950                 ErrorF("[EvdevMappingGamepadKeyToKey] Invalid value\n");
951                 return;
952                 break;
953         }
954     }
955     else if(ev->code == BTN_Y)
956     {
957         if (pEvdev->keycode_btnY == 0)
958        {
959           ev->code = pEvdev->keycode_btnY;
960           return;
961        }
962         switch(ev->value)
963         {
964             case 1:
965                 ev->type = EV_KEY;
966                 ev->code = pEvdev->keycode_btnY;
967                 ev->value = EVDEV_PRESS;
968                 break;
969             case 0:
970                 ev->type = EV_KEY;
971                 ev->code = pEvdev->keycode_btnY;
972                 ev->value = EVDEV_RELEASE;
973                 break;
974             default:
975                 ErrorF("[EvdevMappingGamepadKeyToKey] Invalid value\n");
976                 return;
977                 break;
978         }
979     }
980     else if(ev->code == BTN_TL)
981     {
982         if (pEvdev->keycode_btnTL== 0)
983        {
984           ev->code = pEvdev->keycode_btnTL;
985           return;
986        }
987         switch(ev->value)
988         {
989             case 1:
990                 ev->type = EV_KEY;
991                 ev->code = pEvdev->keycode_btnTL;
992                 ev->value = EVDEV_PRESS;
993                 break;
994             case 0:
995                 ev->type = EV_KEY;
996                 ev->code = pEvdev->keycode_btnTL;
997                 ev->value = EVDEV_RELEASE;
998                 break;
999             default:
1000                 ErrorF("[EvdevMappingGamepadKeyToKey] Invalid value\n");
1001                 return;
1002                 break;
1003         }
1004     }
1005     else if(ev->code == BTN_TR)
1006     {
1007         if (pEvdev->keycode_btnTR == 0)
1008         {
1009             ev->code = pEvdev->keycode_btnTR;
1010             return;
1011         }
1012         switch(ev->value)
1013         {
1014             case 1:
1015                 ev->type = EV_KEY;
1016                 ev->code = pEvdev->keycode_btnTR;
1017                 ev->value = EVDEV_PRESS;
1018                 break;
1019             case 0:
1020                 ev->type = EV_KEY;
1021                 ev->code = pEvdev->keycode_btnTR;
1022                 ev->value = EVDEV_RELEASE;
1023                 break;
1024             default:
1025                 ErrorF("[EvdevMappingGamepadKeyToKey] Invalid value\n");
1026                 return;
1027                 break;
1028         }
1029     }
1030 }
1031 #endif//_F_EVDEV_SUPPORT_GAMEPAD
1032
1033 /**
1034  * Take the valuators and process them accordingly.
1035  */
1036 static void
1037 EvdevProcessValuators(InputInfoPtr pInfo)
1038 {
1039     int tmp;
1040     EvdevPtr pEvdev = pInfo->private;
1041     int *delta = pEvdev->delta;
1042
1043     /* convert to relative motion for touchpads */
1044     if (pEvdev->abs_queued && (pEvdev->flags & EVDEV_RELATIVE_MODE)) {
1045         if (pEvdev->in_proximity) {
1046             if (valuator_mask_isset(pEvdev->vals, 0))
1047             {
1048                 if (valuator_mask_isset(pEvdev->old_vals, 0))
1049                     delta[REL_X] = valuator_mask_get(pEvdev->vals, 0) -
1050                                    valuator_mask_get(pEvdev->old_vals, 0);
1051                 valuator_mask_set(pEvdev->old_vals, 0,
1052                                   valuator_mask_get(pEvdev->vals, 0));
1053             }
1054             if (valuator_mask_isset(pEvdev->vals, 1))
1055             {
1056                 if (valuator_mask_isset(pEvdev->old_vals, 1))
1057                     delta[REL_Y] = valuator_mask_get(pEvdev->vals, 1) -
1058                                    valuator_mask_get(pEvdev->old_vals, 1);
1059                 valuator_mask_set(pEvdev->old_vals, 1,
1060                                   valuator_mask_get(pEvdev->vals, 1));
1061             }
1062         } else {
1063             valuator_mask_zero(pEvdev->old_vals);
1064         }
1065         valuator_mask_zero(pEvdev->vals);
1066         pEvdev->abs_queued = 0;
1067         pEvdev->rel_queued = 1;
1068     }
1069
1070     if (pEvdev->rel_queued) {
1071         int i;
1072
1073         if (pEvdev->swap_axes) {
1074             tmp = pEvdev->delta[REL_X];
1075             pEvdev->delta[REL_X] = pEvdev->delta[REL_Y];
1076             pEvdev->delta[REL_Y] = tmp;
1077             if (pEvdev->delta[REL_X] == 0)
1078                 valuator_mask_unset(pEvdev->vals, REL_X);
1079             if (pEvdev->delta[REL_Y] == 0)
1080                 valuator_mask_unset(pEvdev->vals, REL_Y);
1081         }
1082         if (pEvdev->invert_x)
1083             pEvdev->delta[REL_X] *= -1;
1084         if (pEvdev->invert_y)
1085             pEvdev->delta[REL_Y] *= -1;
1086
1087
1088         Evdev3BEmuProcessRelMotion(pInfo,
1089                                    pEvdev->delta[REL_X],
1090                                    pEvdev->delta[REL_Y]);
1091
1092         for (i = 0; i < REL_CNT; i++)
1093         {
1094             int map = pEvdev->axis_map[i];
1095             if (pEvdev->delta[i] && map != -1)
1096                 valuator_mask_set(pEvdev->vals, map, pEvdev->delta[i]);
1097         }
1098     }
1099     /*
1100      * Some devices only generate valid abs coords when BTN_TOOL_PEN is
1101      * pressed.  On wacom tablets, this means that the pen is in
1102      * proximity of the tablet.  After the pen is removed, BTN_TOOL_PEN is
1103      * released, and a (0, 0) absolute event is generated.  Checking
1104      * pEvdev->in_proximity here lets us ignore that event.  pEvdev is
1105      * initialized to 1 so devices that don't use this scheme still
1106      * just works.
1107      */
1108     else if (pEvdev->abs_queued && pEvdev->in_proximity) {
1109         int i;
1110
1111         if (pEvdev->swap_axes) {
1112             int swapped_isset[2] = {0, 0};
1113             int swapped_values[2];
1114
1115             for(i = 0; i <= 1; i++)
1116                 if (valuator_mask_isset(pEvdev->vals, i)) {
1117                     swapped_isset[1 - i] = 1;
1118                     swapped_values[1 - i] =
1119                         xf86ScaleAxis(valuator_mask_get(pEvdev->vals, i),
1120                                       pEvdev->absinfo[1 - i].maximum,
1121                                       pEvdev->absinfo[1 - i].minimum,
1122                                       pEvdev->absinfo[i].maximum,
1123                                       pEvdev->absinfo[i].minimum);
1124                 }
1125
1126             for (i = 0; i <= 1; i++)
1127                 if (swapped_isset[i])
1128                     valuator_mask_set(pEvdev->vals, i, swapped_values[i]);
1129                 else
1130                     valuator_mask_unset(pEvdev->vals, i);
1131         }
1132
1133         for (i = 0; i <= 1; i++) {
1134             int val;
1135             int calib_min;
1136             int calib_max;
1137
1138             if (!valuator_mask_isset(pEvdev->vals, i))
1139                 continue;
1140
1141             val = valuator_mask_get(pEvdev->vals, i);
1142
1143             if (i == 0) {
1144                 calib_min = pEvdev->calibration.min_x;
1145                 calib_max = pEvdev->calibration.max_x;
1146             } else {
1147                 calib_min = pEvdev->calibration.min_y;
1148                 calib_max = pEvdev->calibration.max_y;
1149             }
1150
1151             if (pEvdev->flags & EVDEV_CALIBRATED)
1152                 val = xf86ScaleAxis(val, pEvdev->absinfo[i].maximum,
1153                                     pEvdev->absinfo[i].minimum, calib_max,
1154                                     calib_min);
1155
1156             if ((i == 0 && pEvdev->invert_x) || (i == 1 && pEvdev->invert_y))
1157                 val = (pEvdev->absinfo[i].maximum - val +
1158                        pEvdev->absinfo[i].minimum);
1159
1160             valuator_mask_set(pEvdev->vals, i, val);
1161         }
1162         Evdev3BEmuProcessAbsMotion(pInfo, pEvdev->vals);
1163     }
1164 }
1165
1166 static void
1167 EvdevProcessProximityEvent(InputInfoPtr pInfo, struct input_event *ev)
1168 {
1169     EvdevPtr pEvdev = pInfo->private;
1170
1171     if (!pEvdev->use_proximity)
1172         return;
1173
1174     pEvdev->prox_queued = 1;
1175
1176     EvdevQueueProximityEvent(pInfo, ev->value);
1177 }
1178
1179 /**
1180  * Proximity handling is rather weird because of tablet-specific issues.
1181  * Some tablets, notably Wacoms, send a 0/0 coordinate in the same EV_SYN as
1182  * the out-of-proximity notify. We need to ignore those, hence we only
1183  * actually post valuator events when we're in proximity.
1184  *
1185  * Other tablets send the x/y coordinates, then EV_SYN, then the proximity
1186  * event. For those, we need to remember x/y to post it when the proximity
1187  * comes.
1188  *
1189  * If we're not in proximity and we get valuator events, remember that, they
1190  * won't be posted though. If we move into proximity without valuators, use
1191  * the last ones we got and let the rest of the code post them.
1192  */
1193 static int
1194 EvdevProcessProximityState(InputInfoPtr pInfo)
1195 {
1196     EvdevPtr pEvdev = pInfo->private;
1197     int prox_state = 0;
1198     int i;
1199
1200     /* Does this device have any proximity axes? */
1201     if (!pEvdev->prox)
1202         return 0;
1203
1204     /* no proximity change in the queue */
1205     if (!pEvdev->prox_queued)
1206     {
1207         if (pEvdev->abs_queued && !pEvdev->in_proximity)
1208             for (i = 0; i < valuator_mask_size(pEvdev->vals); i++)
1209                 if (valuator_mask_isset(pEvdev->vals, i))
1210                     valuator_mask_set(pEvdev->prox, i,
1211                                       valuator_mask_get(pEvdev->vals, i));
1212         return 0;
1213     }
1214
1215     for (i = 0; i < pEvdev->num_queue; i++)
1216     {
1217         if (pEvdev->queue[i].type == EV_QUEUE_PROXIMITY)
1218         {
1219             prox_state = pEvdev->queue[i].val;
1220             break;
1221         }
1222     }
1223
1224     if ((prox_state && !pEvdev->in_proximity) ||
1225         (!prox_state && pEvdev->in_proximity))
1226     {
1227         /* We're about to go into/out of proximity but have no abs events
1228          * within the EV_SYN. Use the last coordinates we have. */
1229         for (i = 0; i < valuator_mask_size(pEvdev->prox); i++)
1230             if (!valuator_mask_isset(pEvdev->vals, i) &&
1231                 valuator_mask_isset(pEvdev->prox, i))
1232                 valuator_mask_set(pEvdev->vals, i,
1233                                   valuator_mask_get(pEvdev->prox, i));
1234         valuator_mask_zero(pEvdev->prox);
1235
1236         pEvdev->abs_queued = valuator_mask_size(pEvdev->vals);
1237     }
1238
1239     pEvdev->in_proximity = prox_state;
1240     return 1;
1241 }
1242
1243 /**
1244  * Take a button input event and process it accordingly.
1245  */
1246 static void
1247 EvdevProcessButtonEvent(InputInfoPtr pInfo, struct input_event *ev)
1248 {
1249     unsigned int button;
1250     int value;
1251     EvdevPtr pEvdev = pInfo->private;
1252
1253     button = EvdevUtilButtonEventToButtonNumber(pEvdev, ev->code);
1254
1255     /* Get the signed value, earlier kernels had this as unsigned */
1256     value = ev->value;
1257
1258     /* Handle drag lock */
1259     if (EvdevDragLockFilterEvent(pInfo, button, value))
1260         return;
1261
1262     if (EvdevWheelEmuFilterButton(pInfo, button, value))
1263         return;
1264
1265     if (EvdevMBEmuFilterEvent(pInfo, button, value))
1266         return;
1267
1268     if (button) {
1269 #ifdef _F_PICTURE_OFF_MODE_ENABLE_
1270        if((pictureOffMode == 1) && (button == 1)) {
1271           if(value == 0) {
1272              /* Send right button press and release instead of left button press/release */
1273              button = 3;
1274              EvdevQueueButtonEvent(pInfo, button, 1);
1275              EvdevQueueButtonEvent(pInfo, button, 0);
1276           } else ; /* Do nothing Ignore the left button press event */
1277        }
1278        else {
1279           /* When button is pressed, cancel timer for cursor hide*/
1280           if(value == 1) {
1281              isButtonPressed = TRUE;
1282           } else {
1283              isButtonPressed = FALSE;
1284              if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
1285              TimerCancel(pEvdev->rel_move_timer);
1286              if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
1287              pEvdev->rel_move_timer = TimerSet(pEvdev->rel_move_timer, 0, EVDEV_RMS_TIMEOUT, EvdevRelativeMoveTimer, pInfo);
1288              if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
1289           }
1290           EvdevQueueButtonEvent(pInfo, button, value);
1291        }
1292 #else //_F_PICTURE_OFF_MODE_ENABLE_
1293        EvdevQueueButtonEvent(pInfo, button, value);
1294 #endif //_F_PICTURE_OFF_MODE_ENABLE_
1295     }
1296     else
1297         EvdevQueueKbdEvent(pInfo, ev, value);
1298 }
1299
1300 /**
1301  * Take the relative motion input event and process it accordingly.
1302  */
1303 static void
1304 EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
1305 {
1306     int value;
1307     EvdevPtr pEvdev = pInfo->private;
1308     int map;
1309
1310     TTRACE_BEGIN("XORG:EVDEV:PROCESS_REL_MOTION");
1311
1312     /* Get the signed value, earlier kernels had this as unsigned */
1313     value = ev->value;
1314
1315     switch (ev->code) {
1316 #ifndef HAVE_SMOOTH_SCROLLING
1317         case REL_WHEEL:
1318             if (value > 0)
1319                 EvdevQueueButtonClicks(pInfo, wheel_up_button, value);
1320             else if (value < 0)
1321                 EvdevQueueButtonClicks(pInfo, wheel_down_button, -value);
1322             break;
1323
1324         case REL_DIAL:
1325         case REL_HWHEEL:
1326             if (value > 0)
1327                 EvdevQueueButtonClicks(pInfo, wheel_right_button, value);
1328             else if (value < 0)
1329                 EvdevQueueButtonClicks(pInfo, wheel_left_button, -value);
1330             break;
1331         /* We don't post wheel events as axis motion. */
1332 #endif
1333         default:
1334             /* Ignore EV_REL events if we never set up for them. */
1335             if (!(pEvdev->flags & EVDEV_RELATIVE_EVENTS)) {
1336                 TTRACE_END();
1337                 return;
1338             }
1339
1340             /* Handle mouse wheel emulation */
1341             if (EvdevWheelEmuFilterMotion(pInfo, ev)) {
1342                 TTRACE_END();
1343                 return;
1344             }
1345
1346             pEvdev->rel_queued = 1;
1347             pEvdev->delta[ev->code] += value;
1348             map = pEvdev->axis_map[ev->code];
1349             valuator_mask_set(pEvdev->vals, map, value);
1350             break;
1351     }
1352     TTRACE_END();
1353 }
1354
1355 #ifdef MULTITOUCH
1356 static void
1357 EvdevProcessTouch(InputInfoPtr pInfo)
1358 {
1359     EvdevPtr pEvdev = pInfo->private;
1360     int type;
1361
1362     if (pEvdev->cur_slot < 0 || !pEvdev->mt_mask)
1363         return;
1364
1365     /* If the ABS_MT_SLOT is the first event we get after EV_SYN, skip this */
1366     if (pEvdev->slot_state == SLOTSTATE_EMPTY)
1367         return;
1368
1369     if (pEvdev->slot_state == SLOTSTATE_CLOSE)
1370         type = XI_TouchEnd;
1371     else if (pEvdev->slot_state == SLOTSTATE_OPEN)
1372         type = XI_TouchBegin;
1373     else
1374         type = XI_TouchUpdate;
1375
1376     EvdevQueueTouchEvent(pInfo, pEvdev->cur_slot, pEvdev->mt_mask, type);
1377
1378     pEvdev->slot_state = SLOTSTATE_EMPTY;
1379
1380     valuator_mask_zero(pEvdev->mt_mask);
1381 }
1382
1383 static int
1384 num_slots(EvdevPtr pEvdev)
1385 {
1386     int value = 0;
1387
1388     if (pEvdev->mtdev) {
1389         value = pEvdev->mtdev->caps.slot.maximum + 1;
1390     }
1391     else {
1392         value= pEvdev->absinfo[ABS_MT_SLOT].maximum -
1393                     pEvdev->absinfo[ABS_MT_SLOT].minimum + 1;
1394     }
1395
1396     /* If we don't know how many slots there are, assume at least 10 */
1397     return value > 1 ? value : 10;
1398 }
1399
1400 static int
1401 last_mt_vals_slot(EvdevPtr pEvdev)
1402 {
1403     int value = pEvdev->cur_slot - pEvdev->absinfo[ABS_MT_SLOT].minimum;
1404
1405     return value < num_slots(pEvdev) ? value : -1;
1406 }
1407
1408 static void
1409 EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
1410 {
1411     EvdevPtr pEvdev = pInfo->private;
1412     int map;
1413
1414     if (ev->code == ABS_MT_SLOT) {
1415         EvdevProcessTouch(pInfo);
1416         pEvdev->cur_slot = ev->value;
1417     } else
1418     {
1419         int slot_index = last_mt_vals_slot(pEvdev);
1420
1421         if (pEvdev->slot_state == SLOTSTATE_EMPTY)
1422             pEvdev->slot_state = SLOTSTATE_UPDATE;
1423         if (ev->code == ABS_MT_TRACKING_ID) {
1424             if (ev->value >= 0) {
1425                 pEvdev->slot_state = SLOTSTATE_OPEN;
1426
1427                 if (slot_index >= 0)
1428                     valuator_mask_copy(pEvdev->mt_mask,
1429                                        pEvdev->last_mt_vals[slot_index]);
1430                 else
1431                     xf86IDrvMsg(pInfo, X_WARNING,
1432                                 "Attempted to copy values from out-of-range "
1433                                 "slot, touch events may be incorrect.\n");
1434             } else
1435                 pEvdev->slot_state = SLOTSTATE_CLOSE;
1436         } else {
1437             map = pEvdev->axis_map[ev->code];
1438             valuator_mask_set(pEvdev->mt_mask, map, ev->value);
1439             if (slot_index >= 0)
1440                 valuator_mask_set(pEvdev->last_mt_vals[slot_index], map,
1441                                   ev->value);
1442         }
1443     }
1444 }
1445 #else
1446 #define EvdevProcessTouch(pInfo)
1447 #define EvdevProcessTouchEvent(pInfo, ev)
1448 #endif /* MULTITOUCH */
1449
1450 /**
1451  * Take the absolute motion input event and process it accordingly.
1452  */
1453 static void
1454 EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
1455 {
1456     int value;
1457     EvdevPtr pEvdev = pInfo->private;
1458     int map;
1459
1460     TTRACE_BEGIN("XORG:EVDEV:PROCESS_ABS_MOTION");
1461
1462     /* Get the signed value, earlier kernels had this as unsigned */
1463     value = ev->value;
1464 #ifdef _F_EVDEV_SUPPORT_GAMEPAD
1465     if(pEvdev->flags & EVDEV_GAMEPAD)
1466     {
1467       EvdevMappingGamepadAbsToKey(pInfo, ev);
1468       goto out;
1469     }
1470 #endif//_F_EVDEV_SUPPORT_GAMEPAD
1471
1472     /* Ignore EV_ABS events if we never set up for them. */
1473     if (!(pEvdev->flags & EVDEV_ABSOLUTE_EVENTS))
1474         goto out;
1475
1476     if (ev->code > ABS_MAX)
1477         goto out;
1478
1479     if (EvdevWheelEmuFilterMotion(pInfo, ev))
1480         goto out;
1481
1482     if (ev->code >= ABS_MT_SLOT) {
1483         EvdevProcessTouchEvent(pInfo, ev);
1484         pEvdev->abs_queued = 1;
1485     } else if (!pEvdev->mt_mask) {
1486         map = pEvdev->axis_map[ev->code];
1487
1488         if(map < 0)
1489         {
1490                 xf86IDrvMsg(pInfo, X_INFO, "[EvdevProcessAbsoluteMotionEvent] Invalid valuator (=%d), value=%d\nThis is going to be skipped.", map, value);
1491                 goto out;
1492         }
1493
1494         valuator_mask_set(pEvdev->vals, map, value);
1495         pEvdev->abs_queued = 1;
1496     }
1497 out:
1498     TTRACE_END();
1499 }
1500
1501 /**
1502  * Take the key press/release input event and process it accordingly.
1503  */
1504 static void
1505 EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev)
1506 {
1507     int value, i;
1508     EvdevPtr pEvdev = pInfo->private;
1509
1510     TTRACE_BEGIN("XORG:EVDEV:PROCESS_KEY_MOTION");
1511
1512     /* Get the signed value, earlier kernels had this as unsigned */
1513     value = ev->value;
1514
1515     /* don't repeat mouse buttons */
1516     if (ev->code >= BTN_MOUSE && ev->code < KEY_OK) {
1517         if (value == 2) {
1518             goto out;
1519         }
1520     }
1521 #ifdef _F_EVDEV_SUPPORT_GAMEPAD
1522     if(pEvdev->flags & EVDEV_GAMEPAD)
1523     {
1524         EvdevMappingGamepadKeyToKey(pInfo, ev);
1525         if (ev->code == 0) {
1526             goto out;
1527         }
1528     }
1529 #endif//_F_EVDEV_SUPPORT_GAMEPAD
1530
1531
1532     for (i = 0; i < ArrayLength(proximity_bits); i++)
1533     {
1534         if (ev->code == proximity_bits[i])
1535         {
1536             EvdevProcessProximityEvent(pInfo, ev);
1537             goto out;
1538         }
1539     }
1540
1541     switch (ev->code) {
1542         case BTN_TOUCH:
1543             /* For devices that have but don't use proximity, use
1544              * BTN_TOUCH as the proximity notifier */
1545             if (!pEvdev->use_proximity)
1546                 pEvdev->in_proximity = value ? ev->code : 0;
1547             if (!(pEvdev->flags & (EVDEV_TOUCHSCREEN | EVDEV_TABLET)) ||
1548                 pEvdev->mt_mask)
1549                 break;
1550             /* Treat BTN_TOUCH from devices that only have BTN_TOUCH as
1551              * BTN_LEFT. */
1552             ev->code = BTN_LEFT;
1553             /* Intentional fallthrough! */
1554
1555         default:
1556             EvdevProcessButtonEvent(pInfo, ev);
1557             break;
1558     }
1559 out:
1560     TTRACE_END();
1561 }
1562
1563 #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_
1564 static CARD32
1565 EvdevRelativeMoveTimer(OsTimerPtr timer, CARD32 time, pointer arg)
1566 {
1567     InputInfoPtr pInfo = (InputInfoPtr)arg;
1568     EvdevPtr pEvdev;
1569
1570     if(pInfo) pEvdev = pInfo->private;
1571     else return 0;
1572
1573     if(!pEvdev) return 0;
1574     if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
1575     if(pEvdev->rel_move_timer)
1576         TimerCancel(pEvdev->rel_move_timer);
1577     if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
1578 #ifdef _F_DONOT_SEND_RMA_BTN_RELEASE_
1579     if(!isButtonPressed)
1580     {
1581 #endif //_F_DONOT_SEND_RMA_BTN_RELEASE_
1582         pEvdev->rel_move_status = 0;
1583         if (pEvdev->rel_move_ack != 2)
1584             pEvdev->rel_move_ack = 0;
1585         int rc = XIDeleteDeviceProperty(pInfo->dev, prop_relative_move_status, TRUE);
1586
1587         if (rc != Success)
1588         {       if (pEvdev->rel_move_ack != 2)
1589          pEvdev->rel_move_ack = 0;
1590             xf86IDrvMsg(pInfo, X_ERROR, "[%s] Failed to delete device property (id:%d, prop=%d)\n", __FUNCTION__, pInfo->dev->id, prop_relative_move_status);
1591         }
1592 #ifdef _F_DONOT_SEND_RMA_BTN_RELEASE_
1593     }
1594 #endif //_F_DONOT_SEND_RMA_BTN_RELEASE_
1595
1596     return 0;
1597 }
1598 #endif /* #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_ */
1599
1600 #ifdef _F_GESTURE_EXTENSION_
1601 static BOOL EvdevMTStatusGet(InputInfoPtr pInfo, MTSyncType sync)
1602 {
1603     int i;
1604     static int nslots;
1605     int pressed = 0;
1606     const int first_press = XI_TouchEnd - XI_TouchBegin;
1607     EvdevPtr pEvdev = pInfo->private;
1608
1609     if (!pEvdev || !pEvdev->mt_status )
1610          return FALSE;
1611
1612     nslots = num_slots(pEvdev);
1613     for(i = 0; i < nslots; i++)
1614     {
1615         pressed += pEvdev->mt_status[i];
1616
1617          if (pressed > first_press)
1618                 return FALSE;
1619     }
1620
1621     if ((sync == MTOUCH_FRAME_SYNC_BEGIN) && (pressed == first_press))
1622         return TRUE;
1623
1624     if ((sync == MTOUCH_FRAME_SYNC_END) && !pressed)
1625         return TRUE;
1626
1627     return FALSE;
1628 }
1629
1630 static void EvdevMTSync(InputInfoPtr pInfo, MTSyncType sync)
1631 {
1632         AnyEvent event;
1633
1634         memset(&event, 0, sizeof(event));
1635         event.header = ET_Internal;
1636         event.type = ET_MTSync;
1637         event.length = sizeof(event);
1638         event.time = GetTimeInMillis();
1639         event.deviceid = pInfo->dev->id;
1640         event.sync = sync;
1641
1642         mieqEnqueue (pInfo->dev, (InternalEvent*)&event);
1643
1644 #ifdef __MTSYNC_DEBUG__
1645         xf86IDrvMsg(pInfo, X_INFO, "[EvdevMTSync] %s has been sent !\n",
1646                 (sync==MTOUCH_FRAME_SYNC_BEGIN) ? "MTOUCH_FRAME_SYNC_BEGIN" : "MTOUCH_FRAME_SYNC_END");
1647 #endif /* #ifdef __MTSYNC_DEBUG__ */
1648 }
1649 #endif /* #ifdef _F_GESTURE_EXTENSION_ */
1650
1651 static void
1652 EvdevBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead)
1653 {
1654     InputInfoPtr pInfo = (InputInfoPtr)data;
1655     EvdevPtr pEvdev = pInfo->private;
1656
1657     RemoveBlockAndWakeupHandlers(EvdevBlockHandler,
1658                                  (WakeupHandlerProcPtr)NoopDDA,
1659                                  data);
1660     pEvdev->block_handler_registered = FALSE;
1661     ErrorF("Block Handler Called, [%d]pEvdev->rel_move_status %d, pEvdev->rel_move_status_ack %d\n", pInfo->dev->id, pEvdev->rel_move_status, pEvdev->rel_move_ack);
1662
1663
1664     int rc = XIChangeDeviceProperty(pInfo->dev, prop_relative_move_status, XA_INTEGER, 8,
1665                                 PropModeReplace, 1, &pEvdev->rel_move_status, TRUE);
1666
1667     if (rc != Success)
1668     {
1669         xf86IDrvMsg(pInfo, X_ERROR, "[%s] Failed to change device property (id:%d, prop=%d)\n", __FUNCTION__, pInfo->dev->id, prop_relative_move_status);
1670     }
1671 }
1672
1673 /**
1674  * Post the relative motion events.
1675  */
1676 void
1677 EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
1678                               int v[MAX_VALUATORS])
1679 {
1680     EvdevPtr pEvdev = pInfo->private;
1681
1682 #ifdef _F_BLOCK_MOTION_DEVICE_
1683     if (pEvdev->rel_queued && (block_motion_device ==0)) {
1684 #else //_F_BLOCK_MOTION_DEVICE_
1685     if (pEvdev->rel_queued) {
1686 #endif //_F_BLOCK_MOTION_DEVICE_
1687 #ifdef _F_EVDEV_SUPPORT_ROTARY_
1688         if (pEvdev->flags & EVDEV_OFM) {
1689             pEvdev->extra_rel_post_ofm(pInfo, num_v, first_v, v);
1690             return;
1691         }
1692
1693         if (pEvdev->flags & EVDEV_HALLIC) {
1694             pEvdev->extra_rel_post_hallic(pInfo, num_v, first_v, v);
1695             return;
1696         }
1697 #endif //_F_EVDEV_SUPPORT_ROTARY_
1698 #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_
1699         if(!pEvdev->rel_move_prop_set)
1700                 pEvdev->rel_move_prop_set = 1;
1701
1702         if((!pEvdev->block_handler_registered) && (!pEvdev->rel_move_status || !pEvdev->rel_move_ack))
1703         {
1704                 pEvdev->rel_move_status = 1;
1705                 pEvdev->block_handler_registered = TRUE;
1706                 RegisterBlockAndWakeupHandlers(EvdevBlockHandler ,(WakeupHandlerProcPtr) NoopDDA, pInfo);
1707         }
1708
1709         if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
1710         TimerCancel(pEvdev->rel_move_timer);
1711         if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
1712         pEvdev->rel_move_timer = TimerSet(pEvdev->rel_move_timer, 0, EVDEV_RMS_TIMEOUT, EvdevRelativeMoveTimer, pInfo);
1713         if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
1714 #endif /* #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_ */
1715         xf86PostMotionEventM(pInfo->dev, Relative, pEvdev->vals);
1716     }
1717 }
1718
1719 /**
1720  * Post the absolute motion events.
1721  */
1722 void
1723 EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
1724                               int v[MAX_VALUATORS])
1725 {
1726     EvdevPtr pEvdev = pInfo->private;
1727
1728     /*
1729      * Some devices only generate valid abs coords when BTN_TOOL_PEN is
1730      * pressed.  On wacom tablets, this means that the pen is in
1731      * proximity of the tablet.  After the pen is removed, BTN_TOOL_PEN is
1732      * released, and a (0, 0) absolute event is generated.  Checking
1733      * pEvdev->in_proximity here lets us ignore that event.
1734      * pEvdev->in_proximity is initialized to 1 so devices that don't use
1735      * this scheme still just work.
1736      */
1737 #ifdef _F_BLOCK_MOTION_DEVICE_
1738     if (pEvdev->abs_queued && pEvdev->in_proximity && block_motion_device == 0 ) {
1739 #else //_F_BLOCK_MOTION_DEVICE_
1740     if (pEvdev->abs_queued && pEvdev->in_proximity) {
1741 #endif //_F_BLOCK_MOTION_DEVICE_
1742         xf86PostMotionEventM(pInfo->dev, Absolute, pEvdev->vals);
1743     }
1744 }
1745
1746 static void
1747 EvdevPostProximityEvents(InputInfoPtr pInfo, int which, int num_v, int first_v,
1748                                   int v[MAX_VALUATORS])
1749 {
1750     int i;
1751     EvdevPtr pEvdev = pInfo->private;
1752
1753     for (i = 0; pEvdev->prox_queued && i < pEvdev->num_queue; i++) {
1754         switch (pEvdev->queue[i].type) {
1755             case EV_QUEUE_KEY:
1756             case EV_QUEUE_BTN:
1757 #ifdef MULTITOUCH
1758             case EV_QUEUE_TOUCH:
1759 #endif
1760                 break;
1761             case EV_QUEUE_PROXIMITY:
1762                 if (pEvdev->queue[i].val == which)
1763                     xf86PostProximityEventP(pInfo->dev, which, first_v, num_v,
1764                             v + first_v);
1765                 break;
1766         }
1767     }
1768 }
1769
1770 /**
1771  * Post the queued key/button events.
1772  */
1773 static void EvdevPostQueuedEvents(InputInfoPtr pInfo, int num_v, int first_v,
1774                                   int v[MAX_VALUATORS])
1775 {
1776     int i;
1777 #ifdef _F_GESTURE_EXTENSION_
1778     int sync_value;
1779     int event_type;
1780     int slot_idx;
1781     int pressed = 0;
1782 #endif /* #ifdef _F_GESTURE_EXTENSION_ */
1783 #ifdef _F_TOUCH_TRANSFORM_MATRIX_
1784     pixman_vector_t p;
1785     static int lastx;
1786     static int lasty;
1787 #endif /* #ifdef _F_TOUCH_TRANSFORM_MATRIX_ */
1788
1789     EvdevPtr pEvdev = pInfo->private;
1790
1791 #ifdef _F_PROXY_DEVICE_ENABLED_
1792 #ifdef _F_PROXY_DEVICE_CHANGE_SOURCE_ID
1793     if(!(pInfo->dev))
1794     {
1795         return;
1796     }
1797
1798     EvdevCheckDevChange(pEvdev, pInfo->dev->id);
1799 #else
1800     if(pEvdev->proxy_device){
1801         EvdevPostDevChangeEvent(pEvdev->proxy_device);
1802     }
1803 #endif
1804 #endif /* #ifdef _F_PROXY_DEVICE_ENABLED_ */
1805
1806     for (i = 0; i < pEvdev->num_queue; i++) {
1807         switch (pEvdev->queue[i].type) {
1808         case EV_QUEUE_KEY:
1809             xf86PostKeyboardEvent(pInfo->dev, pEvdev->queue[i].detail.key,
1810                                   pEvdev->queue[i].val);
1811             break;
1812         case EV_QUEUE_BTN:
1813             if (Evdev3BEmuFilterEvent(pInfo,
1814                                       pEvdev->queue[i].detail.key,
1815                                       pEvdev->queue[i].val))
1816                 break;
1817
1818             if (pEvdev->abs_queued && pEvdev->in_proximity) {
1819                 xf86PostButtonEventP(pInfo->dev, Absolute, pEvdev->queue[i].detail.key,
1820                                      pEvdev->queue[i].val, first_v, num_v,
1821                                      v + first_v);
1822
1823             } else
1824                 xf86PostButtonEvent(pInfo->dev, Relative, pEvdev->queue[i].detail.key,
1825                                     pEvdev->queue[i].val, 0, 0);
1826
1827             break;
1828         case EV_QUEUE_PROXIMITY:
1829             break;
1830 #ifdef MULTITOUCH
1831         case EV_QUEUE_TOUCH:
1832 #ifdef _F_TOUCH_TRANSFORM_MATRIX_
1833             if( pEvdev->use_transform )
1834             {
1835                 int x, y, slot;
1836
1837                 x = valuator_mask_get(pEvdev->queue[i].touchMask, 0);
1838                 y = valuator_mask_get(pEvdev->queue[i].touchMask, 1);
1839
1840                 if(x || y)
1841                 {
1842                         slot = pEvdev->queue[i].detail.touch;
1843                         x = valuator_mask_get(pEvdev->last_mt_vals[slot], 0);
1844                         y = valuator_mask_get(pEvdev->last_mt_vals[slot], 1);
1845
1846                         p.vector[0] = pixman_int_to_fixed(x);
1847                         p.vector[1] = pixman_int_to_fixed(y);
1848                         p.vector[2] = pixman_int_to_fixed(1);
1849
1850                         pixman_transform_point(&pEvdev->inv_transform, &p);
1851
1852                         valuator_mask_set(pEvdev->queue[i].touchMask, 0, pixman_fixed_to_int(p.vector[0]));
1853                         valuator_mask_set(pEvdev->queue[i].touchMask, 1, pixman_fixed_to_int(p.vector[1]));
1854                 }
1855             }
1856 #endif /* #ifdef _F_TOUCH_TRANSFORM_MATRIX_ */
1857 #ifdef _F_GESTURE_EXTENSION_
1858             sync_value = -1;
1859             event_type = pEvdev->queue[i].val;
1860             slot_idx = pEvdev->queue[i].detail.touch;
1861
1862             if (pEvdev->mt_status)
1863             {
1864                 pEvdev->mt_status[slot_idx] = XI_TouchEnd - event_type;
1865
1866                 if ((XI_TouchBegin == event_type) && (slot_idx == 0))
1867                 {
1868                      if (EvdevMTStatusGet(pInfo, MTOUCH_FRAME_SYNC_BEGIN))
1869                      {
1870                          sync_value = MTOUCH_FRAME_SYNC_BEGIN;
1871                          EvdevMTSync(pInfo, MTOUCH_FRAME_SYNC_BEGIN);
1872                      }
1873                  }
1874
1875                 xf86PostTouchEvent(pInfo->dev, slot_idx,
1876                                event_type, 0,
1877                                pEvdev->queue[i].touchMask);
1878
1879                 if ((sync_value < 0) && (XI_TouchEnd == event_type))
1880                 {
1881                     if (EvdevMTStatusGet(pInfo, MTOUCH_FRAME_SYNC_END))
1882                     {
1883                         EvdevMTSync(pInfo, MTOUCH_FRAME_SYNC_END);
1884                     }
1885                     else
1886                     {
1887                         EvdevMTSync(pInfo, MTOUCH_FRAME_SYNC_UPDATE);
1888                     }
1889                 }
1890             }
1891 #else /* #ifdef _F_GESTURE_EXTENSION_ */
1892             xf86PostTouchEvent(pInfo->dev, pEvdev->queue[i].detail.touch,
1893                                pEvdev->queue[i].val, 0,
1894                                pEvdev->queue[i].touchMask);
1895 #endif /* #ifdef _F_GESTURE_EXTENSION_ */
1896             break;
1897 #endif
1898         }
1899     }
1900 }
1901
1902 /**
1903  * Take the synchronization input event and process it accordingly; the motion
1904  * notify events are sent first, then any button/key press/release events.
1905  */
1906 static void
1907 EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
1908 {
1909     int i;
1910     int num_v = 0, first_v = 0;
1911     int v[MAX_VALUATORS] = {};
1912     EvdevPtr pEvdev = pInfo->private;
1913     TTRACE_BEGIN("XORG:EVDEV:PROCESS_SYNC_MOTION");
1914
1915     EvdevProcessProximityState(pInfo);
1916
1917     EvdevProcessValuators(pInfo);
1918     EvdevProcessTouch(pInfo);
1919
1920     EvdevPostProximityEvents(pInfo, TRUE, num_v, first_v, v);
1921     EvdevPostRelativeMotionEvents(pInfo, num_v, first_v, v);
1922     EvdevPostAbsoluteMotionEvents(pInfo, num_v, first_v, v);
1923     EvdevPostQueuedEvents(pInfo, num_v, first_v, v);
1924     EvdevPostProximityEvents(pInfo, FALSE, num_v, first_v, v);
1925
1926     memset(pEvdev->delta, 0, sizeof(pEvdev->delta));
1927     for (i = 0; i < ArrayLength(pEvdev->queue); i++)
1928     {
1929         EvdevEventQueuePtr queue = &pEvdev->queue[i];
1930         queue->detail.key = 0;
1931         queue->type = 0;
1932         queue->val = 0;
1933         /* don't reset the touchMask */
1934     }
1935
1936     if (pEvdev->vals)
1937         valuator_mask_zero(pEvdev->vals);
1938     pEvdev->num_queue = 0;
1939     pEvdev->abs_queued = 0;
1940     pEvdev->rel_queued = 0;
1941     pEvdev->prox_queued = 0;
1942
1943     TTRACE_END();
1944 }
1945
1946 /**
1947  * Process the events from the device; nothing is actually posted to the server
1948  * until an EV_SYN event is received.
1949  */
1950 static void
1951 EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
1952 {
1953     TTRACE_BEGIN("XORG:EVDEV:PROCESS_EVENT");
1954
1955     EvdevPtr pEvdev = pInfo->private;
1956     int result = 0;
1957
1958 #ifdef _F_EVDEV_SUPPORT_SMARTRC_
1959     if (pEvdev->extra_input_process) {
1960 #ifdef _F_SMART_RC_CHG_KBD_SRC_DEV_
1961         result = pEvdev->extra_input_process(&pInfo, ev);
1962 #else
1963         result = pEvdev->extra_input_process(pInfo, ev);
1964 #endif
1965         if (!result) {
1966             return;
1967         }
1968     }
1969 #endif //_F_EVDEV_SUPPORT_SMARTRC_
1970
1971 #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_
1972     if (pEvdev->rel_move_ack == 2) {
1973         if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
1974         TimerCancel(pEvdev->rel_move_timer);
1975         if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
1976         pEvdev->rel_move_status = 0;
1977
1978         return;
1979     }
1980 #endif//_F_ENABLE_REL_MOVE_STATUS_PROP_
1981     switch (ev->type) {
1982         case EV_REL:
1983             EvdevProcessRelativeMotionEvent(pInfo, ev);
1984             break;
1985         case EV_ABS:
1986             EvdevProcessAbsoluteMotionEvent(pInfo, ev);
1987             break;
1988         case EV_KEY:
1989             EvdevProcessKeyEvent(pInfo, ev);
1990             break;
1991         case EV_SYN:
1992             EvdevProcessSyncEvent(pInfo, ev);
1993             break;
1994     }
1995     TTRACE_END();
1996 }
1997
1998 #undef ABS_X_VALUE
1999 #undef ABS_Y_VALUE
2000 #undef ABS_VALUE
2001
2002 static void
2003 EvdevFreeMasks(EvdevPtr pEvdev)
2004 {
2005 #ifdef MULTITOUCH
2006     int i;
2007 #endif
2008
2009     valuator_mask_free(&pEvdev->vals);
2010     valuator_mask_free(&pEvdev->old_vals);
2011     valuator_mask_free(&pEvdev->prox);
2012 #ifdef MULTITOUCH
2013     valuator_mask_free(&pEvdev->mt_mask);
2014     if (pEvdev->last_mt_vals)
2015     {
2016         for (i = 0; i < num_slots(pEvdev); i++)
2017             valuator_mask_free(&pEvdev->last_mt_vals[i]);
2018         free(pEvdev->last_mt_vals);
2019         pEvdev->last_mt_vals = NULL;
2020     }
2021     for (i = 0; i < EVDEV_MAXQUEUE; i++)
2022         valuator_mask_free(&pEvdev->queue[i].touchMask);
2023 #endif
2024 }
2025
2026 /* just a magic number to reduce the number of reads */
2027 #define NUM_EVENTS 16
2028
2029 static void
2030 EvdevReadInput(InputInfoPtr pInfo)
2031 {
2032     struct input_event ev[NUM_EVENTS];
2033     int i, len = sizeof(ev);
2034
2035     TTRACE_BEGIN("XORG:EVDEV:READ_INPUT");
2036
2037     while (len == sizeof(ev))
2038     {
2039 #ifdef MULTITOUCH
2040         EvdevPtr pEvdev = pInfo->private;
2041
2042         if (pEvdev->mtdev)
2043             len = mtdev_get(pEvdev->mtdev, pInfo->fd, ev, NUM_EVENTS) *
2044                 sizeof(struct input_event);
2045         else
2046 #endif
2047             len = read(pInfo->fd, &ev, sizeof(ev));
2048
2049         if (len <= 0)
2050         {
2051             if (errno == ENODEV) /* May happen after resume */
2052             {
2053                 EvdevMBEmuFinalize(pInfo);
2054                 Evdev3BEmuFinalize(pInfo);
2055                 xf86RemoveEnabledDevice(pInfo);
2056             }
2057             else if (errno != EAGAIN)
2058             {
2059                 /* We use X_NONE here because it doesn't alloc */
2060                 xf86MsgVerb(X_NONE, 0, "%s: Read error: %s\n", pInfo->name,
2061                         strerror(errno));
2062             }
2063             break;
2064         }
2065
2066         /* The kernel promises that we always only read a complete
2067          * event, so len != sizeof ev is an error. */
2068         if (len % sizeof(ev[0])) {
2069             /* We use X_NONE here because it doesn't alloc */
2070             xf86MsgVerb(X_NONE, 0, "%s: Read error: %s\n", pInfo->name, strerror(errno));
2071             break;
2072         }
2073
2074         for (i = 0; i < len/sizeof(ev[0]); i++)
2075             EvdevProcessEvent(pInfo, &ev[i]);
2076     }
2077     TTRACE_END();
2078 }
2079
2080 static void
2081 EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
2082 {
2083     /* Nothing to do, dix handles all settings */
2084 }
2085
2086 static void
2087 EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl)
2088 {
2089     static struct { int xbit, code; } bits[] = {
2090         { CAPSFLAG,     LED_CAPSL },
2091         { NUMFLAG,      LED_NUML },
2092         { SCROLLFLAG,   LED_SCROLLL },
2093         { MODEFLAG,     LED_KANA },
2094         { COMPOSEFLAG,  LED_COMPOSE }
2095     };
2096
2097     InputInfoPtr pInfo;
2098     struct input_event ev[ArrayLength(bits)];
2099     int i;
2100
2101     memset(ev, 0, sizeof(ev));
2102
2103     pInfo = device->public.devicePrivate;
2104     for (i = 0; i < ArrayLength(bits); i++) {
2105         ev[i].type = EV_LED;
2106         ev[i].code = bits[i].code;
2107         ev[i].value = (ctrl->leds & bits[i].xbit) > 0;
2108     }
2109
2110     write(pInfo->fd, ev, sizeof ev);
2111 }
2112
2113 #ifdef _F_USE_DEFAULT_XKB_RULES_
2114 void
2115 EvdevGetXkbRules(DeviceIntPtr device, XkbRMLVOSet * rmlvo)
2116 {
2117     WindowPtr root=NULL;
2118     PropertyPtr pProp;
2119     int rc=0;
2120     char * keymap;
2121     if(screenInfo.numScreens > 0 && screenInfo.screens[0])
2122     {
2123         root = screenInfo.screens[0]->root;
2124     }
2125     else
2126         return;
2127
2128     if( prop_xkb_rules == None )
2129         prop_xkb_rules = MakeAtom("_XKB_RULES_NAMES", strlen("_XKB_RULES_NAMES"), TRUE);
2130
2131     rc = dixLookupProperty (&pProp, root, prop_xkb_rules, serverClient, DixReadAccess);
2132     if (rc == Success && pProp->data){
2133         keymap = (char *)pProp->data;
2134         rmlvo->rules = keymap;
2135         keymap = keymap+strlen(keymap)+1;
2136         rmlvo->model = keymap;
2137         keymap = keymap+strlen(keymap)+1;
2138         rmlvo->layout = keymap;
2139         keymap = keymap+strlen(keymap)+1;
2140         rmlvo->variant = keymap;
2141         keymap = keymap+strlen(keymap)+1;
2142         rmlvo->options = keymap;
2143     }
2144     else
2145     {
2146         XkbGetRulesDflts(rmlvo);
2147     }
2148 }
2149 #endif //_F_USE_DEFAULT_XKB_RULES_
2150
2151 static int
2152 EvdevAddKeyClass(DeviceIntPtr device)
2153 {
2154     InputInfoPtr pInfo;
2155     EvdevPtr pEvdev;
2156
2157     pInfo = device->public.devicePrivate;
2158     pEvdev = pInfo->private;
2159
2160 #ifdef _F_USE_DEFAULT_XKB_RULES_
2161     XkbRMLVOSet dflts = { NULL };
2162
2163     if (pEvdev->use_default_xkb_rmlvo)
2164     {
2165         EvdevGetXkbRules(device, &dflts);
2166
2167         pEvdev->rmlvo.rules = (dflts.rules) ? strdup(dflts.rules) : NULL;
2168         pEvdev->rmlvo.model = (dflts.model) ? strdup(dflts.model) : NULL;
2169         pEvdev->rmlvo.layout = (dflts.layout) ? strdup(dflts.layout) : NULL;
2170         pEvdev->rmlvo.variant = (dflts.variant) ? strdup(dflts.variant) : NULL;
2171         pEvdev->rmlvo.options = (dflts.options) ? strdup(dflts.options) : NULL;
2172
2173         ErrorF("[%s] Set default XKB RMLVO !\n", __FUNCTION__);
2174
2175         ErrorF("[%s] pEvdev->rmlvo.rules=%s\n", __FUNCTION__, pEvdev->rmlvo.rules ? pEvdev->rmlvo.rules : "NULL");
2176         ErrorF("[%s] pEvdev->rmlvo.model=%s\n", __FUNCTION__, pEvdev->rmlvo.model ? pEvdev->rmlvo.model : "NULL");
2177         ErrorF("[%s] pEvdev->rmlvo.layout=%s\n", __FUNCTION__, pEvdev->rmlvo.layout ? pEvdev->rmlvo.layout : "NULL");
2178         ErrorF("[%s] pEvdev->rmlvo.variant=%s\n", __FUNCTION__, pEvdev->rmlvo.variant ? pEvdev->rmlvo.variant : "NULL");
2179         ErrorF("[%s] pEvdev->rmlvo.options=%s\n", __FUNCTION__, pEvdev->rmlvo.options ? pEvdev->rmlvo.options : "NULL");
2180     }
2181     else
2182     {
2183 #endif
2184     /* sorry, no rules change allowed for you */
2185     xf86ReplaceStrOption(pInfo->options, "xkb_rules", "evdev");
2186     SetXkbOption(pInfo, "xkb_rules", &pEvdev->rmlvo.rules);
2187     SetXkbOption(pInfo, "xkb_model", &pEvdev->rmlvo.model);
2188     if (!pEvdev->rmlvo.model)
2189         SetXkbOption(pInfo, "XkbModel", &pEvdev->rmlvo.model);
2190     SetXkbOption(pInfo, "xkb_layout", &pEvdev->rmlvo.layout);
2191     if (!pEvdev->rmlvo.layout)
2192         SetXkbOption(pInfo, "XkbLayout", &pEvdev->rmlvo.layout);
2193     SetXkbOption(pInfo, "xkb_variant", &pEvdev->rmlvo.variant);
2194     if (!pEvdev->rmlvo.variant)
2195         SetXkbOption(pInfo, "XkbVariant", &pEvdev->rmlvo.variant);
2196     SetXkbOption(pInfo, "xkb_options", &pEvdev->rmlvo.options);
2197     if (!pEvdev->rmlvo.options)
2198         SetXkbOption(pInfo, "XkbOptions", &pEvdev->rmlvo.options);
2199 #ifdef _F_USE_DEFAULT_XKB_RULES_
2200     }
2201 #endif
2202
2203     if (!InitKeyboardDeviceStruct(device, &pEvdev->rmlvo, NULL, EvdevKbdCtrl))
2204         return !Success;
2205
2206 #ifdef _F_REMAP_KEYS_
2207     SetRemapOption(pInfo,"event_key_remap");
2208 #endif //_F_REMAP_KEYS_
2209
2210     return Success;
2211 }
2212
2213 #ifdef MULTITOUCH
2214 /* MT axes are counted twice - once as ABS_X (which the kernel keeps for
2215  * backwards compatibility), once as ABS_MT_POSITION_X. So we need to keep a
2216  * mapping of those axes to make sure we only count them once
2217  */
2218 struct mt_axis_mappings {
2219     int mt_code;
2220     int code;
2221     Bool needs_mapping; /* TRUE if both code and mt_code are present */
2222     int mapping;        /* Logical mapping of 'code' axis */
2223 };
2224
2225 static struct mt_axis_mappings mt_axis_mappings[] = {
2226     {ABS_MT_POSITION_X, ABS_X},
2227     {ABS_MT_POSITION_Y, ABS_Y},
2228     {ABS_MT_PRESSURE, ABS_PRESSURE},
2229     {ABS_MT_DISTANCE, ABS_DISTANCE},
2230 };
2231 #endif
2232
2233 /**
2234  * return TRUE if the axis is not one we should count as true axis
2235  */
2236 static int
2237 is_blacklisted_axis(int axis)
2238 {
2239     switch(axis)
2240     {
2241         case ABS_MT_SLOT:
2242         case ABS_MT_TRACKING_ID:
2243             return TRUE;
2244         default:
2245             return FALSE;
2246     }
2247 }
2248
2249
2250 static int
2251 EvdevAddAbsValuatorClass(DeviceIntPtr device)
2252 {
2253     InputInfoPtr pInfo;
2254     EvdevPtr pEvdev;
2255     int num_axes, axis, i = 0;
2256     int num_mt_axes = 0, /* number of MT-only axes */
2257         num_mt_axes_total = 0; /* total number of MT axes, including
2258                                   double-counted ones, excluding blacklisted */
2259     Atom *atoms = NULL;
2260
2261     pInfo = device->public.devicePrivate;
2262     pEvdev = pInfo->private;
2263
2264     if (!EvdevBitIsSet(pEvdev->bitmask, EV_ABS))
2265         goto out;
2266
2267     num_axes = EvdevCountBits(pEvdev->abs_bitmask, NLONGS(ABS_MAX));
2268     if (num_axes < 1)
2269         goto out;
2270
2271 #ifdef MULTITOUCH
2272     for (axis = ABS_MT_SLOT; axis < ABS_MAX; axis++)
2273     {
2274         if (EvdevBitIsSet(pEvdev->abs_bitmask, axis))
2275         {
2276             int j;
2277             Bool skip = FALSE;
2278
2279             for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
2280             {
2281                 if (mt_axis_mappings[j].mt_code == axis &&
2282                     BitIsOn(pEvdev->abs_bitmask, mt_axis_mappings[j].code))
2283                 {
2284                     mt_axis_mappings[j].needs_mapping = TRUE;
2285                     skip = TRUE;
2286                 }
2287             }
2288
2289             if (!is_blacklisted_axis(axis))
2290             {
2291                 num_mt_axes_total++;
2292                 if (!skip)
2293                     num_mt_axes++;
2294             }
2295             num_axes--;
2296         }
2297     }
2298 #endif
2299     if (num_axes + num_mt_axes > MAX_VALUATORS) {
2300         xf86IDrvMsg(pInfo, X_WARNING, "found %d axes, limiting to %d.\n", num_axes, MAX_VALUATORS);
2301         num_axes = MAX_VALUATORS;
2302     }
2303
2304     if (num_axes < 1 && num_mt_axes_total < 1) {
2305         xf86Msg(X_WARNING, "%s: no absolute or touch axes found.\n",
2306                 device->name);
2307         return !Success;
2308     }
2309
2310     pEvdev->num_vals = num_axes;
2311     if (num_axes > 0) {
2312         pEvdev->vals = valuator_mask_new(num_axes);
2313         pEvdev->old_vals = valuator_mask_new(num_axes);
2314         if (!pEvdev->vals || !pEvdev->old_vals) {
2315             xf86IDrvMsg(pInfo, X_ERROR, "failed to allocate valuator masks.\n");
2316             goto out;
2317         }
2318     }
2319 #ifdef MULTITOUCH
2320     if (num_mt_axes_total > 0) {
2321         pEvdev->num_mt_vals = num_mt_axes_total;
2322         pEvdev->mt_mask = valuator_mask_new(num_mt_axes_total);
2323         if (!pEvdev->mt_mask) {
2324             xf86Msg(X_ERROR, "%s: failed to allocate MT valuator mask.\n",
2325                     device->name);
2326             goto out;
2327         }
2328
2329         pEvdev->last_mt_vals = calloc(num_slots(pEvdev), sizeof(ValuatorMask *));
2330         if (!pEvdev->last_mt_vals) {
2331             xf86IDrvMsg(pInfo, X_ERROR,
2332                         "%s: failed to allocate MT last values mask array.\n",
2333                         device->name);
2334             goto out;
2335         }
2336
2337         for (i = 0; i < num_slots(pEvdev); i++) {
2338             pEvdev->last_mt_vals[i] = valuator_mask_new(num_mt_axes_total);
2339             if (!pEvdev->last_mt_vals[i]) {
2340                 xf86IDrvMsg(pInfo, X_ERROR,
2341                             "%s: failed to allocate MT last values mask.\n",
2342                             device->name);
2343                 goto out;
2344             }
2345         }
2346
2347         for (i = 0; i < EVDEV_MAXQUEUE; i++) {
2348             pEvdev->queue[i].touchMask =
2349                 valuator_mask_new(num_mt_axes_total);
2350             if (!pEvdev->queue[i].touchMask) {
2351                 xf86Msg(X_ERROR, "%s: failed to allocate MT valuator masks for "
2352                         "evdev event queue.\n", device->name);
2353                 goto out;
2354             }
2355         }
2356     }
2357 #endif
2358     atoms = malloc((pEvdev->num_vals + num_mt_axes) * sizeof(Atom));
2359
2360     i = 0;
2361     for (axis = ABS_X; i < MAX_VALUATORS && axis <= ABS_MAX; axis++) {
2362 #ifdef MULTITOUCH
2363         int j;
2364 #endif
2365         int mapping;
2366         pEvdev->axis_map[axis] = -1;
2367         if (!EvdevBitIsSet(pEvdev->abs_bitmask, axis) ||
2368             is_blacklisted_axis(axis))
2369             continue;
2370
2371         mapping = i;
2372
2373 #ifdef MULTITOUCH
2374         for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
2375         {
2376             if (mt_axis_mappings[j].code == axis)
2377                 mt_axis_mappings[j].mapping = mapping;
2378             else if (mt_axis_mappings[j].mt_code == axis &&
2379                     mt_axis_mappings[j].needs_mapping)
2380                 mapping = mt_axis_mappings[j].mapping;
2381         }
2382 #endif
2383         pEvdev->axis_map[axis] = mapping;
2384         if (mapping == i)
2385             i++;
2386     }
2387
2388     EvdevInitAxesLabels(pEvdev, Absolute, pEvdev->num_vals + num_mt_axes, atoms);
2389
2390     if (!InitValuatorClassDeviceStruct(device, num_axes + num_mt_axes, atoms,
2391                                        GetMotionHistorySize(), Absolute)) {
2392         xf86IDrvMsg(pInfo, X_ERROR, "failed to initialize valuator class device.\n");
2393         goto out;
2394     }
2395
2396 #ifdef MULTITOUCH
2397     if (num_mt_axes_total > 0)
2398     {
2399         int num_touches = 0;
2400         int mode = pEvdev->flags & EVDEV_TOUCHPAD ?
2401             XIDependentTouch : XIDirectTouch;
2402
2403         num_touches = num_slots(pEvdev);
2404
2405         if (!InitTouchClassDeviceStruct(device, num_touches, mode,
2406                                         num_mt_axes_total)) {
2407             xf86Msg(X_ERROR, "%s: failed to initialize touch class device.\n",
2408                     device->name);
2409             goto out;
2410         }
2411
2412         for (i = 0; i < num_slots(pEvdev); i++) {
2413             for (axis = ABS_MT_TOUCH_MAJOR; axis < ABS_MAX; axis++) {
2414                 if (pEvdev->axis_map[axis] >= 0) {
2415                     /* XXX: read initial values from mtdev when it adds support
2416                      *      for doing so. */
2417                     valuator_mask_set(pEvdev->last_mt_vals[i],
2418                                       pEvdev->axis_map[axis], 0);
2419                 }
2420             }
2421         }
2422     }
2423 #endif
2424
2425     for (axis = ABS_X; axis < ABS_MT_SLOT; axis++) {
2426         int axnum = pEvdev->axis_map[axis];
2427         int resolution = 0;
2428
2429         if (axnum == -1)
2430             continue;
2431
2432 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 30)
2433         /* Kernel provides units/mm, X wants units/m */
2434         if (pEvdev->absinfo[axis].resolution)
2435             resolution = pEvdev->absinfo[axis].resolution * 1000;
2436 #endif
2437
2438         xf86InitValuatorAxisStruct(device, axnum,
2439                                    atoms[axnum],
2440                                    pEvdev->absinfo[axis].minimum,
2441                                    pEvdev->absinfo[axis].maximum,
2442                                    resolution, 0, resolution, Absolute);
2443         xf86InitValuatorDefaults(device, axnum);
2444     }
2445
2446 #ifdef MULTITOUCH
2447     for (axis = ABS_MT_TOUCH_MAJOR; axis <= ABS_MAX; axis++) {
2448         int axnum = pEvdev->axis_map[axis];
2449         int resolution = 0;
2450         int j;
2451         BOOL skip = FALSE;
2452
2453         if (axnum < 0)
2454             continue;
2455
2456         for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
2457             if (mt_axis_mappings[j].mt_code == axis &&
2458                     mt_axis_mappings[j].needs_mapping)
2459             {
2460                 skip = TRUE;
2461                 break;
2462             }
2463
2464         /* MT axis is mapped, don't set up twice */
2465         if (skip)
2466             continue;
2467
2468         if (pEvdev->absinfo[axis].resolution)
2469             resolution = pEvdev->absinfo[axis].resolution * 1000;
2470
2471         xf86InitValuatorAxisStruct(device, axnum,
2472                                    atoms[axnum],
2473                                    pEvdev->absinfo[axis].minimum,
2474                                    pEvdev->absinfo[axis].maximum,
2475                                    resolution, 0, resolution,
2476                                    Absolute);
2477     }
2478 #endif
2479
2480     free(atoms);
2481     atoms = NULL;
2482
2483     for (i = 0; i < ArrayLength(proximity_bits); i++)
2484     {
2485         if (!pEvdev->use_proximity)
2486             break;
2487
2488         if (EvdevBitIsSet(pEvdev->key_bitmask, proximity_bits[i]))
2489         {
2490             InitProximityClassDeviceStruct(device);
2491             pEvdev->prox = valuator_mask_new(num_axes);
2492             if (!pEvdev->prox) {
2493                 xf86IDrvMsg(pInfo, X_ERROR,
2494                             "failed to allocate proximity valuator " "mask.\n");
2495                 goto out;
2496             }
2497             break;
2498         }
2499     }
2500
2501     if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc)) {
2502         xf86IDrvMsg(pInfo, X_ERROR,
2503                     "failed to initialize pointer feedback class device.\n");
2504         goto out;
2505     }
2506
2507     if (pEvdev->flags & EVDEV_TOUCHPAD)
2508         pEvdev->flags |= EVDEV_RELATIVE_MODE;
2509     else
2510         pEvdev->flags &= ~EVDEV_RELATIVE_MODE;
2511
2512     if (xf86FindOption(pInfo->options, "Mode"))
2513     {
2514         char *mode;
2515         mode = xf86SetStrOption(pInfo->options, "Mode", NULL);
2516         if (!strcasecmp("absolute", mode))
2517             pEvdev->flags &= ~EVDEV_RELATIVE_MODE;
2518         else if (!strcasecmp("relative", mode))
2519             pEvdev->flags |= EVDEV_RELATIVE_MODE;
2520         else
2521             xf86IDrvMsg(pInfo, X_INFO, "unknown mode, use default\n");
2522         free(mode);
2523     }
2524
2525     return Success;
2526
2527 out:
2528     EvdevFreeMasks(pEvdev);
2529     if (atoms)
2530         free(atoms);
2531     return !Success;
2532 }
2533
2534 static int
2535 EvdevAddRelValuatorClass(DeviceIntPtr device)
2536 {
2537     InputInfoPtr pInfo;
2538     EvdevPtr pEvdev;
2539     int num_axes, axis, i = 0;
2540     Atom *atoms = NULL;
2541
2542     pInfo = device->public.devicePrivate;
2543     pEvdev = pInfo->private;
2544
2545     if (!EvdevBitIsSet(pEvdev->bitmask, EV_REL))
2546         goto out;
2547
2548     num_axes = EvdevCountBits(pEvdev->rel_bitmask, NLONGS(REL_MAX));
2549     if (num_axes < 1)
2550         goto out;
2551
2552 #ifndef HAVE_SMOOTH_SCROLLING
2553     /* Wheels are special, we post them as button events. So let's ignore them
2554      * in the axes list too */
2555     if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL))
2556         num_axes--;
2557     if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL))
2558         num_axes--;
2559     if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL))
2560         num_axes--;
2561
2562     if (num_axes <= 0)
2563         goto out;
2564 #endif
2565
2566     if (num_axes > MAX_VALUATORS) {
2567         xf86IDrvMsg(pInfo, X_WARNING, "found %d axes, limiting to %d.\n", num_axes, MAX_VALUATORS);
2568         num_axes = MAX_VALUATORS;
2569     }
2570
2571     pEvdev->num_vals = num_axes;
2572     if (num_axes > 0) {
2573         pEvdev->vals = valuator_mask_new(num_axes);
2574         if (!pEvdev->vals)
2575             goto out;
2576     }
2577     atoms = malloc(pEvdev->num_vals * sizeof(Atom));
2578
2579     for (axis = REL_X; i < MAX_VALUATORS && axis <= REL_MAX; axis++)
2580     {
2581         pEvdev->axis_map[axis] = -1;
2582 #ifndef HAVE_SMOOTH_SCROLLING
2583         /* We don't post wheel events, so ignore them here too */
2584         if (axis == REL_WHEEL || axis == REL_HWHEEL || axis == REL_DIAL)
2585             continue;
2586 #endif
2587         if (!EvdevBitIsSet(pEvdev->rel_bitmask, axis))
2588             continue;
2589         pEvdev->axis_map[axis] = i;
2590         i++;
2591     }
2592
2593     EvdevInitAxesLabels(pEvdev, Relative, pEvdev->num_vals, atoms);
2594
2595     if (!InitValuatorClassDeviceStruct(device, num_axes, atoms,
2596                                        GetMotionHistorySize(), Relative)) {
2597         xf86IDrvMsg(pInfo, X_ERROR, "failed to initialize valuator class device.\n");
2598         goto out;
2599     }
2600
2601     if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc)) {
2602         xf86IDrvMsg(pInfo, X_ERROR, "failed to initialize pointer feedback class "
2603                 "device.\n");
2604         goto out;
2605     }
2606
2607     for (axis = REL_X; axis <= REL_MAX; axis++)
2608     {
2609         int axnum = pEvdev->axis_map[axis];
2610
2611         if (axnum == -1)
2612             continue;
2613         xf86InitValuatorAxisStruct(device, axnum, atoms[axnum], -1, -1, 1, 0, 1,
2614                                    Relative);
2615         xf86InitValuatorDefaults(device, axnum);
2616 #ifdef HAVE_SMOOTH_SCROLLING
2617         if (axis == REL_WHEEL)
2618             SetScrollValuator(device, axnum, SCROLL_TYPE_VERTICAL, -1.0, SCROLL_FLAG_PREFERRED);
2619         else if (axis == REL_DIAL)
2620             SetScrollValuator(device, axnum, SCROLL_TYPE_VERTICAL, -1.0, SCROLL_FLAG_NONE);
2621         else if (axis == REL_HWHEEL)
2622             SetScrollValuator(device, axnum, SCROLL_TYPE_HORIZONTAL, 1.0, SCROLL_FLAG_NONE);
2623 #endif
2624     }
2625
2626     free(atoms);
2627
2628     return Success;
2629
2630 out:
2631     valuator_mask_free(&pEvdev->vals);
2632     if (atoms)
2633         free(atoms);
2634     return !Success;
2635 }
2636
2637 static int
2638 EvdevAddButtonClass(DeviceIntPtr device)
2639 {
2640     InputInfoPtr pInfo;
2641     EvdevPtr pEvdev;
2642     Atom *labels = NULL;
2643
2644     pInfo = device->public.devicePrivate;
2645     pEvdev = pInfo->private;
2646
2647     labels = malloc(pEvdev->num_buttons * sizeof(Atom));
2648     if (!labels) return BadAlloc;
2649     EvdevInitButtonLabels(pEvdev, pEvdev->num_buttons, labels);
2650
2651     if (!InitButtonClassDeviceStruct(device, pEvdev->num_buttons, labels,
2652                                      pEvdev->btnmap))
2653     {
2654          free(labels);
2655         return !Success;
2656     }
2657
2658     free(labels);
2659     return Success;
2660 }
2661
2662 /**
2663  * Init the button mapping for the device. By default, this is a 1:1 mapping,
2664  * i.e. Button 1 maps to Button 1, Button 2 to 2, etc.
2665  *
2666  * If a mapping has been specified, the mapping is the default, with the
2667  * user-defined ones overwriting the defaults.
2668  * i.e. a user-defined mapping of "3 2 1" results in a mapping of 3 2 1 4 5 6 ...
2669  *
2670  * Invalid button mappings revert to the default.
2671  *
2672  * Note that index 0 is unused, button 0 does not exist.
2673  * This mapping is initialised for all devices, but only applied if the device
2674  * has buttons (in EvdevAddButtonClass).
2675  */
2676 static void
2677 EvdevInitButtonMapping(InputInfoPtr pInfo)
2678 {
2679     int         i, nbuttons     = 1;
2680     char       *mapping         = NULL;
2681     EvdevPtr    pEvdev          = pInfo->private;
2682
2683     /* Check for user-defined button mapping */
2684     if ((mapping = xf86CheckStrOption(pInfo->options, "ButtonMapping", NULL)))
2685     {
2686         char    *map, *s = NULL;
2687         int     btn = 0;
2688
2689         xf86IDrvMsg(pInfo, X_CONFIG, "ButtonMapping '%s'\n", mapping);
2690         map = mapping;
2691         do
2692         {
2693             btn = strtol(map, &s, 10);
2694
2695             if (s == map || btn < 0 || btn > EVDEV_MAXBUTTONS)
2696             {
2697                 xf86IDrvMsg(pInfo, X_ERROR,
2698                             "... Invalid button mapping. Using defaults\n");
2699                 nbuttons = 1; /* ensure defaults start at 1 */
2700                 break;
2701             }
2702
2703             pEvdev->btnmap[nbuttons++] = btn;
2704             map = s;
2705         } while (s && *s != '\0' && nbuttons < EVDEV_MAXBUTTONS);
2706         free(mapping);
2707     }
2708
2709     for (i = nbuttons; i < ArrayLength(pEvdev->btnmap); i++)
2710         pEvdev->btnmap[i] = i;
2711
2712 }
2713
2714 static void
2715 EvdevInitAnyValuators(DeviceIntPtr device, EvdevPtr pEvdev)
2716 {
2717     InputInfoPtr pInfo = device->public.devicePrivate;
2718
2719     if (pEvdev->flags & EVDEV_RELATIVE_EVENTS &&
2720         EvdevAddRelValuatorClass(device) == Success)
2721         xf86IDrvMsg(pInfo, X_INFO, "initialized for relative axes.\n");
2722     if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS &&
2723         EvdevAddAbsValuatorClass(device) == Success)
2724         xf86IDrvMsg(pInfo, X_INFO, "initialized for absolute axes.\n");
2725 }
2726
2727 static void
2728 EvdevInitAbsValuators(DeviceIntPtr device, EvdevPtr pEvdev)
2729 {
2730     InputInfoPtr pInfo = device->public.devicePrivate;
2731
2732     if (EvdevAddAbsValuatorClass(device) == Success) {
2733         xf86IDrvMsg(pInfo, X_INFO,"initialized for absolute axes.\n");
2734     } else {
2735         xf86IDrvMsg(pInfo, X_ERROR,"failed to initialize for absolute axes.\n");
2736         pEvdev->flags &= ~EVDEV_ABSOLUTE_EVENTS;
2737     }
2738 }
2739
2740 static void
2741 EvdevInitRelValuators(DeviceIntPtr device, EvdevPtr pEvdev)
2742 {
2743     InputInfoPtr pInfo = device->public.devicePrivate;
2744     int has_abs_axes = pEvdev->flags & EVDEV_ABSOLUTE_EVENTS;
2745 #ifdef _F_EVDEV_SUPPORT_GAMEPAD
2746     if ( (pEvdev->flags & EVDEV_GAMEPAD) && (has_abs_axes) ) {
2747         xf86IDrvMsg(pInfo, X_INFO,"initialized for game pad axes. Ignore relative axes.\n");
2748
2749         pEvdev->flags &= ~EVDEV_RELATIVE_EVENTS;
2750
2751         EvdevInitAbsValuators(device, pEvdev);
2752     } else if (EvdevAddRelValuatorClass(device) == Success) {
2753 #else
2754     if (EvdevAddRelValuatorClass(device) == Success) {
2755 #endif//_F_EVDEV_SUPPORT_GAMEPAD
2756         xf86IDrvMsg(pInfo, X_INFO,"initialized for relative axes.\n");
2757
2758         if (has_abs_axes) {
2759             xf86IDrvMsg(pInfo, X_WARNING,"ignoring absolute axes.\n");
2760             pEvdev->flags &= ~EVDEV_ABSOLUTE_EVENTS;
2761         }
2762
2763     } else {
2764         xf86IDrvMsg(pInfo, X_ERROR,"failed to initialize for relative axes.\n");
2765
2766         pEvdev->flags &= ~EVDEV_RELATIVE_EVENTS;
2767
2768         if (has_abs_axes)
2769             EvdevInitAbsValuators(device, pEvdev);
2770     }
2771 }
2772
2773 static void
2774 EvdevInitTouchDevice(DeviceIntPtr device, EvdevPtr pEvdev)
2775 {
2776     InputInfoPtr pInfo = device->public.devicePrivate;
2777
2778     if (pEvdev->flags & EVDEV_RELATIVE_EVENTS) {
2779         xf86IDrvMsg(pInfo, X_WARNING, "touchpads, tablets and touchscreens "
2780                     "ignore relative axes.\n");
2781         pEvdev->flags &= ~EVDEV_RELATIVE_EVENTS;
2782     }
2783
2784     EvdevInitAbsValuators(device, pEvdev);
2785 }
2786
2787 #ifdef _F_EVDEV_SUPPORT_GAMEPAD
2788 static int
2789 EvdevIsGamePad(InputInfoPtr pInfo)
2790 {
2791     int i;
2792     EvdevPtr pEvdev = pInfo->private;
2793     int result = 1;
2794
2795     for(i=0; i<MAX_GAMEPAD_DEFINITION_ABS; i++)
2796     {
2797         if(pEvdev->abs_gamepad_labels[i] == 0)
2798             break;
2799
2800         if(!EvdevBitIsSet(pEvdev->abs_bitmask, pEvdev->abs_gamepad_labels[i]))
2801         {
2802             ErrorF("[EvdevIsGamePad] %s device doesn't support abs code(%d)\n", pInfo->name, pEvdev->abs_gamepad_labels[i]);
2803             result = 0;
2804             return result;
2805         }
2806     }
2807
2808     for(i=0; i<MAX_GAMEPAD_DEFINITION_KEY; i++)
2809     {
2810         if(pEvdev->key_gamepad_labels[i] == 0)
2811             break;
2812
2813         if(!EvdevBitIsSet(pEvdev->key_bitmask, pEvdev->key_gamepad_labels[i]))
2814         {
2815             ErrorF("[EvdevIsGamePad] %s device doesn't support key code(%d)\n", pInfo->name, pEvdev->key_gamepad_labels[i]);
2816             result = 0;
2817             return result;
2818         }
2819     }
2820     return result;
2821 }
2822 #endif//_F_EVDEV_SUPPORT_GAMEPAD
2823
2824 static int
2825 EvdevInit(DeviceIntPtr device)
2826 {
2827     int i;
2828     InputInfoPtr pInfo;
2829     EvdevPtr pEvdev;
2830
2831     pInfo = device->public.devicePrivate;
2832     pEvdev = pInfo->private;
2833     TTRACE_BEGIN("XORG:EVDEV:INIT");
2834
2835     /* clear all axis_map entries */
2836     for(i = 0; i < max(ABS_CNT,REL_CNT); i++)
2837       pEvdev->axis_map[i]=-1;
2838
2839     if (pEvdev->flags & EVDEV_KEYBOARD_EVENTS)
2840         EvdevAddKeyClass(device);
2841     if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
2842         EvdevAddButtonClass(device);
2843
2844     /* We don't allow relative and absolute axes on the same device. The
2845      * reason is that some devices (MS Optical Desktop 2000) register both
2846      * rel and abs axes for x/y.
2847      *
2848      * The abs axes register min/max; this min/max then also applies to the
2849      * relative device (the mouse) and caps it at 0..255 for both axes.
2850      * So, unless you have a small screen, you won't be enjoying it much;
2851      * consequently, absolute axes are generally ignored.
2852      *
2853      * However, currenly only a device with absolute axes can be registered
2854      * as a touch{pad,screen}. Thus, given such a device, absolute axes are
2855      * used and relative axes are ignored.
2856      */
2857
2858     if (pEvdev->flags & (EVDEV_UNIGNORE_RELATIVE | EVDEV_UNIGNORE_ABSOLUTE))
2859         EvdevInitAnyValuators(device, pEvdev);
2860     else if (pEvdev->flags & (EVDEV_TOUCHPAD | EVDEV_TOUCHSCREEN | EVDEV_TABLET))
2861         EvdevInitTouchDevice(device, pEvdev);
2862     else if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
2863         EvdevInitRelValuators(device, pEvdev);
2864
2865 #ifdef _F_INIT_ABS_ONLY_FOR_POINTER_
2866     else if ( !(pEvdev->flags & EVDEV_KEYBOARD_EVENTS) && (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) )
2867 #else /* #ifdef _F_INIT_ABS_ONLY_FOR_POINTER_ */
2868     else if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
2869 #endif /* #ifdef _F_INIT_ABS_ONLY_FOR_POINTER_ */
2870         EvdevInitAbsValuators(device, pEvdev);
2871
2872     /* We drop the return value, the only time we ever want the handlers to
2873      * unregister is when the device dies. In which case we don't have to
2874      * unregister anyway */
2875     EvdevInitProperty(device);
2876 #ifdef _F_PROXY_DEVICE_ENABLED_
2877     if (!strncmp(pInfo->name, PROXY_DEV_NAME, sizeof(PROXY_DEV_NAME))) {
2878         EvdevProxyInit(device);
2879     }
2880     else
2881         XIRegisterPropertyHandler(device, EvdevSetProperty, NULL, NULL);
2882 #else //_F_PROXY_DEVICE_ENABLED_
2883     XIRegisterPropertyHandler(device, EvdevSetProperty, NULL, NULL);
2884 #endif //_F_PROXY_DEVICE_ENABLED_
2885     EvdevMBEmuInitProperty(device);
2886     Evdev3BEmuInitProperty(device);
2887     EvdevWheelEmuInitProperty(device);
2888     EvdevDragLockInitProperty(device);
2889     EvdevAppleInitProperty(device);
2890 #ifdef _F_EVDEV_SUPPORT_ROTARY_
2891     EvdevRotaryInit(device);
2892 #endif //_F_EVDEV_SUPPORT_ROTARY_
2893 #ifdef _F_EVDEV_SUPPORT_SMARTRC_
2894     EvdevRCInit(device);
2895 #endif //_F_EVDEV_SUPPORT_SMARTRC_
2896
2897     TTRACE_END();
2898
2899     return Success;
2900 }
2901
2902 /**
2903  * Init all extras (wheel emulation, etc.) and grab the device.
2904  */
2905 static int
2906 EvdevOn(DeviceIntPtr device)
2907 {
2908     InputInfoPtr pInfo;
2909     EvdevPtr pEvdev;
2910     int rc = Success;
2911     ErrorF("[EvdevOn][id:%d] find device (%s)\n", device->id, device->name);
2912     TTRACE_BEGIN("XORG:EVDEV:ON");
2913
2914     pInfo = device->public.devicePrivate;
2915     pEvdev = pInfo->private;
2916
2917 #ifdef _F_PROXY_DEVICE_ENABLED_
2918     /*Check if its proxy device.. in that case just set flag and return..*/
2919     if(pEvdev->b_proxy_device)
2920     {
2921         pEvdev->flags |= EVDEV_INITIALIZED;
2922         device->public.on = TRUE;
2923         return Success;
2924     }
2925 #endif /* #ifdef _F_PROXY_DEVICE_ENABLED_ */
2926
2927     /* after PreInit fd is still open */
2928     rc = EvdevOpenDevice(pInfo);
2929     if (rc != Success) {
2930         TTRACE_END();
2931         return rc;
2932     }
2933
2934     EvdevGrabDevice(pInfo, 1, 0);
2935
2936     xf86FlushInput(pInfo->fd);
2937     xf86AddEnabledDevice(pInfo);
2938     EvdevMBEmuOn(pInfo);
2939     Evdev3BEmuOn(pInfo);
2940     pEvdev->flags |= EVDEV_INITIALIZED;
2941     device->public.on = TRUE;
2942
2943     TTRACE_END();
2944     return Success;
2945 }
2946
2947
2948 static int
2949 EvdevProc(DeviceIntPtr device, int what)
2950 {
2951     InputInfoPtr pInfo;
2952     EvdevPtr pEvdev;
2953 #ifdef _F_EVDEV_CONFINE_REGION_
2954     int region[6] = { 0, };
2955 #endif /* #ifdef _F_EVDEV_CONFINE_REGION_ */
2956
2957     pInfo = device->public.devicePrivate;
2958     pEvdev = pInfo->private;
2959
2960     switch (what)
2961     {
2962     case DEVICE_INIT:
2963         return EvdevInit(device);
2964
2965     case DEVICE_ON:
2966         return EvdevOn(device);
2967
2968     case DEVICE_OFF:
2969 #ifdef _F_PROXY_DEVICE_ENABLED_
2970     if(pEvdev->b_proxy_device)
2971     {
2972         if (pEvdev->flags & EVDEV_INITIALIZED)
2973         {
2974             pEvdev->min_maj = 0;
2975             pEvdev->flags &= ~EVDEV_INITIALIZED;
2976             device->public.on = FALSE;
2977         }
2978         if (pInfo->fd != -1)
2979         {
2980             xf86RemoveEnabledDevice(pInfo);
2981             close(pInfo->fd);
2982             pInfo->fd = -1;
2983         }
2984         return Success;
2985     }
2986 #endif /* #ifdef _F_PROXY_DEVICE_ENABLED_ */
2987         if (pEvdev->flags & EVDEV_INITIALIZED)
2988         {
2989             EvdevMBEmuFinalize(pInfo);
2990             Evdev3BEmuFinalize(pInfo);
2991         }
2992         if (pInfo->fd != -1)
2993         {
2994             EvdevGrabDevice(pInfo, 0, 1);
2995             xf86RemoveEnabledDevice(pInfo);
2996             EvdevCloseDevice(pInfo);
2997         }
2998
2999 #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_
3000         if (pEvdev->rel_move_timer)
3001         {
3002             if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
3003             TimerCancel(pEvdev->rel_move_timer);
3004             if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
3005             pEvdev->rel_move_status = 0;
3006             pEvdev->rel_move_ack = 0;
3007             ErrorF("[%s][dev:%d] DEVICE_OFF (rel_move_status=%d, rel_move_prop_set=%d)\n", __FUNCTION__, pInfo->dev->id, pEvdev->rel_move_status,
3008                     pEvdev->rel_move_prop_set);
3009         }
3010 #endif /* #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_ */
3011
3012         pEvdev->min_maj = 0;
3013         pEvdev->flags &= ~EVDEV_INITIALIZED;
3014         device->public.on = FALSE;
3015         break;
3016
3017     case DEVICE_CLOSE:
3018 #ifdef _F_EVDEV_CONFINE_REGION_
3019         if(pEvdev->pointer_confine_region && pEvdev->confined_id)
3020                 EvdevSetConfineRegion(pInfo, 1, &region[0]);
3021 #endif /* _F_EVDEV_CONFINE_REGION_ */
3022         xf86IDrvMsg(pInfo, X_INFO, "Close\n");
3023         EvdevCloseDevice(pInfo);
3024         EvdevFreeMasks(pEvdev);
3025         EvdevRemoveDevice(pInfo);
3026 #ifdef _F_REMAP_KEYS_
3027         freeRemap(pEvdev);
3028 #endif //_F_REMAP_KEYS_
3029         pEvdev->min_maj = 0;
3030         break;
3031
3032     default:
3033         return BadValue;
3034     }
3035
3036     return Success;
3037 }
3038
3039 /**
3040  * Get as much information as we can from the fd and cache it.
3041  *
3042  * @return Success if the information was cached, or !Success otherwise.
3043  */
3044 static int
3045 EvdevCache(InputInfoPtr pInfo)
3046 {
3047     EvdevPtr pEvdev = pInfo->private;
3048     int i, len;
3049     struct input_id id;
3050
3051     char name[1024]                  = {0};
3052     unsigned long bitmask[NLONGS(EV_CNT)]      = {0};
3053     unsigned long key_bitmask[NLONGS(KEY_CNT)] = {0};
3054     unsigned long rel_bitmask[NLONGS(REL_CNT)] = {0};
3055     unsigned long abs_bitmask[NLONGS(ABS_CNT)] = {0};
3056     unsigned long led_bitmask[NLONGS(LED_CNT)] = {0};
3057
3058
3059     if (ioctl(pInfo->fd, EVIOCGID, &id) < 0)
3060     {
3061         xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGID failed: %s\n", strerror(errno));
3062         goto error;
3063     }
3064
3065     pEvdev->id_vendor = id.vendor;
3066     pEvdev->id_product = id.product;
3067
3068     if (ioctl(pInfo->fd, EVIOCGNAME(sizeof(name) - 1), name) < 0) {
3069         xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
3070         goto error;
3071     }
3072
3073     len = strlen(name);
3074     if (len < sizeof(pEvdev->name)) {
3075         strncpy(pEvdev->name, name, len+1);
3076     } else {
3077         strncpy(pEvdev->name, name, sizeof(pEvdev->name)-1);
3078         xf86DrvMsg(pInfo, X_WARNING, "Device's name(%s) is too long. Restrict name to inside of buffer size\n", pEvdev->name);
3079     }
3080
3081     len = ioctl(pInfo->fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask);
3082     if (len < 0) {
3083         xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT failed: %s\n",
3084                     strerror(errno));
3085         goto error;
3086     }
3087
3088     memcpy(pEvdev->bitmask, bitmask, len);
3089
3090     len = ioctl(pInfo->fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask);
3091     if (len < 0) {
3092         xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT failed: %s\n",
3093                     strerror(errno));
3094         goto error;
3095     }
3096
3097     memcpy(pEvdev->rel_bitmask, rel_bitmask, len);
3098
3099     len = ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
3100     if (len < 0) {
3101         xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT failed: %s\n",
3102                     strerror(errno));
3103         goto error;
3104     }
3105
3106     memcpy(pEvdev->abs_bitmask, abs_bitmask, len);
3107
3108     len = ioctl(pInfo->fd, EVIOCGBIT(EV_LED, sizeof(led_bitmask)), led_bitmask);
3109     if (len < 0) {
3110         xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT failed: %s\n",
3111                     strerror(errno));
3112         goto error;
3113     }
3114
3115     memcpy(pEvdev->led_bitmask, led_bitmask, len);
3116
3117     /*
3118      * Do not try to validate absinfo data since it is not expected
3119      * to be static, always refresh it in evdev structure.
3120      */
3121     for (i = ABS_X; i <= ABS_MAX; i++) {
3122         if (EvdevBitIsSet(abs_bitmask, i)) {
3123             len = ioctl(pInfo->fd, EVIOCGABS(i), &pEvdev->absinfo[i]);
3124             if (len < 0) {
3125                 xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGABSi(%d) failed: %s\n",
3126                             i, strerror(errno));
3127                 goto error;
3128             }
3129             xf86IDrvMsgVerb(pInfo, X_PROBED, 6, "absolute axis %#x [%d..%d]\n",
3130                             i, pEvdev->absinfo[i].maximum, pEvdev->absinfo[i].minimum);
3131         }
3132     }
3133
3134     len = ioctl(pInfo->fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask);
3135     if (len < 0) {
3136         xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT failed: %s\n",
3137                     strerror(errno));
3138         goto error;
3139     }
3140
3141     /* Copy the data so we have reasonably up-to-date info */
3142     memcpy(pEvdev->key_bitmask, key_bitmask, len);
3143
3144     return Success;
3145
3146 error:
3147     return !Success;
3148
3149 }
3150
3151 /**
3152  * Issue an EVIOCGRAB on the device file, either as a grab or to ungrab, or
3153  * both. Return TRUE on success, otherwise FALSE. Failing the release is a
3154  * still considered a success, because it's not as if you could do anything
3155  * about it.
3156  */
3157 static BOOL
3158 EvdevGrabDevice(InputInfoPtr pInfo, int grab, int ungrab)
3159 {
3160     EvdevPtr pEvdev = pInfo->private;
3161
3162     if (pEvdev->grabDevice)
3163     {
3164         if (grab && ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
3165             xf86IDrvMsg(pInfo, X_WARNING, "Grab failed (%s)\n",
3166                         strerror(errno));
3167             return FALSE;
3168         } else if (ungrab && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
3169             xf86IDrvMsg(pInfo, X_WARNING, "Release failed (%s)\n",
3170                         strerror(errno));
3171     }
3172
3173     return TRUE;
3174 }
3175
3176 /**
3177  * Some devices only have other axes (e.g. wheels), but we
3178  * still need x/y for these. The server relies on devices having
3179  * x/y as axes 0/1 and core/XI 1.x clients expect it too (#44655)
3180  */
3181 static void
3182 EvdevForceXY(InputInfoPtr pInfo, int mode)
3183 {
3184     EvdevPtr pEvdev = pInfo->private;
3185
3186     xf86IDrvMsg(pInfo, X_INFO, "Forcing %s x/y axes to exist.\n",
3187                 (mode == Relative) ? "relative" : "absolute");
3188
3189     if (mode == Relative)
3190     {
3191         EvdevSetBit(pEvdev->rel_bitmask, REL_X);
3192         EvdevSetBit(pEvdev->rel_bitmask, REL_Y);
3193     } else if (mode == Absolute)
3194     {
3195         EvdevSetBit(pEvdev->abs_bitmask, ABS_X);
3196         EvdevSetBit(pEvdev->abs_bitmask, ABS_Y);
3197         pEvdev->absinfo[ABS_X].minimum = 0;
3198         pEvdev->absinfo[ABS_X].maximum = 1000;
3199         pEvdev->absinfo[ABS_X].value = 0;
3200         pEvdev->absinfo[ABS_X].resolution = 0;
3201         pEvdev->absinfo[ABS_Y].minimum = 0;
3202         pEvdev->absinfo[ABS_Y].maximum = 1000;
3203         pEvdev->absinfo[ABS_Y].value = 0;
3204         pEvdev->absinfo[ABS_Y].resolution = 0;
3205     }
3206 }
3207
3208 static int
3209 EvdevProbe(InputInfoPtr pInfo)
3210 {
3211     int i, has_rel_axes, has_abs_axes, has_keys, num_buttons, has_scroll;
3212     int has_lmr; /* left middle right */
3213     int has_mt; /* multitouch */
3214     int ignore_abs = 0, ignore_rel = 0;
3215     EvdevPtr pEvdev = pInfo->private;
3216     int rc = 1;
3217
3218     xf86IDrvMsg(pInfo, X_PROBED, "Vendor %#hx Product %#hx\n",
3219                 pEvdev->id_vendor, pEvdev->id_product);
3220
3221     /* Trinary state for ignoring axes:
3222        - unset: do the normal thing.
3223        - TRUE: explicitly ignore them.
3224        - FALSE: unignore axes, use them at all cost if they're present.
3225      */
3226     if (xf86FindOption(pInfo->options, "IgnoreRelativeAxes"))
3227     {
3228         if (xf86SetBoolOption(pInfo->options, "IgnoreRelativeAxes", FALSE))
3229             ignore_rel = TRUE;
3230         else
3231             pEvdev->flags |= EVDEV_UNIGNORE_RELATIVE;
3232
3233     }
3234     if (xf86FindOption(pInfo->options, "IgnoreAbsoluteAxes"))
3235     {
3236         if (xf86SetBoolOption(pInfo->options, "IgnoreAbsoluteAxes", FALSE))
3237            ignore_abs = TRUE;
3238         else
3239             pEvdev->flags |= EVDEV_UNIGNORE_ABSOLUTE;
3240     }
3241
3242     has_rel_axes = FALSE;
3243     has_abs_axes = FALSE;
3244     has_keys = FALSE;
3245     has_scroll = FALSE;
3246     has_lmr = FALSE;
3247     has_mt = FALSE;
3248     num_buttons = 0;
3249
3250     /* count all buttons */
3251 #ifdef _F_EVDEV_SUPPORT_GAMEPAD
3252     for (i = BTN_MISC; i < BTN_THUMBR; i++)
3253 #else
3254     for (i = BTN_MISC; i < BTN_JOYSTICK; i++)
3255 #endif//_F_EVDEV_SUPPORT_GAMEPAD
3256     {
3257         int mapping = 0;
3258         if (EvdevBitIsSet(pEvdev->key_bitmask, i))
3259         {
3260             mapping = EvdevUtilButtonEventToButtonNumber(pEvdev, i);
3261             if (mapping > num_buttons)
3262                 num_buttons = mapping;
3263         }
3264     }
3265
3266     has_lmr = EvdevBitIsSet(pEvdev->key_bitmask, BTN_LEFT) ||
3267                 EvdevBitIsSet(pEvdev->key_bitmask, BTN_MIDDLE) ||
3268                 EvdevBitIsSet(pEvdev->key_bitmask, BTN_RIGHT);
3269
3270     if (num_buttons)
3271     {
3272         pEvdev->flags |= EVDEV_BUTTON_EVENTS;
3273         pEvdev->num_buttons = num_buttons;
3274         xf86IDrvMsg(pInfo, X_PROBED, "Found %d mouse buttons\n", num_buttons);
3275     }
3276
3277     for (i = 0; i < REL_MAX; i++) {
3278         if (EvdevBitIsSet(pEvdev->rel_bitmask, i)) {
3279             has_rel_axes = TRUE;
3280             break;
3281         }
3282     }
3283
3284     if (has_rel_axes) {
3285         if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL) ||
3286             EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL) ||
3287             EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL)) {
3288             xf86IDrvMsg(pInfo, X_PROBED, "Found scroll wheel(s)\n");
3289             has_scroll = TRUE;
3290             if (!num_buttons)
3291                 xf86IDrvMsg(pInfo, X_INFO,
3292                             "Forcing buttons for scroll wheel(s)\n");
3293             num_buttons = (num_buttons < 3) ? 7 : num_buttons + 4;
3294             pEvdev->num_buttons = num_buttons;
3295         }
3296
3297         if (!ignore_rel)
3298         {
3299             xf86IDrvMsg(pInfo, X_PROBED, "Found relative axes\n");
3300             pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
3301
3302             if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_X) &&
3303                 EvdevBitIsSet(pEvdev->rel_bitmask, REL_Y)) {
3304                 xf86IDrvMsg(pInfo, X_PROBED, "Found x and y relative axes\n");
3305             } else if (!EvdevBitIsSet(pEvdev->abs_bitmask, ABS_X) ||
3306                        !EvdevBitIsSet(pEvdev->abs_bitmask, ABS_Y))
3307                 EvdevForceXY(pInfo, Relative);
3308         } else {
3309             xf86IDrvMsg(pInfo, X_INFO, "Relative axes present but ignored.\n");
3310             has_rel_axes = FALSE;
3311         }
3312     }
3313
3314     for (i = 0; i < ABS_MAX; i++) {
3315         if (EvdevBitIsSet(pEvdev->abs_bitmask, i)) {
3316             has_abs_axes = TRUE;
3317             break;
3318         }
3319     }
3320
3321 #ifdef MULTITOUCH
3322     for (i = ABS_MT_SLOT; i < ABS_MAX; i++) {
3323         if (EvdevBitIsSet(pEvdev->abs_bitmask, i)) {
3324             has_mt = TRUE;
3325             break;
3326         }
3327     }
3328 #endif
3329 #ifdef _F_EVDEV_SUPPORT_SMARTRC_
3330     if (EvdevBitIsSet(pEvdev->key_bitmask, BTN_EXTRA))
3331     {
3332         xf86IDrvMsg(pInfo, X_PROBED, "Found extra button\n");
3333         if (!strncmp(pEvdev->name, AIR_TOUCH_MOUSE, strlen(AIR_TOUCH_MOUSE)))
3334         {
3335             xf86IDrvMsg(pInfo, X_PROBED, "... regarding smart rc\n");
3336             pEvdev->flags |= EVDEV_SMART_RC;
3337         }
3338     }
3339     if (EvdevBitIsSet(pEvdev->key_bitmask, BTN_SIDE))
3340     {
3341        xf86IDrvMsg(pInfo, X_PROBED, "Found extra button\n");
3342        if (!strncmp(pEvdev->name, AIR_TOUCH_MOUSE, strlen(AIR_TOUCH_MOUSE)))
3343        {
3344           xf86IDrvMsg(pInfo, X_PROBED, "... regarding smart rc\n");
3345           pEvdev->flags |= EVDEV_SMART_RC;
3346        }
3347     }
3348 #endif //_F_EVDEV_SUPPORT_SMARTRC_
3349     if (ignore_abs && has_abs_axes)
3350     {
3351         xf86IDrvMsg(pInfo, X_INFO, "Absolute axes present but ignored.\n");
3352         has_abs_axes = FALSE;
3353     } else if (has_abs_axes) {
3354         xf86IDrvMsg(pInfo, X_PROBED, "Found absolute axes\n");
3355         pEvdev->flags |= EVDEV_ABSOLUTE_EVENTS;
3356
3357         if (has_mt)
3358             xf86IDrvMsg(pInfo, X_PROBED, "Found absolute multitouch axes\n");
3359
3360         if ((EvdevBitIsSet(pEvdev->abs_bitmask, ABS_X) &&
3361              EvdevBitIsSet(pEvdev->abs_bitmask, ABS_Y))) {
3362             xf86IDrvMsg(pInfo, X_PROBED, "Found x and y absolute axes\n");
3363             if (EvdevBitIsSet(pEvdev->key_bitmask, BTN_TOOL_PEN) ||
3364                 EvdevBitIsSet(pEvdev->key_bitmask, BTN_STYLUS) ||
3365                 EvdevBitIsSet(pEvdev->key_bitmask, BTN_STYLUS2))
3366             {
3367                 xf86IDrvMsg(pInfo, X_PROBED, "Found absolute tablet.\n");
3368                 pEvdev->flags |= EVDEV_TABLET;
3369                 if (!pEvdev->num_buttons)
3370                 {
3371                     pEvdev->num_buttons = 7; /* LMR + scroll wheels */
3372                     pEvdev->flags |= EVDEV_BUTTON_EVENTS;
3373                 }
3374             } else if (EvdevBitIsSet(pEvdev->abs_bitmask, ABS_PRESSURE) ||
3375                 EvdevBitIsSet(pEvdev->key_bitmask, BTN_TOUCH)) {
3376                 if (has_lmr || EvdevBitIsSet(pEvdev->key_bitmask, BTN_TOOL_FINGER)) {
3377                     xf86IDrvMsg(pInfo, X_PROBED, "Found absolute touchpad.\n");
3378                     pEvdev->flags |= EVDEV_TOUCHPAD;
3379                 } else {
3380                     xf86IDrvMsg(pInfo, X_PROBED, "Found absolute touchscreen\n");
3381                     pEvdev->flags |= EVDEV_TOUCHSCREEN;
3382                     pEvdev->flags |= EVDEV_BUTTON_EVENTS;
3383                 }
3384             } else if (!(EvdevBitIsSet(pEvdev->rel_bitmask, REL_X) &&
3385                          EvdevBitIsSet(pEvdev->rel_bitmask, REL_Y)) && has_lmr) {
3386                     /* some touchscreens use BTN_LEFT rather than BTN_TOUCH */
3387                     xf86IDrvMsg(pInfo, X_PROBED, "Found absolute touchscreen\n");
3388                     pEvdev->flags |= EVDEV_TOUCHSCREEN;
3389                     pEvdev->flags |= EVDEV_BUTTON_EVENTS;
3390 #ifdef _F_EVDEV_SUPPORT_GAMEPAD
3391             }  else if(EvdevIsGamePad(pInfo)) {
3392                     xf86IDrvMsg(pInfo, X_PROBED, "Found gamepad\n");
3393                     pEvdev->flags |= EVDEV_GAMEPAD;
3394 #endif // _F_EVDEV_SUPPORT_GAMEPAD
3395             }
3396         } else {
3397 #ifdef MULTITOUCH
3398             if (!EvdevBitIsSet(pEvdev->abs_bitmask, ABS_MT_POSITION_X) ||
3399                 !EvdevBitIsSet(pEvdev->abs_bitmask, ABS_MT_POSITION_Y))
3400 #endif
3401                 EvdevForceXY(pInfo, Absolute);
3402         }
3403     }
3404
3405     for (i = 0; i < BTN_MISC; i++) {
3406         if (EvdevBitIsSet(pEvdev->key_bitmask, i)) {
3407             xf86IDrvMsg(pInfo, X_PROBED, "Found keys\n");
3408             pEvdev->flags |= EVDEV_KEYBOARD_EVENTS;
3409             has_keys = TRUE;
3410             break;
3411         }
3412     }
3413
3414     if (has_rel_axes || has_abs_axes)
3415     {
3416         char *str;
3417         int num_calibration = 0, calibration[4] = { 0, 0, 0, 0 };
3418
3419         pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE);
3420         pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
3421         pEvdev->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE);
3422
3423         str = xf86CheckStrOption(pInfo->options, "Calibration", NULL);
3424         if (str) {
3425             num_calibration = sscanf(str, "%d %d %d %d",
3426                     &calibration[0], &calibration[1],
3427                     &calibration[2], &calibration[3]);
3428             free(str);
3429             if (num_calibration == 4)
3430                 EvdevSetCalibration(pInfo, num_calibration, calibration);
3431             else
3432                 xf86IDrvMsg(pInfo, X_ERROR,
3433                             "Insufficient calibration factors (%d). Ignoring calibration\n",
3434                             num_calibration);
3435         }
3436     }
3437
3438     if (has_rel_axes || has_abs_axes || num_buttons) {
3439         pInfo->flags |= XI86_SEND_DRAG_EVENTS;
3440         if (pEvdev->flags & EVDEV_TOUCHPAD) {
3441             xf86IDrvMsg(pInfo, X_INFO, "Configuring as touchpad\n");
3442             pInfo->type_name = XI_TOUCHPAD;
3443             pEvdev->use_proximity = 0;
3444         } else if (pEvdev->flags & EVDEV_TABLET) {
3445             xf86IDrvMsg(pInfo, X_INFO, "Configuring as tablet\n");
3446             pInfo->type_name = XI_TABLET;
3447         } else if (pEvdev->flags & EVDEV_TOUCHSCREEN) {
3448             xf86IDrvMsg(pInfo, X_INFO, "Configuring as touchscreen\n");
3449             pInfo->type_name = XI_TOUCHSCREEN;
3450         } else {
3451             if (!EvdevBitIsSet(pEvdev->rel_bitmask, REL_X) ||
3452                 !EvdevBitIsSet(pEvdev->rel_bitmask, REL_Y))
3453                 EvdevForceXY(pInfo, Relative);
3454             xf86IDrvMsg(pInfo, X_INFO, "Configuring as mouse\n");
3455             pInfo->type_name = XI_MOUSE;
3456         }
3457
3458         rc = 0;
3459     }
3460
3461     if (has_keys) {
3462         xf86IDrvMsg(pInfo, X_INFO, "Configuring as keyboard\n");
3463         pInfo->type_name = XI_KEYBOARD;
3464         rc = 0;
3465     }
3466
3467     if (has_scroll &&
3468         (has_rel_axes || has_abs_axes || num_buttons || has_keys))
3469     {
3470         xf86IDrvMsg(pInfo, X_INFO, "Adding scrollwheel support\n");
3471         pEvdev->flags |= EVDEV_BUTTON_EVENTS;
3472         pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
3473     }
3474
3475 #ifdef _F_EVDEV_SUPPORT_ROTARY_
3476     if ((!strncmp(pInfo->name, "tizen_rotary", sizeof("tizen_rotary"))) && (pEvdev->flags & EVDEV_RELATIVE_EVENTS)) {
3477         xf86IDrvMsg(pInfo, X_PROBED, "Found rotary device.\n");
3478         pEvdev->flags |= EVDEV_OFM;
3479
3480         EvdevSetBit(pEvdev->rel_bitmask, REL_Z);
3481     }
3482
3483     if ((!strncmp(pInfo->name, "tizen_detent", sizeof("tizen_detent"))) && (pEvdev->flags & EVDEV_RELATIVE_EVENTS)) {
3484         xf86IDrvMsg(pInfo, X_PROBED, "Found hall device.\n");
3485         pEvdev->flags |= EVDEV_HALLIC;
3486     }
3487 #endif //_F_EVDEV_SUPPORT_ROTARY_
3488 #ifdef _F_EVDEV_SUPPORT_SMARTRC_
3489     if (pEvdev->flags & EVDEV_SMART_RC) {
3490         xf86IDrvMsg(pInfo, X_INFO, "Configuring as smart rc\n");
3491         pInfo->type_name = XI_MOUSE;
3492
3493         EvdevSetBit(pEvdev->rel_bitmask, REL_WHEEL);
3494         EvdevSetBit(pEvdev->rel_bitmask, REL_HWHEEL);
3495     }
3496     pEvdev->origin_input_process = EvdevProcessEvent;
3497 #endif //_F_EVDEV_SUPPORT_SMARTRC_
3498     if (rc)
3499         xf86IDrvMsg(pInfo, X_WARNING, "Don't know how to use device\n");
3500
3501     return rc;
3502 }
3503
3504 static void
3505 EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4])
3506 {
3507     EvdevPtr pEvdev = pInfo->private;
3508
3509     if (num_calibration == 0) {
3510         pEvdev->flags &= ~EVDEV_CALIBRATED;
3511         pEvdev->calibration.min_x = 0;
3512         pEvdev->calibration.max_x = 0;
3513         pEvdev->calibration.min_y = 0;
3514         pEvdev->calibration.max_y = 0;
3515     } else if (num_calibration == 4) {
3516         pEvdev->flags |= EVDEV_CALIBRATED;
3517         pEvdev->calibration.min_x = calibration[0];
3518         pEvdev->calibration.max_x = calibration[1];
3519         pEvdev->calibration.min_y = calibration[2];
3520         pEvdev->calibration.max_y = calibration[3];
3521     }
3522 }
3523
3524 static int
3525 EvdevOpenDevice(InputInfoPtr pInfo)
3526 {
3527     EvdevPtr pEvdev = pInfo->private;
3528     char *device = pEvdev->device;
3529
3530     if (!device)
3531     {
3532         device = xf86CheckStrOption(pInfo->options, "Device", NULL);
3533         if (!device) {
3534             xf86IDrvMsg(pInfo, X_ERROR, "No device specified.\n");
3535             return BadValue;
3536         }
3537
3538         pEvdev->device = device;
3539         xf86IDrvMsg(pInfo, X_CONFIG, "Device: \"%s\"\n", device);
3540     }
3541
3542     if (pInfo->fd < 0)
3543     {
3544         do {
3545             pInfo->fd = open(device, O_RDWR | O_NONBLOCK, 0);
3546         } while (pInfo->fd < 0 && errno == EINTR);
3547
3548         if (pInfo->fd < 0) {
3549             xf86IDrvMsg(pInfo, X_ERROR, "Unable to open evdev device \"%s\".\n", device);
3550             return BadValue;
3551         }
3552     }
3553
3554 #ifdef MULTITOUCH
3555     if (!pEvdev->mtdev) { /* after PreInit mtdev is still valid */
3556         pEvdev->mtdev = mtdev_new_open(pInfo->fd);
3557         if (!pEvdev->mtdev) {
3558             xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
3559             EvdevCloseDevice(pInfo);
3560             return FALSE;
3561         }
3562     }
3563     if (pEvdev->mtdev)
3564         pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
3565 #endif
3566
3567     /* Check major/minor of device node to avoid adding duplicate devices. */
3568     pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
3569     if (EvdevIsDuplicate(pInfo))
3570     {
3571         xf86IDrvMsg(pInfo, X_WARNING, "device file is duplicate. Ignoring.\n");
3572         EvdevCloseDevice(pInfo);
3573         return BadMatch;
3574     }
3575
3576     return Success;
3577 }
3578
3579 static void
3580 EvdevCloseDevice(InputInfoPtr pInfo)
3581 {
3582     EvdevPtr pEvdev = pInfo->private;
3583     if (pInfo->fd >= 0)
3584     {
3585         close(pInfo->fd);
3586         pInfo->fd = -1;
3587     }
3588
3589 #ifdef MULTITOUCH
3590     if (pEvdev->mtdev)
3591     {
3592         mtdev_close_delete(pEvdev->mtdev);
3593         pEvdev->mtdev = NULL;
3594     }
3595 #endif
3596
3597 }
3598
3599 #ifdef _F_EVDEV_CONFINE_REGION_
3600 DeviceIntPtr
3601 GetMasterPointerFromId(int deviceid)
3602 {
3603         DeviceIntPtr pDev = inputInfo.devices;
3604         while(pDev)
3605         {
3606                 if( pDev->id == deviceid && pDev->master )
3607                 {
3608                         return pDev->master;
3609                 }
3610                 pDev = pDev->next;
3611         }
3612
3613         return NULL;
3614 }
3615
3616 Bool
3617 IsMaster(DeviceIntPtr dev)
3618 {
3619     return dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD;
3620 }
3621
3622 DeviceIntPtr
3623 GetPairedDevice(DeviceIntPtr dev)
3624 {
3625     if (!IsMaster(dev) && dev->master)
3626         dev = dev->master;
3627
3628     return dev->spriteInfo->paired;
3629 }
3630
3631 DeviceIntPtr
3632 GetMaster(DeviceIntPtr dev, int which)
3633 {
3634     DeviceIntPtr master;
3635
3636     if (IsMaster(dev))
3637         master = dev;
3638     else
3639         master = dev->master;
3640
3641     if (master)
3642     {
3643         if (which == MASTER_KEYBOARD)
3644         {
3645             if (master->type != MASTER_KEYBOARD)
3646                 master = GetPairedDevice(master);
3647         } else
3648         {
3649             if (master->type != MASTER_POINTER)
3650                 master = GetPairedDevice(master);
3651         }
3652     }
3653
3654     return master;
3655 }
3656
3657 static void
3658 EvdevHookPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
3659                       BoxPtr pHotBox, BoxPtr pTopLeftBox)
3660 {
3661     *pTopLeftBox = *pHotBox;
3662 }
3663
3664 static void
3665 EvdevHookPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox)
3666 {
3667     InputInfoPtr pInfo;
3668     EvdevPtr pEvdev;
3669     BoxPtr pConfineBox;
3670
3671     pInfo =  pDev->public.devicePrivate;
3672     if(!pInfo || !pInfo->private) return;
3673     pEvdev = pInfo->private;
3674
3675     xf86IDrvMsg(pInfo, X_INFO, "[X11][EvdevHookPointerConstrainCursor] Enter !\n");
3676
3677     miPointerPtr pPointer;
3678     pPointer = MIPOINTER(pDev);
3679
3680     pConfineBox = pEvdev->pointer_confine_region;
3681     if(pConfineBox && pEvdev->confined_id)
3682     {
3683             xf86IDrvMsg(pInfo, X_INFO, "[X11][EvdevHookPointerConstrainCursor][before] pBox (%d, %d, %d, %d), pPointer->limits (%d, %d, %d, %d), confined=%d\n",
3684                         pBox->x1, pBox->y1, pBox->x2, pBox->y2, pPointer->limits.x1, pPointer->limits.y1, pPointer->limits.x2, pPointer->limits.y2, pPointer->confined);
3685
3686             if( IsMaster(pDev) && GetMasterPointerFromId(pEvdev->confined_id) == pDev )
3687             {
3688                   xf86IDrvMsg(pInfo, X_INFO, "[X11][EvdevHookPointerConstrainCursor] confine routine --begin (pDev->id=%d)\n", pDev->id);
3689                   if( pBox->x1 < pConfineBox->x1 )
3690                         pBox->x1 = pConfineBox->x1;
3691                   if( pBox->y1 < pConfineBox->y1 )
3692                         pBox->y1 = pConfineBox->y1;
3693                   if( pBox->x2 > pConfineBox->x2 )
3694                         pBox->x2 = pConfineBox->x2;
3695                   if( pBox->y2 > pConfineBox->y2 )
3696                         pBox->y2 = pConfineBox->y2;
3697                   xf86IDrvMsg(pInfo, X_INFO, "[X11][EvdevHookPointerConstrainCursor] confine routine --end (pDev->id=%d)\n", pDev->id);
3698             }
3699     }
3700
3701     pPointer->limits = *pBox;
3702     pPointer->confined = PointerConfinedToScreen(pDev);
3703
3704     if(pEvdev->confined_id)
3705     {
3706             xf86IDrvMsg(pInfo, X_INFO, "[X11][EvdevHookPointerConstrainCursor][after] pBox (%d, %d, %d, %d), pPointer->limits (%d, %d, %d, %d), confined=%d\n",
3707                         pBox->x1, pBox->y1, pBox->x2, pBox->y2, pPointer->limits.x1, pPointer->limits.y1, pPointer->limits.x2, pPointer->limits.y2, pPointer->confined);
3708     }
3709
3710     xf86IDrvMsg(pInfo, X_INFO, "[X11][EvdevHookPointerConstrainCursor] Leave !\n");
3711 }
3712
3713 static void
3714 EvdevSetCursorLimits(InputInfoPtr pInfo, int region[6], int isSet)
3715 {
3716         EvdevPtr pEvdev = pInfo->private;
3717         BoxPtr pConfineBox = pEvdev->pointer_confine_region;
3718         int v[2];
3719         int x, y;
3720
3721         ScreenPtr pCursorScreen = NULL;
3722
3723         pCursorScreen = miPointerGetScreen(pInfo->dev);
3724
3725         if( !pCursorScreen )
3726         {
3727                 xf86IDrvMsg(pInfo, X_ERROR, "[X11][SetCursorLimits] Failed to get screen information for pointer !\n");
3728                 return;
3729         }
3730
3731         if( isSet )
3732         {
3733                 xf86IDrvMsg(pInfo, X_INFO, "[X11][SetCursorLimits] isSet = TRUE !!\n");
3734
3735                 //Clip confine region with screen's width/height
3736                 if( region[0] < 0 )
3737                         region[0] = 0;
3738                 if( region[2] >= pCursorScreen->width )
3739                         region[2] = pCursorScreen->width - 1;
3740                 if( region [1] < 0 )
3741                         region[1] = 0;
3742                 if( region[3] >= pCursorScreen->height )
3743                         region[3] = pCursorScreen->height - 1;
3744
3745                 //Do pointerwarp if region[4] is not zero and region[5] is zero
3746                 if(region[4] && !region[5])
3747                         goto warp_only;
3748
3749                 pConfineBox->x1 = region[0];
3750                 pConfineBox->y1 = region[1];
3751                 pConfineBox->x2 = region[2];
3752                 pConfineBox->y2 = region[3];
3753                 pEvdev->confined_id = pInfo->dev->id;
3754
3755                 pCursorScreen->ConstrainCursor(inputInfo.pointer, pCursorScreen, pConfineBox);
3756                 xf86IDrvMsg(pInfo, X_INFO, "[X11][SetCursorLimits] Constrain information for cursor was set to TOPLEFT(%d, %d) BOTTOMRIGHT(%d, %d) !\n",
3757                         region[0], region[1], region[2], region[3]);
3758
3759                 if( pCursorScreen->CursorLimits != EvdevHookPointerCursorLimits &&
3760                         pCursorScreen->ConstrainCursor != EvdevHookPointerConstrainCursor)
3761                 {
3762                         //Backup original function pointer(s)
3763                         pEvdev->pOrgConstrainCursor = pCursorScreen->ConstrainCursor;
3764                         pEvdev->pOrgCursorLimits = pCursorScreen->CursorLimits;
3765
3766                         //Overriding function pointer(s)
3767                         pCursorScreen->CursorLimits = EvdevHookPointerCursorLimits;
3768                         pCursorScreen->ConstrainCursor = EvdevHookPointerConstrainCursor;
3769                 }
3770
3771                 //Skip pointer warp if region[4] is zero
3772                 if(!region[4])
3773                 {
3774                         xf86IDrvMsg(pInfo, X_INFO, "[X11][SetCursorLimits] region[4]=%d NOT pointer warp !\n", region[4]);
3775                         return;
3776                 }
3777
3778 warp_only:
3779                 v[0] = region[0] + (int)((float)(region[2]-region[0])/2);
3780                 v[1] = region[1] + (int)((float)(region[3]-region[1])/2);
3781
3782                 xf86PostMotionEventP(pInfo->dev, TRUE, REL_X, 2, v);
3783                 xf86IDrvMsg(pInfo, X_INFO, "[X11][SetCursorLimits] Cursor was warped to (%d, %d) !\n", v[0], v[1]);
3784                 miPointerGetPosition(pInfo->dev, &x, &y);
3785                 xf86IDrvMsg(pInfo, X_INFO, "[X11][SetCursorLimits] Cursor is located at (%d, %d) !\n", x, y);
3786         }
3787         else
3788         {
3789                 xf86IDrvMsg(pInfo, X_INFO, "[X11][SetCursorLimits] isSet = FALSE !!\n");
3790
3791                 pConfineBox->x1 = 0;
3792                 pConfineBox->y1 = 0;
3793                 pConfineBox->x2 = pCursorScreen->width - 1;
3794                 pConfineBox->y2 = pCursorScreen->height - 1;
3795                 pEvdev->confined_id = 0;
3796
3797                 pCursorScreen->ConstrainCursor(inputInfo.pointer, pCursorScreen, pConfineBox);
3798                 xf86IDrvMsg(pInfo, X_INFO, "[X11][SetCursorLimits] Constrain information for cursor was restored ! TOPLEFT(%d, %d) BOTTOMRIGHT(%d, %d) !\n",
3799                         pConfineBox->x1, pConfineBox->y1,
3800                         pConfineBox->x2, pConfineBox->y2);
3801
3802                 //Restore original function pointer(s)
3803                 pCursorScreen->CursorLimits = pEvdev->pOrgCursorLimits;
3804                 pCursorScreen->ConstrainCursor = pEvdev->pOrgConstrainCursor;
3805         }
3806 }
3807
3808 static void
3809 EvdevSetConfineRegion(InputInfoPtr pInfo, int num_item, int region[6])
3810 {
3811         EvdevPtr pEvdev = pInfo ? pInfo->private : NULL;
3812
3813         if(!pEvdev)
3814         {
3815                 xf86IDrvMsg(pInfo, X_ERROR, "[X11][SetConfineRegion] num_item != 6 && num_item != 1 !!\n");
3816                 return;
3817         }
3818
3819         if ((num_item != 6) && (num_item != 1) )
3820         {
3821                 xf86IDrvMsg(pInfo, X_ERROR, "[X11][SetConfineRegion] num_item != 6 && num_item != 1 !!\n");
3822                 return;
3823         }
3824
3825         if (!pEvdev->pointer_confine_region)
3826         {
3827                 xf86IDrvMsg(pInfo, X_ERROR, "[X11][SetConfineRegion] pEvdev->pointer_confine_region is NULL\n");
3828                 xf86IDrvMsg(pInfo, X_ERROR, "[X11][SetConfineRegion] num_item=%d\n", num_item);
3829                 return;
3830         }
3831
3832         if( num_item == 6 )
3833         {
3834                 xf86IDrvMsg(pInfo, X_INFO, "[X11][SetConfineRegion] num_item == 6\n");
3835                 if ( (region[2]-region[0]>0) && (region[3]-region[1]>0) )
3836                 {
3837                         EvdevSetCursorLimits(pInfo, &region[0], 1);
3838                         xf86IDrvMsg(pInfo, X_INFO, "[X11][SetConfineRegion] Confine region was set to TOPLEFT(%d, %d) BOTTOMRIGHT(%d, %d) pointerwarp=%d, confine=%d\n",
3839                                 region[0], region[1], region[2], region[3], region[4], region[5]);
3840                         pEvdev->flags |= EVDEV_CONFINE_REGION;
3841                 }
3842         }
3843         else//if( num_item == 1 )
3844         {
3845                 xf86IDrvMsg(pInfo, X_INFO, "[X11][SetConfineRegion] num_item == 1\n");
3846                 if( !region[0] && (pEvdev->flags & EVDEV_CONFINE_REGION) )
3847                 {
3848                         EvdevSetCursorLimits(pInfo, &region[0], 0);
3849                         xf86IDrvMsg(pInfo, X_INFO, "[X11][SetConfineRegion] Confine region was unset !\n");
3850                         pEvdev->flags &= ~EVDEV_CONFINE_REGION;
3851                 }
3852         }
3853 }
3854 #endif /* #ifdef _F_EVDEV_CONFINE_REGION_ */
3855
3856 #ifdef _F_TOUCH_TRANSFORM_MATRIX_
3857 static void
3858 EvdevSetTransformMatrix(InputInfoPtr pInfo, int num_transform, float *tmatrix)
3859 {
3860         int x, y;
3861         struct pixman_transform tr;
3862         EvdevPtr pEvdev = pInfo ? pInfo->private : NULL;
3863
3864         if(!pEvdev)
3865                 return;
3866
3867         if( (num_transform != 9) && (num_transform != 1) )
3868         {
3869                 pEvdev->use_transform = FALSE;
3870                 return;
3871         }
3872
3873         if( num_transform == 9 )
3874         {
3875                 pEvdev->use_transform = TRUE;
3876
3877                 memcpy(pEvdev->transform, tmatrix, sizeof(pEvdev->transform));
3878                 for (y=0; y<3; y++)
3879                         for (x=0; x<3; x++)
3880                                 tr.matrix[y][x] = pixman_double_to_fixed((double)*tmatrix++);
3881
3882                 pixman_transform_invert(&pEvdev->inv_transform, &tr);
3883                 ErrorF("[X11][EvdevSetTransformMatrix] Touch transform has been enabled !\n");
3884         }
3885         else if( (num_transform == 1) && (tmatrix[0] == 0) )
3886         {
3887                 pEvdev->use_transform = FALSE;
3888                 ErrorF("[X11][EvdevSetTransformMatrix] Touch transform has been disabled !\n");
3889         }
3890 }
3891 #endif /* #ifdef _F_TOUCH_TRANSFORM_MATRIX_ */
3892
3893 #ifdef _F_SUPPORT_ROTATION_ANGLE_
3894 static void
3895 EvdevSetRotationAngle(EvdevPtr pEvdev, int angle)
3896 {
3897         if(pEvdev->rotation_node <= 0)
3898         {
3899                 xf86Msg(X_INFO, "[%s] Rotation node doesn't exist. Ignored. (angle=%d)\n", __FUNCTION__, angle);
3900                 return;
3901         }
3902
3903         if(pEvdev->rotation_angle != angle)
3904         {
3905                 {
3906                         int nwrite = 0;
3907                         char buf;
3908
3909                         buf = (char)(angle + '0');
3910
3911                         nwrite = write(pEvdev->rotation_node, &buf, sizeof(buf));
3912
3913                         if(nwrite <= 0)
3914                                 xf86Msg(X_ERROR, "[%s] Failed to write angle(=%d) on rotation_node. (errno=%d)\n", __FUNCTION__, angle, errno);
3915                         else
3916                                 xf86Msg(X_ERROR, "[%s] Succeed to write angle(=%d) on rotation_node.\n", __FUNCTION__, angle);
3917                 }
3918
3919                 pEvdev->rotation_angle = angle;
3920         }
3921         else
3922         {
3923                 xf86Msg(X_INFO, "[%s] Rotation angle has not been changed. Ignored. (angle=%d)\n", __FUNCTION__, angle);
3924         }
3925 }
3926 #endif// _F_SUPPORT_ROTATION_ANGLE_
3927
3928 static void
3929 EvdevUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
3930 {
3931     EvdevPtr pEvdev = pInfo ? pInfo->private : NULL;
3932     if (pEvdev)
3933     {
3934 #ifdef _F_EVDEV_SUPPORT_ROTARY_
3935         EvdevRotaryUnInit(pEvdev);
3936 #endif //_F_EVDEV_SUPPORT_ROTARY_
3937
3938         /* Release strings allocated in EvdevAddKeyClass. */
3939         XkbFreeRMLVOSet(&pEvdev->rmlvo, FALSE);
3940         /* Release string allocated in EvdevOpenDevice. */
3941         free(pEvdev->device);
3942         pEvdev->device = NULL;
3943         free(pEvdev);
3944         pEvdev = NULL;
3945     }
3946     xf86DeleteInput(pInfo, flags);
3947 }
3948
3949 static int
3950 EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
3951 {
3952     EvdevPtr pEvdev;
3953     int rc = BadAlloc;
3954 #ifdef _F_TOUCH_TRANSFORM_MATRIX_
3955     float tr[9];
3956     int num_transform = 0;
3957     const char *str;
3958 #endif /* #ifdef _F_TOUCH_TRANSFORM_MATRIX_ */
3959
3960 #ifdef _F_PROXY_DEVICE_ENABLED_
3961     char *type;
3962 #endif /* #ifdef _F_PROXY_DEVICE_ENABLED_ */
3963
3964 #ifdef _F_BOOST_PULSE_
3965     if(fd_boostpulse == NULL)
3966        fd_boostpulse = open("sys/kernel/hmp/boostpulse", O_RDWR);
3967 #endif //_F_BOOST_PULSE_
3968
3969     if (!(pEvdev = calloc(sizeof(EvdevRec), 1)))
3970     {
3971         xf86IDrvMsg(pInfo, X_ERROR, "Failed to allocate memory for private member of pInfo !\n");
3972         goto error;
3973     }
3974
3975     TTRACE_END();
3976
3977     pInfo->private = pEvdev;
3978     pInfo->type_name = "UNKNOWN";
3979     pInfo->device_control = EvdevProc;
3980     pInfo->read_input = EvdevReadInput;
3981     pInfo->switch_mode = EvdevSwitchMode;
3982 #ifdef _F_EVDEV_SUPPORT_SMARTRC_
3983     pEvdev->extra_input_process = NULL;
3984     pEvdev->rc_state = 0;
3985     pEvdev->proxy_enabled = xf86SetBoolOption(pInfo->options, "ProxyDeviceEnabled", FALSE);
3986 #endif //_F_EVDEV_SUPPORT_SMARTRC_
3987
3988 #ifdef _F_PROXY_DEVICE_ENABLED_
3989     /* If Type == ProxyDev, this is a proxy device */
3990     type = xf86CheckStrOption(pInfo->options, "Type", NULL);
3991
3992     xf86Msg(X_INFO, "%s: Evdev Type %s found\n", pInfo->name, type);
3993
3994     if (type != NULL && strcmp(type, OPT_TYPE_VAL) == 0)
3995     {
3996         EvdevPtr pCreatorEvdev;
3997         free(type);
3998         if (!pCreatorInfo){
3999             return Success;
4000         }
4001         pCreatorEvdev = pCreatorInfo->private;
4002         xf86Msg(X_INFO, "%s: Evdev proxy device found\n", pInfo->name);
4003         memcpy(pEvdev, pCreatorEvdev, sizeof(EvdevRec));
4004         pInfo->read_input = EvdevProxydevReadInput;
4005         pInfo->type_name = pCreatorInfo->type_name;
4006         pEvdev->b_proxy_device = TRUE;
4007         pEvdev->proxy_device = NULL;
4008         return Success;
4009     }
4010     else
4011     {
4012         free(type);
4013         pEvdev->b_proxy_device = FALSE;
4014         pEvdev->proxy_device = NULL;
4015     }
4016 #endif /* #ifdef _F_PROXY_DEVICE_ENABLED_ */
4017
4018 #ifdef _F_EVDEV_SUPPORT_ROTARY_
4019     pEvdev->extra_rel_post_hallic= NULL;
4020     pEvdev->extra_rel_post_ofm= NULL;
4021 #endif //_F_EVDEV_SUPPORT_ROTARY_
4022
4023     rc = EvdevOpenDevice(pInfo);
4024     if (rc != Success)
4025         goto error;
4026
4027 #ifdef MULTITOUCH
4028     pEvdev->cur_slot = -1;
4029 #endif
4030 #ifdef MULTI_PASSIVE_GRAB_
4031     pEvdev->activatedkeylist = NULL;
4032 #endif //MULTI_PASSIVE_GRAB_
4033
4034     /*
4035      * We initialize pEvdev->in_proximity to 1 so that device that doesn't use
4036      * proximity will still report events.
4037      */
4038     pEvdev->in_proximity = 1;
4039     pEvdev->use_proximity = 1;
4040
4041     /* Grabbing the event device stops in-kernel event forwarding. In other
4042        words, it disables rfkill and the "Macintosh mouse button emulation".
4043        Note that this needs a server that sets the console to RAW mode. */
4044     pEvdev->grabDevice = xf86CheckBoolOption(pInfo->options, "GrabDevice", 0);
4045
4046     /* If grabDevice is set, ungrab immediately since we only want to grab
4047      * between DEVICE_ON and DEVICE_OFF. If we never get DEVICE_ON, don't
4048      * hold a grab. */
4049     if (!EvdevGrabDevice(pInfo, 1, 1))
4050     {
4051         xf86IDrvMsg(pInfo, X_WARNING, "Device may already be configured.\n");
4052         rc = BadMatch;
4053         goto error;
4054     }
4055
4056     EvdevInitButtonMapping(pInfo);
4057
4058 #ifdef _F_EVDEV_SUPPORT_GAMEPAD
4059     {
4060         int i;
4061         char tmp[25];
4062
4063         memset(&pEvdev->abs_gamepad_labels, 0, sizeof(pEvdev->abs_gamepad_labels));
4064
4065         for(i = 0 ; i < MAX_GAMEPAD_DEFINITION_ABS ; i++)
4066         {
4067             snprintf(tmp, sizeof(tmp), "GamePad_Condition_ABS%d", i+1);
4068             pEvdev->abs_gamepad_labels[i] = xf86SetIntOption(pInfo->options, tmp, 0);
4069         }
4070     }
4071
4072     {
4073         int i;
4074         char tmp[25];
4075
4076         memset(&pEvdev->key_gamepad_labels, 0, sizeof(pEvdev->key_gamepad_labels));
4077
4078         for(i = 0 ; i < MAX_GAMEPAD_DEFINITION_KEY ; i++)
4079         {
4080             snprintf(tmp, sizeof(tmp), "GamePad_Condition_KEY%d", i+1);
4081             if(i == 0)
4082                 pEvdev->key_gamepad_labels[i] = xf86SetIntOption(pInfo->options, tmp, BTN_GAMEPAD);
4083             else
4084                 pEvdev->key_gamepad_labels[i] = xf86SetIntOption(pInfo->options, tmp, 0);
4085         }
4086     }
4087 #endif//_F_EVDEV_SUPPORT_GAMEPAD
4088
4089 #ifdef _F_USE_DEFAULT_XKB_RULES_
4090     pEvdev->use_default_xkb_rmlvo = xf86SetBoolOption(pInfo->options, "UseDefaultXkbRMLVO", FALSE);
4091 #endif
4092
4093 #ifdef _F_EVDEV_SUPPORT_ROTARY_
4094     pEvdev->HW_Calibration = xf86SetIntOption(pInfo->options, "HW_ROTARY_MAX", DEFAULT_HW_ROTARY_MAX);
4095 #endif //_F_EVDEV_SUPPORT_ROTARY_
4096
4097     if (EvdevCache(pInfo) || EvdevProbe(pInfo)) {
4098         rc = BadMatch;
4099         goto error;
4100     }
4101
4102     EvdevAddDevice(pInfo);
4103
4104     if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
4105     {
4106         EvdevMBEmuPreInit(pInfo);
4107         Evdev3BEmuPreInit(pInfo);
4108         EvdevWheelEmuPreInit(pInfo);
4109         EvdevDragLockPreInit(pInfo);
4110     }
4111
4112 #ifdef MULTITOUCH
4113     if (strstr(pInfo->type_name, XI_TOUCHSCREEN))
4114     {
4115         pEvdev->mtdev = mtdev_new_open(pInfo->fd);
4116
4117         if (pEvdev->mtdev)
4118         {
4119                 pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
4120         }
4121         else
4122         {
4123                 xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
4124                 TTRACE_END();
4125                 return FALSE;
4126         }
4127     }
4128     else
4129     {
4130         pEvdev->mtdev = NULL;
4131     }
4132 #endif
4133
4134 #ifdef _F_TOUCH_TRANSFORM_MATRIX_
4135     pEvdev->use_transform = FALSE;
4136
4137     if (strstr(pInfo->type_name, XI_TOUCHSCREEN))
4138     {
4139         str = xf86CheckStrOption(pInfo->options, "Transform", NULL);
4140
4141         if (str)
4142         {
4143                 num_transform = sscanf(str, "%f %f %f %f %f %f %f %f %f",
4144                                                 &tr[0], &tr[1], &tr[2],
4145                                                 &tr[3], &tr[4], &tr[5],
4146                                                 &tr[6], &tr[7], &tr[8]);
4147                 if (num_transform == 9)
4148                     EvdevSetTransformMatrix(pInfo, num_transform, tr);
4149                 else
4150                 {
4151                     xf86Msg(X_ERROR, "%s: Insufficient transform factors (%d). Ignoring transform\n",
4152                         pInfo->name, num_transform);
4153                 }
4154         }
4155     }
4156 #endif /* #ifdef _F_TOUCH_TRANSFORM_MATRIX_ */
4157
4158 #ifdef _F_EVDEV_CONFINE_REGION_
4159     pEvdev->confined_id = 0;
4160     pEvdev->pointer_confine_region = NULL;
4161
4162     if (strstr(pInfo->name, XI_TOUCHPAD)
4163                 || strstr(pInfo->type_name, XI_MOUSE)
4164                 || strstr(pInfo->name, "Virtual Touchpad"))
4165     {
4166         pEvdev->pointer_confine_region = (BoxPtr)malloc(sizeof(BoxRec));
4167
4168         if (!pEvdev->pointer_confine_region)
4169         {
4170                 xf86IDrvMsg(pInfo, X_ERROR, "Failed to allocate memory for pointer confine region\nConfine feature may not work properly.");
4171                 rc = BadAlloc;
4172                 goto error;
4173         }
4174         else
4175         {
4176                 xf86IDrvMsg(pInfo, X_INFO, "Succeed to allocate memory for pointer confine region\nConfine feature will work properly.");
4177         }
4178
4179         memset(pEvdev->pointer_confine_region, 0, sizeof(BoxRec));
4180     }
4181 #endif /* #ifdef _F_EVDEV_CONFINE_REGION_ */
4182
4183 #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_
4184     pEvdev->rel_move_timer = NULL;
4185     if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
4186     {
4187 #ifdef _F_PROXY_DEVICE_ENABLED_
4188         if (!pEvdev->b_proxy_device)
4189         {
4190 #endif //_F_PROXY_DEVICE_ENABLED_
4191         if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
4192         pEvdev->rel_move_timer = TimerSet(pEvdev->rel_move_timer, 0, EVDEV_RMS_TIMEOUT, EvdevRelativeMoveTimer, pInfo);
4193         if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
4194         TimerCancel(pEvdev->rel_move_timer);
4195         ErrorF("[EvdevPreinit] Device: %s has relative events create RMS timer(%p)\n", pInfo->name, pEvdev->rel_move_timer);
4196 #ifdef _F_PROXY_DEVICE_ENABLED_
4197         }
4198 #endif //_F_PROXY_DEVICE_ENABLED_
4199     }
4200     pEvdev->rel_move_prop_set = 0;
4201     pEvdev->rel_move_status = 0;
4202 #endif /* #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_ */
4203
4204 #ifdef _F_GESTURE_EXTENSION_
4205     int alloc_size = sizeof(int)*num_slots(pEvdev);
4206     pEvdev->mt_status = NULL;
4207
4208     if (strstr(pInfo->type_name, XI_TOUCHSCREEN))
4209     {
4210             pEvdev->mt_status = (int *)malloc(alloc_size);
4211
4212             if (!pEvdev->mt_status)
4213             {
4214                 xf86IDrvMsg(pInfo, X_ERROR, "Failed to allocate memory to maintain multitouch status !\nX Gesture driver may not work properly.\n");
4215                 rc = BadAlloc;
4216                 goto error;
4217             }
4218
4219             memset(pEvdev->mt_status, 0, alloc_size);
4220     }
4221 #endif /* #ifdef _F_GESTURE_EXTENSION_ */
4222 #ifdef _F_EVDEV_SUPPORT_GAMEPAD
4223     pEvdev->pre_x = 128;
4224     pEvdev->pre_y = 128;
4225
4226     pEvdev->support_directional_key = xf86SetBoolOption(pInfo->options, "Support_Directional_Keys", FALSE);
4227
4228     pEvdev->keycode_btnA = xf86SetIntOption(pInfo->options, "GamePad_ButtonA", 0);
4229     pEvdev->keycode_btnB = xf86SetIntOption(pInfo->options, "GamePad_ButtonB", 0);
4230     pEvdev->keycode_btnX = xf86SetIntOption(pInfo->options, "GamePad_ButtonX", 0);
4231     pEvdev->keycode_btnY = xf86SetIntOption(pInfo->options, "GamePad_ButtonY", 0);
4232     pEvdev->keycode_btnTL = xf86SetIntOption(pInfo->options, "GamePad_ButtonTL", 0);
4233     pEvdev->keycode_btnTR = xf86SetIntOption(pInfo->options, "GamePad_ButtonTR", 0);
4234     pEvdev->keycode_btnStart = xf86SetIntOption(pInfo->options, "GamePad_ButtonStart", 0);
4235     pEvdev->keycode_btnSelect = xf86SetIntOption(pInfo->options, "GamePad_ButtonSelect", 0);
4236     pEvdev->keycode_btnPlay = xf86SetIntOption(pInfo->options, "GamePad_ButtonPlay", 0);
4237 #endif//_F_EVDEV_SUPPORT_GAMEPAD
4238
4239 #ifdef _F_SUPPORT_ROTATION_ANGLE_
4240     pEvdev->rotation_angle = xf86SetIntOption(pInfo->options, "RotationAngle", 0);
4241
4242     str = xf86CheckStrOption(pInfo->options, "RotationNode", NULL);
4243     if (str)
4244     {
4245         do {
4246             pEvdev->rotation_node = open(str, O_WRONLY, 0);
4247         } while (pEvdev->rotation_node < 0 && errno == EINTR);
4248     }
4249     else xf86Msg(X_INFO, "%s: No rotation node exists..\n", pInfo->name);
4250
4251     if (pEvdev->rotation_node < 0) {
4252         xf86Msg(X_ERROR, "Unable to open evdevmultitouch rotation_node\"%s\".\n", str);
4253         xf86Msg(X_ERROR, "Input rotation will be done inside evdevmultitouch driver.\n");
4254         pEvdev->rotation_node = 0;
4255     }
4256 #endif// _F_SUPPORT_ROTATION_ANGLE_
4257
4258     TTRACE_END();
4259     return Success;
4260
4261 error:
4262     EvdevCloseDevice(pInfo);
4263     TTRACE_END();
4264     return rc;
4265 }
4266
4267 _X_EXPORT InputDriverRec EVDEV = {
4268     1,
4269     "evdev",
4270     NULL,
4271     EvdevPreInit,
4272     EvdevUnInit,
4273     NULL,
4274     evdevDefaults
4275 };
4276
4277 static void
4278 EvdevUnplug(pointer     p)
4279 {
4280 }
4281
4282 static pointer
4283 EvdevPlug(pointer       module,
4284           pointer       options,
4285           int           *errmaj,
4286           int           *errmin)
4287 {
4288     xf86AddInputDriver(&EVDEV, module, 0);
4289     return module;
4290 }
4291
4292 static XF86ModuleVersionInfo EvdevVersionRec =
4293 {
4294     "evdev",
4295     MODULEVENDORSTRING,
4296     MODINFOSTRING1,
4297     MODINFOSTRING2,
4298     XORG_VERSION_CURRENT,
4299     PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
4300     ABI_CLASS_XINPUT,
4301     ABI_XINPUT_VERSION,
4302     MOD_CLASS_XINPUT,
4303     {0, 0, 0, 0}
4304 };
4305
4306 _X_EXPORT XF86ModuleData evdevModuleData =
4307 {
4308     &EvdevVersionRec,
4309     EvdevPlug,
4310     EvdevUnplug
4311 };
4312
4313
4314 /* Return an index value for a given button event code
4315  * returns 0 on non-button event.
4316  */
4317 unsigned int
4318 EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code)
4319 {
4320     switch (code)
4321     {
4322         /* Mouse buttons */
4323         case BTN_LEFT:
4324             return 1;
4325         case BTN_MIDDLE:
4326             return 2;
4327         case BTN_RIGHT:
4328             return 3;
4329         case BTN_SIDE ... BTN_JOYSTICK - 1:
4330             return 8 + code - BTN_SIDE;
4331
4332         /* Generic buttons */
4333         case BTN_0 ... BTN_2:
4334             return 1 + code - BTN_0;
4335         case BTN_3 ... BTN_MOUSE - 1:
4336             return 8 + code - BTN_3;
4337
4338         /* Tablet stylus buttons */
4339         case BTN_TOUCH ... BTN_STYLUS2:
4340             return 1 + code - BTN_TOUCH;
4341 #ifdef _F_EVDEV_SUPPORT_GAMEPAD
4342         /* Game pad buttons */
4343         case BTN_A ... BTN_THUMBR:
4344             return 8 + code - BTN_A;
4345 #endif//_F_EVDEV_SUPPORT_GAMEPAD
4346
4347         /* The rest */
4348         default:
4349             /* Ignore */
4350             return 0;
4351     }
4352 }
4353
4354 /* Aligned with linux/input.h.
4355    Note that there are holes in the ABS_ range, these are simply replaced with
4356    MISC here */
4357 static char* abs_labels[] = {
4358     AXIS_LABEL_PROP_ABS_X,              /* 0x00 */
4359     AXIS_LABEL_PROP_ABS_Y,              /* 0x01 */
4360     AXIS_LABEL_PROP_ABS_Z,              /* 0x02 */
4361     AXIS_LABEL_PROP_ABS_RX,             /* 0x03 */
4362     AXIS_LABEL_PROP_ABS_RY,             /* 0x04 */
4363     AXIS_LABEL_PROP_ABS_RZ,             /* 0x05 */
4364     AXIS_LABEL_PROP_ABS_THROTTLE,       /* 0x06 */
4365     AXIS_LABEL_PROP_ABS_RUDDER,         /* 0x07 */
4366     AXIS_LABEL_PROP_ABS_WHEEL,          /* 0x08 */
4367     AXIS_LABEL_PROP_ABS_GAS,            /* 0x09 */
4368     AXIS_LABEL_PROP_ABS_BRAKE,          /* 0x0a */
4369     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4370     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4371     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4372     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4373     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4374     AXIS_LABEL_PROP_ABS_HAT0X,          /* 0x10 */
4375     AXIS_LABEL_PROP_ABS_HAT0Y,          /* 0x11 */
4376     AXIS_LABEL_PROP_ABS_HAT1X,          /* 0x12 */
4377     AXIS_LABEL_PROP_ABS_HAT1Y,          /* 0x13 */
4378     AXIS_LABEL_PROP_ABS_HAT2X,          /* 0x14 */
4379     AXIS_LABEL_PROP_ABS_HAT2Y,          /* 0x15 */
4380     AXIS_LABEL_PROP_ABS_HAT3X,          /* 0x16 */
4381     AXIS_LABEL_PROP_ABS_HAT3Y,          /* 0x17 */
4382     AXIS_LABEL_PROP_ABS_PRESSURE,       /* 0x18 */
4383     AXIS_LABEL_PROP_ABS_DISTANCE,       /* 0x19 */
4384     AXIS_LABEL_PROP_ABS_TILT_X,         /* 0x1a */
4385     AXIS_LABEL_PROP_ABS_TILT_Y,         /* 0x1b */
4386     AXIS_LABEL_PROP_ABS_TOOL_WIDTH,     /* 0x1c */
4387     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4388     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4389     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4390     AXIS_LABEL_PROP_ABS_VOLUME          /* 0x20 */
4391     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4392     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4393     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4394     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4395     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4396     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4397     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4398     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4399     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4400     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4401     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4402     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4403     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4404     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4405     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4406     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
4407     AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR, /* 0x30 */
4408     AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR, /* 0x31 */
4409     AXIS_LABEL_PROP_ABS_MT_WIDTH_MAJOR, /* 0x32 */
4410     AXIS_LABEL_PROP_ABS_MT_WIDTH_MINOR, /* 0x33 */
4411     AXIS_LABEL_PROP_ABS_MT_ORIENTATION, /* 0x34 */
4412     AXIS_LABEL_PROP_ABS_MT_POSITION_X,  /* 0x35 */
4413     AXIS_LABEL_PROP_ABS_MT_POSITION_Y,  /* 0x36 */
4414     AXIS_LABEL_PROP_ABS_MT_TOOL_TYPE,   /* 0x37 */
4415     AXIS_LABEL_PROP_ABS_MT_BLOB_ID,     /* 0x38 */
4416     AXIS_LABEL_PROP_ABS_MT_TRACKING_ID, /* 0x39 */
4417     AXIS_LABEL_PROP_ABS_MT_PRESSURE,    /* 0x3a */
4418 };
4419
4420 static char* rel_labels[] = {
4421     AXIS_LABEL_PROP_REL_X,
4422     AXIS_LABEL_PROP_REL_Y,
4423     AXIS_LABEL_PROP_REL_Z,
4424     AXIS_LABEL_PROP_REL_RX,
4425     AXIS_LABEL_PROP_REL_RY,
4426     AXIS_LABEL_PROP_REL_RZ,
4427     AXIS_LABEL_PROP_REL_HWHEEL,
4428     AXIS_LABEL_PROP_REL_DIAL,
4429     AXIS_LABEL_PROP_REL_WHEEL,
4430     AXIS_LABEL_PROP_REL_MISC
4431 };
4432
4433 static char* btn_labels[][16] = {
4434     { /* BTN_MISC group                 offset 0x100*/
4435         BTN_LABEL_PROP_BTN_0,           /* 0x00 */
4436         BTN_LABEL_PROP_BTN_1,           /* 0x01 */
4437         BTN_LABEL_PROP_BTN_2,           /* 0x02 */
4438         BTN_LABEL_PROP_BTN_3,           /* 0x03 */
4439         BTN_LABEL_PROP_BTN_4,           /* 0x04 */
4440         BTN_LABEL_PROP_BTN_5,           /* 0x05 */
4441         BTN_LABEL_PROP_BTN_6,           /* 0x06 */
4442         BTN_LABEL_PROP_BTN_7,           /* 0x07 */
4443         BTN_LABEL_PROP_BTN_8,           /* 0x08 */
4444         BTN_LABEL_PROP_BTN_9            /* 0x09 */
4445     },
4446     { /* BTN_MOUSE group                offset 0x110 */
4447         BTN_LABEL_PROP_BTN_LEFT,        /* 0x00 */
4448         BTN_LABEL_PROP_BTN_RIGHT,       /* 0x01 */
4449         BTN_LABEL_PROP_BTN_MIDDLE,      /* 0x02 */
4450         BTN_LABEL_PROP_BTN_SIDE,        /* 0x03 */
4451         BTN_LABEL_PROP_BTN_EXTRA,       /* 0x04 */
4452         BTN_LABEL_PROP_BTN_FORWARD,     /* 0x05 */
4453         BTN_LABEL_PROP_BTN_BACK,        /* 0x06 */
4454         BTN_LABEL_PROP_BTN_TASK         /* 0x07 */
4455     },
4456     { /* BTN_JOYSTICK group             offset 0x120 */
4457         BTN_LABEL_PROP_BTN_TRIGGER,     /* 0x00 */
4458         BTN_LABEL_PROP_BTN_THUMB,       /* 0x01 */
4459         BTN_LABEL_PROP_BTN_THUMB2,      /* 0x02 */
4460         BTN_LABEL_PROP_BTN_TOP,         /* 0x03 */
4461         BTN_LABEL_PROP_BTN_TOP2,        /* 0x04 */
4462         BTN_LABEL_PROP_BTN_PINKIE,      /* 0x05 */
4463         BTN_LABEL_PROP_BTN_BASE,        /* 0x06 */
4464         BTN_LABEL_PROP_BTN_BASE2,       /* 0x07 */
4465         BTN_LABEL_PROP_BTN_BASE3,       /* 0x08 */
4466         BTN_LABEL_PROP_BTN_BASE4,       /* 0x09 */
4467         BTN_LABEL_PROP_BTN_BASE5,       /* 0x0a */
4468         BTN_LABEL_PROP_BTN_BASE6,       /* 0x0b */
4469         NULL,
4470         NULL,
4471         NULL,
4472         BTN_LABEL_PROP_BTN_DEAD         /* 0x0f */
4473     },
4474     { /* BTN_GAMEPAD group              offset 0x130 */
4475         BTN_LABEL_PROP_BTN_A,           /* 0x00 */
4476         BTN_LABEL_PROP_BTN_B,           /* 0x01 */
4477         BTN_LABEL_PROP_BTN_C,           /* 0x02 */
4478         BTN_LABEL_PROP_BTN_X,           /* 0x03 */
4479         BTN_LABEL_PROP_BTN_Y,           /* 0x04 */
4480         BTN_LABEL_PROP_BTN_Z,           /* 0x05 */
4481         BTN_LABEL_PROP_BTN_TL,          /* 0x06 */
4482         BTN_LABEL_PROP_BTN_TR,          /* 0x07 */
4483         BTN_LABEL_PROP_BTN_TL2,         /* 0x08 */
4484         BTN_LABEL_PROP_BTN_TR2,         /* 0x09 */
4485         BTN_LABEL_PROP_BTN_SELECT,      /* 0x0a */
4486         BTN_LABEL_PROP_BTN_START,       /* 0x0b */
4487         BTN_LABEL_PROP_BTN_MODE,        /* 0x0c */
4488         BTN_LABEL_PROP_BTN_THUMBL,      /* 0x0d */
4489         BTN_LABEL_PROP_BTN_THUMBR       /* 0x0e */
4490     },
4491     { /* BTN_DIGI group                         offset 0x140 */
4492         BTN_LABEL_PROP_BTN_TOOL_PEN,            /* 0x00 */
4493         BTN_LABEL_PROP_BTN_TOOL_RUBBER,         /* 0x01 */
4494         BTN_LABEL_PROP_BTN_TOOL_BRUSH,          /* 0x02 */
4495         BTN_LABEL_PROP_BTN_TOOL_PENCIL,         /* 0x03 */
4496         BTN_LABEL_PROP_BTN_TOOL_AIRBRUSH,       /* 0x04 */
4497         BTN_LABEL_PROP_BTN_TOOL_FINGER,         /* 0x05 */
4498         BTN_LABEL_PROP_BTN_TOOL_MOUSE,          /* 0x06 */
4499         BTN_LABEL_PROP_BTN_TOOL_LENS,           /* 0x07 */
4500         NULL,
4501         NULL,
4502         BTN_LABEL_PROP_BTN_TOUCH,               /* 0x0a */
4503         BTN_LABEL_PROP_BTN_STYLUS,              /* 0x0b */
4504         BTN_LABEL_PROP_BTN_STYLUS2,             /* 0x0c */
4505         BTN_LABEL_PROP_BTN_TOOL_DOUBLETAP,      /* 0x0d */
4506         BTN_LABEL_PROP_BTN_TOOL_TRIPLETAP       /* 0x0e */
4507     },
4508     { /* BTN_WHEEL group                        offset 0x150 */
4509         BTN_LABEL_PROP_BTN_GEAR_DOWN,           /* 0x00 */
4510         BTN_LABEL_PROP_BTN_GEAR_UP              /* 0x01 */
4511     }
4512 };
4513
4514 static void EvdevInitAxesLabels(EvdevPtr pEvdev, int mode, int natoms, Atom *atoms)
4515 {
4516     Atom atom;
4517     int axis;
4518     char **labels;
4519     int labels_len = 0;
4520
4521 #ifdef _F_EVDEV_SUPPORT_GAMEPAD
4522     if (mode == Absolute || pEvdev->flags & EVDEV_GAMEPAD)
4523 #else
4524     if (mode == Absolute)
4525 #endif//_F_EVDEV_SUPPORT_GAMEPAD
4526     {
4527         labels     = abs_labels;
4528         labels_len = ArrayLength(abs_labels);
4529     } else if (mode == Relative)
4530     {
4531         labels     = rel_labels;
4532         labels_len = ArrayLength(rel_labels);
4533     } else
4534         return;
4535
4536     memset(atoms, 0, natoms * sizeof(Atom));
4537
4538     /* Now fill the ones we know */
4539     for (axis = 0; axis < labels_len; axis++)
4540     {
4541         if (pEvdev->axis_map[axis] == -1)
4542             continue;
4543
4544         atom = XIGetKnownProperty(labels[axis]);
4545         if (!atom) /* Should not happen */
4546             continue;
4547
4548         atoms[pEvdev->axis_map[axis]] = atom;
4549     }
4550 }
4551
4552 static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms)
4553 {
4554     Atom atom;
4555     int button, bmap;
4556
4557     /* First, make sure all atoms are initialized */
4558     atom = XIGetKnownProperty(BTN_LABEL_PROP_BTN_UNKNOWN);
4559     for (button = 0; button < natoms; button++)
4560         atoms[button] = atom;
4561
4562 #ifdef _F_EVDEV_SUPPORT_GAMEPAD
4563     for (button = BTN_MISC; button < BTN_THUMBR; button++)
4564 #else
4565     for (button = BTN_MISC; button < BTN_JOYSTICK; button++)
4566 #endif//_F_EVDEV_SUPPORT_GAMEPAD
4567     {
4568         if (EvdevBitIsSet(pEvdev->key_bitmask, button))
4569         {
4570             int group = (button % 0x100)/16;
4571             int idx = button - ((button/16) * 16);
4572
4573             if ((unsigned int)group >= sizeof(btn_labels)/sizeof(btn_labels[0]))
4574                 continue;
4575
4576             if (!btn_labels[group][idx])
4577                 continue;
4578
4579             atom = XIGetKnownProperty(btn_labels[group][idx]);
4580             if (!atom)
4581                 continue;
4582
4583             /* Props are 0-indexed, button numbers start with 1 */
4584             bmap = EvdevUtilButtonEventToButtonNumber(pEvdev, button) - 1;
4585             if(bmap <0)
4586                continue;
4587
4588             atoms[bmap] = atom;
4589         }
4590     }
4591
4592     /* wheel buttons, hardcoded anyway */
4593     if (natoms > 3)
4594         atoms[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
4595     if (natoms > 4)
4596         atoms[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
4597     if (natoms > 5)
4598         atoms[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
4599     if (natoms > 6)
4600         atoms[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
4601 }
4602
4603 static void
4604 EvdevInitProperty(DeviceIntPtr dev)
4605 {
4606     InputInfoPtr pInfo  = dev->public.devicePrivate;
4607     EvdevPtr     pEvdev = pInfo->private;
4608     int          rc;
4609     char         *device_node;
4610 #ifdef _F_ENABLE_DEVICE_TYPE_PROP_
4611     char         *device_type;
4612 #endif /* #ifdef _F_ENABLE_DEVICE_TYPE_PROP_ */
4613 #ifdef _F_EVDEV_CONFINE_REGION_
4614     int region[6] = { 0, };
4615 #endif /* _F_EVDEV_CONFINE_REGION_ */
4616 #ifdef _F_PROXY_DEVICE_ENABLED_
4617     int slave_proxy;
4618 #endif /* _F_PROXY_DEVICE_ENABLED_ */
4619
4620     CARD32       product[2];
4621 #ifdef _F_PICTURE_OFF_MODE_ENABLE_
4622     atomPictureOffMode = MakeAtom(XI_PROP_PICTURE_OFF_MODE,strlen(XI_PROP_PICTURE_OFF_MODE), TRUE);
4623 #endif //_F_PICTURE_OFF_MODE_ENABLE_
4624     prop_product_id = MakeAtom(XI_PROP_PRODUCT_ID, strlen(XI_PROP_PRODUCT_ID), TRUE);
4625     product[0] = pEvdev->id_vendor;
4626     product[1] = pEvdev->id_product;
4627     rc = XIChangeDeviceProperty(dev, prop_product_id, XA_INTEGER, 32,
4628                                 PropModeReplace, 2, product, FALSE);
4629     if (rc != Success)
4630         return;
4631
4632     XISetDevicePropertyDeletable(dev, prop_product_id, FALSE);
4633
4634     /* Device node property */
4635     device_node = strdup(pEvdev->device);
4636     prop_device = MakeAtom(XI_PROP_DEVICE_NODE,
4637                            strlen(XI_PROP_DEVICE_NODE), TRUE);
4638     if (device_node)
4639     {
4640         rc = XIChangeDeviceProperty(dev, prop_device, XA_STRING, 8,
4641                                     PropModeReplace,
4642                                     strlen(device_node), device_node,
4643                                     FALSE);
4644         free(device_node);
4645
4646         if (rc == Success)
4647             XISetDevicePropertyDeletable(dev, prop_device, FALSE);
4648     }
4649
4650 #ifdef _F_ENABLE_DEVICE_TYPE_PROP_
4651     /* Device node property */
4652     device_type = strdup(pInfo->type_name);
4653     prop_device_type = MakeAtom(XI_PROP_DEVICE_TYPE,
4654                            strlen(XI_PROP_DEVICE_TYPE), TRUE);
4655     if (device_type)
4656     {
4657         rc = XIChangeDeviceProperty(dev, prop_device_type, XA_STRING, 8,
4658                                     PropModeReplace,
4659                                     strlen(device_type), device_type,
4660                                     FALSE);
4661         free(device_type);
4662     }
4663 #endif /* #ifdef _F_ENABLE_DEVICE_TYPE_PROP_ */
4664
4665 #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_
4666     pEvdev->rel_move_status = 0;
4667
4668     /* Relative movement property */
4669     prop_relative_move_status = MakeAtom(XI_PROP_REL_MOVE_STATUS,
4670                                         strlen(XI_PROP_REL_MOVE_STATUS), TRUE);
4671     prop_relative_move_ack = MakeAtom(XI_PROP_REL_MOVE_ACK,
4672                                         strlen(XI_PROP_REL_MOVE_ACK), TRUE);
4673 #ifdef _F_BLOCK_MOTION_DEVICE_
4674     prop_block_motion_status = MakeAtom(XI_PROP_BLOCK_MOTION_DEVICE,
4675                                         strlen(XI_PROP_BLOCK_MOTION_DEVICE), TRUE);
4676 #endif //_F_BLOCK_MOTION_DEVICE_
4677     ErrorF("[%s] prop_relative_move_status = %d, prop_relative_move_ack = %d\n", __FUNCTION__, prop_relative_move_status, prop_relative_move_ack);
4678 #endif /* #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_ */
4679
4680     if (EvdevDeviceIsVirtual(pEvdev->device))
4681     {
4682         BOOL virtual = 1;
4683         prop_virtual = MakeAtom(XI_PROP_VIRTUAL_DEVICE,
4684                                 strlen(XI_PROP_VIRTUAL_DEVICE), TRUE);
4685         rc = XIChangeDeviceProperty(dev, prop_virtual, XA_INTEGER, 8,
4686                                     PropModeReplace, 1, &virtual, FALSE);
4687         XISetDevicePropertyDeletable(dev, prop_virtual, FALSE);
4688     }
4689
4690     XISetDevicePropertyDeletable(dev, prop_device, FALSE);
4691
4692 #ifdef _F_EVDEV_CONFINE_REGION_
4693     if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
4694     {
4695         prop_confine_region = MakeAtom(EVDEV_PROP_CONFINE_REGION,
4696                 strlen(EVDEV_PROP_CONFINE_REGION), TRUE);
4697         rc = XIChangeDeviceProperty(dev, prop_confine_region, XA_INTEGER,
4698                     32, PropModeReplace, 4, region, FALSE);
4699                     //here
4700                     //32, PropModeReplace, 6, region, FALSE);
4701
4702         if (rc != Success)
4703             return;
4704
4705         XISetDevicePropertyDeletable(dev, prop_confine_region, FALSE);
4706     }
4707 #endif /* #ifdef _F_EVDEV_CONFINE_REGION_ */
4708
4709 #ifdef _F_TOUCH_TRANSFORM_MATRIX_
4710     if (strstr(pInfo->type_name, XI_TOUCHSCREEN))
4711     {
4712         /* matrix to transform */
4713         prop_transform = MakeAtom(EVDEV_PROP_TOUCH_TRANSFORM_MATRIX, strlen(EVDEV_PROP_TOUCH_TRANSFORM_MATRIX),  TRUE);
4714         rc = XIChangeDeviceProperty(dev, prop_transform, XIGetKnownProperty(XATOM_FLOAT), 32, PropModeReplace, 9, pEvdev->transform, FALSE);
4715
4716         if (rc != Success)
4717             return;
4718
4719         XISetDevicePropertyDeletable(dev, prop_transform, FALSE);
4720     }
4721 #endif /* #ifdef _F_TOUCH_TRANSFORM_MATRIX_ */
4722
4723
4724     if (pEvdev->flags & (EVDEV_RELATIVE_EVENTS | EVDEV_ABSOLUTE_EVENTS))
4725     {
4726         BOOL invert[2];
4727         invert[0] = pEvdev->invert_x;
4728         invert[1] = pEvdev->invert_y;
4729
4730         prop_invert = MakeAtom(EVDEV_PROP_INVERT_AXES, strlen(EVDEV_PROP_INVERT_AXES), TRUE);
4731
4732         rc = XIChangeDeviceProperty(dev, prop_invert, XA_INTEGER, 8,
4733                 PropModeReplace, 2,
4734                 invert, FALSE);
4735         if (rc != Success)
4736             return;
4737
4738         XISetDevicePropertyDeletable(dev, prop_invert, FALSE);
4739
4740         prop_calibration = MakeAtom(EVDEV_PROP_CALIBRATION,
4741                 strlen(EVDEV_PROP_CALIBRATION), TRUE);
4742         if (pEvdev->flags & EVDEV_CALIBRATED) {
4743             int calibration[4];
4744
4745             calibration[0] = pEvdev->calibration.min_x;
4746             calibration[1] = pEvdev->calibration.max_x;
4747             calibration[2] = pEvdev->calibration.min_y;
4748             calibration[3] = pEvdev->calibration.max_y;
4749
4750             rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER,
4751                     32, PropModeReplace, 4, calibration,
4752                     FALSE);
4753         } else if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) {
4754             rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER,
4755                     32, PropModeReplace, 0, NULL,
4756                     FALSE);
4757         }
4758         if (rc != Success)
4759             return;
4760
4761         XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
4762
4763         prop_swap = MakeAtom(EVDEV_PROP_SWAP_AXES,
4764                 strlen(EVDEV_PROP_SWAP_AXES), TRUE);
4765
4766         rc = XIChangeDeviceProperty(dev, prop_swap, XA_INTEGER, 8,
4767                 PropModeReplace, 1, &pEvdev->swap_axes, FALSE);
4768         if (rc != Success)
4769             return;
4770
4771         XISetDevicePropertyDeletable(dev, prop_swap, FALSE);
4772
4773         /* Axis labelling */
4774         if ((pEvdev->num_vals > 0) && (prop_axis_label = XIGetKnownProperty(AXIS_LABEL_PROP)))
4775         {
4776             int mode;
4777             int num_axes = pEvdev->num_vals + pEvdev->num_mt_vals;
4778             Atom atoms[num_axes];
4779
4780             if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
4781                 mode = Absolute;
4782             else if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
4783                 mode = Relative;
4784             else {
4785                 xf86IDrvMsg(pInfo, X_ERROR, "BUG: mode is neither absolute nor relative\n");
4786                 mode = Absolute;
4787             }
4788
4789             EvdevInitAxesLabels(pEvdev, mode, num_axes, atoms);
4790             XIChangeDeviceProperty(dev, prop_axis_label, XA_ATOM, 32,
4791                                    PropModeReplace, num_axes, atoms, FALSE);
4792             XISetDevicePropertyDeletable(dev, prop_axis_label, FALSE);
4793         }
4794         /* Button labelling */
4795         if ((pEvdev->num_buttons > 0) && (prop_btn_label = XIGetKnownProperty(BTN_LABEL_PROP)))
4796         {
4797             Atom atoms[EVDEV_MAXBUTTONS];
4798             EvdevInitButtonLabels(pEvdev, EVDEV_MAXBUTTONS, atoms);
4799             XIChangeDeviceProperty(dev, prop_btn_label, XA_ATOM, 32,
4800                                    PropModeReplace, pEvdev->num_buttons, atoms, FALSE);
4801             XISetDevicePropertyDeletable(dev, prop_btn_label, FALSE);
4802         }
4803 #ifdef _F_SUPPORT_ROTATION_ANGLE_
4804         if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) {
4805             int rotation_angle;
4806             prop_rotation_angle = MakeAtom(EVDEV_PROP_ROTATION_ANGLE,
4807                                     strlen(EVDEV_PROP_ROTATION_ANGLE), TRUE);
4808
4809             rotation_angle = pEvdev->rotation_angle;
4810             rc = XIChangeDeviceProperty(dev, prop_rotation_angle, XA_INTEGER, 8,
4811                                     PropModeReplace, 1, &rotation_angle, TRUE);
4812             if (rc != Success)
4813                 return;
4814
4815             XISetDevicePropertyDeletable(dev, prop_rotation_angle, FALSE);
4816
4817             int rotation_node;
4818             prop_rotation_node = MakeAtom(EVDEV_PROP_ROTATION_NODE,
4819                                     strlen(EVDEV_PROP_ROTATION_NODE), TRUE);
4820
4821             rotation_node = pEvdev->rotation_node;
4822             rc = XIChangeDeviceProperty(dev, prop_rotation_node, XA_INTEGER, 32,
4823                                     PropModeReplace, 1, &rotation_node, FALSE);
4824             if (rc != Success)
4825                 return;
4826
4827             XISetDevicePropertyDeletable(dev, prop_rotation_node, FALSE);
4828         }
4829 #endif //_F_SUPPORT_ROTATION_ANGLE_
4830
4831 #ifdef _F_PROXY_DEVICE_ENABLED_
4832         slave_proxy = 0;
4833         prop_use_proxy_slave_device = MakeAtom(XI_PROP_USE_PROXY_SLAVE_DEVICE, strlen(XI_PROP_USE_PROXY_SLAVE_DEVICE), TRUE);
4834         XIChangeDeviceProperty(dev, prop_use_proxy_slave_device, XA_INTEGER, 8,
4835                                PropModeReplace, 1, &slave_proxy, FALSE);
4836         XISetDevicePropertyDeletable(dev, prop_use_proxy_slave_device, FALSE);
4837         pEvdev->proxy_device = NULL;
4838 #endif // _F_PROXY_DEVICE_ENABLED_
4839     }
4840 #ifdef _F_PROXY_DEVICE_ENABLED_
4841     slave_proxy = 0;
4842     prop_use_proxy_slave_device = MakeAtom(XI_PROP_USE_PROXY_SLAVE_DEVICE, strlen(XI_PROP_USE_PROXY_SLAVE_DEVICE), TRUE);
4843     XIChangeDeviceProperty(dev, prop_use_proxy_slave_device, XA_INTEGER, 8,
4844                            PropModeReplace, 1, &slave_proxy, FALSE);
4845     XISetDevicePropertyDeletable(dev, prop_use_proxy_slave_device, FALSE);
4846     pEvdev->proxy_device = NULL;
4847 #endif /* #ifdef _F_PROXY_DEVICE_ENABLED_ */
4848 }
4849
4850 static int
4851 EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
4852                  BOOL checkonly)
4853 {
4854     InputInfoPtr pInfo  = dev->public.devicePrivate;
4855     EvdevPtr     pEvdev = pInfo->private;
4856
4857     if (atom == prop_invert)
4858     {
4859         BOOL* data;
4860         if (val->format != 8 || val->size != 2 || val->type != XA_INTEGER)
4861             return BadMatch;
4862
4863         if (!checkonly)
4864         {
4865             data = (BOOL*)val->data;
4866             pEvdev->invert_x = data[0];
4867             pEvdev->invert_y = data[1];
4868         }
4869     } else if (atom == prop_calibration)
4870     {
4871         if (val->format != 32 || val->type != XA_INTEGER)
4872             return BadMatch;
4873         if (val->size != 4 && val->size != 0)
4874             return BadMatch;
4875
4876         if (!checkonly)
4877             EvdevSetCalibration(pInfo, val->size, val->data);
4878     } else if (atom == prop_swap)
4879     {
4880         if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
4881             return BadMatch;
4882
4883         if (!checkonly)
4884             pEvdev->swap_axes = *((BOOL*)val->data);
4885     } else if (atom == prop_axis_label || atom == prop_btn_label ||
4886                atom == prop_product_id || atom == prop_device ||
4887 #ifdef _F_ENABLE_DEVICE_TYPE_PROP_
4888                atom == prop_virtual || atom == prop_device_type)
4889 #else /* #ifdef _F_ENABLE_DEVICE_TYPE_PROP_ */
4890                atom == prop_virtual)
4891 #endif /* #ifdef _F_ENABLE_DEVICE_TYPE_PROP_ */
4892         return BadAccess; /* Read-only properties */
4893 #ifdef _F_TOUCH_TRANSFORM_MATRIX_
4894     else if (atom == prop_transform)
4895     {
4896         float *f;
4897
4898         if (val->format != 32 || val->type != XIGetKnownProperty(XATOM_FLOAT)
4899                         || ((val->size != 9) && (val->size != 1)))
4900             return BadMatch;
4901         if (!checkonly) {
4902             f = (float*)val->data;
4903             EvdevSetTransformMatrix(pInfo, val->size, f);
4904         }
4905     }
4906 #endif /* #ifdef _F_TOUCH_TRANSFORM_MATRIX_ */
4907 #ifdef _F_EVDEV_CONFINE_REGION_
4908     else if (atom == prop_confine_region)
4909     {
4910         if (val->format != 32 || val->type != XA_INTEGER)
4911             return BadMatch;
4912         if (val->size != 1 && val->size != 6)
4913             return BadMatch;
4914
4915         if (!checkonly)
4916             EvdevSetConfineRegion(pInfo, val->size, val->data);
4917     }
4918 #endif /* #ifdef _F_EVDEV_CONFINE_REGION_ */
4919 #ifdef _F_ENABLE_REL_MOVE_STATUS_PROP_
4920     else if (atom == prop_relative_move_ack)
4921     {
4922         int data;
4923
4924         if (val->format != 8 || val->type != XA_INTEGER)
4925             return BadMatch;
4926         if (val->size != 1)
4927             return BadMatch;
4928
4929         if (!checkonly) {
4930             data = *((CARD8*)val->data);
4931             pEvdev->rel_move_ack = data;
4932         }
4933
4934         if ((pEvdev->rel_move_ack == 2) || (pEvdev->rel_move_ack == 3))
4935         {
4936             if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
4937             TimerCancel(pEvdev->rel_move_timer);
4938             if (pEvdev->rel_move_timer == NULL) ErrorF("[%s:%d] pEvdev->rel_move_timer: %p\n", __FUNCTION__, __LINE__, pEvdev->rel_move_timer);
4939             pEvdev->rel_move_status = 0;
4940         }
4941     }
4942 #endif /* _F_ENABLE_REL_MOVE_STATUS_PROP_ */
4943 #ifdef _F_GESTURE_EXTENSION_
4944     else if (atom == XIGetKnownProperty(XI_PROP_ENABLED))
4945     {
4946         if (val->format != 8 || val->type != XA_INTEGER)
4947             return BadMatch;
4948
4949         if (val->size != 1)
4950             return BadMatch;
4951
4952         if (!checkonly && strcasestr(dev->name, "touchscreen"))
4953         {
4954             DeviceIntPtr device;
4955             for (device = inputInfo.devices; device; device = device->next)
4956             {
4957                 if(!strncmp(device->name, GESTURE_DEV_NAME, sizeof(GESTURE_DEV_NAME)-1))
4958                 {
4959                     InputInfoPtr gestureInfo = device->public.devicePrivate;
4960                     ErrorF("[EvdevSetProperty][id:%d] find device (%s)\n", device->id, device->name);
4961                     gestureInfo->device_control(device, DEVICE_READY);
4962                     break;
4963                 }
4964             }
4965         }
4966     }
4967 #endif //_F_GESTURE_EXTENSION_
4968
4969 #ifdef _F_SUPPORT_ROTATION_ANGLE_
4970     else if (atom == prop_rotation_angle)
4971     {
4972         int data;
4973         char cdata;
4974         if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
4975             return BadMatch;
4976
4977         if (!checkonly)
4978         {
4979             cdata = *((char*)val->data);
4980             data = (int)cdata;
4981
4982             EvdevSetRotationAngle(pEvdev, data);
4983         }
4984     }
4985 #endif //_F_SUPPORT_ROTATION_ANGLE_
4986
4987 #ifdef _F_PROXY_DEVICE_ENABLED_
4988     else if (atom == prop_use_proxy_slave_device)
4989     {
4990         int data;
4991
4992         if (val->format != 8 || val->type != XA_INTEGER)
4993             return BadMatch;
4994         if (val->size != 1)
4995             return BadMatch;
4996
4997         if (!pEvdev->proxy_enabled)
4998             return Success;
4999
5000         if (!checkonly) {
5001             data = *((CARD8*)val->data);
5002             EvdevSetProxyDevice(dev,data);
5003         }
5004     }
5005 #endif // #ifdef _F_PROXY_DEVICE_ENABLED_
5006 #ifdef _F_BLOCK_MOTION_DEVICE_
5007     else if (atom == prop_block_motion_status )
5008     {
5009         int data;
5010
5011         if (!checkonly) {
5012             data = *((CARD8*)val->data);
5013             block_motion_device = data;
5014         }
5015     }
5016     else if ((atom == atomPictureOffMode))
5017     {
5018         int data;
5019         data = *((CARD8*)val->data);
5020         pictureOffMode  = data;
5021     }
5022 #endif //_F_BLOCK_MOTION_DEVICE_
5023
5024     return Success;
5025 }
5026
5027 #ifdef _F_PROXY_DEVICE_ENABLED_
5028
5029 static int EvdevSetProxyDevice(DeviceIntPtr dev, int val)
5030 {
5031     InputInfoPtr pInfo  = dev->public.devicePrivate;
5032     EvdevPtr     pEvdev = pInfo->private;
5033     if(0 == val) {
5034         pEvdev->proxy_device = NULL;
5035     } else {
5036         if(NULL == pProxyDeviceInfo) {
5037                 pProxyDeviceInfo = EvdevCreateProxyDevice(pInfo);
5038         }
5039         pEvdev->proxy_device = pProxyDeviceInfo;
5040     }
5041     return 1;
5042 }
5043
5044 /* Duplicate xf86 options and convert them to InputOption */
5045 static InputOption *EvdevOptionDupConvert(pointer original)
5046 {
5047     InputOption *iopts = NULL, *new;
5048     InputInfoRec dummy;
5049
5050     memset(&dummy, 0, sizeof(dummy));
5051     dummy.options = xf86OptionListDuplicate(original);
5052
5053     while(dummy.options)
5054     {
5055         if (xf86NameCmp(xf86OptionName(dummy.options), "config_info") == 0) {
5056             /*should not copy config_info as its used by hotplugging layer*/
5057             dummy.options = xf86NextOption(dummy.options);
5058             continue;
5059         }
5060         new = calloc(1, sizeof(struct _InputOption));
5061         if (!new) return iopts;
5062
5063         new->opt_name = xf86OptionName(dummy.options);
5064         new->opt_val = xf86OptionValue(dummy.options);
5065         new->list.next = iopts;
5066         iopts = new;
5067         dummy.options = xf86NextOption(dummy.options);
5068     }
5069
5070     return iopts;
5071 }
5072
5073 static void EvdevFreeInputOpts(InputOption* opts)
5074 {
5075     InputOption *tmp = opts;
5076     while(opts)
5077     {
5078         tmp = opts->list.next;
5079         free(opts->opt_name);
5080         free(opts->opt_val);
5081         free(opts);
5082         opts = tmp;
5083     }
5084 }
5085
5086 static void EvdevReplaceOption(InputOption *opts,const char* key, char * value)
5087 {
5088     while(opts)
5089     {
5090         if (xf86NameCmp(opts->opt_name, key) == 0)
5091         {
5092             free(opts->opt_val);
5093             opts->opt_val = strdup(value);
5094         }
5095         opts = opts->list.next;
5096     }
5097 }
5098
5099
5100 /*
5101 * @return 0 if successful, 1 if failure pProxyDeviceInfo
5102 */
5103 static InputInfoPtr
5104 EvdevCreateProxyDevice(InputInfoPtr pInfo) {
5105     InputInfoPtr pProxyDev;
5106
5107     DeviceIntPtr dev; /* dummy */
5108     InputOption *input_options = NULL;
5109     char* name;
5110     char str_OPT_TYPE_VAL[sizeof(OPT_TYPE_VAL)];
5111     char str_dev_null[sizeof("/dev/null")];
5112
5113     pInfo->options = xf86AddNewOption(pInfo->options, "Type", "core");
5114     pInfo->options = xf86AddNewOption(pInfo->options, "SendCoreEvents", "on");
5115
5116     /* Create new device */
5117     input_options = EvdevOptionDupConvert(pInfo->options);
5118     snprintf(str_OPT_TYPE_VAL, sizeof(OPT_TYPE_VAL), OPT_TYPE_VAL);
5119     EvdevReplaceOption(input_options, "type",str_OPT_TYPE_VAL);
5120
5121     name = malloc( (strlen(PROXY_DEV_NAME) + 1)*sizeof(char));
5122
5123     if( !name )
5124     {
5125         EvdevFreeInputOpts(input_options);
5126         xf86DrvMsg(-1, X_ERROR, "[X11][%s] Failed to allocate memory !\n", __FUNCTION__);
5127         return NULL;
5128     }
5129
5130     snprintf(name, strlen(PROXY_DEV_NAME)+1, PROXY_DEV_NAME);
5131     snprintf(str_dev_null, sizeof("/dev/null"), "/dev/null");
5132     EvdevReplaceOption(input_options, "name",name);
5133     EvdevReplaceOption(input_options, "Device",str_dev_null);
5134     EvdevReplaceOption(input_options, "Path",str_dev_null);
5135
5136     pCreatorInfo = pInfo;
5137     NewInputDeviceRequest(input_options, NULL, &dev);
5138     pProxyDev = dev->public.devicePrivate;
5139     pCreatorInfo = NULL;
5140
5141     EvdevFreeInputOpts(input_options);
5142
5143     free(name);
5144     return pProxyDev;
5145 }
5146
5147 static void
5148 EvdevProxydevReadInput(InputInfoPtr pInfo)
5149 {
5150
5151 }
5152
5153 static void
5154 MakeClassesChangedEvent(DeviceChangedEvent *dce,
5155                           DeviceIntPtr master, DeviceIntPtr slave, int flags)
5156 {
5157     int i;
5158     CARD32 ms = GetTimeInMillis();
5159
5160     memset(dce, 0, sizeof(DeviceChangedEvent));
5161     dce->deviceid = slave->id;
5162     dce->masterid = master ? master->id : 0;
5163     dce->header = ET_Internal;
5164     dce->length = sizeof(DeviceChangedEvent);
5165     dce->type = ET_DeviceChanged;
5166     dce->time = ms;
5167     dce->flags = flags;
5168     dce->sourceid = slave->id;
5169
5170     if (slave->button) {
5171         dce->buttons.num_buttons = slave->button->numButtons;
5172         for (i = 0; i < dce->buttons.num_buttons; i++)
5173             dce->buttons.names[i] = slave->button->labels[i];
5174     }
5175     if (slave->valuator) {
5176         dce->num_valuators = slave->valuator->numAxes;
5177         for (i = 0; i < dce->num_valuators; i++) {
5178             dce->valuators[i].min = slave->valuator->axes[i].min_value;
5179             dce->valuators[i].max = slave->valuator->axes[i].max_value;
5180             dce->valuators[i].resolution = slave->valuator->axes[i].resolution;
5181             dce->valuators[i].mode = slave->valuator->axes[i].mode;
5182             dce->valuators[i].name = slave->valuator->axes[i].label;
5183             dce->valuators[i].scroll = slave->valuator->axes[i].scroll;
5184         }
5185     }
5186     if (slave->key) {
5187         dce->keys.min_keycode = slave->key->xkbInfo->desc->min_key_code;
5188         dce->keys.max_keycode = slave->key->xkbInfo->desc->max_key_code;
5189     }
5190 }
5191 #ifndef _F_PROXY_DEVICE_CHANGE_SOURCE_ID
5192 static void EvdevPostDevChangeEvent(InputInfoPtr pInfo)
5193 {
5194     DeviceChangedEvent event;
5195     DeviceIntPtr master = inputInfo.keyboard;
5196     DeviceIntPtr dummyDevice = pInfo->dev;
5197     int flag;
5198
5199     if(master->last.slave == dummyDevice) {
5200         return;
5201         }
5202
5203     flag = DEVCHANGE_KEYBOARD_EVENT | DEVCHANGE_SLAVE_SWITCH;
5204
5205     MakeClassesChangedEvent(&event,master,dummyDevice,flag);
5206
5207     master->last.slave = dummyDevice;
5208
5209     mieqEnqueue (dummyDevice, (InternalEvent*)&event);
5210 }
5211 #else /* _F_PROXY_DEVICE_CHANGE_SOURCE_ID */
5212 static void EvdevCheckDevChange(EvdevPtr pEvdev, int deviceid)
5213 {
5214     DeviceChangedEvent event;
5215     DeviceIntPtr master;
5216     DeviceIntPtr dummyDevice;
5217     int flag;
5218     if(!pProxyDeviceInfo || !pEvdev) return;
5219
5220     //if proxydevice is created but is not used by the current device,
5221     //reset the sourcedid of keyclass of the proxy device to its own id
5222     //and return..
5223     if(pProxyDeviceInfo && !pEvdev->proxy_device) {
5224         pProxyDeviceInfo->dev->key->sourceid = pProxyDeviceInfo->dev->id;
5225         return;
5226     }
5227
5228     master = inputInfo.keyboard;
5229     dummyDevice = pProxyDeviceInfo->dev;
5230
5231     //if nothing has changed.. return
5232     //the first check is for differentiating between attached slaves and the second
5233     //differentiates between the floating slaves represented by the proxy device
5234     if(master->last.slave == dummyDevice &&
5235         pProxyDeviceInfo->dev->key->sourceid == deviceid) {
5236         return;
5237     }
5238
5239     flag = DEVCHANGE_KEYBOARD_EVENT | DEVCHANGE_SLAVE_SWITCH;
5240
5241     MakeClassesChangedEvent(&event,master,dummyDevice,flag);
5242
5243     master->last.slave = dummyDevice;
5244
5245     //setting the source id of the device key class to the id of the actual slave it represents.
5246     //clients can query the same to know which device the actual events are coming from
5247     pProxyDeviceInfo->dev->key->sourceid = deviceid;
5248
5249     mieqEnqueue (dummyDevice, (InternalEvent*)&event);
5250 }
5251 #endif /* _F_PROXY_DEVICE_CHANGE_SOURCE_ID */
5252 #endif /* #ifdef _F_PROXY_DEVICE_ENABLED_ */