Setup 2.0alpha branch for IVI and add spec fix
[profile/ivi/xorg-x11-drv-evdev.git] / src / evdev.c
1 /*
2  * Copyright © 2004-2008 Red Hat, Inc.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software
5  * and its documentation for any purpose is hereby granted without
6  * fee, provided that the above copyright notice appear in all copies
7  * and that both that copyright notice and this permission notice
8  * appear in supporting documentation, and that the name of Red Hat
9  * not be used in advertising or publicity pertaining to distribution
10  * of the software without specific, written prior permission.  Red
11  * Hat makes no representations about the suitability of this software
12  * for any purpose.  It is provided "as is" without express or implied
13  * warranty.
14  *
15  * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17  * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Authors:
24  *      Kristian Høgsberg (krh@redhat.com)
25  *      Adam Jackson (ajax@redhat.com)
26  *      Peter Hutterer (peter.hutterer@redhat.com)
27  *      Oliver McFadden (oliver.mcfadden@nokia.com)
28  */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include <X11/keysym.h>
35
36 #include <sys/stat.h>
37 #include <unistd.h>
38 #include <errno.h>
39 #include <fcntl.h>
40
41 #include <xf86.h>
42 #include <xf86Xinput.h>
43 #include <exevents.h>
44 #include <xorgVersion.h>
45 #include <xkbsrv.h>
46
47 #include "evdev.h"
48 #ifdef _F_EVDEV_CONFINE_REGION_
49 #include <xorg/mipointrst.h>
50
51 #define MIPOINTER(dev) \
52     ((!IsMaster(dev) && !dev->master) ? \
53         (miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \
54         (miPointerPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miPointerPrivKey))
55
56 #endif /* _F_EVDEV_CONFINE_REGION_ */
57
58 #ifdef HAVE_PROPERTIES
59 #include <X11/Xatom.h>
60 #include <evdev-properties.h>
61 #include <xserver-properties.h>
62 /* 1.6 has properties, but no labels */
63 #ifdef AXIS_LABEL_PROP
64 #define HAVE_LABELS
65 #else
66 #undef HAVE_LABELS
67 #endif
68
69 #endif
70
71 #ifndef MAXDEVICES
72 #include <inputstr.h> /* for MAX_DEVICES */
73 #define MAXDEVICES MAX_DEVICES
74 #endif
75
76 /* 2.4 compatibility */
77 #ifndef EVIOCGRAB
78 #define EVIOCGRAB _IOW('E', 0x90, int)
79 #endif
80
81 #ifndef BTN_TASK
82 #define BTN_TASK 0x117
83 #endif
84
85 #ifndef EV_SYN
86 #define EV_SYN EV_RST
87 #endif
88 /* end compat */
89
90 #define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
91
92 /* evdev flags */
93 #define EVDEV_KEYBOARD_EVENTS   (1 << 0)
94 #define EVDEV_BUTTON_EVENTS     (1 << 1)
95 #define EVDEV_RELATIVE_EVENTS   (1 << 2)
96 #define EVDEV_ABSOLUTE_EVENTS   (1 << 3)
97 #define EVDEV_TOUCHPAD          (1 << 4)
98 #define EVDEV_INITIALIZED       (1 << 5) /* WheelInit etc. called already? */
99 #define EVDEV_TOUCHSCREEN       (1 << 6)
100 #define EVDEV_CALIBRATED        (1 << 7) /* run-time calibrated? */
101 #define EVDEV_TABLET            (1 << 8) /* device looks like a tablet? */
102 #define EVDEV_UNIGNORE_ABSOLUTE (1 << 9) /* explicitly unignore abs axes */
103 #define EVDEV_UNIGNORE_RELATIVE (1 << 10) /* explicitly unignore rel axes */
104 #define EVDEV_RESOLUTION (1 << 12) /* device looks like a multi-touch screen? */
105 #ifdef _F_EVDEV_CONFINE_REGION_
106 #define EVDEV_CONFINE_REGION    (1 << 13)
107 #endif /* _F_EVDEV_CONFINE_REGION_ */
108
109 #define MIN_KEYCODE 8
110 #define GLYPHS_PER_KEY 2
111 #define AltMask         Mod1Mask
112 #define NumLockMask     Mod2Mask
113 #define AltLangMask     Mod3Mask
114 #define KanaMask        Mod4Mask
115 #define ScrollLockMask  Mod5Mask
116
117 #define CAPSFLAG        1
118 #define NUMFLAG         2
119 #define SCROLLFLAG      4
120 #define MODEFLAG        8
121 #define COMPOSEFLAG     16
122
123 static const char *evdevDefaults[] = {
124     "XkbRules",     "evdev",
125     "XkbModel",     "evdev",
126     "XkbLayout",    "us",
127     NULL
128 };
129
130 static int EvdevOn(DeviceIntPtr);
131 static int EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare);
132 static void EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl);
133 static void EvdevSwapAxes(EvdevPtr pEvdev);
134 static void EvdevSetResolution(InputInfoPtr pInfo, int num_resolution, int resolution[4]);
135
136 #ifdef HAVE_PROPERTIES
137 static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
138 static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
139 static void EvdevInitProperty(DeviceIntPtr dev);
140 static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
141                             XIPropertyValuePtr val, BOOL checkonly);
142 #ifdef _F_EVDEV_CONFINE_REGION_
143 Bool IsMaster(DeviceIntPtr dev);
144 DeviceIntPtr GetPairedDevice(DeviceIntPtr dev);
145 DeviceIntPtr GetMaster(DeviceIntPtr dev, int which);
146 DeviceIntPtr GetMasterPointerFromId(int deviceid);
147 static void EvdevHookPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, BoxPtr pHotBox, BoxPtr pTopLeftBox);
148 static void EvdevHookPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox);
149 static void EvdevSetCursorLimits(InputInfoPtr pInfo, int region[5], int isSet);
150 static void EvdevSetConfineRegion(InputInfoPtr pInfo, int num_item, int region[5]);
151 static Atom prop_confine_region = 0;
152 #endif /* _F_EVDEV_CONFINE_REGION_ */
153 static Atom prop_invert = 0;
154 static Atom prop_reopen = 0;
155 static Atom prop_calibration = 0;
156 static Atom prop_swap = 0;
157 static Atom prop_axis_label = 0;
158 static Atom prop_btn_label = 0;
159 #endif
160
161 /* All devices the evdev driver has allocated and knows about.
162  * MAXDEVICES is safe as null-terminated array, as two devices (VCP and VCK)
163  * cannot be used by evdev, leaving us with a space of 2 at the end. */
164 static EvdevPtr evdev_devices[MAXDEVICES] = {NULL};
165
166 static size_t EvdevCountBits(unsigned long *array, size_t nlongs)
167 {
168     unsigned int i;
169     size_t count = 0;
170
171     for (i = 0; i < nlongs; i++) {
172         unsigned long x = array[i];
173
174         while (x > 0)
175         {
176             count += (x & 0x1);
177             x >>= 1;
178         }
179     }
180     return count;
181 }
182
183 static int
184 EvdevGetMajorMinor(InputInfoPtr pInfo)
185 {
186     struct stat st;
187
188     if (fstat(pInfo->fd, &st) == -1)
189     {
190         xf86Msg(X_ERROR, "%s: stat failed (%s). cannot check for duplicates.\n",
191                 pInfo->name, strerror(errno));
192         return 0;
193     }
194
195     return st.st_rdev;
196 }
197
198 /**
199  * Return TRUE if one of the devices we know about has the same min/maj
200  * number.
201  */
202 static BOOL
203 EvdevIsDuplicate(InputInfoPtr pInfo)
204 {
205     EvdevPtr pEvdev = pInfo->private;
206     EvdevPtr* dev   = evdev_devices;
207
208     if (pEvdev->min_maj)
209     {
210         while(*dev)
211         {
212             if ((*dev) != pEvdev &&
213                 (*dev)->min_maj &&
214                 (*dev)->min_maj == pEvdev->min_maj)
215                 return TRUE;
216             dev++;
217         }
218     }
219     return FALSE;
220 }
221
222 /**
223  * Add to internal device list.
224  */
225 static void
226 EvdevAddDevice(InputInfoPtr pInfo)
227 {
228     EvdevPtr pEvdev = pInfo->private;
229     EvdevPtr* dev = evdev_devices;
230
231     while(*dev)
232         dev++;
233
234     *dev = pEvdev;
235 }
236
237 /**
238  * Remove from internal device list.
239  */
240 static void
241 EvdevRemoveDevice(InputInfoPtr pInfo)
242 {
243     EvdevPtr pEvdev = pInfo->private;
244     EvdevPtr *dev   = evdev_devices;
245     int count       = 0;
246
247     while(*dev)
248     {
249         count++;
250         if (*dev == pEvdev)
251         {
252             memmove(dev, dev + 1,
253                     sizeof(evdev_devices) - (count * sizeof(EvdevPtr)));
254             break;
255         }
256         dev++;
257     }
258 }
259
260
261 static void
262 SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
263 {
264     char *s;
265
266     if ((s = xf86SetStrOption(pInfo->options, name, NULL))) {
267         if (!s[0]) {
268             free(s);
269             *option = NULL;
270         } else {
271             *option = s;
272         }
273     }
274 }
275
276 static int wheel_up_button = 4;
277 static int wheel_down_button = 5;
278 static int wheel_left_button = 6;
279 static int wheel_right_button = 7;
280
281 void
282 EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
283 {
284     int code = ev->code + MIN_KEYCODE;
285     static char warned[KEY_CNT];
286     EventQueuePtr pQueue;
287     EvdevPtr pEvdev = pInfo->private;
288
289     /* Filter all repeated events from device.
290        We'll do softrepeat in the server, but only since 1.6 */
291     if (value == 2
292 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) <= 2
293         && (ev->code == KEY_LEFTCTRL || ev->code == KEY_RIGHTCTRL ||
294             ev->code == KEY_LEFTSHIFT || ev->code == KEY_RIGHTSHIFT ||
295             ev->code == KEY_LEFTALT || ev->code == KEY_RIGHTALT ||
296             ev->code == KEY_LEFTMETA || ev->code == KEY_RIGHTMETA ||
297             ev->code == KEY_CAPSLOCK || ev->code == KEY_NUMLOCK ||
298             ev->code == KEY_SCROLLLOCK) /* XXX windows keys? */
299 #endif
300             )
301         return;
302
303     if (code > 255)
304     {
305         if (ev->code <= KEY_MAX && !warned[ev->code])
306         {
307             xf86Msg(X_WARNING, "%s: unable to handle keycode %d\n",
308                     pInfo->name, ev->code);
309             warned[ev->code] = 1;
310         }
311
312         /* The X server can't handle keycodes > 255. */
313         return;
314     }
315
316     if (pEvdev->num_queue >= EVDEV_MAXQUEUE)
317     {
318         xf86Msg(X_NONE, "%s: dropping event due to full queue!\n", pInfo->name);
319         return;
320     }
321
322     pQueue = &pEvdev->queue[pEvdev->num_queue];
323     pQueue->type = EV_QUEUE_KEY;
324     pQueue->key = code;
325     pQueue->val = value;
326     pEvdev->num_queue++;
327 }
328
329 void
330 EvdevQueueButtonEvent(InputInfoPtr pInfo, int button, int value)
331 {
332     EventQueuePtr pQueue;
333     EvdevPtr pEvdev = pInfo->private;
334
335     if (pEvdev->num_queue >= EVDEV_MAXQUEUE)
336     {
337         xf86Msg(X_NONE, "%s: dropping event due to full queue!\n", pInfo->name);
338         return;
339     }
340
341     pQueue = &pEvdev->queue[pEvdev->num_queue];
342     pQueue->type = EV_QUEUE_BTN;
343     pQueue->key = button;
344     pQueue->val = value;
345     pEvdev->num_queue++;
346 }
347
348 /**
349  * Post button event right here, right now.
350  * Interface for MB emulation since these need to post immediately.
351  */
352 void
353 EvdevPostButtonEvent(InputInfoPtr pInfo, int button, int value)
354 {
355     xf86PostButtonEvent(pInfo->dev, 0, button, value, 0, 0);
356 }
357
358 void
359 EvdevQueueButtonClicks(InputInfoPtr pInfo, int button, int count)
360 {
361     int i;
362
363     for (i = 0; i < count; i++) {
364         EvdevQueueButtonEvent(pInfo, button, 1);
365         EvdevQueueButtonEvent(pInfo, button, 0);
366     }
367 }
368
369 /**
370  * Coming back from resume may leave us with a file descriptor that can be
371  * opened but fails on the first read (ENODEV).
372  * In this case, try to open the device until it becomes available or until
373  * the predefined count expires.
374  */
375 static CARD32
376 EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
377 {
378     InputInfoPtr pInfo = (InputInfoPtr)arg;
379     EvdevPtr pEvdev = pInfo->private;
380
381     do {
382         pInfo->fd = open(pEvdev->device, O_RDWR | O_NONBLOCK, 0);
383     } while (pInfo->fd < 0 && errno == EINTR);
384
385     if (pInfo->fd != -1)
386     {
387         if (EvdevCacheCompare(pInfo, TRUE) == Success)
388         {
389             xf86Msg(X_INFO, "%s: Device reopened after %d attempts.\n", pInfo->name,
390                     pEvdev->reopen_attempts - pEvdev->reopen_left + 1);
391             EvdevOn(pInfo->dev);
392         } else
393         {
394             xf86Msg(X_ERROR, "%s: Device has changed - disabling.\n",
395                     pInfo->name);
396             xf86DisableDevice(pInfo->dev, FALSE);
397             close(pInfo->fd);
398             pInfo->fd = -1;
399             pEvdev->min_maj = 0; /* don't hog the device */
400         }
401         pEvdev->reopen_left = 0;
402         return 0;
403     }
404
405     pEvdev->reopen_left--;
406
407     if (!pEvdev->reopen_left)
408     {
409         xf86Msg(X_ERROR, "%s: Failed to reopen device after %d attempts.\n",
410                 pInfo->name, pEvdev->reopen_attempts);
411         xf86DisableDevice(pInfo->dev, FALSE);
412         pEvdev->min_maj = 0; /* don't hog the device */
413         return 0;
414     }
415
416     return 100; /* come back in 100 ms */
417 }
418
419 #define ABS_X_VALUE 0x1
420 #define ABS_Y_VALUE 0x2
421 #define ABS_VALUE   0x4
422 /**
423  * Take the valuators and process them accordingly.
424  */
425 static void
426 EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
427                       int *first_v)
428 {
429     int tmp;
430     EvdevPtr pEvdev = pInfo->private;
431
432     *num_v = *first_v = 0;
433
434     /* convert to relative motion for touchpads */
435     if (pEvdev->abs && (pEvdev->flags & EVDEV_TOUCHPAD)) {
436         if (pEvdev->tool) { /* meaning, touch is active */
437             if (pEvdev->old_vals[0] != -1)
438                 pEvdev->delta[REL_X] = pEvdev->vals[0] - pEvdev->old_vals[0];
439             if (pEvdev->old_vals[1] != -1)
440                 pEvdev->delta[REL_Y] = pEvdev->vals[1] - pEvdev->old_vals[1];
441             if (pEvdev->abs & ABS_X_VALUE)
442                 pEvdev->old_vals[0] = pEvdev->vals[0];
443             if (pEvdev->abs & ABS_Y_VALUE)
444                 pEvdev->old_vals[1] = pEvdev->vals[1];
445         } else {
446             pEvdev->old_vals[0] = pEvdev->old_vals[1] = -1;
447         }
448         pEvdev->abs = 0;
449         pEvdev->rel = 1;
450     }
451
452     if (pEvdev->rel) {
453         int first = REL_CNT, last = 0;
454         int i;
455
456         if (pEvdev->swap_axes) {
457             tmp = pEvdev->delta[REL_X];
458             pEvdev->delta[REL_X] = pEvdev->delta[REL_Y];
459             pEvdev->delta[REL_Y] = tmp;
460         }
461         if (pEvdev->invert_x)
462             pEvdev->delta[REL_X] *= -1;
463         if (pEvdev->invert_y)
464             pEvdev->delta[REL_Y] *= -1;
465
466         for (i = 0; i < REL_CNT; i++)
467         {
468             int map = pEvdev->axis_map[i];
469             if (map != -1)
470             {
471                 v[map] = pEvdev->delta[i];
472                 if (map < first)
473                     first = map;
474                 if (map > last)
475                     last = map;
476             }
477         }
478
479         *num_v = (last - first + 1);
480         *first_v = first;
481     }
482     /*
483      * Some devices only generate valid abs coords when BTN_DIGI is
484      * pressed.  On wacom tablets, this means that the pen is in
485      * proximity of the tablet.  After the pen is removed, BTN_DIGI is
486      * released, and a (0, 0) absolute event is generated.  Checking
487      * pEvdev->digi here, lets us ignore that event.  pEvdev is
488      * initialized to 1 so devices that doesn't use this scheme still
489      * just works.
490      */
491     else if (pEvdev->abs && pEvdev->tool) {
492         memcpy(v, pEvdev->vals, sizeof(int) * pEvdev->num_vals);
493
494         if (pEvdev->swap_axes) {
495             int tmp = v[0];
496             v[0] = v[1];
497             v[1] = tmp;
498         }
499
500         if (pEvdev->flags & EVDEV_CALIBRATED)
501         {
502             v[0] = xf86ScaleAxis(v[0],
503                     pEvdev->absinfo[ABS_X].maximum,
504                     pEvdev->absinfo[ABS_X].minimum,
505                     pEvdev->calibration.max_x, pEvdev->calibration.min_x);
506             v[1] = xf86ScaleAxis(v[1],
507                     pEvdev->absinfo[ABS_Y].maximum,
508                     pEvdev->absinfo[ABS_Y].minimum,
509                     pEvdev->calibration.max_y, pEvdev->calibration.min_y);
510         }
511
512         if (pEvdev->invert_x)
513             v[0] = (pEvdev->absinfo[ABS_X].maximum - v[0] +
514                     pEvdev->absinfo[ABS_X].minimum);
515         if (pEvdev->invert_y)
516             v[1] = (pEvdev->absinfo[ABS_Y].maximum - v[1] +
517                     pEvdev->absinfo[ABS_Y].minimum);
518
519         *num_v = pEvdev->num_vals;
520         *first_v = 0;
521     }
522 }
523
524 /**
525  * Take a button input event and process it accordingly.
526  */
527 static void
528 EvdevProcessButtonEvent(InputInfoPtr pInfo, struct input_event *ev)
529 {
530     unsigned int button;
531     int value;
532     EvdevPtr pEvdev = pInfo->private;
533
534     button = EvdevUtilButtonEventToButtonNumber(pEvdev, ev->code);
535
536     /* Get the signed value, earlier kernels had this as unsigned */
537     value = ev->value;
538
539     /* Handle drag lock */
540     if (EvdevDragLockFilterEvent(pInfo, button, value))
541         return;
542
543     if (EvdevWheelEmuFilterButton(pInfo, button, value))
544         return;
545
546     if (EvdevMBEmuFilterEvent(pInfo, button, value))
547         return;
548
549     if (button)
550         EvdevQueueButtonEvent(pInfo, button, value);
551     else
552         EvdevQueueKbdEvent(pInfo, ev, value);
553 }
554
555 /**
556  * Take the relative motion input event and process it accordingly.
557  */
558 static void
559 EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
560 {
561     static int value;
562     EvdevPtr pEvdev = pInfo->private;
563
564     /* Get the signed value, earlier kernels had this as unsigned */
565     value = ev->value;
566
567     pEvdev->rel = 1;
568
569     switch (ev->code) {
570         case REL_WHEEL:
571             if (value > 0)
572                 EvdevQueueButtonClicks(pInfo, wheel_up_button, value);
573             else if (value < 0)
574                 EvdevQueueButtonClicks(pInfo, wheel_down_button, -value);
575             break;
576
577         case REL_DIAL:
578         case REL_HWHEEL:
579             if (value > 0)
580                 EvdevQueueButtonClicks(pInfo, wheel_right_button, value);
581             else if (value < 0)
582                 EvdevQueueButtonClicks(pInfo, wheel_left_button, -value);
583             break;
584
585         /* We don't post wheel events as axis motion. */
586         default:
587             /* Ignore EV_REL events if we never set up for them. */
588             if (!(pEvdev->flags & EVDEV_RELATIVE_EVENTS))
589                 return;
590
591             /* Handle mouse wheel emulation */
592             if (EvdevWheelEmuFilterMotion(pInfo, ev))
593                 return;
594
595             pEvdev->delta[ev->code] += value;
596             break;
597     }
598 }
599
600 /**
601  * Take the absolute motion input event and process it accordingly.
602  */
603 static void
604 EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
605 {
606     static int value;
607     EvdevPtr pEvdev = pInfo->private;
608
609     /* Get the signed value, earlier kernels had this as unsigned */
610     value = ev->value;
611
612     /* Ignore EV_ABS events if we never set up for them. */
613     if (!(pEvdev->flags & EVDEV_ABSOLUTE_EVENTS))
614         return;
615
616     if (ev->code > ABS_MAX)
617         return;
618
619     pEvdev->vals[pEvdev->axis_map[ev->code]] = value;
620     if (ev->code == ABS_X)
621         pEvdev->abs |= ABS_X_VALUE;
622     else if (ev->code == ABS_Y)
623         pEvdev->abs |= ABS_Y_VALUE;
624     else
625         pEvdev->abs |= ABS_VALUE;
626 }
627
628 /**
629  * Take the key press/release input event and process it accordingly.
630  */
631 static void
632 EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev)
633 {
634     static int value;
635     EvdevPtr pEvdev = pInfo->private;
636
637     /* Get the signed value, earlier kernels had this as unsigned */
638     value = ev->value;
639
640     /* don't repeat mouse buttons */
641     if (ev->code >= BTN_MOUSE && ev->code < KEY_OK)
642         if (value == 2)
643             return;
644
645     switch (ev->code) {
646         case BTN_TOOL_PEN:
647         case BTN_TOOL_RUBBER:
648         case BTN_TOOL_BRUSH:
649         case BTN_TOOL_PENCIL:
650         case BTN_TOOL_AIRBRUSH:
651         case BTN_TOOL_FINGER:
652         case BTN_TOOL_MOUSE:
653         case BTN_TOOL_LENS:
654             pEvdev->tool = value ? ev->code : 0;
655             break;
656
657         case BTN_TOUCH:
658             pEvdev->tool = value ? ev->code : 0;
659             if (!(pEvdev->flags & (EVDEV_TOUCHSCREEN | EVDEV_TABLET)))
660                 break;
661             /* Treat BTN_TOUCH from devices that only have BTN_TOUCH as
662              * BTN_LEFT. */
663             ev->code = BTN_LEFT;
664             /* Intentional fallthrough! */
665
666         default:
667             EvdevProcessButtonEvent(pInfo, ev);
668             break;
669     }
670 }
671
672 /**
673  * Post the relative motion events.
674  */
675 void
676 EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
677                               int v[MAX_VALUATORS])
678 {
679     EvdevPtr pEvdev = pInfo->private;
680
681     if (pEvdev->rel) {
682         xf86PostMotionEventP(pInfo->dev, FALSE, *first_v, *num_v, v + *first_v);
683     }
684 }
685
686 /**
687  * Post the absolute motion events.
688  */
689 void
690 EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
691                               int v[MAX_VALUATORS])
692 {
693     EvdevPtr pEvdev = pInfo->private;
694
695     /*
696      * Some devices only generate valid abs coords when BTN_DIGI is
697      * pressed.  On wacom tablets, this means that the pen is in
698      * proximity of the tablet.  After the pen is removed, BTN_DIGI is
699      * released, and a (0, 0) absolute event is generated.  Checking
700      * pEvdev->digi here, lets us ignore that event.  pEvdev is
701      * initialized to 1 so devices that doesn't use this scheme still
702      * just works.
703      */
704     if (pEvdev->abs && pEvdev->tool)
705         xf86PostMotionEventP(pInfo->dev, TRUE, *first_v, *num_v, v);
706 }
707
708 /**
709  * Post the queued key/button events.
710  */
711 static void EvdevPostQueuedEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
712                                   int v[MAX_VALUATORS])
713 {
714     int i;
715     EvdevPtr pEvdev = pInfo->private;
716
717     for (i = 0; i < pEvdev->num_queue; i++) {
718         switch (pEvdev->queue[i].type) {
719         case EV_QUEUE_KEY:
720             xf86PostKeyboardEvent(pInfo->dev, pEvdev->queue[i].key,
721                                   pEvdev->queue[i].val);
722             break;
723         case EV_QUEUE_BTN:
724             /* FIXME: Add xf86PostButtonEventP to the X server so that we may
725              * pass the valuators on ButtonPress/Release events, too.  Currently
726              * only MotionNotify events contain the pointer position. */
727             xf86PostButtonEvent(pInfo->dev, 0, pEvdev->queue[i].key,
728                                 pEvdev->queue[i].val, 0, 0);
729             break;
730         }
731     }
732 }
733
734 /**
735  * Take the synchronization input event and process it accordingly; the motion
736  * notify events are sent first, then any button/key press/release events.
737  */
738 static void
739 EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
740 {
741     int num_v = 0, first_v = 0;
742     int v[MAX_VALUATORS];
743     EvdevPtr pEvdev = pInfo->private;
744
745     EvdevProcessValuators(pInfo, v, &num_v, &first_v);
746
747     EvdevPostRelativeMotionEvents(pInfo, &num_v, &first_v, v);
748     EvdevPostAbsoluteMotionEvents(pInfo, &num_v, &first_v, v);
749     EvdevPostQueuedEvents(pInfo, &num_v, &first_v, v);
750
751     memset(pEvdev->delta, 0, sizeof(pEvdev->delta));
752     memset(pEvdev->queue, 0, sizeof(pEvdev->queue));
753     pEvdev->num_queue = 0;
754     pEvdev->abs = 0;
755     pEvdev->rel = 0;
756 }
757
758 /**
759  * Process the events from the device; nothing is actually posted to the server
760  * until an EV_SYN event is received.
761  */
762 static void
763 EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
764 {
765     switch (ev->type) {
766         case EV_REL:
767             EvdevProcessRelativeMotionEvent(pInfo, ev);
768             break;
769         case EV_ABS:
770             EvdevProcessAbsoluteMotionEvent(pInfo, ev);
771             break;
772         case EV_KEY:
773             EvdevProcessKeyEvent(pInfo, ev);
774             break;
775         case EV_SYN:
776             EvdevProcessSyncEvent(pInfo, ev);
777             break;
778     }
779 }
780
781 #undef ABS_X_VALUE
782 #undef ABS_Y_VALUE
783 #undef ABS_VALUE
784
785 /* just a magic number to reduce the number of reads */
786 #define NUM_EVENTS 16
787
788 static void
789 EvdevReadInput(InputInfoPtr pInfo)
790 {
791     struct input_event ev[NUM_EVENTS];
792     int i, len = sizeof(ev);
793     EvdevPtr pEvdev = pInfo->private;
794
795     while (len == sizeof(ev))
796     {
797         len = read(pInfo->fd, &ev, sizeof(ev));
798         if (len <= 0)
799         {
800             if (errno == ENODEV) /* May happen after resume */
801             {
802                 EvdevMBEmuFinalize(pInfo);
803                 xf86RemoveEnabledDevice(pInfo);
804                 close(pInfo->fd);
805                 pInfo->fd = -1;
806                 if (pEvdev->reopen_timer)
807                 {
808                     pEvdev->reopen_left = pEvdev->reopen_attempts;
809                     pEvdev->reopen_timer = TimerSet(pEvdev->reopen_timer, 0, 100, EvdevReopenTimer, pInfo);
810                 }
811             } else if (errno != EAGAIN)
812             {
813                 /* We use X_NONE here because it doesn't alloc */
814                 xf86MsgVerb(X_NONE, 0, "%s: Read error: %s\n", pInfo->name,
815                         strerror(errno));
816             }
817             break;
818         }
819
820         /* The kernel promises that we always only read a complete
821          * event, so len != sizeof ev is an error. */
822         if (len % sizeof(ev[0])) {
823             /* We use X_NONE here because it doesn't alloc */
824             xf86MsgVerb(X_NONE, 0, "%s: Read error: %s\n", pInfo->name, strerror(errno));
825             break;
826         }
827
828         for (i = 0; i < len/sizeof(ev[0]); i++)
829             EvdevProcessEvent(pInfo, &ev[i]);
830     }
831 }
832
833 #define TestBit(bit, array) ((array[(bit) / LONG_BITS]) & (1L << ((bit) % LONG_BITS)))
834
835 static void
836 EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
837 {
838     /* Nothing to do, dix handles all settings */
839 }
840
841 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 5
842 static KeySym map[] = {
843     /* 0x00 */  NoSymbol,       NoSymbol,
844     /* 0x01 */  XK_Escape,      NoSymbol,
845     /* 0x02 */  XK_1,           XK_exclam,
846     /* 0x03 */  XK_2,           XK_at,
847     /* 0x04 */  XK_3,           XK_numbersign,
848     /* 0x05 */  XK_4,           XK_dollar,
849     /* 0x06 */  XK_5,           XK_percent,
850     /* 0x07 */  XK_6,           XK_asciicircum,
851     /* 0x08 */  XK_7,           XK_ampersand,
852     /* 0x09 */  XK_8,           XK_asterisk,
853     /* 0x0a */  XK_9,           XK_parenleft,
854     /* 0x0b */  XK_0,           XK_parenright,
855     /* 0x0c */  XK_minus,       XK_underscore,
856     /* 0x0d */  XK_equal,       XK_plus,
857     /* 0x0e */  XK_BackSpace,   NoSymbol,
858     /* 0x0f */  XK_Tab,         XK_ISO_Left_Tab,
859     /* 0x10 */  XK_Q,           NoSymbol,
860     /* 0x11 */  XK_W,           NoSymbol,
861     /* 0x12 */  XK_E,           NoSymbol,
862     /* 0x13 */  XK_R,           NoSymbol,
863     /* 0x14 */  XK_T,           NoSymbol,
864     /* 0x15 */  XK_Y,           NoSymbol,
865     /* 0x16 */  XK_U,           NoSymbol,
866     /* 0x17 */  XK_I,           NoSymbol,
867     /* 0x18 */  XK_O,           NoSymbol,
868     /* 0x19 */  XK_P,           NoSymbol,
869     /* 0x1a */  XK_bracketleft, XK_braceleft,
870     /* 0x1b */  XK_bracketright,XK_braceright,
871     /* 0x1c */  XK_Return,      NoSymbol,
872     /* 0x1d */  XK_Control_L,   NoSymbol,
873     /* 0x1e */  XK_A,           NoSymbol,
874     /* 0x1f */  XK_S,           NoSymbol,
875     /* 0x20 */  XK_D,           NoSymbol,
876     /* 0x21 */  XK_F,           NoSymbol,
877     /* 0x22 */  XK_G,           NoSymbol,
878     /* 0x23 */  XK_H,           NoSymbol,
879     /* 0x24 */  XK_J,           NoSymbol,
880     /* 0x25 */  XK_K,           NoSymbol,
881     /* 0x26 */  XK_L,           NoSymbol,
882     /* 0x27 */  XK_semicolon,   XK_colon,
883     /* 0x28 */  XK_quoteright,  XK_quotedbl,
884     /* 0x29 */  XK_quoteleft,   XK_asciitilde,
885     /* 0x2a */  XK_Shift_L,     NoSymbol,
886     /* 0x2b */  XK_backslash,   XK_bar,
887     /* 0x2c */  XK_Z,           NoSymbol,
888     /* 0x2d */  XK_X,           NoSymbol,
889     /* 0x2e */  XK_C,           NoSymbol,
890     /* 0x2f */  XK_V,           NoSymbol,
891     /* 0x30 */  XK_B,           NoSymbol,
892     /* 0x31 */  XK_N,           NoSymbol,
893     /* 0x32 */  XK_M,           NoSymbol,
894     /* 0x33 */  XK_comma,       XK_less,
895     /* 0x34 */  XK_period,      XK_greater,
896     /* 0x35 */  XK_slash,       XK_question,
897     /* 0x36 */  XK_Shift_R,     NoSymbol,
898     /* 0x37 */  XK_KP_Multiply, NoSymbol,
899     /* 0x38 */  XK_Alt_L,       XK_Meta_L,
900     /* 0x39 */  XK_space,       NoSymbol,
901     /* 0x3a */  XK_Caps_Lock,   NoSymbol,
902     /* 0x3b */  XK_F1,          NoSymbol,
903     /* 0x3c */  XK_F2,          NoSymbol,
904     /* 0x3d */  XK_F3,          NoSymbol,
905     /* 0x3e */  XK_F4,          NoSymbol,
906     /* 0x3f */  XK_F5,          NoSymbol,
907     /* 0x40 */  XK_F6,          NoSymbol,
908     /* 0x41 */  XK_F7,          NoSymbol,
909     /* 0x42 */  XK_F8,          NoSymbol,
910     /* 0x43 */  XK_F9,          NoSymbol,
911     /* 0x44 */  XK_F10,         NoSymbol,
912     /* 0x45 */  XK_Num_Lock,    NoSymbol,
913     /* 0x46 */  XK_Scroll_Lock, NoSymbol,
914     /* These KP keys should have the KP_7 keysyms in the numlock
915      * modifer... ? */
916     /* 0x47 */  XK_KP_Home,     XK_KP_7,
917     /* 0x48 */  XK_KP_Up,       XK_KP_8,
918     /* 0x49 */  XK_KP_Prior,    XK_KP_9,
919     /* 0x4a */  XK_KP_Subtract, NoSymbol,
920     /* 0x4b */  XK_KP_Left,     XK_KP_4,
921     /* 0x4c */  XK_KP_Begin,    XK_KP_5,
922     /* 0x4d */  XK_KP_Right,    XK_KP_6,
923     /* 0x4e */  XK_KP_Add,      NoSymbol,
924     /* 0x4f */  XK_KP_End,      XK_KP_1,
925     /* 0x50 */  XK_KP_Down,     XK_KP_2,
926     /* 0x51 */  XK_KP_Next,     XK_KP_3,
927     /* 0x52 */  XK_KP_Insert,   XK_KP_0,
928     /* 0x53 */  XK_KP_Delete,   XK_KP_Decimal,
929     /* 0x54 */  NoSymbol,       NoSymbol,
930     /* 0x55 */  XK_F13,         NoSymbol,
931     /* 0x56 */  XK_less,        XK_greater,
932     /* 0x57 */  XK_F11,         NoSymbol,
933     /* 0x58 */  XK_F12,         NoSymbol,
934     /* 0x59 */  XK_F14,         NoSymbol,
935     /* 0x5a */  XK_F15,         NoSymbol,
936     /* 0x5b */  XK_F16,         NoSymbol,
937     /* 0x5c */  XK_F17,         NoSymbol,
938     /* 0x5d */  XK_F18,         NoSymbol,
939     /* 0x5e */  XK_F19,         NoSymbol,
940     /* 0x5f */  XK_F20,         NoSymbol,
941     /* 0x60 */  XK_KP_Enter,    NoSymbol,
942     /* 0x61 */  XK_Control_R,   NoSymbol,
943     /* 0x62 */  XK_KP_Divide,   NoSymbol,
944     /* 0x63 */  XK_Print,       XK_Sys_Req,
945     /* 0x64 */  XK_Alt_R,       XK_Meta_R,
946     /* 0x65 */  NoSymbol,       NoSymbol, /* KEY_LINEFEED */
947     /* 0x66 */  XK_Home,        NoSymbol,
948     /* 0x67 */  XK_Up,          NoSymbol,
949     /* 0x68 */  XK_Prior,       NoSymbol,
950     /* 0x69 */  XK_Left,        NoSymbol,
951     /* 0x6a */  XK_Right,       NoSymbol,
952     /* 0x6b */  XK_End,         NoSymbol,
953     /* 0x6c */  XK_Down,        NoSymbol,
954     /* 0x6d */  XK_Next,        NoSymbol,
955     /* 0x6e */  XK_Insert,      NoSymbol,
956     /* 0x6f */  XK_Delete,      NoSymbol,
957     /* 0x70 */  NoSymbol,       NoSymbol, /* KEY_MACRO */
958     /* 0x71 */  NoSymbol,       NoSymbol,
959     /* 0x72 */  NoSymbol,       NoSymbol,
960     /* 0x73 */  NoSymbol,       NoSymbol,
961     /* 0x74 */  NoSymbol,       NoSymbol,
962     /* 0x75 */  XK_KP_Equal,    NoSymbol,
963     /* 0x76 */  NoSymbol,       NoSymbol,
964     /* 0x77 */  NoSymbol,       NoSymbol,
965     /* 0x78 */  XK_F21,         NoSymbol,
966     /* 0x79 */  XK_F22,         NoSymbol,
967     /* 0x7a */  XK_F23,         NoSymbol,
968     /* 0x7b */  XK_F24,         NoSymbol,
969     /* 0x7c */  XK_KP_Separator, NoSymbol,
970     /* 0x7d */  XK_Meta_L,      NoSymbol,
971     /* 0x7e */  XK_Meta_R,      NoSymbol,
972     /* 0x7f */  XK_Multi_key,   NoSymbol,
973     /* 0x80 */  NoSymbol,       NoSymbol,
974     /* 0x81 */  NoSymbol,       NoSymbol,
975     /* 0x82 */  NoSymbol,       NoSymbol,
976     /* 0x83 */  NoSymbol,       NoSymbol,
977     /* 0x84 */  NoSymbol,       NoSymbol,
978     /* 0x85 */  NoSymbol,       NoSymbol,
979     /* 0x86 */  NoSymbol,       NoSymbol,
980     /* 0x87 */  NoSymbol,       NoSymbol,
981     /* 0x88 */  NoSymbol,       NoSymbol,
982     /* 0x89 */  NoSymbol,       NoSymbol,
983     /* 0x8a */  NoSymbol,       NoSymbol,
984     /* 0x8b */  NoSymbol,       NoSymbol,
985     /* 0x8c */  NoSymbol,       NoSymbol,
986     /* 0x8d */  NoSymbol,       NoSymbol,
987     /* 0x8e */  NoSymbol,       NoSymbol,
988     /* 0x8f */  NoSymbol,       NoSymbol,
989     /* 0x90 */  NoSymbol,       NoSymbol,
990     /* 0x91 */  NoSymbol,       NoSymbol,
991     /* 0x92 */  NoSymbol,       NoSymbol,
992     /* 0x93 */  NoSymbol,       NoSymbol,
993     /* 0x94 */  NoSymbol,       NoSymbol,
994     /* 0x95 */  NoSymbol,       NoSymbol,
995     /* 0x96 */  NoSymbol,       NoSymbol,
996     /* 0x97 */  NoSymbol,       NoSymbol,
997     /* 0x98 */  NoSymbol,       NoSymbol,
998     /* 0x99 */  NoSymbol,       NoSymbol,
999     /* 0x9a */  NoSymbol,       NoSymbol,
1000     /* 0x9b */  NoSymbol,       NoSymbol,
1001     /* 0x9c */  NoSymbol,       NoSymbol,
1002     /* 0x9d */  NoSymbol,       NoSymbol,
1003     /* 0x9e */  NoSymbol,       NoSymbol,
1004     /* 0x9f */  NoSymbol,       NoSymbol,
1005     /* 0xa0 */  NoSymbol,       NoSymbol,
1006     /* 0xa1 */  NoSymbol,       NoSymbol,
1007     /* 0xa2 */  NoSymbol,       NoSymbol,
1008     /* 0xa3 */  NoSymbol,       NoSymbol,
1009     /* 0xa4 */  NoSymbol,       NoSymbol,
1010     /* 0xa5 */  NoSymbol,       NoSymbol,
1011     /* 0xa6 */  NoSymbol,       NoSymbol,
1012     /* 0xa7 */  NoSymbol,       NoSymbol,
1013     /* 0xa8 */  NoSymbol,       NoSymbol,
1014     /* 0xa9 */  NoSymbol,       NoSymbol,
1015     /* 0xaa */  NoSymbol,       NoSymbol,
1016     /* 0xab */  NoSymbol,       NoSymbol,
1017     /* 0xac */  NoSymbol,       NoSymbol,
1018     /* 0xad */  NoSymbol,       NoSymbol,
1019     /* 0xae */  NoSymbol,       NoSymbol,
1020     /* 0xaf */  NoSymbol,       NoSymbol,
1021     /* 0xb0 */  NoSymbol,       NoSymbol,
1022     /* 0xb1 */  NoSymbol,       NoSymbol,
1023     /* 0xb2 */  NoSymbol,       NoSymbol,
1024     /* 0xb3 */  NoSymbol,       NoSymbol,
1025     /* 0xb4 */  NoSymbol,       NoSymbol,
1026     /* 0xb5 */  NoSymbol,       NoSymbol,
1027     /* 0xb6 */  NoSymbol,       NoSymbol,
1028     /* 0xb7 */  NoSymbol,       NoSymbol,
1029     /* 0xb8 */  NoSymbol,       NoSymbol,
1030     /* 0xb9 */  NoSymbol,       NoSymbol,
1031     /* 0xba */  NoSymbol,       NoSymbol,
1032     /* 0xbb */  NoSymbol,       NoSymbol,
1033     /* 0xbc */  NoSymbol,       NoSymbol,
1034     /* 0xbd */  NoSymbol,       NoSymbol,
1035     /* 0xbe */  NoSymbol,       NoSymbol,
1036     /* 0xbf */  NoSymbol,       NoSymbol,
1037     /* 0xc0 */  NoSymbol,       NoSymbol,
1038     /* 0xc1 */  NoSymbol,       NoSymbol,
1039     /* 0xc2 */  NoSymbol,       NoSymbol,
1040     /* 0xc3 */  NoSymbol,       NoSymbol,
1041     /* 0xc4 */  NoSymbol,       NoSymbol,
1042     /* 0xc5 */  NoSymbol,       NoSymbol,
1043     /* 0xc6 */  NoSymbol,       NoSymbol,
1044     /* 0xc7 */  NoSymbol,       NoSymbol,
1045     /* 0xc8 */  NoSymbol,       NoSymbol,
1046     /* 0xc9 */  NoSymbol,       NoSymbol,
1047     /* 0xca */  NoSymbol,       NoSymbol,
1048     /* 0xcb */  NoSymbol,       NoSymbol,
1049     /* 0xcc */  NoSymbol,       NoSymbol,
1050     /* 0xcd */  NoSymbol,       NoSymbol,
1051     /* 0xce */  NoSymbol,       NoSymbol,
1052     /* 0xcf */  NoSymbol,       NoSymbol,
1053     /* 0xd0 */  NoSymbol,       NoSymbol,
1054     /* 0xd1 */  NoSymbol,       NoSymbol,
1055     /* 0xd2 */  NoSymbol,       NoSymbol,
1056     /* 0xd3 */  NoSymbol,       NoSymbol,
1057     /* 0xd4 */  NoSymbol,       NoSymbol,
1058     /* 0xd5 */  NoSymbol,       NoSymbol,
1059     /* 0xd6 */  NoSymbol,       NoSymbol,
1060     /* 0xd7 */  NoSymbol,       NoSymbol,
1061     /* 0xd8 */  NoSymbol,       NoSymbol,
1062     /* 0xd9 */  NoSymbol,       NoSymbol,
1063     /* 0xda */  NoSymbol,       NoSymbol,
1064     /* 0xdb */  NoSymbol,       NoSymbol,
1065     /* 0xdc */  NoSymbol,       NoSymbol,
1066     /* 0xdd */  NoSymbol,       NoSymbol,
1067     /* 0xde */  NoSymbol,       NoSymbol,
1068     /* 0xdf */  NoSymbol,       NoSymbol,
1069     /* 0xe0 */  NoSymbol,       NoSymbol,
1070     /* 0xe1 */  NoSymbol,       NoSymbol,
1071     /* 0xe2 */  NoSymbol,       NoSymbol,
1072     /* 0xe3 */  NoSymbol,       NoSymbol,
1073     /* 0xe4 */  NoSymbol,       NoSymbol,
1074     /* 0xe5 */  NoSymbol,       NoSymbol,
1075     /* 0xe6 */  NoSymbol,       NoSymbol,
1076     /* 0xe7 */  NoSymbol,       NoSymbol,
1077     /* 0xe8 */  NoSymbol,       NoSymbol,
1078     /* 0xe9 */  NoSymbol,       NoSymbol,
1079     /* 0xea */  NoSymbol,       NoSymbol,
1080     /* 0xeb */  NoSymbol,       NoSymbol,
1081     /* 0xec */  NoSymbol,       NoSymbol,
1082     /* 0xed */  NoSymbol,       NoSymbol,
1083     /* 0xee */  NoSymbol,       NoSymbol,
1084     /* 0xef */  NoSymbol,       NoSymbol,
1085     /* 0xf0 */  NoSymbol,       NoSymbol,
1086     /* 0xf1 */  NoSymbol,       NoSymbol,
1087     /* 0xf2 */  NoSymbol,       NoSymbol,
1088     /* 0xf3 */  NoSymbol,       NoSymbol,
1089     /* 0xf4 */  NoSymbol,       NoSymbol,
1090     /* 0xf5 */  NoSymbol,       NoSymbol,
1091     /* 0xf6 */  NoSymbol,       NoSymbol,
1092     /* 0xf7 */  NoSymbol,       NoSymbol,
1093 };
1094
1095 static struct { KeySym keysym; CARD8 mask; } modifiers[] = {
1096     { XK_Shift_L,               ShiftMask },
1097     { XK_Shift_R,               ShiftMask },
1098     { XK_Control_L,             ControlMask },
1099     { XK_Control_R,             ControlMask },
1100     { XK_Caps_Lock,             LockMask },
1101     { XK_Alt_L,         AltMask },
1102     { XK_Alt_R,         AltMask },
1103     { XK_Meta_L,                Mod4Mask },
1104     { XK_Meta_R,                Mod4Mask },
1105     { XK_Num_Lock,              NumLockMask },
1106     { XK_Scroll_Lock,   ScrollLockMask },
1107     { XK_Mode_switch,   AltLangMask }
1108 };
1109
1110 /* Server 1.6 and earlier */
1111 static int
1112 EvdevInitKeysyms(DeviceIntPtr device)
1113 {
1114     InputInfoPtr pInfo;
1115     EvdevPtr pEvdev;
1116     KeySymsRec keySyms;
1117     CARD8 modMap[MAP_LENGTH];
1118     KeySym sym;
1119     int i, j;
1120
1121     pInfo = device->public.devicePrivate;
1122     pEvdev = pInfo->private;
1123
1124      /* Compute the modifier map */
1125     memset(modMap, 0, sizeof modMap);
1126
1127     for (i = 0; i < ArrayLength(map) / GLYPHS_PER_KEY; i++) {
1128         sym = map[i * GLYPHS_PER_KEY];
1129         for (j = 0; j < ArrayLength(modifiers); j++) {
1130             if (modifiers[j].keysym == sym)
1131                 modMap[i + MIN_KEYCODE] = modifiers[j].mask;
1132         }
1133     }
1134
1135     keySyms.map        = map;
1136     keySyms.mapWidth   = GLYPHS_PER_KEY;
1137     keySyms.minKeyCode = MIN_KEYCODE;
1138     keySyms.maxKeyCode = MIN_KEYCODE + ArrayLength(map) / GLYPHS_PER_KEY - 1;
1139
1140     XkbSetRulesDflts(pEvdev->rmlvo.rules, pEvdev->rmlvo.model,
1141             pEvdev->rmlvo.layout, pEvdev->rmlvo.variant,
1142             pEvdev->rmlvo.options);
1143     if (!XkbInitKeyboardDeviceStruct(device, &pEvdev->xkbnames,
1144                 &keySyms, modMap, NULL,
1145                 EvdevKbdCtrl))
1146         return 0;
1147
1148     return 1;
1149 }
1150 #endif
1151
1152 static void
1153 EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl)
1154 {
1155     static struct { int xbit, code; } bits[] = {
1156         { CAPSFLAG,     LED_CAPSL },
1157         { NUMFLAG,      LED_NUML },
1158         { SCROLLFLAG,   LED_SCROLLL },
1159         { MODEFLAG,     LED_KANA },
1160         { COMPOSEFLAG,  LED_COMPOSE }
1161     };
1162
1163     InputInfoPtr pInfo;
1164     struct input_event ev[ArrayLength(bits)];
1165     int i;
1166
1167     memset(ev, 0, sizeof(ev));
1168
1169     pInfo = device->public.devicePrivate;
1170     for (i = 0; i < ArrayLength(bits); i++) {
1171         ev[i].type = EV_LED;
1172         ev[i].code = bits[i].code;
1173         ev[i].value = (ctrl->leds & bits[i].xbit) > 0;
1174     }
1175
1176     write(pInfo->fd, ev, sizeof ev);
1177 }
1178
1179 static int
1180 EvdevAddKeyClass(DeviceIntPtr device)
1181 {
1182     InputInfoPtr pInfo;
1183     EvdevPtr pEvdev;
1184
1185     pInfo = device->public.devicePrivate;
1186     pEvdev = pInfo->private;
1187
1188     /* sorry, no rules change allowed for you */
1189     xf86ReplaceStrOption(pInfo->options, "xkb_rules", "evdev");
1190     SetXkbOption(pInfo, "xkb_rules", &pEvdev->rmlvo.rules);
1191     SetXkbOption(pInfo, "xkb_model", &pEvdev->rmlvo.model);
1192     if (!pEvdev->rmlvo.model)
1193         SetXkbOption(pInfo, "XkbModel", &pEvdev->rmlvo.model);
1194     SetXkbOption(pInfo, "xkb_layout", &pEvdev->rmlvo.layout);
1195     if (!pEvdev->rmlvo.layout)
1196         SetXkbOption(pInfo, "XkbLayout", &pEvdev->rmlvo.layout);
1197     SetXkbOption(pInfo, "xkb_variant", &pEvdev->rmlvo.variant);
1198     if (!pEvdev->rmlvo.variant)
1199         SetXkbOption(pInfo, "XkbVariant", &pEvdev->rmlvo.variant);
1200     SetXkbOption(pInfo, "xkb_options", &pEvdev->rmlvo.options);
1201     if (!pEvdev->rmlvo.options)
1202         SetXkbOption(pInfo, "XkbOptions", &pEvdev->rmlvo.options);
1203
1204 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 5
1205     if (!InitKeyboardDeviceStruct(device, &pEvdev->rmlvo, NULL, EvdevKbdCtrl))
1206         return !Success;
1207 #else
1208     if (!EvdevInitKeysyms(device))
1209         return !Success;
1210
1211 #endif
1212
1213     return Success;
1214 }
1215
1216 static int
1217 EvdevAddAbsClass(DeviceIntPtr device)
1218 {
1219     InputInfoPtr pInfo;
1220     EvdevPtr pEvdev;
1221     int num_axes, axis, i = 0;
1222     Atom *atoms;
1223
1224     pInfo = device->public.devicePrivate;
1225     pEvdev = pInfo->private;
1226
1227     if (!TestBit(EV_ABS, pEvdev->bitmask))
1228             return !Success;
1229
1230     num_axes = EvdevCountBits(pEvdev->abs_bitmask, NLONGS(ABS_MAX));
1231     if (num_axes < 1)
1232         return !Success;
1233     pEvdev->num_vals = num_axes;
1234     memset(pEvdev->vals, 0, num_axes * sizeof(int));
1235     memset(pEvdev->old_vals, -1, num_axes * sizeof(int));
1236     atoms = malloc(pEvdev->num_vals * sizeof(Atom));
1237
1238     for (axis = ABS_X; axis <= ABS_MAX; axis++) {
1239         pEvdev->axis_map[axis] = -1;
1240         if (!TestBit(axis, pEvdev->abs_bitmask))
1241             continue;
1242         pEvdev->axis_map[axis] = i;
1243         i++;
1244     }
1245
1246     EvdevInitAxesLabels(pEvdev, pEvdev->num_vals, atoms);
1247
1248     if (!InitValuatorClassDeviceStruct(device, num_axes,
1249 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
1250                                        atoms,
1251 #endif
1252 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
1253                                        GetMotionHistory,
1254 #endif
1255                                        GetMotionHistorySize(), Absolute))
1256         return !Success;
1257
1258     for (axis = ABS_X; axis <= ABS_MAX; axis++) {
1259         int axnum = pEvdev->axis_map[axis];
1260         if (axnum == -1)
1261             continue;
1262         xf86InitValuatorAxisStruct(device, axnum,
1263 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
1264                                    atoms[axnum],
1265 #endif
1266                                    pEvdev->absinfo[axis].minimum,
1267                                    pEvdev->absinfo[axis].maximum,
1268                                    10000, 0, 10000, Absolute);
1269         xf86InitValuatorDefaults(device, axnum);
1270         pEvdev->old_vals[axnum] = -1;
1271     }
1272
1273     free(atoms);
1274
1275     if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
1276         return !Success;
1277
1278     return Success;
1279 }
1280
1281 static int
1282 EvdevAddRelClass(DeviceIntPtr device)
1283 {
1284     InputInfoPtr pInfo;
1285     EvdevPtr pEvdev;
1286     int num_axes, axis, i = 0;
1287     Atom *atoms;
1288
1289     pInfo = device->public.devicePrivate;
1290     pEvdev = pInfo->private;
1291
1292     if (!TestBit(EV_REL, pEvdev->bitmask))
1293         return !Success;
1294
1295     num_axes = EvdevCountBits(pEvdev->rel_bitmask, NLONGS(REL_MAX));
1296     if (num_axes < 1)
1297         return !Success;
1298
1299     /* Wheels are special, we post them as button events. So let's ignore them
1300      * in the axes list too */
1301     if (TestBit(REL_WHEEL, pEvdev->rel_bitmask))
1302         num_axes--;
1303     if (TestBit(REL_HWHEEL, pEvdev->rel_bitmask))
1304         num_axes--;
1305     if (TestBit(REL_DIAL, pEvdev->rel_bitmask))
1306         num_axes--;
1307
1308     if (num_axes <= 0)
1309         return !Success;
1310
1311     pEvdev->num_vals = num_axes;
1312     memset(pEvdev->vals, 0, num_axes * sizeof(int));
1313     atoms = malloc(pEvdev->num_vals * sizeof(Atom));
1314
1315     for (axis = REL_X; axis <= REL_MAX; axis++)
1316     {
1317         pEvdev->axis_map[axis] = -1;
1318         /* We don't post wheel events, so ignore them here too */
1319         if (axis == REL_WHEEL || axis == REL_HWHEEL || axis == REL_DIAL)
1320             continue;
1321         if (!TestBit(axis, pEvdev->rel_bitmask))
1322             continue;
1323         pEvdev->axis_map[axis] = i;
1324         i++;
1325     }
1326
1327     EvdevInitAxesLabels(pEvdev, pEvdev->num_vals, atoms);
1328
1329     if (!InitValuatorClassDeviceStruct(device, num_axes,
1330 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
1331                                        atoms,
1332 #endif
1333 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
1334                                        GetMotionHistory,
1335 #endif
1336                                        GetMotionHistorySize(), Relative))
1337         return !Success;
1338
1339     for (axis = REL_X; axis <= REL_MAX; axis++)
1340     {
1341         int axnum = pEvdev->axis_map[axis];
1342
1343         if (axnum == -1)
1344             continue;
1345         xf86InitValuatorAxisStruct(device, axnum,
1346 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
1347                 atoms[axnum],
1348 #endif
1349                 -1, -1, 1, 0, 1, Relative);
1350         xf86InitValuatorDefaults(device, axnum);
1351     }
1352
1353     free(atoms);
1354
1355     if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
1356         return !Success;
1357
1358     return Success;
1359 }
1360
1361 static int
1362 EvdevAddButtonClass(DeviceIntPtr device)
1363 {
1364     InputInfoPtr pInfo;
1365     EvdevPtr pEvdev;
1366     Atom *labels;
1367
1368     pInfo = device->public.devicePrivate;
1369     pEvdev = pInfo->private;
1370
1371     labels = malloc(pEvdev->num_buttons * sizeof(Atom));
1372     EvdevInitButtonLabels(pEvdev, pEvdev->num_buttons, labels);
1373
1374     if (!InitButtonClassDeviceStruct(device, pEvdev->num_buttons,
1375 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
1376                                      labels,
1377 #endif
1378                                      pEvdev->btnmap))
1379         return !Success;
1380
1381     free(labels);
1382     return Success;
1383 }
1384
1385 /**
1386  * Init the button mapping for the device. By default, this is a 1:1 mapping,
1387  * i.e. Button 1 maps to Button 1, Button 2 to 2, etc.
1388  *
1389  * If a mapping has been specified, the mapping is the default, with the
1390  * user-defined ones overwriting the defaults.
1391  * i.e. a user-defined mapping of "3 2 1" results in a mapping of 3 2 1 4 5 6 ...
1392  *
1393  * Invalid button mappings revert to the default.
1394  *
1395  * Note that index 0 is unused, button 0 does not exist.
1396  * This mapping is initialised for all devices, but only applied if the device
1397  * has buttons (in EvdevAddButtonClass).
1398  */
1399 static void
1400 EvdevInitButtonMapping(InputInfoPtr pInfo)
1401 {
1402     int         i, nbuttons     = 1;
1403     char       *mapping         = NULL;
1404     EvdevPtr    pEvdev          = pInfo->private;
1405
1406     /* Check for user-defined button mapping */
1407     if ((mapping = xf86CheckStrOption(pInfo->options, "ButtonMapping", NULL)))
1408     {
1409         char    *s  = " ";
1410         int     btn = 0;
1411
1412         xf86Msg(X_CONFIG, "%s: ButtonMapping '%s'\n", pInfo->name, mapping);
1413         while (s && *s != '\0' && nbuttons < EVDEV_MAXBUTTONS)
1414         {
1415             btn = strtol(mapping, &s, 10);
1416
1417             if (s == mapping || btn < 0 || btn > EVDEV_MAXBUTTONS)
1418             {
1419                 xf86Msg(X_ERROR,
1420                         "%s: ... Invalid button mapping. Using defaults\n",
1421                         pInfo->name);
1422                 nbuttons = 1; /* ensure defaults start at 1 */
1423                 break;
1424             }
1425
1426             pEvdev->btnmap[nbuttons++] = btn;
1427             mapping = s;
1428         }
1429     }
1430
1431     for (i = nbuttons; i < ArrayLength(pEvdev->btnmap); i++)
1432         pEvdev->btnmap[i] = i;
1433
1434 }
1435
1436 static void
1437 EvdevInitAnyClass(DeviceIntPtr device, EvdevPtr pEvdev)
1438 {
1439     if (pEvdev->flags & EVDEV_RELATIVE_EVENTS &&
1440         EvdevAddRelClass(device) == Success)
1441         xf86Msg(X_INFO, "%s: initialized for relative axes.\n", device->name);
1442     if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS &&
1443         EvdevAddAbsClass(device) == Success)
1444         xf86Msg(X_INFO, "%s: initialized for absolute axes.\n", device->name);
1445 }
1446
1447 static void
1448 EvdevInitAbsClass(DeviceIntPtr device, EvdevPtr pEvdev)
1449 {
1450     if (EvdevAddAbsClass(device) == Success) {
1451
1452         xf86Msg(X_INFO,"%s: initialized for absolute axes.\n", device->name);
1453
1454     } else {
1455
1456         xf86Msg(X_ERROR,"%s: failed to initialize for absolute axes.\n",
1457                 device->name);
1458
1459         pEvdev->flags &= ~EVDEV_ABSOLUTE_EVENTS;
1460
1461     }
1462 }
1463
1464 static void
1465 EvdevInitRelClass(DeviceIntPtr device, EvdevPtr pEvdev)
1466 {
1467     int has_abs_axes = pEvdev->flags & EVDEV_ABSOLUTE_EVENTS;
1468
1469     if (EvdevAddRelClass(device) == Success) {
1470
1471         xf86Msg(X_INFO,"%s: initialized for relative axes.\n", device->name);
1472
1473         if (has_abs_axes) {
1474
1475             xf86Msg(X_WARNING,"%s: ignoring absolute axes.\n", device->name);
1476             pEvdev->flags &= ~EVDEV_ABSOLUTE_EVENTS;
1477         }
1478
1479     } else {
1480
1481         xf86Msg(X_ERROR,"%s: failed to initialize for relative axes.\n",
1482                 device->name);
1483
1484         pEvdev->flags &= ~EVDEV_RELATIVE_EVENTS;
1485
1486         if (has_abs_axes)
1487             EvdevInitAbsClass(device, pEvdev);
1488     }
1489 }
1490
1491 static void
1492 EvdevInitTouchDevice(DeviceIntPtr device, EvdevPtr pEvdev)
1493 {
1494     if (pEvdev->flags & EVDEV_RELATIVE_EVENTS) {
1495
1496         xf86Msg(X_WARNING,"%s: touchpads, tablets and touchscreens ignore "
1497                 "relative axes.\n", device->name);
1498
1499         pEvdev->flags &= ~EVDEV_RELATIVE_EVENTS;
1500     }
1501
1502     EvdevInitAbsClass(device, pEvdev);
1503 }
1504
1505 static int
1506 EvdevInit(DeviceIntPtr device)
1507 {
1508     int i;
1509     InputInfoPtr pInfo;
1510     EvdevPtr pEvdev;
1511
1512     pInfo = device->public.devicePrivate;
1513     pEvdev = pInfo->private;
1514
1515     /* clear all axis_map entries */
1516     for(i = 0; i < max(ABS_CNT,REL_CNT); i++)
1517       pEvdev->axis_map[i]=-1;
1518
1519     if (pEvdev->flags & EVDEV_KEYBOARD_EVENTS)
1520         EvdevAddKeyClass(device);
1521     if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
1522         EvdevAddButtonClass(device);
1523
1524     /* We don't allow relative and absolute axes on the same device. The
1525      * reason is that some devices (MS Optical Desktop 2000) register both
1526      * rel and abs axes for x/y.
1527      *
1528      * The abs axes register min/max; this min/max then also applies to the
1529      * relative device (the mouse) and caps it at 0..255 for both axes.
1530      * So, unless you have a small screen, you won't be enjoying it much;
1531      * consequently, absolute axes are generally ignored.
1532      *
1533      * However, currenly only a device with absolute axes can be registered
1534      * as a touch{pad,screen}. Thus, given such a device, absolute axes are
1535      * used and relative axes are ignored.
1536      */
1537
1538     if (pEvdev->flags & (EVDEV_UNIGNORE_RELATIVE | EVDEV_UNIGNORE_ABSOLUTE))
1539         EvdevInitAnyClass(device, pEvdev);
1540     else if (pEvdev->flags & (EVDEV_TOUCHPAD | EVDEV_TOUCHSCREEN | EVDEV_TABLET))
1541         EvdevInitTouchDevice(device, pEvdev);
1542     else if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
1543         EvdevInitRelClass(device, pEvdev);
1544 #ifdef _F_INIT_ABS_ONLY_FOR_POINTER_
1545     else if ( !(pEvdev->flags & EVDEV_KEYBOARD_EVENTS) && (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) )
1546 #else
1547     else if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
1548 #endif
1549         EvdevInitAbsClass(device, pEvdev);
1550
1551 #ifdef HAVE_PROPERTIES
1552     /* We drop the return value, the only time we ever want the handlers to
1553      * unregister is when the device dies. In which case we don't have to
1554      * unregister anyway */
1555     EvdevInitProperty(device);
1556     XIRegisterPropertyHandler(device, EvdevSetProperty, NULL, NULL);
1557     EvdevMBEmuInitProperty(device);
1558     EvdevWheelEmuInitProperty(device);
1559     EvdevDragLockInitProperty(device);
1560 #endif
1561
1562     return Success;
1563 }
1564
1565 /**
1566  * Init all extras (wheel emulation, etc.) and grab the device.
1567  *
1568  * Coming from a resume, the grab may fail with ENODEV. In this case, we set a
1569  * timer to wake up and try to reopen the device later.
1570  */
1571 static int
1572 EvdevOn(DeviceIntPtr device)
1573 {
1574     InputInfoPtr pInfo;
1575     EvdevPtr pEvdev;
1576     int rc = 0;
1577
1578     pInfo = device->public.devicePrivate;
1579     pEvdev = pInfo->private;
1580
1581     if (pInfo->fd != -1 && pEvdev->grabDevice &&
1582         (rc = ioctl(pInfo->fd, EVIOCGRAB, (void *)1)))
1583     {
1584         xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name,
1585                 strerror(errno));
1586
1587         /* ENODEV - device has disappeared after resume */
1588         if (rc && errno == ENODEV)
1589         {
1590             close(pInfo->fd);
1591             pInfo->fd = -1;
1592         }
1593     }
1594
1595     if (pInfo->fd == -1)
1596     {
1597         pEvdev->reopen_left = pEvdev->reopen_attempts;
1598         pEvdev->reopen_timer = TimerSet(pEvdev->reopen_timer, 0, 100, EvdevReopenTimer, pInfo);
1599     } else
1600     {
1601         pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
1602         if (EvdevIsDuplicate(pInfo))
1603         {
1604             xf86Msg(X_WARNING, "%s: Refusing to enable duplicate device.\n",
1605                     pInfo->name);
1606             return !Success;
1607         }
1608
1609         pEvdev->reopen_timer = TimerSet(pEvdev->reopen_timer, 0, 0, NULL, NULL);
1610
1611         xf86FlushInput(pInfo->fd);
1612         xf86AddEnabledDevice(pInfo);
1613         EvdevMBEmuOn(pInfo);
1614         pEvdev->flags |= EVDEV_INITIALIZED;
1615         device->public.on = TRUE;
1616     }
1617
1618     return Success;
1619 }
1620
1621
1622 static int
1623 EvdevProc(DeviceIntPtr device, int what)
1624 {
1625     InputInfoPtr pInfo;
1626     EvdevPtr pEvdev;
1627     int region[4] = { 0, };
1628
1629     pInfo = device->public.devicePrivate;
1630     pEvdev = pInfo->private;
1631
1632     switch (what)
1633     {
1634     case DEVICE_INIT:
1635         return EvdevInit(device);
1636
1637     case DEVICE_ON:
1638         return EvdevOn(device);
1639
1640     case DEVICE_OFF:
1641         if (pEvdev->flags & EVDEV_INITIALIZED)
1642             EvdevMBEmuFinalize(pInfo);
1643
1644         if (pInfo->fd != -1)
1645         {
1646             if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
1647                 xf86Msg(X_WARNING, "%s: Release failed (%s)\n", pInfo->name,
1648                         strerror(errno));
1649             xf86RemoveEnabledDevice(pInfo);
1650             close(pInfo->fd);
1651             pInfo->fd = -1;
1652         }
1653         pEvdev->min_maj = 0;
1654         pEvdev->flags &= ~EVDEV_INITIALIZED;
1655         device->public.on = FALSE;
1656         if (pEvdev->reopen_timer)
1657         {
1658             TimerFree(pEvdev->reopen_timer);
1659             pEvdev->reopen_timer = NULL;
1660         }
1661         break;
1662
1663     case DEVICE_CLOSE:
1664 #ifdef _F_EVDEV_CONFINE_REGION_
1665         if( pEvdev->confined_id )
1666                 EvdevSetConfineRegion(pInfo, 1, &region[0]);
1667 #endif//_F_EVDEV_CONFINE_REGION_
1668         xf86Msg(X_INFO, "%s: Close\n", pInfo->name);
1669         if (pInfo->fd != -1) {
1670             close(pInfo->fd);
1671             pInfo->fd = -1;
1672         }
1673         EvdevRemoveDevice(pInfo);
1674         pEvdev->min_maj = 0;
1675         break;
1676     }
1677
1678     return Success;
1679 }
1680
1681 /**
1682  * Get as much information as we can from the fd and cache it.
1683  * If compare is True, then the information retrieved will be compared to the
1684  * one already cached. If the information does not match, then this function
1685  * returns an error.
1686  *
1687  * @return Success if the information was cached, or !Success otherwise.
1688  */
1689 static int
1690 EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
1691 {
1692     EvdevPtr pEvdev = pInfo->private;
1693     size_t len;
1694     int i;
1695
1696     char name[1024]                  = {0};
1697     unsigned long bitmask[NLONGS(EV_CNT)]      = {0};
1698     unsigned long key_bitmask[NLONGS(KEY_CNT)] = {0};
1699     unsigned long rel_bitmask[NLONGS(REL_CNT)] = {0};
1700     unsigned long abs_bitmask[NLONGS(ABS_CNT)] = {0};
1701     unsigned long led_bitmask[NLONGS(LED_CNT)] = {0};
1702
1703     if (ioctl(pInfo->fd, EVIOCGNAME(sizeof(name) - 1), name) < 0) {
1704         xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
1705         goto error;
1706     }
1707
1708     if (!compare) {
1709         strcpy(pEvdev->name, name);
1710     } else if (strcmp(pEvdev->name, name)) {
1711         xf86Msg(X_ERROR, "%s: device name changed: %s != %s\n",
1712                 pInfo->name, pEvdev->name, name);
1713         goto error;
1714     }
1715
1716     len = ioctl(pInfo->fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask);
1717     if (len < 0) {
1718         xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
1719                 pInfo->name, strerror(errno));
1720         goto error;
1721     }
1722
1723     if (!compare) {
1724         memcpy(pEvdev->bitmask, bitmask, len);
1725     } else if (memcmp(pEvdev->bitmask, bitmask, len)) {
1726         xf86Msg(X_ERROR, "%s: device bitmask has changed\n", pInfo->name);
1727         goto error;
1728     }
1729
1730     len = ioctl(pInfo->fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask);
1731     if (len < 0) {
1732         xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
1733                 pInfo->name, strerror(errno));
1734         goto error;
1735     }
1736
1737     if (!compare) {
1738         memcpy(pEvdev->rel_bitmask, rel_bitmask, len);
1739     } else if (memcmp(pEvdev->rel_bitmask, rel_bitmask, len)) {
1740         xf86Msg(X_ERROR, "%s: device rel_bitmask has changed\n", pInfo->name);
1741         goto error;
1742     }
1743
1744     len = ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
1745     if (len < 0) {
1746         xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
1747                 pInfo->name, strerror(errno));
1748         goto error;
1749     }
1750
1751     if (!compare) {
1752         memcpy(pEvdev->abs_bitmask, abs_bitmask, len);
1753     } else if (memcmp(pEvdev->abs_bitmask, abs_bitmask, len)) {
1754         xf86Msg(X_ERROR, "%s: device abs_bitmask has changed\n", pInfo->name);
1755         goto error;
1756     }
1757
1758     len = ioctl(pInfo->fd, EVIOCGBIT(EV_LED, sizeof(led_bitmask)), led_bitmask);
1759     if (len < 0) {
1760         xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
1761                 pInfo->name, strerror(errno));
1762         goto error;
1763     }
1764
1765     if (!compare) {
1766         memcpy(pEvdev->led_bitmask, led_bitmask, len);
1767     } else if (memcmp(pEvdev->led_bitmask, led_bitmask, len)) {
1768         xf86Msg(X_ERROR, "%s: device led_bitmask has changed\n", pInfo->name);
1769         goto error;
1770     }
1771
1772     /*
1773      * Do not try to validate absinfo data since it is not expected
1774      * to be static, always refresh it in evdev structure.
1775      */
1776     for (i = ABS_X; i <= ABS_MAX; i++) {
1777         if (TestBit(i, abs_bitmask)) {
1778             len = ioctl(pInfo->fd, EVIOCGABS(i), &pEvdev->absinfo[i]);
1779             if (len < 0) {
1780                 xf86Msg(X_ERROR, "%s: ioctl EVIOCGABSi(%d) failed: %s\n",
1781                         pInfo->name, i, strerror(errno));
1782                 goto error;
1783             }
1784         }
1785     }
1786
1787     len = ioctl(pInfo->fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask);
1788     if (len < 0) {
1789         xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
1790                 pInfo->name, strerror(errno));
1791         goto error;
1792     }
1793
1794     if (compare) {
1795         /*
1796          * Keys are special as user can adjust keymap at any time (on
1797          * devices that support EVIOCSKEYCODE. However we do not expect
1798          * buttons reserved for mice/tablets/digitizers and so on to
1799          * appear/disappear so we will check only those in
1800          * [BTN_MISC, KEY_OK) range.
1801          */
1802         size_t start_word = BTN_MISC / LONG_BITS;
1803         size_t start_byte = start_word * sizeof(unsigned long);
1804         size_t end_word = KEY_OK / LONG_BITS;
1805         size_t end_byte = end_word * sizeof(unsigned long);
1806
1807         if (len >= start_byte &&
1808             memcmp(&pEvdev->key_bitmask[start_word], &key_bitmask[start_word],
1809                    min(len, end_byte) - start_byte + 1)) {
1810             xf86Msg(X_ERROR, "%s: device key_bitmask has changed\n", pInfo->name);
1811             goto error;
1812         }
1813     }
1814
1815     /* Copy the data so we have reasonably up-to-date info */
1816     memcpy(pEvdev->key_bitmask, key_bitmask, len);
1817
1818     return Success;
1819
1820 error:
1821     return !Success;
1822
1823 }
1824
1825 static int
1826 EvdevProbe(InputInfoPtr pInfo)
1827 {
1828     int i, has_rel_axes, has_abs_axes, has_keys, num_buttons, has_scroll;
1829     int kernel24 = 0;
1830     int ignore_abs = 0, ignore_rel = 0;
1831     EvdevPtr pEvdev = pInfo->private;
1832
1833     if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
1834         if (errno == EINVAL) {
1835             /* keyboards are unsafe in 2.4 */
1836             kernel24 = 1;
1837             pEvdev->grabDevice = 0;
1838         } else {
1839             xf86Msg(X_ERROR, "Grab failed. Device already configured?\n");
1840             return 1;
1841         }
1842     } else if (pEvdev->grabDevice) {
1843         ioctl(pInfo->fd, EVIOCGRAB, (void *)0);
1844     }
1845
1846     /* Trinary state for ignoring axes:
1847        - unset: do the normal thing.
1848        - TRUE: explicitly ignore them.
1849        - FALSE: unignore axes, use them at all cost if they're present.
1850      */
1851     if (xf86FindOption(pInfo->options, "IgnoreRelativeAxes"))
1852     {
1853         if (xf86SetBoolOption(pInfo->options, "IgnoreRelativeAxes", FALSE))
1854             ignore_rel = TRUE;
1855         else
1856             pEvdev->flags |= EVDEV_UNIGNORE_RELATIVE;
1857
1858     }
1859     if (xf86FindOption(pInfo->options, "IgnoreAbsoluteAxes"))
1860     {
1861         if (xf86SetBoolOption(pInfo->options, "IgnoreAbsoluteAxes", FALSE))
1862            ignore_abs = TRUE;
1863         else
1864             pEvdev->flags |= EVDEV_UNIGNORE_ABSOLUTE;
1865     }
1866
1867     has_rel_axes = FALSE;
1868     has_abs_axes = FALSE;
1869     has_keys = FALSE;
1870     has_scroll = FALSE;
1871     num_buttons = 0;
1872
1873     /* count all buttons */
1874     for (i = BTN_MISC; i < BTN_JOYSTICK; i++)
1875     {
1876         int mapping = 0;
1877         if (TestBit(i, pEvdev->key_bitmask))
1878         {
1879             mapping = EvdevUtilButtonEventToButtonNumber(pEvdev, i);
1880             if (mapping > num_buttons)
1881                 num_buttons = mapping;
1882         }
1883     }
1884
1885     if (num_buttons)
1886     {
1887         pEvdev->flags |= EVDEV_BUTTON_EVENTS;
1888         pEvdev->num_buttons = num_buttons;
1889         xf86Msg(X_INFO, "%s: Found %d mouse buttons\n", pInfo->name,
1890                 num_buttons);
1891     }
1892
1893     for (i = 0; i < REL_MAX; i++) {
1894         if (TestBit(i, pEvdev->rel_bitmask)) {
1895             has_rel_axes = TRUE;
1896             break;
1897         }
1898     }
1899
1900     if (has_rel_axes) {
1901         if (TestBit(REL_WHEEL, pEvdev->rel_bitmask) ||
1902             TestBit(REL_HWHEEL, pEvdev->rel_bitmask) ||
1903             TestBit(REL_DIAL, pEvdev->rel_bitmask)) {
1904             xf86Msg(X_INFO, "%s: Found scroll wheel(s)\n", pInfo->name);
1905             has_scroll = TRUE;
1906             if (!num_buttons)
1907                 xf86Msg(X_INFO, "%s: Forcing buttons for scroll wheel(s)\n",
1908                         pInfo->name);
1909             num_buttons = (num_buttons < 3) ? 7 : num_buttons + 4;
1910             pEvdev->num_buttons = num_buttons;
1911         }
1912
1913         if (!ignore_rel)
1914         {
1915             xf86Msg(X_INFO, "%s: Found relative axes\n", pInfo->name);
1916             pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
1917
1918             if (TestBit(REL_X, pEvdev->rel_bitmask) &&
1919                 TestBit(REL_Y, pEvdev->rel_bitmask)) {
1920                 xf86Msg(X_INFO, "%s: Found x and y relative axes\n", pInfo->name);
1921             }
1922         } else {
1923             xf86Msg(X_INFO, "%s: Relative axes present but ignored.\n", pInfo->name);
1924             has_rel_axes = FALSE;
1925         }
1926     }
1927
1928     for (i = 0; i < ABS_MAX; i++) {
1929         if (TestBit(i, pEvdev->abs_bitmask)) {
1930             has_abs_axes = TRUE;
1931             break;
1932         }
1933     }
1934
1935     if (ignore_abs && has_abs_axes)
1936     {
1937         xf86Msg(X_INFO, "%s: Absolute axes present but ignored.\n", pInfo->name);
1938         has_abs_axes = FALSE;
1939     } else if (has_abs_axes) {
1940         xf86Msg(X_INFO, "%s: Found absolute axes\n", pInfo->name);
1941         pEvdev->flags |= EVDEV_ABSOLUTE_EVENTS;
1942
1943         if ((TestBit(ABS_X, pEvdev->abs_bitmask) &&
1944              TestBit(ABS_Y, pEvdev->abs_bitmask))) {
1945             xf86Msg(X_INFO, "%s: Found x and y absolute axes\n", pInfo->name);
1946             if (TestBit(BTN_TOOL_PEN, pEvdev->key_bitmask))
1947             {
1948                 xf86Msg(X_INFO, "%s: Found absolute tablet.\n", pInfo->name);
1949                 pEvdev->flags |= EVDEV_TABLET;
1950                 if (!pEvdev->num_buttons)
1951                 {
1952                     pEvdev->num_buttons = 7; /* LMR + scroll wheels */
1953                     pEvdev->flags |= EVDEV_BUTTON_EVENTS;
1954                 }
1955             } else if (TestBit(ABS_PRESSURE, pEvdev->abs_bitmask) ||
1956                 TestBit(BTN_TOUCH, pEvdev->key_bitmask)) {
1957                 if (num_buttons || TestBit(BTN_TOOL_FINGER, pEvdev->key_bitmask)) {
1958                     xf86Msg(X_INFO, "%s: Found absolute touchpad.\n", pInfo->name);
1959                     pEvdev->flags |= EVDEV_TOUCHPAD;
1960                     memset(pEvdev->old_vals, -1, sizeof(int) * pEvdev->num_vals);
1961                 } else {
1962                     xf86Msg(X_INFO, "%s: Found absolute touchscreen\n", pInfo->name);
1963                     pEvdev->flags |= EVDEV_TOUCHSCREEN;
1964                     pEvdev->flags |= EVDEV_BUTTON_EVENTS;
1965                 }
1966             }
1967         }
1968     }
1969
1970     for (i = 0; i < BTN_MISC; i++) {
1971         if (TestBit(i, pEvdev->key_bitmask)) {
1972             xf86Msg(X_INFO, "%s: Found keys\n", pInfo->name);
1973             pEvdev->flags |= EVDEV_KEYBOARD_EVENTS;
1974             has_keys = TRUE;
1975             break;
1976         }
1977     }
1978
1979     if (has_rel_axes || has_abs_axes || num_buttons) {
1980         if (pEvdev->flags & EVDEV_TOUCHPAD) {
1981             xf86Msg(X_INFO, "%s: Configuring as touchpad\n", pInfo->name);
1982             pInfo->type_name = XI_TOUCHPAD;
1983         } else if (pEvdev->flags & EVDEV_TABLET) {
1984             xf86Msg(X_INFO, "%s: Configuring as tablet\n", pInfo->name);
1985             pInfo->type_name = XI_TABLET;
1986         } else if (pEvdev->flags & EVDEV_TOUCHSCREEN) {
1987             xf86Msg(X_INFO, "%s: Configuring as touchscreen\n", pInfo->name);
1988             pInfo->type_name = XI_TOUCHSCREEN;
1989         } else {
1990             xf86Msg(X_INFO, "%s: Configuring as mouse\n", pInfo->name);
1991             pInfo->type_name = XI_MOUSE;
1992         }
1993     }
1994
1995     if (has_keys) {
1996         if (kernel24) {
1997             xf86Msg(X_INFO, "%s: Kernel < 2.6 is too old, ignoring keyboard\n",
1998                     pInfo->name);
1999         } else {
2000             xf86Msg(X_INFO, "%s: Configuring as keyboard\n", pInfo->name);
2001             pInfo->type_name = XI_KEYBOARD;
2002         }
2003     }
2004
2005     if (has_scroll)
2006     {
2007         xf86Msg(X_INFO, "%s: Adding scrollwheel support\n", pInfo->name);
2008         pEvdev->flags |= EVDEV_BUTTON_EVENTS;
2009         pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
2010     }
2011
2012     return 0;
2013 }
2014
2015 static void
2016 EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4])
2017 {
2018     EvdevPtr pEvdev = pInfo->private;
2019
2020     if (num_calibration == 0) {
2021         pEvdev->flags &= ~EVDEV_CALIBRATED;
2022         pEvdev->calibration.min_x = 0;
2023         pEvdev->calibration.max_x = 0;
2024         pEvdev->calibration.min_y = 0;
2025         pEvdev->calibration.max_y = 0;
2026     } else if (num_calibration == 4) {
2027         pEvdev->flags |= EVDEV_CALIBRATED;
2028         pEvdev->calibration.min_x = calibration[0];
2029         pEvdev->calibration.max_x = calibration[1];
2030         pEvdev->calibration.min_y = calibration[2];
2031         pEvdev->calibration.max_y = calibration[3];
2032     }
2033 }
2034
2035 #ifdef _F_EVDEV_CONFINE_REGION_
2036 DeviceIntPtr
2037 GetMasterPointerFromId(int deviceid)
2038 {
2039         DeviceIntPtr pDev = inputInfo.devices;
2040         while(pDev)
2041         {
2042                 if( pDev->id == deviceid && pDev->master )
2043                 {
2044                         return pDev->master;
2045                 }
2046                 pDev = pDev->next;
2047         }
2048
2049         return NULL;
2050 }
2051
2052 Bool
2053 IsMaster(DeviceIntPtr dev)
2054 {
2055     return dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD;
2056 }
2057
2058 DeviceIntPtr
2059 GetPairedDevice(DeviceIntPtr dev)
2060 {
2061     if (!IsMaster(dev) && dev->master)
2062         dev = dev->master;
2063
2064     return dev->spriteInfo->paired;
2065 }
2066
2067 DeviceIntPtr
2068 GetMaster(DeviceIntPtr dev, int which)
2069 {
2070     DeviceIntPtr master;
2071
2072     if (IsMaster(dev))
2073         master = dev;
2074     else
2075         master = dev->master;
2076
2077     if (master)
2078     {
2079         if (which == MASTER_KEYBOARD)
2080         {
2081             if (master->type != MASTER_KEYBOARD)
2082                 master = GetPairedDevice(master);
2083         } else
2084         {
2085             if (master->type != MASTER_POINTER)
2086                 master = GetPairedDevice(master);
2087         }
2088     }
2089
2090     return master;
2091 }
2092
2093 static void
2094 EvdevHookPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
2095                       BoxPtr pHotBox, BoxPtr pTopLeftBox)
2096 {
2097     *pTopLeftBox = *pHotBox;
2098 }
2099
2100 static void
2101 EvdevHookPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox)
2102 {
2103     InputInfoPtr pInfo;
2104     EvdevPtr pEvdev;
2105
2106     pInfo =  pDev->public.devicePrivate;
2107     if(!pInfo || !pInfo->private) return;
2108     pEvdev = pInfo->private;
2109
2110     miPointerPtr pPointer;
2111     pPointer = MIPOINTER(pDev);
2112
2113     if( IsMaster(pDev) && GetMasterPointerFromId(pEvdev->confined_id) == pDev )
2114     {
2115           if( pBox->x1 < pEvdev->pointer_confine_region.x1 )
2116                 pBox->x1 = pEvdev->pointer_confine_region.x1;
2117           if( pBox->y1 < pEvdev->pointer_confine_region.y1 )
2118                 pBox->y1 = pEvdev->pointer_confine_region.y1;
2119           if( pBox->x2 > pEvdev->pointer_confine_region.x2 )
2120                 pBox->x2 = pEvdev->pointer_confine_region.x2;
2121           if( pBox->y2 > pEvdev->pointer_confine_region.y2 )
2122                 pBox->y2 = pEvdev->pointer_confine_region.y2;
2123     }
2124
2125     pPointer->limits = *pBox;
2126     pPointer->confined = PointerConfinedToScreen(pDev);
2127 }
2128
2129 static void
2130 EvdevSetCursorLimits(InputInfoPtr pInfo, int region[5], int isSet)
2131 {
2132         EvdevPtr pEvdev = pInfo->private;
2133         int v[2];
2134         int x, y;
2135
2136         ScreenPtr pCursorScreen = NULL;
2137
2138         pCursorScreen = miPointerGetScreen(pInfo->dev);
2139
2140         if( !pCursorScreen )
2141         {
2142                 xf86DrvMsg(-1, X_ERROR, "[X11][SetCursorLimits] Failed to get screen information for pointer !\n");
2143                 return;
2144         }
2145
2146         if( isSet )
2147         {
2148                 //Clip confine region with screen's width/height
2149                 if( region[0] < 0 )
2150                         region[0] = 0;
2151                 if( region[2] >= pCursorScreen->width )
2152                         region[2] = pCursorScreen->width - 1;
2153                 if( region [1] < 0 )
2154                         region[1] = 0;
2155                 if( region[3] >= pCursorScreen->height )
2156                         region[3] = pCursorScreen->height - 1;
2157
2158                 pEvdev->pointer_confine_region.x1 = region[0];
2159                 pEvdev->pointer_confine_region.y1 = region[1];
2160                 pEvdev->pointer_confine_region.x2 = region[2];
2161                 pEvdev->pointer_confine_region.y2 = region[3];
2162                 pEvdev->confined_id = pInfo->dev->id;
2163
2164                 pCursorScreen->ConstrainCursor(inputInfo.pointer, pCursorScreen, &pEvdev->pointer_confine_region);
2165                 xf86DrvMsg(-1, X_INFO, "[X11][SetCursorLimits] Constrain information for cursor was set to TOPLEFT(%d, %d) BOTTOMRIGHT(%d, %d) !\n",
2166                         region[0], region[1], region[2], region[3]);
2167
2168                 if( pCursorScreen->ConstrainCursor != EvdevHookPointerCursorLimits &&
2169                         pCursorScreen->ConstrainCursor != EvdevHookPointerConstrainCursor)
2170                 {
2171                         //Backup original function pointer(s)
2172                         pEvdev->pOrgConstrainCursor = pCursorScreen->ConstrainCursor;
2173                         pEvdev->pOrgCursorLimits = pCursorScreen->CursorLimits;
2174
2175                         //Overriding function pointer(s)
2176                         pCursorScreen->CursorLimits = EvdevHookPointerCursorLimits;
2177                         pCursorScreen->ConstrainCursor = EvdevHookPointerConstrainCursor;
2178                 }
2179
2180                 //Skip pointer warp if region[4] is zero
2181                 if(!region[4])
2182                         return;
2183
2184                 v[0] = region[0] + (int)((float)(region[2]-region[0])/2);
2185                 v[1] = region[1] + (int)((float)(region[3]-region[1])/2);
2186
2187                 xf86PostMotionEventP(pInfo->dev, TRUE, REL_X, 2, v);
2188                 xf86DrvMsg(-1, X_INFO, "[X11][SetCursorLimits] Cursor was warped to (%d, %d) !\n", v[0], v[1]);
2189                 miPointerGetPosition(pInfo->dev, &x, &y);
2190                 xf86DrvMsg(-1, X_INFO, "[X11][SetCursorLimits] Cursor is located at (%d, %d) !\n", x, y);
2191         }
2192         else
2193         {
2194                 pEvdev->pointer_confine_region.x1 = 0;
2195                 pEvdev->pointer_confine_region.y1 = 0;
2196                 pEvdev->pointer_confine_region.x2 = pCursorScreen->width - 1;
2197                 pEvdev->pointer_confine_region.y2 = pCursorScreen->height - 1;
2198                 pEvdev->confined_id = 0;
2199
2200                 pCursorScreen->ConstrainCursor(inputInfo.pointer, pCursorScreen, &pEvdev->pointer_confine_region);
2201                 xf86DrvMsg(-1, X_INFO, "[X11][SetCursorLimits] Constrain information for cursor was restored ! TOPLEFT(%d, %d) BOTTOMRIGHT(%d, %d) !\n",
2202                         pEvdev->pointer_confine_region.x1, pEvdev->pointer_confine_region.y1,
2203                         pEvdev->pointer_confine_region.x2, pEvdev->pointer_confine_region.y2);
2204
2205                 //Restore original function pointer(s)
2206                 pCursorScreen->CursorLimits = pEvdev->pOrgCursorLimits;
2207                 pCursorScreen->ConstrainCursor = pEvdev->pOrgConstrainCursor;
2208         }
2209 }
2210
2211 static void
2212 EvdevSetConfineRegion(InputInfoPtr pInfo, int num_item, int region[5])
2213 {
2214         EvdevPtr pEvdev = pInfo->private;
2215
2216         if( num_item != 5 && num_item != 1 )
2217                 return;
2218
2219         if( num_item == 5 )
2220         {
2221                 if ( (region[2]-region[0]>0) && (region[3]-region[1]>0) )
2222                 {
2223                         EvdevSetCursorLimits(pInfo, &region[0], 1);
2224                         xf86DrvMsg(-1, X_INFO, "[X11][SetConfineRegion] Confine region was set to TOPLEFT(%d, %d) BOTTOMRIGHT(%d, %d) pointerwarp=%d\n",
2225                                 region[0], region[1], region[2], region[3], region[4]);
2226                         pEvdev->flags |= EVDEV_CONFINE_REGION;
2227                 }
2228         }
2229         else if( num_item == 1 )
2230         {
2231                 if( !region[0] && (pEvdev->flags & EVDEV_CONFINE_REGION) )
2232                 {
2233                         EvdevSetCursorLimits(pInfo, &region[0], 0);
2234                         xf86DrvMsg(-1, X_INFO, "[X11][SetConfineRegion] Confine region was unset !\n");
2235                         pEvdev->flags &= ~EVDEV_CONFINE_REGION;
2236                 }
2237         }
2238 }
2239 #endif /* _F_EVDEV_CONFINE_REGION_ */
2240
2241 static int
2242 EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2243 {
2244     int rc = BadAlloc;
2245     const char *device, *str;
2246     int num_calibration = 0, calibration[4] = { 0, 0, 0, 0 };
2247     int num_resolution = 0, resolution[4] = { 0, 0, 0, 0 };
2248     EvdevPtr pEvdev;
2249
2250         if(!pInfo)
2251         {
2252                 ErrorF("[X11][EvdevPreInit] pInfo is NULL !\n");
2253                 goto error;
2254         }
2255
2256     /* Initialise the InputInfoRec. */
2257     pInfo->flags = 0;
2258     pInfo->type_name = "UNKNOWN";
2259     pInfo->device_control = EvdevProc;
2260     pInfo->read_input = EvdevReadInput;
2261     pInfo->switch_mode = NULL;
2262     pInfo->dev = NULL;
2263
2264     if (!(pEvdev = calloc(sizeof(EvdevRec), 1)))
2265         goto error;
2266
2267     pInfo->private = pEvdev;
2268
2269     xf86CollectInputOptions(pInfo, evdevDefaults);
2270     xf86ProcessCommonOptions(pInfo, pInfo->options);
2271
2272     /*
2273      * We initialize pEvdev->tool to 1 so that device that doesn't use
2274      * proximity will still report events.
2275      */
2276     pEvdev->tool = 1;
2277
2278     device = xf86CheckStrOption(pInfo->options, "Device", NULL);
2279     if (!device) {
2280         xf86Msg(X_ERROR, "%s: No device specified.\n", pInfo->name);
2281         xf86DeleteInput(pInfo, 0);
2282         rc = BadValue;
2283         goto error;
2284     }
2285
2286     pEvdev->device = device;
2287
2288     xf86Msg(X_CONFIG, "%s: Device: \"%s\"\n", pInfo->name, device);
2289     do {
2290         pInfo->fd = open(device, O_RDWR | O_NONBLOCK, 0);
2291     } while (pInfo->fd < 0 && errno == EINTR);
2292
2293     if (pInfo->fd < 0) {
2294         xf86Msg(X_ERROR, "Unable to open evdev device \"%s\".\n", device);
2295         xf86DeleteInput(pInfo, 0);
2296         rc = BadValue;
2297         goto error;
2298     }
2299
2300     /* Check major/minor of device node to avoid adding duplicate devices. */
2301     pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
2302     if (EvdevIsDuplicate(pInfo))
2303     {
2304         xf86Msg(X_WARNING, "%s: device file already in use. Ignoring.\n",
2305                 pInfo->name);
2306         close(pInfo->fd);
2307         xf86DeleteInput(pInfo, 0);
2308         rc = BadValue;
2309         goto error;
2310     }
2311
2312     pEvdev->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10);
2313     pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE);
2314     pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
2315     pEvdev->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE);
2316
2317     str = xf86CheckStrOption(pInfo->options, "Calibration", NULL);
2318     if (str) {
2319         num_calibration = sscanf(str, "%d %d %d %d",
2320                                  &calibration[0], &calibration[1],
2321                                  &calibration[2], &calibration[3]);
2322         if (num_calibration == 4)
2323             EvdevSetCalibration(pInfo, num_calibration, calibration);
2324         else
2325             xf86Msg(X_ERROR,
2326                     "%s: Insufficient calibration factors (%d). Ignoring calibration\n",
2327                     pInfo->name, num_calibration);
2328     }
2329
2330         str = xf86CheckStrOption(pInfo->options, "Resolution", NULL);
2331         if (str) {
2332             num_resolution = sscanf(str, "%d %d %d %d",
2333                                      &resolution[0], &resolution[1],
2334                                      &resolution[2], &resolution[3]);
2335             if (num_resolution == 4)
2336                 EvdevSetResolution(pInfo, num_resolution, resolution);
2337             else
2338                 xf86Msg(X_ERROR,
2339                         "%s: Insufficient resolution factors (%d). Ignoring resolution\n",
2340                         pInfo->name, num_resolution);
2341         }
2342
2343     /* Grabbing the event device stops in-kernel event forwarding. In other
2344        words, it disables rfkill and the "Macintosh mouse button emulation".
2345        Note that this needs a server that sets the console to RAW mode. */
2346     pEvdev->grabDevice = xf86CheckBoolOption(pInfo->options, "GrabDevice", 0);
2347
2348     EvdevInitButtonMapping(pInfo);
2349
2350     if (EvdevCacheCompare(pInfo, FALSE) ||
2351         EvdevProbe(pInfo)) {
2352         close(pInfo->fd);
2353         xf86DeleteInput(pInfo, 0);
2354        rc = BadMatch;
2355        goto error;
2356     }
2357
2358         if(pEvdev->flags & EVDEV_RESOLUTION)
2359         {
2360                 EvdevSwapAxes(pEvdev);
2361         }
2362 #ifdef _F_IGNORE_TSP_RESOLUTION_
2363         else
2364         {
2365                 pEvdev->absinfo[ABS_X].maximum = 0;
2366                 pEvdev->absinfo[ABS_X].minimum = 0;
2367                 pEvdev->absinfo[ABS_Y].maximum = 0;
2368                 pEvdev->absinfo[ABS_Y].minimum = 0;
2369         }
2370 #endif//_F_IGNORE_TSP_RESOLUTION_
2371
2372     EvdevAddDevice(pInfo);
2373
2374     if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
2375     {
2376         EvdevMBEmuPreInit(pInfo);
2377         EvdevWheelEmuPreInit(pInfo);
2378         EvdevDragLockPreInit(pInfo);
2379     }
2380
2381     memset(&pEvdev->pointer_confine_region, 0, sizeof(pEvdev->pointer_confine_region));
2382
2383     return Success;
2384
2385 error:
2386     if (pInfo->fd >= 0)
2387         close(pInfo->fd);
2388     return rc;
2389 }
2390
2391 _X_EXPORT InputDriverRec EVDEV = {
2392     1,
2393     "evdev",
2394     NULL,
2395     EvdevPreInit,
2396     NULL,
2397     NULL,
2398     0
2399 };
2400
2401 static void
2402 EvdevUnplug(pointer     p)
2403 {
2404 }
2405
2406 static pointer
2407 EvdevPlug(pointer       module,
2408           pointer       options,
2409           int           *errmaj,
2410           int           *errmin)
2411 {
2412     xf86AddInputDriver(&EVDEV, module, 0);
2413     return module;
2414 }
2415
2416 static XF86ModuleVersionInfo EvdevVersionRec =
2417 {
2418     "evdev",
2419     MODULEVENDORSTRING,
2420     MODINFOSTRING1,
2421     MODINFOSTRING2,
2422     XORG_VERSION_CURRENT,
2423     PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
2424     ABI_CLASS_XINPUT,
2425     ABI_XINPUT_VERSION,
2426     MOD_CLASS_XINPUT,
2427     {0, 0, 0, 0}
2428 };
2429
2430 _X_EXPORT XF86ModuleData evdevModuleData =
2431 {
2432     &EvdevVersionRec,
2433     EvdevPlug,
2434     EvdevUnplug
2435 };
2436
2437
2438 /* Return an index value for a given button event code
2439  * returns 0 on non-button event.
2440  */
2441 unsigned int
2442 EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code)
2443 {
2444     unsigned int button = 0;
2445
2446     switch(code) {
2447     case BTN_LEFT:
2448         button = 1;
2449         break;
2450
2451     case BTN_RIGHT:
2452         button = 3;
2453         break;
2454
2455     case BTN_MIDDLE:
2456         button = 2;
2457         break;
2458
2459         /* Treat BTN_[0-2] as LMR buttons on devices that do not advertise
2460            BTN_LEFT, BTN_MIDDLE, BTN_RIGHT.
2461            Otherwise, treat BTN_[0+n] as button 5+n.
2462            XXX: This causes duplicate mappings for BTN_0 + n and BTN_SIDE + n
2463          */
2464     case BTN_0:
2465         button = (TestBit(BTN_LEFT, pEvdev->key_bitmask)) ?  8 : 1;
2466         break;
2467     case BTN_1:
2468         button = (TestBit(BTN_MIDDLE, pEvdev->key_bitmask)) ?  9 : 2;
2469         break;
2470     case BTN_2:
2471         button = (TestBit(BTN_RIGHT, pEvdev->key_bitmask)) ?  10 : 3;
2472         break;
2473
2474         /* FIXME: BTN_3.. and BTN_SIDE.. have the same button mapping */
2475     case BTN_3:
2476     case BTN_4:
2477     case BTN_5:
2478     case BTN_6:
2479     case BTN_7:
2480     case BTN_8:
2481     case BTN_9:
2482         button = (code - BTN_0 + 5);
2483         break;
2484
2485     case BTN_SIDE:
2486     case BTN_EXTRA:
2487     case BTN_FORWARD:
2488     case BTN_BACK:
2489     case BTN_TASK:
2490         button = (code - BTN_LEFT + 5);
2491         break;
2492
2493     default:
2494         if ((code > BTN_TASK) && (code < KEY_OK)) {
2495             if (code < BTN_JOYSTICK) {
2496                 if (code < BTN_MOUSE)
2497                     button = (code - BTN_0 + 5);
2498                 else
2499                     button = (code - BTN_LEFT + 5);
2500             }
2501         }
2502     }
2503
2504     if (button > EVDEV_MAXBUTTONS)
2505         return 0;
2506
2507     return button;
2508 }
2509
2510 #ifdef HAVE_PROPERTIES
2511 #ifdef HAVE_LABELS
2512 /* Aligned with linux/input.h.
2513    Note that there are holes in the ABS_ range, these are simply replaced with
2514    MISC here */
2515 static char* abs_labels[] = {
2516     AXIS_LABEL_PROP_ABS_X,              /* 0x00 */
2517     AXIS_LABEL_PROP_ABS_Y,              /* 0x01 */
2518     AXIS_LABEL_PROP_ABS_Z,              /* 0x02 */
2519     AXIS_LABEL_PROP_ABS_RX,             /* 0x03 */
2520     AXIS_LABEL_PROP_ABS_RY,             /* 0x04 */
2521     AXIS_LABEL_PROP_ABS_RZ,             /* 0x05 */
2522     AXIS_LABEL_PROP_ABS_THROTTLE,       /* 0x06 */
2523     AXIS_LABEL_PROP_ABS_RUDDER,         /* 0x07 */
2524     AXIS_LABEL_PROP_ABS_WHEEL,          /* 0x08 */
2525     AXIS_LABEL_PROP_ABS_GAS,            /* 0x09 */
2526     AXIS_LABEL_PROP_ABS_BRAKE,          /* 0x0a */
2527     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
2528     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
2529     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
2530     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
2531     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
2532     AXIS_LABEL_PROP_ABS_HAT0X,          /* 0x10 */
2533     AXIS_LABEL_PROP_ABS_HAT0Y,          /* 0x11 */
2534     AXIS_LABEL_PROP_ABS_HAT1X,          /* 0x12 */
2535     AXIS_LABEL_PROP_ABS_HAT1Y,          /* 0x13 */
2536     AXIS_LABEL_PROP_ABS_HAT2X,          /* 0x14 */
2537     AXIS_LABEL_PROP_ABS_HAT2Y,          /* 0x15 */
2538     AXIS_LABEL_PROP_ABS_HAT3X,          /* 0x16 */
2539     AXIS_LABEL_PROP_ABS_HAT3Y,          /* 0x17 */
2540     AXIS_LABEL_PROP_ABS_PRESSURE,       /* 0x18 */
2541     AXIS_LABEL_PROP_ABS_DISTANCE,       /* 0x19 */
2542     AXIS_LABEL_PROP_ABS_TILT_X,         /* 0x1a */
2543     AXIS_LABEL_PROP_ABS_TILT_Y,         /* 0x1b */
2544     AXIS_LABEL_PROP_ABS_TOOL_WIDTH,     /* 0x1c */
2545     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
2546     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
2547     AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
2548     AXIS_LABEL_PROP_ABS_VOLUME          /* 0x20 */
2549 };
2550
2551 static char* rel_labels[] = {
2552     AXIS_LABEL_PROP_REL_X,
2553     AXIS_LABEL_PROP_REL_Y,
2554     AXIS_LABEL_PROP_REL_Z,
2555     AXIS_LABEL_PROP_REL_RX,
2556     AXIS_LABEL_PROP_REL_RY,
2557     AXIS_LABEL_PROP_REL_RZ,
2558     AXIS_LABEL_PROP_REL_HWHEEL,
2559     AXIS_LABEL_PROP_REL_DIAL,
2560     AXIS_LABEL_PROP_REL_WHEEL,
2561     AXIS_LABEL_PROP_REL_MISC
2562 };
2563
2564 static char* btn_labels[][16] = {
2565     { /* BTN_MISC group                 offset 0x100*/
2566         BTN_LABEL_PROP_BTN_0,           /* 0x00 */
2567         BTN_LABEL_PROP_BTN_1,           /* 0x01 */
2568         BTN_LABEL_PROP_BTN_2,           /* 0x02 */
2569         BTN_LABEL_PROP_BTN_3,           /* 0x03 */
2570         BTN_LABEL_PROP_BTN_4,           /* 0x04 */
2571         BTN_LABEL_PROP_BTN_5,           /* 0x05 */
2572         BTN_LABEL_PROP_BTN_6,           /* 0x06 */
2573         BTN_LABEL_PROP_BTN_7,           /* 0x07 */
2574         BTN_LABEL_PROP_BTN_8,           /* 0x08 */
2575         BTN_LABEL_PROP_BTN_9            /* 0x09 */
2576     },
2577     { /* BTN_MOUSE group                offset 0x110 */
2578         BTN_LABEL_PROP_BTN_LEFT,        /* 0x00 */
2579         BTN_LABEL_PROP_BTN_RIGHT,       /* 0x01 */
2580         BTN_LABEL_PROP_BTN_MIDDLE,      /* 0x02 */
2581         BTN_LABEL_PROP_BTN_SIDE,        /* 0x03 */
2582         BTN_LABEL_PROP_BTN_EXTRA,       /* 0x04 */
2583         BTN_LABEL_PROP_BTN_FORWARD,     /* 0x05 */
2584         BTN_LABEL_PROP_BTN_BACK,        /* 0x06 */
2585         BTN_LABEL_PROP_BTN_TASK         /* 0x07 */
2586     },
2587     { /* BTN_JOYSTICK group             offset 0x120 */
2588         BTN_LABEL_PROP_BTN_TRIGGER,     /* 0x00 */
2589         BTN_LABEL_PROP_BTN_THUMB,       /* 0x01 */
2590         BTN_LABEL_PROP_BTN_THUMB2,      /* 0x02 */
2591         BTN_LABEL_PROP_BTN_TOP,         /* 0x03 */
2592         BTN_LABEL_PROP_BTN_TOP2,        /* 0x04 */
2593         BTN_LABEL_PROP_BTN_PINKIE,      /* 0x05 */
2594         BTN_LABEL_PROP_BTN_BASE,        /* 0x06 */
2595         BTN_LABEL_PROP_BTN_BASE2,       /* 0x07 */
2596         BTN_LABEL_PROP_BTN_BASE3,       /* 0x08 */
2597         BTN_LABEL_PROP_BTN_BASE4,       /* 0x09 */
2598         BTN_LABEL_PROP_BTN_BASE5,       /* 0x0a */
2599         BTN_LABEL_PROP_BTN_BASE6,       /* 0x0b */
2600         NULL,
2601         NULL,
2602         NULL,
2603         BTN_LABEL_PROP_BTN_DEAD         /* 0x0f */
2604     },
2605     { /* BTN_GAMEPAD group              offset 0x130 */
2606         BTN_LABEL_PROP_BTN_A,           /* 0x00 */
2607         BTN_LABEL_PROP_BTN_B,           /* 0x01 */
2608         BTN_LABEL_PROP_BTN_C,           /* 0x02 */
2609         BTN_LABEL_PROP_BTN_X,           /* 0x03 */
2610         BTN_LABEL_PROP_BTN_Y,           /* 0x04 */
2611         BTN_LABEL_PROP_BTN_Z,           /* 0x05 */
2612         BTN_LABEL_PROP_BTN_TL,          /* 0x06 */
2613         BTN_LABEL_PROP_BTN_TR,          /* 0x07 */
2614         BTN_LABEL_PROP_BTN_TL2,         /* 0x08 */
2615         BTN_LABEL_PROP_BTN_TR2,         /* 0x09 */
2616         BTN_LABEL_PROP_BTN_SELECT,      /* 0x0a */
2617         BTN_LABEL_PROP_BTN_START,       /* 0x0b */
2618         BTN_LABEL_PROP_BTN_MODE,        /* 0x0c */
2619         BTN_LABEL_PROP_BTN_THUMBL,      /* 0x0d */
2620         BTN_LABEL_PROP_BTN_THUMBR       /* 0x0e */
2621     },
2622     { /* BTN_DIGI group                         offset 0x140 */
2623         BTN_LABEL_PROP_BTN_TOOL_PEN,            /* 0x00 */
2624         BTN_LABEL_PROP_BTN_TOOL_RUBBER,         /* 0x01 */
2625         BTN_LABEL_PROP_BTN_TOOL_BRUSH,          /* 0x02 */
2626         BTN_LABEL_PROP_BTN_TOOL_PENCIL,         /* 0x03 */
2627         BTN_LABEL_PROP_BTN_TOOL_AIRBRUSH,       /* 0x04 */
2628         BTN_LABEL_PROP_BTN_TOOL_FINGER,         /* 0x05 */
2629         BTN_LABEL_PROP_BTN_TOOL_MOUSE,          /* 0x06 */
2630         BTN_LABEL_PROP_BTN_TOOL_LENS,           /* 0x07 */
2631         NULL,
2632         NULL,
2633         BTN_LABEL_PROP_BTN_TOUCH,               /* 0x0a */
2634         BTN_LABEL_PROP_BTN_STYLUS,              /* 0x0b */
2635         BTN_LABEL_PROP_BTN_STYLUS2,             /* 0x0c */
2636         BTN_LABEL_PROP_BTN_TOOL_DOUBLETAP,      /* 0x0d */
2637         BTN_LABEL_PROP_BTN_TOOL_TRIPLETAP       /* 0x0e */
2638     },
2639     { /* BTN_WHEEL group                        offset 0x150 */
2640         BTN_LABEL_PROP_BTN_GEAR_DOWN,           /* 0x00 */
2641         BTN_LABEL_PROP_BTN_GEAR_UP              /* 0x01 */
2642     }
2643 };
2644
2645 #endif /* HAVE_LABELS */
2646
2647 static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms)
2648 {
2649 #ifdef HAVE_LABELS
2650     Atom atom;
2651     int axis;
2652     char **labels;
2653     int labels_len = 0;
2654     char *misc_label;
2655
2656     if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
2657     {
2658         labels     = abs_labels;
2659         labels_len = ArrayLength(abs_labels);
2660         misc_label = AXIS_LABEL_PROP_ABS_MISC;
2661     } else if ((pEvdev->flags & EVDEV_RELATIVE_EVENTS))
2662     {
2663         labels     = rel_labels;
2664         labels_len = ArrayLength(rel_labels);
2665         misc_label = AXIS_LABEL_PROP_REL_MISC;
2666     }
2667
2668     memset(atoms, 0, natoms * sizeof(Atom));
2669
2670     /* Now fill the ones we know */
2671     for (axis = 0; axis < labels_len; axis++)
2672     {
2673         if (pEvdev->axis_map[axis] == -1)
2674             continue;
2675
2676         atom = XIGetKnownProperty(labels[axis]);
2677         if (!atom) /* Should not happen */
2678             continue;
2679
2680         atoms[pEvdev->axis_map[axis]] = atom;
2681     }
2682 #endif
2683 }
2684
2685 static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms)
2686 {
2687 #ifdef HAVE_LABELS
2688     Atom atom;
2689     int button, bmap;
2690
2691     /* First, make sure all atoms are initialized */
2692     atom = XIGetKnownProperty(BTN_LABEL_PROP_BTN_UNKNOWN);
2693     for (button = 0; button < natoms; button++)
2694         atoms[button] = atom;
2695
2696     for (button = BTN_MISC; button < BTN_JOYSTICK; button++)
2697     {
2698         if (TestBit(button, pEvdev->key_bitmask))
2699         {
2700             int group = (button % 0x100)/16;
2701             int idx = button - ((button/16) * 16);
2702
2703             if (!btn_labels[group][idx])
2704                 continue;
2705
2706             atom = XIGetKnownProperty(btn_labels[group][idx]);
2707             if (!atom)
2708                 continue;
2709
2710             /* Props are 0-indexed, button numbers start with 1 */
2711             bmap = EvdevUtilButtonEventToButtonNumber(pEvdev, button) - 1;
2712             atoms[bmap] = atom;
2713         }
2714     }
2715
2716     /* wheel buttons, hardcoded anyway */
2717     if (natoms > 3)
2718         atoms[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
2719     if (natoms > 4)
2720         atoms[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
2721     if (natoms > 5)
2722         atoms[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
2723     if (natoms > 6)
2724         atoms[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
2725 #endif
2726 }
2727
2728 static void
2729 EvdevInitProperty(DeviceIntPtr dev)
2730 {
2731     InputInfoPtr pInfo  = dev->public.devicePrivate;
2732     EvdevPtr     pEvdev = pInfo->private;
2733     int          rc;
2734     BOOL         invert[2];
2735     char         reopen;
2736 #ifdef _F_EVDEV_CONFINE_REGION_
2737     int region[4] = { 0, };
2738 #endif//_F_EVDEV_CONFINE_REGION_
2739
2740     prop_reopen = MakeAtom(EVDEV_PROP_REOPEN, strlen(EVDEV_PROP_REOPEN),
2741             TRUE);
2742
2743     reopen = pEvdev->reopen_attempts;
2744     rc = XIChangeDeviceProperty(dev, prop_reopen, XA_INTEGER, 8,
2745                                 PropModeReplace, 1, &reopen, FALSE);
2746     if (rc != Success)
2747         return;
2748
2749     XISetDevicePropertyDeletable(dev, prop_reopen, FALSE);
2750
2751     if (pEvdev->flags & (EVDEV_RELATIVE_EVENTS | EVDEV_ABSOLUTE_EVENTS))
2752     {
2753         invert[0] = pEvdev->invert_x;
2754         invert[1] = pEvdev->invert_y;
2755
2756         prop_invert = MakeAtom(EVDEV_PROP_INVERT_AXES, strlen(EVDEV_PROP_INVERT_AXES), TRUE);
2757
2758         rc = XIChangeDeviceProperty(dev, prop_invert, XA_INTEGER, 8,
2759                 PropModeReplace, 2,
2760                 invert, FALSE);
2761         if (rc != Success)
2762             return;
2763
2764         XISetDevicePropertyDeletable(dev, prop_invert, FALSE);
2765
2766         prop_calibration = MakeAtom(EVDEV_PROP_CALIBRATION,
2767                 strlen(EVDEV_PROP_CALIBRATION), TRUE);
2768         if (pEvdev->flags & EVDEV_CALIBRATED) {
2769             int calibration[4];
2770
2771             calibration[0] = pEvdev->calibration.min_x;
2772             calibration[1] = pEvdev->calibration.max_x;
2773             calibration[2] = pEvdev->calibration.min_y;
2774             calibration[3] = pEvdev->calibration.max_y;
2775
2776             rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER,
2777                     32, PropModeReplace, 4, calibration,
2778                     FALSE);
2779         } else if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) {
2780             rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER,
2781                     32, PropModeReplace, 0, NULL,
2782                     FALSE);
2783         }
2784         if (rc != Success)
2785             return;
2786
2787         XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
2788
2789         prop_swap = MakeAtom(EVDEV_PROP_SWAP_AXES,
2790                 strlen(EVDEV_PROP_SWAP_AXES), TRUE);
2791
2792         rc = XIChangeDeviceProperty(dev, prop_swap, XA_INTEGER, 8,
2793                 PropModeReplace, 1, &pEvdev->swap_axes, FALSE);
2794         if (rc != Success)
2795             return;
2796
2797         XISetDevicePropertyDeletable(dev, prop_swap, FALSE);
2798
2799 #ifdef HAVE_LABELS
2800         /* Axis labelling */
2801         if ((pEvdev->num_vals > 0) && (prop_axis_label = XIGetKnownProperty(AXIS_LABEL_PROP)))
2802         {
2803             Atom atoms[pEvdev->num_vals];
2804             EvdevInitAxesLabels(pEvdev, pEvdev->num_vals, atoms);
2805             XIChangeDeviceProperty(dev, prop_axis_label, XA_ATOM, 32,
2806                                    PropModeReplace, pEvdev->num_vals, atoms, FALSE);
2807             XISetDevicePropertyDeletable(dev, prop_axis_label, FALSE);
2808         }
2809         /* Button labelling */
2810         if ((pEvdev->num_buttons > 0) && (prop_btn_label = XIGetKnownProperty(BTN_LABEL_PROP)))
2811         {
2812             Atom atoms[EVDEV_MAXBUTTONS];
2813             EvdevInitButtonLabels(pEvdev, EVDEV_MAXBUTTONS, atoms);
2814             XIChangeDeviceProperty(dev, prop_btn_label, XA_ATOM, 32,
2815                                    PropModeReplace, pEvdev->num_buttons, atoms, FALSE);
2816             XISetDevicePropertyDeletable(dev, prop_btn_label, FALSE);
2817         }
2818 #endif /* HAVE_LABELS */
2819
2820 #ifdef _F_EVDEV_CONFINE_REGION_
2821         prop_confine_region = MakeAtom(EVDEV_PROP_CONFINE_REGION,
2822                 strlen(EVDEV_PROP_CONFINE_REGION), TRUE);
2823         rc = XIChangeDeviceProperty(dev, prop_confine_region, XA_INTEGER,
2824                     32, PropModeReplace, 4, region, FALSE);
2825
2826         if (rc != Success)
2827             return;
2828 #endif /* _F_EVDEV_CONFINE_REGION_ */
2829     }
2830
2831 }
2832
2833 static void EvdevSwapAxes(EvdevPtr pEvdev)
2834 {
2835     if(pEvdev->swap_axes)
2836     {
2837         pEvdev->absinfo[ABS_Y].maximum = pEvdev->resolution.min_x;
2838         pEvdev->absinfo[ABS_Y].minimum = pEvdev->resolution.max_x;
2839         pEvdev->absinfo[ABS_X].maximum = pEvdev->resolution.min_y;
2840         pEvdev->absinfo[ABS_X].minimum = pEvdev->resolution.max_y;
2841     }
2842     else
2843     {
2844         pEvdev->absinfo[ABS_X].maximum = pEvdev->resolution.min_x;
2845         pEvdev->absinfo[ABS_X].minimum = pEvdev->resolution.max_x;
2846         pEvdev->absinfo[ABS_Y].maximum = pEvdev->resolution.min_y;
2847         pEvdev->absinfo[ABS_Y].minimum = pEvdev->resolution.max_y;
2848     }
2849 }
2850
2851 static void
2852 EvdevSetResolution(InputInfoPtr pInfo, int num_resolution, int resolution[4])
2853 {
2854     EvdevPtr pEvdev = pInfo->private;
2855
2856     if (num_resolution == 0) {
2857         pEvdev->flags &= ~EVDEV_RESOLUTION;
2858         pEvdev->resolution.min_x = 0;
2859         pEvdev->resolution.max_x = 0;
2860         pEvdev->resolution.min_y = 0;
2861         pEvdev->resolution.max_y = 0;
2862     } else if (num_resolution == 4) {
2863         pEvdev->flags |= EVDEV_RESOLUTION;
2864         pEvdev->resolution.min_x = resolution[0];
2865         pEvdev->resolution.max_x = resolution[1];
2866         pEvdev->resolution.min_y = resolution[2];
2867         pEvdev->resolution.max_y = resolution[3];
2868     }
2869 }
2870
2871 static int
2872 EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
2873                  BOOL checkonly)
2874 {
2875     InputInfoPtr pInfo  = dev->public.devicePrivate;
2876     EvdevPtr     pEvdev = pInfo->private;
2877
2878     if (atom == prop_invert)
2879     {
2880         BOOL* data;
2881         if (val->format != 8 || val->size != 2 || val->type != XA_INTEGER)
2882             return BadMatch;
2883
2884         if (!checkonly)
2885         {
2886             data = (BOOL*)val->data;
2887             pEvdev->invert_x = data[0];
2888             pEvdev->invert_y = data[1];
2889         }
2890     } else if (atom == prop_reopen)
2891     {
2892         if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
2893             return BadMatch;
2894
2895         if (!checkonly)
2896             pEvdev->reopen_attempts = *((CARD8*)val->data);
2897     } else if (atom == prop_calibration)
2898     {
2899         if (val->format != 32 || val->type != XA_INTEGER)
2900             return BadMatch;
2901         if (val->size != 4 && val->size != 0)
2902             return BadMatch;
2903
2904         if (!checkonly)
2905             EvdevSetCalibration(pInfo, val->size, val->data);
2906     } else if (atom == prop_swap)
2907     {
2908         if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
2909             return BadMatch;
2910
2911         if (!checkonly)
2912             pEvdev->swap_axes = *((BOOL*)val->data);
2913          EvdevSwapAxes(pEvdev);
2914     } else if (atom == prop_axis_label || atom == prop_btn_label)
2915         return BadAccess; /* Axis/Button labels can't be changed */
2916 #ifdef _F_EVDEV_CONFINE_REGION_
2917     else if (atom == prop_confine_region)
2918     {
2919         if (val->format != 32 || val->type != XA_INTEGER)
2920             return BadMatch;
2921         if (val->size != 1 && val->size != 5)
2922             return BadMatch;
2923
2924         if (!checkonly)
2925             EvdevSetConfineRegion(pInfo, val->size, val->data);
2926     }
2927 #endif /* _F_EVDEV_CONFINE_REGION_ */
2928     return Success;
2929 }
2930 #endif
2931
2932