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  *	Thomas H.P. Andersen (phomes@gmail.com)
29  */
30 
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34 
35 #include "evdev.h"
36 #include "axis_labels.h"
37 
38 #include <X11/keysym.h>
39 #include <X11/extensions/XI.h>
40 
41 #ifdef __linux__
42 #include <linux/version.h>
43 #endif
44 #include <sys/stat.h>
45 #ifdef HAVE_LIBUDEV
46 #include <libudev.h>
47 #endif
48 #include <unistd.h>
49 #include <errno.h>
50 #include <fcntl.h>
51 
52 #include <xf86.h>
53 #include <xf86Xinput.h>
54 #include <exevents.h>
55 #include <xorgVersion.h>
56 #include <xkbsrv.h>
57 
58 #include <X11/Xatom.h>
59 #include <evdev-properties.h>
60 #include <xserver-properties.h>
61 #include <mtdev-plumbing.h>
62 
63 #ifndef XI_PROP_PRODUCT_ID
64 #define XI_PROP_PRODUCT_ID "Device Product ID"
65 #endif
66 
67 #ifndef XI_PROP_VIRTUAL_DEVICE
68 #define XI_PROP_VIRTUAL_DEVICE "Virtual Device"
69 #endif
70 
71 /* removed from server, purge when dropping support for server 1.10 */
72 #define XI86_SEND_DRAG_EVENTS   0x08
73 
74 #define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
75 
76 #define MIN_KEYCODE 8
77 
78 #define CAPSFLAG	1
79 #define NUMFLAG		2
80 #define SCROLLFLAG	4
81 #define MODEFLAG	8
82 #define COMPOSEFLAG	16
83 
84 #ifndef ABS_MT_SLOT
85 #define ABS_MT_SLOT 0x2f
86 #endif
87 
88 #ifndef ABS_MT_TRACKING_ID
89 #define ABS_MT_TRACKING_ID 0x39
90 #endif
91 
92 #ifndef XI86_SERVER_FD
93 #define XI86_SERVER_FD 0x20
94 #endif
95 
96 /* Any of those triggers a proximity event */
97 static int proximity_bits[] = {
98         BTN_TOOL_PEN,
99         BTN_TOOL_RUBBER,
100         BTN_TOOL_BRUSH,
101         BTN_TOOL_PENCIL,
102         BTN_TOOL_AIRBRUSH,
103         BTN_TOOL_FINGER,
104         BTN_TOOL_MOUSE,
105         BTN_TOOL_LENS,
106 };
107 
108 static int EvdevOn(DeviceIntPtr);
109 static int EvdevCache(InputInfoPtr pInfo);
110 static void EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl);
111 static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode);
112 static BOOL EvdevGrabDevice(InputInfoPtr pInfo, int grab, int ungrab);
113 static void EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4]);
114 static int EvdevOpenDevice(InputInfoPtr pInfo);
115 static void EvdevCloseDevice(InputInfoPtr pInfo);
116 
117 static void EvdevInitAxesLabels(EvdevPtr pEvdev, int mode, int natoms, Atom *atoms);
118 static void EvdevInitOneAxisLabel(EvdevPtr pEvdev, int mapped_axis,
119                                   const char **labels, int label_idx, Atom *atoms);
120 static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
121 static void EvdevInitProperty(DeviceIntPtr dev);
122 static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
123                             XIPropertyValuePtr val, BOOL checkonly);
124 static Atom prop_product_id;
125 static Atom prop_invert;
126 static Atom prop_calibration;
127 static Atom prop_swap;
128 static Atom prop_axis_label;
129 static Atom prop_btn_label;
130 static Atom prop_device;
131 static Atom prop_virtual;
132 static Atom prop_scroll_dist;
133 
EvdevSwitchMode(ClientPtr client,DeviceIntPtr device,int mode)134 static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode)
135 {
136     InputInfoPtr pInfo;
137     EvdevPtr pEvdev;
138     int val;
139 
140     pInfo = device->public.devicePrivate;
141     pEvdev = pInfo->private;
142 
143     if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
144     {
145         if (mode == Relative)
146             return Success;
147         else
148             return XI_BadMode;
149     }
150 
151     switch (mode) {
152         case Absolute:
153             pEvdev->flags &= ~EVDEV_RELATIVE_MODE;
154             if (valuator_mask_fetch(pEvdev->old_vals, 0, &val))
155                 valuator_mask_set(pEvdev->abs_vals, 0, val);
156             if (valuator_mask_fetch(pEvdev->old_vals, 1, &val))
157                 valuator_mask_set(pEvdev->abs_vals, 1, val);
158             valuator_mask_zero(pEvdev->old_vals);
159             break;
160 
161         case Relative:
162             pEvdev->flags |= EVDEV_RELATIVE_MODE;
163             if (valuator_mask_fetch(pEvdev->abs_vals, 0, &val))
164                 valuator_mask_set(pEvdev->old_vals, 0, val);
165             if (valuator_mask_fetch(pEvdev->abs_vals, 1, &val))
166                 valuator_mask_set(pEvdev->old_vals, 1, val);
167             valuator_mask_unset(pEvdev->abs_vals, 0);
168             valuator_mask_unset(pEvdev->abs_vals, 1);
169             break;
170 
171         default:
172             return XI_BadMode;
173     }
174 
175     return Success;
176 }
177 
EvdevBitIsSet(const unsigned long * array,int bit)178 static inline int EvdevBitIsSet(const unsigned long *array, int bit)
179 {
180     return !!(array[bit / LONG_BITS] & (1LL << (bit % LONG_BITS)));
181 }
182 
EvdevSetBit(unsigned long * array,int bit)183 static inline void EvdevSetBit(unsigned long *array, int bit)
184 {
185     array[bit / LONG_BITS] |= (1LL << (bit % LONG_BITS));
186 }
187 
188 static int
EvdevGetMajorMinor(InputInfoPtr pInfo)189 EvdevGetMajorMinor(InputInfoPtr pInfo)
190 {
191     struct stat st;
192 
193     if (fstat(pInfo->fd, &st) == -1)
194     {
195         xf86IDrvMsg(pInfo, X_ERROR, "stat failed (%s). cannot check for duplicates.\n",
196                     strerror(errno));
197         return 0;
198     }
199 
200     return st.st_rdev;
201 }
202 
203 /**
204  * Return TRUE if one of the devices we know about has the same min/maj
205  * number.
206  */
207 static BOOL
EvdevIsDuplicate(InputInfoPtr pInfo)208 EvdevIsDuplicate(InputInfoPtr pInfo)
209 {
210     EvdevPtr pEvdev = pInfo->private;
211     InputInfoPtr d;
212 
213     nt_list_for_each_entry(d, xf86FirstLocalDevice(), next)
214     {
215         EvdevPtr e;
216 
217         if (strcmp(d->drv->driverName, "evdev") != 0)
218             continue;
219 
220         e = (EvdevPtr)d->private;
221         if (e != pEvdev &&
222             e->min_maj &&
223             e->min_maj == pEvdev->min_maj)
224             return TRUE;
225     }
226 
227     return FALSE;
228 }
229 
230 static BOOL
EvdevDeviceIsVirtual(const char * devicenode)231 EvdevDeviceIsVirtual(const char* devicenode)
232 {
233 #ifdef HAVE_LIBUDEV
234     struct udev *udev = NULL;
235     struct udev_device *device = NULL;
236     struct stat st;
237     int rc = FALSE;
238     const char *devpath;
239 
240     udev = udev_new();
241     if (!udev)
242         goto out;
243 
244     if (stat(devicenode, &st) == -1)
245         goto out;
246 
247     device = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
248 
249     if (!device)
250         goto out;
251 
252 
253     devpath = udev_device_get_devpath(device);
254     if (!devpath)
255         goto out;
256 
257     if (strstr(devpath, "LNXSYSTM"))
258         rc = TRUE;
259 
260 out:
261     udev_device_unref(device);
262     udev_unref(udev);
263     return rc;
264 #else
265     return FALSE;
266 #endif
267 }
268 
269 
270 static EventQueuePtr
EvdevNextInQueue(InputInfoPtr pInfo)271 EvdevNextInQueue(InputInfoPtr pInfo)
272 {
273     EvdevPtr pEvdev = pInfo->private;
274 
275     if (pEvdev->num_queue >= EVDEV_MAXQUEUE)
276     {
277         LogMessageVerbSigSafe(X_WARNING, 0, "dropping event due to full queue!\n");
278         return NULL;
279     }
280 
281     pEvdev->num_queue++;
282     return &pEvdev->queue[pEvdev->num_queue - 1];
283 }
284 
285 void
EvdevQueueKbdEvent(InputInfoPtr pInfo,struct input_event * ev,int value)286 EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
287 {
288     int code = ev->code + MIN_KEYCODE;
289     EventQueuePtr pQueue;
290 
291     /* Filter all repeated events from device.
292        We'll do softrepeat in the server, but only since 1.6 */
293     if (value == 2)
294         return;
295 
296     if ((pQueue = EvdevNextInQueue(pInfo)))
297     {
298         pQueue->type = EV_QUEUE_KEY;
299         pQueue->detail.key = code;
300         pQueue->val = value;
301     }
302 }
303 
304 void
EvdevQueueButtonEvent(InputInfoPtr pInfo,int button,int value)305 EvdevQueueButtonEvent(InputInfoPtr pInfo, int button, int value)
306 {
307     EventQueuePtr pQueue;
308 
309     if ((pQueue = EvdevNextInQueue(pInfo)))
310     {
311         pQueue->type = EV_QUEUE_BTN;
312         pQueue->detail.key = button;
313         pQueue->val = value;
314     }
315 }
316 
317 void
EvdevQueueProximityEvent(InputInfoPtr pInfo,int value)318 EvdevQueueProximityEvent(InputInfoPtr pInfo, int value)
319 {
320     EventQueuePtr pQueue;
321     if ((pQueue = EvdevNextInQueue(pInfo)))
322     {
323         pQueue->type = EV_QUEUE_PROXIMITY;
324         pQueue->detail.key = 0;
325         pQueue->val = value;
326     }
327 }
328 
329 void
EvdevQueueTouchEvent(InputInfoPtr pInfo,unsigned int touch,ValuatorMask * mask,uint16_t evtype)330 EvdevQueueTouchEvent(InputInfoPtr pInfo, unsigned int touch, ValuatorMask *mask,
331                      uint16_t evtype)
332 {
333     EventQueuePtr pQueue;
334     if ((pQueue = EvdevNextInQueue(pInfo)))
335     {
336         pQueue->type = EV_QUEUE_TOUCH;
337         pQueue->detail.touch = touch;
338         valuator_mask_copy(pQueue->touchMask, mask);
339         pQueue->val = evtype;
340     }
341 }
342 
343 /**
344  * Post button event right here, right now.
345  * Interface for MB emulation since these need to post immediately.
346  */
347 void
EvdevPostButtonEvent(InputInfoPtr pInfo,int button,enum ButtonAction act)348 EvdevPostButtonEvent(InputInfoPtr pInfo, int button, enum ButtonAction act)
349 {
350     xf86PostButtonEvent(pInfo->dev, Relative, button,
351                         (act == BUTTON_PRESS) ? 1 : 0, 0, 0);
352 }
353 
354 void
EvdevQueueButtonClicks(InputInfoPtr pInfo,int button,int count)355 EvdevQueueButtonClicks(InputInfoPtr pInfo, int button, int count)
356 {
357     int i;
358 
359     for (i = 0; i < count; i++) {
360         EvdevQueueButtonEvent(pInfo, button, 1);
361         EvdevQueueButtonEvent(pInfo, button, 0);
362     }
363 }
364 
365 static void
EvdevSwapAbsValuators(EvdevPtr pEvdev,ValuatorMask * mask)366 EvdevSwapAbsValuators(EvdevPtr pEvdev, ValuatorMask *mask)
367 {
368     int i;
369     int swapped_isset[2] = {0, 0};
370     int swapped_values[2];
371 
372     if (!pEvdev->swap_axes)
373         return;
374 
375     for(i = 0; i <= 1; i++) {
376         if (valuator_mask_isset(mask, i)) {
377             const struct input_absinfo *abs1 =
378                 libevdev_get_abs_info(pEvdev->dev, i);
379             const struct input_absinfo *abs2 =
380                 libevdev_get_abs_info(pEvdev->dev, 1 - i);
381 
382             swapped_isset[1 - i] = 1;
383             swapped_values[1 - i] =
384                 xf86ScaleAxis(valuator_mask_get(mask, i),
385                               abs2->maximum, abs2->minimum,
386                               abs1->maximum, abs1->minimum);
387         }
388     }
389 
390     for (i = 0; i <= 1; i++) {
391         if (swapped_isset[i])
392             valuator_mask_set(mask, i, swapped_values[i]);
393         else
394             valuator_mask_unset(mask, i);
395     }
396 }
397 
398 static void
EvdevApplyCalibration(EvdevPtr pEvdev,ValuatorMask * mask)399 EvdevApplyCalibration(EvdevPtr pEvdev, ValuatorMask *mask)
400 {
401     int i;
402 
403     for (i = 0; i <= 1; i++) {
404         const struct input_absinfo *abs;
405         int val;
406         int calib_min;
407         int calib_max;
408 
409         if (!valuator_mask_isset(mask, i))
410             continue;
411 
412         val = valuator_mask_get(mask, i);
413         abs = libevdev_get_abs_info(pEvdev->dev, i);
414 
415         if (i == 0) {
416             calib_min = pEvdev->calibration.min_x;
417             calib_max = pEvdev->calibration.max_x;
418         } else {
419             calib_min = pEvdev->calibration.min_y;
420             calib_max = pEvdev->calibration.max_y;
421         }
422 
423         if (pEvdev->flags & EVDEV_CALIBRATED)
424             val = xf86ScaleAxis(val, abs->maximum, abs->minimum,
425                                 calib_max, calib_min);
426 
427         if ((i == 0 && pEvdev->invert_x) || (i == 1 && pEvdev->invert_y))
428             val = (abs->maximum - val + abs->minimum);
429 
430         valuator_mask_set(mask, i, val);
431     }
432 }
433 
434 /**
435  * Take the valuators and process them accordingly.
436  */
437 static void
EvdevProcessValuators(InputInfoPtr pInfo)438 EvdevProcessValuators(InputInfoPtr pInfo)
439 {
440     EvdevPtr pEvdev = pInfo->private;
441     int val;
442 
443     if (pEvdev->abs_vals) {
444             if (valuator_mask_fetch(pEvdev->abs_vals, 0, &val))
445                     valuator_mask_set(pEvdev->old_vals, 0, val);
446             if (valuator_mask_fetch(pEvdev->abs_vals, 1, &val))
447                     valuator_mask_set(pEvdev->old_vals, 1, val);
448     }
449 
450     /* Apply transformations on relative coordinates */
451     if (pEvdev->rel_queued) {
452         double deltaX = 0, deltaY = 0;
453 
454         if (valuator_mask_isset(pEvdev->rel_vals, REL_X))
455             deltaX = valuator_mask_get_double(pEvdev->rel_vals, REL_X);
456         if (valuator_mask_isset(pEvdev->rel_vals, REL_Y))
457             deltaY = valuator_mask_get_double(pEvdev->rel_vals, REL_Y);
458 
459         if (pEvdev->swap_axes) {
460             double tmp = deltaX;
461             deltaX = deltaY;
462             deltaY = tmp;
463         }
464 
465         if (pEvdev->resolution > 0) {
466             deltaX *= DEFAULT_MOUSE_DPI / pEvdev->resolution;
467             deltaY *= DEFAULT_MOUSE_DPI / pEvdev->resolution;
468         }
469 
470         if (pEvdev->invert_x)
471             deltaX *= -1;
472         if (pEvdev->invert_y)
473             deltaY *= -1;
474 
475         if (deltaX)
476             valuator_mask_set_double(pEvdev->rel_vals, REL_X, deltaX);
477         else
478             valuator_mask_unset(pEvdev->rel_vals, REL_X);
479 
480         if (deltaY)
481             valuator_mask_set_double(pEvdev->rel_vals, REL_Y, deltaY);
482         else
483             valuator_mask_unset(pEvdev->rel_vals, REL_Y);
484 
485         Evdev3BEmuProcessRelMotion(pInfo, deltaX, deltaY);
486 
487     }
488     /*
489      * Some devices only generate valid abs coords when BTN_TOOL_PEN is
490      * pressed.  On wacom tablets, this means that the pen is in
491      * proximity of the tablet.  After the pen is removed, BTN_TOOL_PEN is
492      * released, and a (0, 0) absolute event is generated.  Checking
493      * pEvdev->in_proximity here lets us ignore that event.  pEvdev is
494      * initialized to 1 so devices that don't use this scheme still
495      * just works.
496      */
497     else if (pEvdev->abs_queued && pEvdev->in_proximity) {
498         EvdevSwapAbsValuators(pEvdev, pEvdev->abs_vals);
499         EvdevApplyCalibration(pEvdev, pEvdev->abs_vals);
500         Evdev3BEmuProcessAbsMotion(pInfo, pEvdev->abs_vals);
501     }
502 }
503 
504 static void
EvdevProcessProximityEvent(InputInfoPtr pInfo,struct input_event * ev)505 EvdevProcessProximityEvent(InputInfoPtr pInfo, struct input_event *ev)
506 {
507     EvdevPtr pEvdev = pInfo->private;
508 
509     if (!pEvdev->use_proximity)
510         return;
511 
512     pEvdev->prox_queued = 1;
513 
514     EvdevQueueProximityEvent(pInfo, ev->value);
515 }
516 
517 /**
518  * Proximity handling is rather weird because of tablet-specific issues.
519  * Some tablets, notably Wacoms, send a 0/0 coordinate in the same EV_SYN as
520  * the out-of-proximity notify. We need to ignore those, hence we only
521  * actually post valuator events when we're in proximity.
522  *
523  * Other tablets send the x/y coordinates, then EV_SYN, then the proximity
524  * event. For those, we need to remember x/y to post it when the proximity
525  * comes.
526  *
527  * If we're not in proximity and we get valuator events, remember that, they
528  * won't be posted though. If we move into proximity without valuators, use
529  * the last ones we got and let the rest of the code post them.
530  */
531 static int
EvdevProcessProximityState(InputInfoPtr pInfo)532 EvdevProcessProximityState(InputInfoPtr pInfo)
533 {
534     EvdevPtr pEvdev = pInfo->private;
535     int prox_state = 0;
536     int i;
537 
538     /* Does this device have any proximity axes? */
539     if (!pEvdev->prox)
540         return 0;
541 
542     /* no proximity change in the queue */
543     if (!pEvdev->prox_queued)
544     {
545         if (pEvdev->abs_queued && !pEvdev->in_proximity)
546             for (i = 0; i < valuator_mask_size(pEvdev->abs_vals); i++)
547                 if (valuator_mask_isset(pEvdev->abs_vals, i))
548                     valuator_mask_set(pEvdev->prox, i,
549                                       valuator_mask_get(pEvdev->abs_vals, i));
550         return 0;
551     }
552 
553     for (i = 0; i < pEvdev->num_queue; i++)
554     {
555         if (pEvdev->queue[i].type == EV_QUEUE_PROXIMITY)
556         {
557             prox_state = pEvdev->queue[i].val;
558             break;
559         }
560     }
561 
562     /* Wacom's last frame resets all values to 0, including x/y.
563        Skip over this. */
564     if (prox_state == 0) {
565         int v;
566         if (valuator_mask_fetch(pEvdev->abs_vals, 0, &v) && v == 0)
567             valuator_mask_unset(pEvdev->abs_vals, 0);
568         if (valuator_mask_fetch(pEvdev->abs_vals, 1, &v) && v == 0)
569             valuator_mask_unset(pEvdev->abs_vals, 1);
570     }
571 
572     if ((prox_state && !pEvdev->in_proximity) ||
573         (!prox_state && pEvdev->in_proximity))
574     {
575         /* We're about to go into/out of proximity but have no abs events
576          * within the EV_SYN. Use the last coordinates we have. */
577         for (i = 0; i < valuator_mask_size(pEvdev->prox); i++)
578             if (!valuator_mask_isset(pEvdev->abs_vals, i) &&
579                 valuator_mask_isset(pEvdev->prox, i))
580                 valuator_mask_set(pEvdev->abs_vals, i,
581                                   valuator_mask_get(pEvdev->prox, i));
582         valuator_mask_zero(pEvdev->prox);
583 
584         pEvdev->abs_queued = valuator_mask_size(pEvdev->abs_vals);
585     }
586 
587     pEvdev->in_proximity = prox_state;
588     return 1;
589 }
590 
591 /**
592  * Take a button input event and process it accordingly.
593  */
594 static void
EvdevProcessButtonEvent(InputInfoPtr pInfo,struct input_event * ev)595 EvdevProcessButtonEvent(InputInfoPtr pInfo, struct input_event *ev)
596 {
597     unsigned int button;
598     int value;
599     EvdevPtr pEvdev = pInfo->private;
600 
601     button = EvdevUtilButtonEventToButtonNumber(pEvdev, ev->code);
602 
603     /* Get the signed value, earlier kernels had this as unsigned */
604     value = ev->value;
605 
606     /* Handle drag lock */
607     if (EvdevDragLockFilterEvent(pInfo, button, value))
608         return;
609 
610     if (EvdevWheelEmuFilterButton(pInfo, button, value))
611         return;
612 
613     if (EvdevMBEmuFilterEvent(pInfo, button, value))
614         return;
615 
616     if (button)
617         EvdevQueueButtonEvent(pInfo, button, value);
618     else
619         EvdevQueueKbdEvent(pInfo, ev, value);
620 }
621 
622 /**
623  * Take the relative motion input event and process it accordingly.
624  */
625 static void
EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo,struct input_event * ev)626 EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
627 {
628     int value;
629     EvdevPtr pEvdev = pInfo->private;
630     int map;
631 
632     /* Get the signed value, earlier kernels had this as unsigned */
633     value = ev->value;
634 
635     switch (ev->code) {
636         default:
637             /* Ignore EV_REL events if we never set up for them. */
638             if (!(pEvdev->flags & EVDEV_RELATIVE_EVENTS) &&
639                     ev->code != REL_WHEEL && ev->code != REL_DIAL &&
640                     ev->code != REL_HWHEEL)
641                 return;
642 
643             /* Handle mouse wheel emulation */
644             if (EvdevWheelEmuFilterMotion(pInfo, ev))
645                 return;
646 
647             pEvdev->rel_queued = 1;
648             map = pEvdev->rel_axis_map[ev->code];
649 
650             if (valuator_mask_isset(pEvdev->rel_vals, map))
651                 value += valuator_mask_get(pEvdev->rel_vals, map);
652 
653             valuator_mask_set(pEvdev->rel_vals, map, value);
654             break;
655     }
656 }
657 
658 static void
EvdevProcessTouch(InputInfoPtr pInfo)659 EvdevProcessTouch(InputInfoPtr pInfo)
660 {
661     EvdevPtr pEvdev = pInfo->private;
662     int type;
663     int slot = pEvdev->cur_slot;
664 
665     if (slot < 0 || !pEvdev->mt_mask)
666         return;
667 
668     if (!pEvdev->slots[slot].dirty)
669         return;
670 
671     switch(pEvdev->slots[slot].state)
672     {
673         case SLOTSTATE_EMPTY:
674             return;
675         case SLOTSTATE_CLOSE:
676             type = XI_TouchEnd;
677             pEvdev->slots[slot].state = SLOTSTATE_EMPTY;
678             break;
679         case SLOTSTATE_OPEN:
680             type = XI_TouchBegin;
681             pEvdev->slots[slot].state = SLOTSTATE_UPDATE;
682             break;
683         case SLOTSTATE_UPDATE:
684         default:
685             type = XI_TouchUpdate;
686             break;
687     }
688 
689     EvdevSwapAbsValuators(pEvdev, pEvdev->mt_mask);
690     EvdevApplyCalibration(pEvdev, pEvdev->mt_mask);
691 
692     EvdevQueueTouchEvent(pInfo, pEvdev->cur_slot, pEvdev->mt_mask, type);
693 
694     pEvdev->slots[slot].dirty = 0;
695 
696     valuator_mask_zero(pEvdev->mt_mask);
697 }
698 
699 static int
num_slots(EvdevPtr pEvdev)700 num_slots(EvdevPtr pEvdev)
701 {
702     int value;
703 
704     if (pEvdev->mtdev)
705         value = pEvdev->mtdev->caps.slot.maximum + 1;
706     else
707         value = libevdev_get_num_slots(pEvdev->dev);
708 
709     /* If we don't know how many slots there are, assume at least 10 */
710     return value > 1 ? value : 10;
711 }
712 
713 static int
last_mt_vals_slot(EvdevPtr pEvdev)714 last_mt_vals_slot(EvdevPtr pEvdev)
715 {
716     int value = pEvdev->cur_slot;
717 
718     return value < num_slots(pEvdev) ? value : -1;
719 }
720 
721 static void
EvdevProcessTouchEvent(InputInfoPtr pInfo,struct input_event * ev)722 EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
723 {
724     EvdevPtr pEvdev = pInfo->private;
725     int map;
726 
727     if (!pEvdev->mtdev &&
728         !libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_SLOT))
729         return;
730 
731     if (pEvdev->fake_mt)
732         return;
733 
734     if (ev->code == ABS_MT_SLOT) {
735         EvdevProcessTouch(pInfo);
736         if (ev->value >= num_slots(pEvdev) ) {
737             LogMessageVerbSigSafe(X_WARNING, 0,
738                                   "%s: Slot index %d out of bounds (max %d), touch events may be incorrect.\n",
739                                   pInfo->name,
740                                   ev->value,
741                                   num_slots(pEvdev) - 1);
742             return;
743         }
744         pEvdev->cur_slot = ev->value;
745     } else
746     {
747         int slot_index = last_mt_vals_slot(pEvdev);
748         if (slot_index < 0) {
749                     LogMessageVerbSigSafe(X_WARNING, 0,
750                                           "%s: Invalid slot index %d, touch events may be incorrect.\n",
751                                           pInfo->name,
752                                           slot_index);
753                     return;
754         }
755 
756         pEvdev->slots[slot_index].dirty = 1;
757         if (ev->code == ABS_MT_TRACKING_ID) {
758             if (ev->value >= 0) {
759                 pEvdev->slots[slot_index].state = SLOTSTATE_OPEN;
760 
761                 valuator_mask_copy(pEvdev->mt_mask,
762                                    pEvdev->last_mt_vals[slot_index]);
763             } else if (pEvdev->slots[slot_index].state != SLOTSTATE_EMPTY)
764                 pEvdev->slots[slot_index].state = SLOTSTATE_CLOSE;
765         } else {
766             map = pEvdev->abs_axis_map[ev->code];
767             valuator_mask_set(pEvdev->mt_mask, map, ev->value);
768             valuator_mask_set(pEvdev->last_mt_vals[slot_index], map,
769                               ev->value);
770         }
771     }
772 }
773 
774 /**
775  * Take the absolute motion input event and process it accordingly.
776  */
777 static void
EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo,struct input_event * ev)778 EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
779 {
780     int value;
781     EvdevPtr pEvdev = pInfo->private;
782     int map;
783 
784     /* Get the signed value, earlier kernels had this as unsigned */
785     value = ev->value;
786 
787     /* Ignore EV_ABS events if we never set up for them. */
788     if (!(pEvdev->flags & EVDEV_ABSOLUTE_EVENTS))
789         return;
790 
791     if (ev->code > ABS_MAX)
792         return;
793 
794     /* Always store the current abs valuator, we need it to update old_vals
795      * which is required by wheel emulation */
796     map = pEvdev->abs_axis_map[ev->code];
797     if (map < 2)
798             valuator_mask_set(pEvdev->abs_vals, map, value);
799 
800     if (EvdevWheelEmuFilterMotion(pInfo, ev))
801         return;
802 
803     if (ev->code >= ABS_MT_SLOT) {
804         EvdevProcessTouchEvent(pInfo, ev);
805     } else if (!pEvdev->mt_mask) {
806         map = pEvdev->abs_axis_map[ev->code];
807 
808         /* check if the event must be translated into relative */
809         if (map < 2 && (pEvdev->flags & EVDEV_RELATIVE_MODE)) {
810             int oldval;
811             if (valuator_mask_fetch(pEvdev->old_vals, map, &oldval)) {
812                 valuator_mask_set(pEvdev->rel_vals, map, value - oldval);
813                 pEvdev->rel_queued = 1;
814             }
815         } else {
816             valuator_mask_set(pEvdev->abs_vals, map, value);
817             pEvdev->abs_queued = 1;
818         }
819     }
820 }
821 
822 /**
823  * Take the key press/release input event and process it accordingly.
824  */
825 static void
EvdevProcessKeyEvent(InputInfoPtr pInfo,struct input_event * ev)826 EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev)
827 {
828     int value, i;
829     EvdevPtr pEvdev = pInfo->private;
830 
831     /* Get the signed value, earlier kernels had this as unsigned */
832     value = ev->value;
833 
834     /* don't repeat mouse buttons */
835     if (ev->code >= BTN_MOUSE && ev->code < KEY_OK)
836         if (value == 2)
837             return;
838 
839     for (i = 0; i < ArrayLength(proximity_bits); i++)
840     {
841         if (ev->code == proximity_bits[i])
842         {
843             EvdevProcessProximityEvent(pInfo, ev);
844             return;
845         }
846     }
847 
848     switch (ev->code) {
849         case BTN_TOUCH:
850             /* For devices that have but don't use proximity, use
851              * BTN_TOUCH as the proximity notifier */
852             if (!pEvdev->use_proximity)
853                 pEvdev->in_proximity = value ? ev->code : 0;
854             /* When !pEvdev->use_proximity, we don't report
855              * proximity events to the X server. However, we
856              * still want to keep track if one is in proximity or
857              * not. This is especially important for touchpad
858              * who report proximity information to the computer
859              * (but it is not sent to X) and who might send unreliable
860              * position information when not in_proximity.
861              */
862 
863             if (!(pEvdev->flags & (EVDEV_TOUCHSCREEN | EVDEV_TABLET)) ||
864                 pEvdev->mt_mask)
865                 break;
866             /* Treat BTN_TOUCH from devices that only have BTN_TOUCH as
867              * BTN_LEFT. */
868             ev->code = BTN_LEFT;
869             /* Intentional fallthrough! */
870 
871         default:
872             EvdevProcessButtonEvent(pInfo, ev);
873             break;
874     }
875 }
876 
877 /**
878  * Post the relative motion events.
879  */
880 void
EvdevPostRelativeMotionEvents(InputInfoPtr pInfo)881 EvdevPostRelativeMotionEvents(InputInfoPtr pInfo)
882 {
883     EvdevPtr pEvdev = pInfo->private;
884 
885     if (pEvdev->rel_queued && pEvdev->in_proximity) {
886         xf86PostMotionEventM(pInfo->dev, Relative, pEvdev->rel_vals);
887     }
888 }
889 
890 /**
891  * Post the absolute motion events.
892  */
893 void
EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo)894 EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo)
895 {
896     EvdevPtr pEvdev = pInfo->private;
897 
898     /*
899      * Some devices only generate valid abs coords when BTN_TOOL_PEN is
900      * pressed.  On wacom tablets, this means that the pen is in
901      * proximity of the tablet.  After the pen is removed, BTN_TOOL_PEN is
902      * released, and a (0, 0) absolute event is generated.  Checking
903      * pEvdev->in_proximity here lets us ignore that event.
904      * pEvdev->in_proximity is initialized to 1 so devices that don't use
905      * this scheme still just work.
906      */
907     if (pEvdev->abs_queued && pEvdev->in_proximity) {
908         xf86PostMotionEventM(pInfo->dev, Absolute, pEvdev->abs_vals);
909     }
910 }
911 
912 static void
EvdevPostProximityEvents(InputInfoPtr pInfo,int which)913 EvdevPostProximityEvents(InputInfoPtr pInfo, int which)
914 {
915     int i;
916     EvdevPtr pEvdev = pInfo->private;
917 
918     for (i = 0; pEvdev->prox_queued && i < pEvdev->num_queue; i++) {
919         switch (pEvdev->queue[i].type) {
920             case EV_QUEUE_KEY:
921             case EV_QUEUE_BTN:
922             case EV_QUEUE_TOUCH:
923                 break;
924             case EV_QUEUE_PROXIMITY:
925                 if (pEvdev->queue[i].val == which)
926                     xf86PostProximityEventM(pInfo->dev, which, pEvdev->old_vals);
927                 break;
928         }
929     }
930 }
931 
932 /**
933  * Post the queued key/button events.
934  */
EvdevPostQueuedEvents(InputInfoPtr pInfo)935 static void EvdevPostQueuedEvents(InputInfoPtr pInfo)
936 {
937     int i;
938     EvdevPtr pEvdev = pInfo->private;
939 
940     for (i = 0; i < pEvdev->num_queue; i++) {
941         switch (pEvdev->queue[i].type) {
942         case EV_QUEUE_KEY:
943             xf86PostKeyboardEvent(pInfo->dev, pEvdev->queue[i].detail.key,
944                                   pEvdev->queue[i].val);
945             break;
946         case EV_QUEUE_BTN:
947             if (Evdev3BEmuFilterEvent(pInfo,
948                                       pEvdev->queue[i].detail.key,
949                                       pEvdev->queue[i].val))
950                 break;
951 
952             if (pEvdev->abs_queued && pEvdev->in_proximity) {
953                 xf86PostButtonEvent(pInfo->dev, Absolute, pEvdev->queue[i].detail.key,
954                                      pEvdev->queue[i].val, 0, 0);
955 
956             } else
957                 xf86PostButtonEvent(pInfo->dev, Relative, pEvdev->queue[i].detail.key,
958                                     pEvdev->queue[i].val, 0, 0);
959             break;
960         case EV_QUEUE_PROXIMITY:
961             break;
962         case EV_QUEUE_TOUCH:
963             xf86PostTouchEvent(pInfo->dev, pEvdev->queue[i].detail.touch,
964                                pEvdev->queue[i].val, 0,
965                                pEvdev->queue[i].touchMask);
966             break;
967         }
968     }
969 }
970 
971 /**
972  * Take the synchronization input event and process it accordingly; the motion
973  * notify events are sent first, then any button/key press/release events.
974  */
975 static void
EvdevProcessSyncEvent(InputInfoPtr pInfo,struct input_event * ev)976 EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
977 {
978     int i;
979     EvdevPtr pEvdev = pInfo->private;
980 
981     EvdevProcessProximityState(pInfo);
982 
983     EvdevProcessValuators(pInfo);
984     EvdevProcessTouch(pInfo);
985 
986     EvdevPostProximityEvents(pInfo, TRUE);
987     EvdevPostRelativeMotionEvents(pInfo);
988     EvdevPostAbsoluteMotionEvents(pInfo);
989     EvdevPostQueuedEvents(pInfo);
990     EvdevPostProximityEvents(pInfo, FALSE);
991 
992     for (i = 0; i < ArrayLength(pEvdev->queue); i++)
993     {
994         EventQueuePtr queue = &pEvdev->queue[i];
995         queue->detail.key = 0;
996         queue->type = 0;
997         queue->val = 0;
998         /* don't reset the touchMask */
999     }
1000 
1001     if (pEvdev->rel_vals)
1002         valuator_mask_zero(pEvdev->rel_vals);
1003     if (pEvdev->abs_vals)
1004         valuator_mask_zero(pEvdev->abs_vals);
1005     pEvdev->num_queue = 0;
1006     pEvdev->abs_queued = 0;
1007     pEvdev->rel_queued = 0;
1008     pEvdev->prox_queued = 0;
1009 
1010 }
1011 
1012 /**
1013  * Process the events from the device; nothing is actually posted to the server
1014  * until an EV_SYN event is received.
1015  */
1016 static void
EvdevProcessEvent(InputInfoPtr pInfo,struct input_event * ev)1017 EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
1018 {
1019     switch (ev->type) {
1020         case EV_REL:
1021             EvdevProcessRelativeMotionEvent(pInfo, ev);
1022             break;
1023         case EV_ABS:
1024             EvdevProcessAbsoluteMotionEvent(pInfo, ev);
1025             break;
1026         case EV_KEY:
1027             EvdevProcessKeyEvent(pInfo, ev);
1028             break;
1029         case EV_SYN:
1030             EvdevProcessSyncEvent(pInfo, ev);
1031             break;
1032     }
1033 }
1034 
1035 static void
EvdevFreeMasks(EvdevPtr pEvdev)1036 EvdevFreeMasks(EvdevPtr pEvdev)
1037 {
1038     int i;
1039 
1040     free(pEvdev->slots);
1041     pEvdev->slots = NULL;
1042     valuator_mask_free(&pEvdev->abs_vals);
1043     valuator_mask_free(&pEvdev->rel_vals);
1044     valuator_mask_free(&pEvdev->old_vals);
1045     valuator_mask_free(&pEvdev->prox);
1046     valuator_mask_free(&pEvdev->mt_mask);
1047     if (pEvdev->last_mt_vals)
1048     {
1049         for (i = 0; i < libevdev_get_num_slots(pEvdev->dev); i++)
1050             valuator_mask_free(&pEvdev->last_mt_vals[i]);
1051         free(pEvdev->last_mt_vals);
1052         pEvdev->last_mt_vals = NULL;
1053     }
1054     for (i = 0; i < EVDEV_MAXQUEUE; i++)
1055         valuator_mask_free(&pEvdev->queue[i].touchMask);
1056 }
1057 
1058 static void
EvdevHandleMTDevEvent(InputInfoPtr pInfo,struct input_event * ev)1059 EvdevHandleMTDevEvent(InputInfoPtr pInfo, struct input_event *ev)
1060 {
1061     EvdevPtr pEvdev = pInfo->private;
1062 
1063     mtdev_put_event(pEvdev->mtdev, ev);
1064     if (libevdev_event_is_code(ev, EV_SYN, SYN_REPORT)) {
1065         while (!mtdev_empty(pEvdev->mtdev)) {
1066             struct input_event e;
1067             mtdev_get_event(pEvdev->mtdev, &e);
1068             EvdevProcessEvent(pInfo, &e);
1069         }
1070     }
1071 }
1072 
1073 static void
EvdevReadInput(InputInfoPtr pInfo)1074 EvdevReadInput(InputInfoPtr pInfo)
1075 {
1076     int rc = 0;
1077     EvdevPtr pEvdev = pInfo->private;
1078     struct input_event ev;
1079 
1080     do {
1081         rc = libevdev_next_event(pEvdev->dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
1082         if (rc < 0) {
1083             if (rc != -EAGAIN && rc != -EINTR && rc != -EWOULDBLOCK) {
1084                 /* May happen after resume or at device detach */
1085                 xf86RemoveEnabledDevice(pInfo);
1086                 EvdevCloseDevice(pInfo);
1087                 LogMessageVerbSigSafe(X_ERROR, 0, "%s: Read error: %s\n", pInfo->name,
1088                                        strerror(-rc));
1089             }
1090             break;
1091         } else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) {
1092             if (pEvdev->mtdev)
1093                 EvdevHandleMTDevEvent(pInfo, &ev);
1094             else
1095                 EvdevProcessEvent(pInfo, &ev);
1096         }
1097         else { /* SYN_DROPPED */
1098             rc = libevdev_next_event(pEvdev->dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
1099             while (rc == LIBEVDEV_READ_STATUS_SYNC) {
1100                 if (pEvdev->mtdev)
1101                     EvdevHandleMTDevEvent(pInfo, &ev);
1102                 else
1103                     EvdevProcessEvent(pInfo, &ev);
1104                 rc = libevdev_next_event(pEvdev->dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
1105             }
1106         }
1107     } while (rc == LIBEVDEV_READ_STATUS_SUCCESS);
1108 }
1109 
1110 static void
EvdevPtrCtrlProc(DeviceIntPtr device,PtrCtrl * ctrl)1111 EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
1112 {
1113     /* Nothing to do, dix handles all settings */
1114 }
1115 
1116 static void
EvdevKbdCtrl(DeviceIntPtr device,KeybdCtrl * ctrl)1117 EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl)
1118 {
1119     static struct { int xbit, code; } bits[] = {
1120         { CAPSFLAG,	LED_CAPSL },
1121         { NUMFLAG,	LED_NUML },
1122         { SCROLLFLAG,	LED_SCROLLL },
1123         { MODEFLAG,	LED_KANA },
1124         { COMPOSEFLAG,	LED_COMPOSE }
1125     };
1126 
1127     InputInfoPtr pInfo;
1128     struct input_event ev[ArrayLength(bits) + 1];
1129     int i;
1130     int rc;
1131 
1132     memset(ev, 0, sizeof(ev));
1133 
1134     pInfo = device->public.devicePrivate;
1135     for (i = 0; i < ArrayLength(bits); i++) {
1136         ev[i].type = EV_LED;
1137         ev[i].code = bits[i].code;
1138         ev[i].value = (ctrl->leds & bits[i].xbit) > 0;
1139     }
1140 
1141     ev[i].type = EV_SYN;
1142     ev[i].code = SYN_REPORT;
1143     ev[i].value = 0;
1144 
1145     rc = write(pInfo->fd, ev, sizeof ev);
1146     if (rc != sizeof ev)
1147 	    xf86IDrvMsg(pInfo, X_ERROR, "Failed to set keyboard controls: %s\n", strerror(errno));
1148 }
1149 
1150 static int
EvdevAddKeyClass(DeviceIntPtr device)1151 EvdevAddKeyClass(DeviceIntPtr device)
1152 {
1153     int rc = Success;
1154     XkbRMLVOSet rmlvo = {0},
1155                 defaults;
1156     InputInfoPtr pInfo;
1157 
1158     pInfo = device->public.devicePrivate;
1159 
1160     XkbGetRulesDflts(&defaults);
1161 
1162     /* sorry, no rules change allowed for you */
1163     xf86ReplaceStrOption(pInfo->options, "xkb_rules", "evdev");
1164     rmlvo.rules = xf86SetStrOption(pInfo->options, "xkb_rules", NULL);
1165     rmlvo.model = xf86SetStrOption(pInfo->options, "xkb_model", defaults.model);
1166     rmlvo.layout = xf86SetStrOption(pInfo->options, "xkb_layout", defaults.layout);
1167     rmlvo.variant = xf86SetStrOption(pInfo->options, "xkb_variant", defaults.variant);
1168     rmlvo.options = xf86SetStrOption(pInfo->options, "xkb_options", defaults.options);
1169 
1170     if (!InitKeyboardDeviceStruct(device, &rmlvo, NULL, EvdevKbdCtrl))
1171         rc = !Success;
1172 
1173     XkbFreeRMLVOSet(&rmlvo, FALSE);
1174     XkbFreeRMLVOSet(&defaults, FALSE);
1175 
1176     return rc;
1177 }
1178 
1179 /* MT axes are counted twice - once as ABS_X (which the kernel keeps for
1180  * backwards compatibility), once as ABS_MT_POSITION_X. So we need to keep a
1181  * mapping of those axes to make sure we only count them once
1182  */
1183 struct mt_axis_mappings {
1184     int mt_code;
1185     int code;
1186     Bool needs_mapping; /* TRUE if both code and mt_code are present */
1187     int mapping;        /* Logical mapping of 'code' axis */
1188 };
1189 
1190 static struct mt_axis_mappings mt_axis_mappings[] = {
1191     {ABS_MT_POSITION_X, ABS_X},
1192     {ABS_MT_POSITION_Y, ABS_Y},
1193     {ABS_MT_PRESSURE, ABS_PRESSURE},
1194     {ABS_MT_DISTANCE, ABS_DISTANCE},
1195 };
1196 
1197 /**
1198  * return TRUE if the axis is not one we should count as true axis
1199  */
1200 static int
is_blacklisted_axis(int axis)1201 is_blacklisted_axis(int axis)
1202 {
1203     switch(axis)
1204     {
1205         case ABS_MT_SLOT:
1206         case ABS_MT_TRACKING_ID:
1207             return TRUE;
1208         default:
1209             return FALSE;
1210     }
1211 }
1212 
1213 static int
EvdevAddFakeSingleTouchAxes(InputInfoPtr pInfo)1214 EvdevAddFakeSingleTouchAxes(InputInfoPtr pInfo)
1215 {
1216     EvdevPtr pEvdev = pInfo->private;
1217     int num_axes = 0;
1218     int i;
1219 
1220     if (pEvdev->fake_mt)
1221         return 0;
1222 
1223     /* Android drivers often have ABS_MT_POSITION_X but not ABS_X.
1224        Loop over the MT->legacy axis table and add fake axes. */
1225     for (i = 0; i < ArrayLength(mt_axis_mappings); i++)
1226     {
1227         int mt_code = mt_axis_mappings[i].mt_code;
1228         int code = mt_axis_mappings[i].code;
1229         const struct input_absinfo* abs;
1230 
1231         if (!libevdev_has_event_code(pEvdev->dev, EV_ABS, mt_code) ||
1232             libevdev_has_event_code(pEvdev->dev, EV_ABS, code))
1233             continue;
1234 
1235         abs = libevdev_get_abs_info(pEvdev->dev, mt_code);
1236         if (libevdev_enable_event_code(pEvdev->dev, EV_ABS, code, abs))
1237         {
1238             xf86IDrvMsg(pInfo, X_ERROR, "Failed to fake axis %s.\n",
1239                         libevdev_event_code_get_name(EV_ABS, code));
1240             return -1;
1241         }
1242         xf86IDrvMsg(pInfo, X_INFO, "Faking axis %s.\n",
1243                     libevdev_event_code_get_name(EV_ABS, code));
1244         num_axes++;
1245     }
1246 
1247     return num_axes;
1248 }
1249 
1250 static void
EvdevCountMTAxes(EvdevPtr pEvdev,int * num_mt_axes_total,int * num_mt_axes,int * num_axes)1251 EvdevCountMTAxes(EvdevPtr pEvdev, int *num_mt_axes_total,
1252                  int *num_mt_axes, int *num_axes)
1253 {
1254     int axis;
1255 
1256     if (pEvdev->fake_mt)
1257         return;
1258 
1259     /* Absolute multitouch axes: adjust mapping and axes counts. */
1260     for (axis = ABS_MT_SLOT; axis <= ABS_MAX; axis++)
1261     {
1262         int j;
1263         Bool skip = FALSE;
1264 
1265         if (!libevdev_has_event_code(pEvdev->dev, EV_ABS, axis))
1266             continue;
1267 
1268         /* Setup mapping if axis is in MT->legacy axis table. */
1269         for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
1270         {
1271             if (mt_axis_mappings[j].mt_code == axis &&
1272                 libevdev_has_event_code(pEvdev->dev, EV_ABS, mt_axis_mappings[j].code))
1273             {
1274                 mt_axis_mappings[j].needs_mapping = TRUE;
1275                 skip = TRUE;
1276             }
1277         }
1278 
1279         if (!is_blacklisted_axis(axis))
1280         {
1281             (*num_mt_axes_total)++;
1282             if (!skip)
1283                 (*num_mt_axes)++;
1284         }
1285         (*num_axes)--;
1286     }
1287 }
1288 
1289 static int
EvdevAddAbsValuatorClass(DeviceIntPtr device,int num_scroll_axes)1290 EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_axes)
1291 {
1292     InputInfoPtr pInfo;
1293     EvdevPtr pEvdev;
1294     int axis, i = 0;
1295     int num_axes = 0; /* number of non-MT axes */
1296     int num_mt_axes = 0, /* number of MT-only axes */
1297         num_mt_axes_total = 0; /* total number of MT axes, including
1298                                   double-counted ones, excluding blacklisted */
1299     int num_faked_axes;
1300     Atom *atoms;
1301     int mapping = 0;
1302 
1303     pInfo = device->public.devicePrivate;
1304     pEvdev = pInfo->private;
1305 
1306     if (!libevdev_has_event_type(pEvdev->dev, EV_ABS))
1307         goto out;
1308 
1309     /* Find number of absolute axis, including MT ones, will decrease later. */
1310     for (i = 0; i <= ABS_MAX; i++)
1311         if (libevdev_has_event_code(pEvdev->dev, EV_ABS, i))
1312             num_axes++;
1313 
1314     if (num_axes < 1)
1315         goto out;
1316 
1317     num_faked_axes = EvdevAddFakeSingleTouchAxes(pInfo);
1318     if (num_faked_axes < 0)
1319         goto out;
1320 
1321     num_axes += num_faked_axes;
1322 
1323     EvdevCountMTAxes(pEvdev, &num_mt_axes_total, &num_mt_axes, &num_axes);
1324 
1325     /* Panic if, after faking ABS_X etc, we still only have mt-axes. */
1326     if (num_axes == 0 && num_mt_axes > 0) {
1327         xf86IDrvMsg(pInfo, X_ERROR,
1328                     "found only multitouch-axes. That shouldn't happen.\n");
1329         goto out;
1330     }
1331 
1332 
1333 
1334     num_axes += num_scroll_axes;
1335 
1336     if (num_axes + num_mt_axes > MAX_VALUATORS) {
1337         xf86IDrvMsg(pInfo, X_WARNING, "found %d axes, limiting to %d.\n", num_axes, MAX_VALUATORS);
1338         num_axes = MAX_VALUATORS;
1339     }
1340 
1341     if (num_axes < 1 && num_mt_axes_total < 1) {
1342         xf86Msg(X_WARNING, "%s: no absolute or touch axes found.\n",
1343                 device->name);
1344         return !Success;
1345     }
1346 
1347     pEvdev->num_vals = num_axes;
1348     if (num_axes > 0) {
1349         pEvdev->abs_vals = valuator_mask_new(num_axes);
1350         pEvdev->old_vals = valuator_mask_new(num_axes);
1351         pEvdev->rel_vals = valuator_mask_new(num_axes);
1352         /* One needs rel_vals for an absolute device because
1353          *   a) their might be some (relative) scroll axes
1354          *   b) the device could be set in EVDEV_RELATIVE_MODE
1355          */
1356         if (!pEvdev->abs_vals || !pEvdev->rel_vals || !pEvdev->old_vals) {
1357             xf86IDrvMsg(pInfo, X_ERROR, "failed to allocate valuator masks.\n");
1358             goto out;
1359         }
1360     }
1361 
1362     if (num_mt_axes_total > 0) {
1363         int nslots = num_slots(pEvdev);
1364 
1365         pEvdev->num_mt_vals = num_mt_axes_total;
1366         pEvdev->mt_mask = valuator_mask_new(num_mt_axes_total);
1367         if (!pEvdev->mt_mask) {
1368             xf86Msg(X_ERROR, "%s: failed to allocate MT valuator mask.\n",
1369                     device->name);
1370             goto out;
1371         }
1372 
1373         pEvdev->slots = calloc(nslots, sizeof(*pEvdev->slots));
1374         if (!pEvdev->slots) {
1375             xf86Msg(X_ERROR, "%s: failed to allocate slot state array.\n",
1376                     device->name);
1377             goto out;
1378         }
1379         for (i = 0; i < nslots; i++) {
1380             pEvdev->slots[i].state = SLOTSTATE_EMPTY;
1381             pEvdev->slots[i].dirty = 0;
1382         }
1383 
1384         pEvdev->last_mt_vals = calloc(nslots, sizeof(ValuatorMask *));
1385         if (!pEvdev->last_mt_vals) {
1386             xf86IDrvMsg(pInfo, X_ERROR,
1387                         "%s: failed to allocate MT last values mask array.\n",
1388                         device->name);
1389             goto out;
1390         }
1391 
1392         for (i = 0; i < nslots; i++) {
1393             pEvdev->last_mt_vals[i] = valuator_mask_new(num_mt_axes_total);
1394             if (!pEvdev->last_mt_vals[i]) {
1395                 xf86IDrvMsg(pInfo, X_ERROR,
1396                             "%s: failed to allocate MT last values mask.\n",
1397                             device->name);
1398                 goto out;
1399             }
1400         }
1401 
1402         for (i = 0; i < EVDEV_MAXQUEUE; i++) {
1403             pEvdev->queue[i].touchMask =
1404                 valuator_mask_new(num_mt_axes_total);
1405             if (!pEvdev->queue[i].touchMask) {
1406                 xf86Msg(X_ERROR, "%s: failed to allocate MT valuator masks for "
1407                         "evdev event queue.\n", device->name);
1408                 goto out;
1409             }
1410         }
1411     }
1412     atoms = malloc((pEvdev->num_vals + num_mt_axes) * sizeof(Atom));
1413 
1414     i = 2;
1415     for (axis = ABS_X; i < MAX_VALUATORS && axis <= ABS_MAX; axis++) {
1416         int j;
1417         pEvdev->abs_axis_map[axis] = -1;
1418         if (!libevdev_has_event_code(pEvdev->dev, EV_ABS, axis) ||
1419             is_blacklisted_axis(axis))
1420             continue;
1421 
1422         if (axis == ABS_X)
1423             mapping = 0;
1424         else if (axis == ABS_Y)
1425             mapping = 1;
1426         else
1427             mapping = i;
1428 
1429         for (j = 0; !pEvdev->fake_mt && j < ArrayLength(mt_axis_mappings); j++)
1430         {
1431             if (mt_axis_mappings[j].code == axis)
1432                 mt_axis_mappings[j].mapping = mapping;
1433             else if (mt_axis_mappings[j].mt_code == axis &&
1434                     mt_axis_mappings[j].needs_mapping)
1435                 mapping = mt_axis_mappings[j].mapping;
1436         }
1437         pEvdev->abs_axis_map[axis] = mapping;
1438         if (mapping == i)
1439             i++;
1440     }
1441 
1442     if (num_scroll_axes > 0)
1443     {
1444         mapping++; /* continue from abs axis mapping */
1445 
1446         if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
1447             pEvdev->rel_axis_map[REL_HWHEEL] = mapping++;
1448         if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
1449             pEvdev->rel_axis_map[REL_DIAL] = mapping++;
1450         if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
1451             pEvdev->rel_axis_map[REL_WHEEL] = mapping++;
1452     }
1453 
1454     EvdevInitAxesLabels(pEvdev, Absolute, pEvdev->num_vals + num_mt_axes, atoms);
1455 
1456     if (!InitValuatorClassDeviceStruct(device, num_axes + num_mt_axes, atoms,
1457                                        GetMotionHistorySize(), Absolute)) {
1458         xf86IDrvMsg(pInfo, X_ERROR, "failed to initialize valuator class device.\n");
1459         goto out;
1460     }
1461 
1462     if (num_mt_axes_total > 0)
1463     {
1464         int num_touches = 0;
1465         int mode = pEvdev->flags & EVDEV_TOUCHPAD ?
1466             XIDependentTouch : XIDirectTouch;
1467 
1468         num_touches = num_slots(pEvdev);
1469 
1470         if (!InitTouchClassDeviceStruct(device, num_touches, mode,
1471                                         num_mt_axes_total)) {
1472             xf86Msg(X_ERROR, "%s: failed to initialize touch class device.\n",
1473                     device->name);
1474             goto out;
1475         }
1476 
1477         for (i = 0; i < num_touches; i++) {
1478             for (axis = ABS_MT_TOUCH_MAJOR; axis <= ABS_MAX; axis++) {
1479                 if (pEvdev->abs_axis_map[axis] >= 0) {
1480                     int val = pEvdev->mtdev ? 0 : libevdev_get_current_slot(pEvdev->dev);
1481                     /* XXX: read initial values from mtdev when it adds support
1482                      *      for doing so. */
1483                     valuator_mask_set(pEvdev->last_mt_vals[i],
1484                                       pEvdev->abs_axis_map[axis], val);
1485                 }
1486             }
1487         }
1488     }
1489 
1490     for (axis = ABS_X; axis < ABS_MT_SLOT; axis++) {
1491         const struct input_absinfo *abs;
1492         int axnum = pEvdev->abs_axis_map[axis];
1493         int resolution = 0;
1494 
1495         if (axnum == -1)
1496             continue;
1497 
1498         abs = libevdev_get_abs_info(pEvdev->dev, axis);
1499 #ifdef __linux__
1500 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 30)
1501         /* Kernel provides units/mm, X wants units/m */
1502         resolution = abs->resolution * 1000;
1503 #endif
1504 #else
1505         /* Kernel provides units/mm, X wants units/m */
1506         resolution = abs->resolution * 1000;
1507 #endif
1508 
1509         xf86InitValuatorAxisStruct(device, axnum,
1510                                    atoms[axnum],
1511                                    abs->minimum,
1512                                    abs->maximum,
1513                                    resolution, 0, resolution, Absolute);
1514         xf86InitValuatorDefaults(device, axnum);
1515     }
1516 
1517     for (axis = ABS_MT_TOUCH_MAJOR; axis <= ABS_MAX; axis++) {
1518         const struct input_absinfo *abs;
1519         int axnum = pEvdev->abs_axis_map[axis];
1520         int resolution = 0;
1521         int j;
1522         BOOL skip = FALSE;
1523 
1524         if (axnum < 0)
1525             continue;
1526 
1527         abs = libevdev_get_abs_info(pEvdev->dev, axis);
1528 
1529         for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
1530             if (mt_axis_mappings[j].mt_code == axis &&
1531                     mt_axis_mappings[j].needs_mapping)
1532             {
1533                 skip = TRUE;
1534                 break;
1535             }
1536 
1537         /* MT axis is mapped, don't set up twice */
1538         if (skip)
1539             continue;
1540 
1541         resolution = abs->resolution * 1000;
1542 
1543         xf86InitValuatorAxisStruct(device, axnum,
1544                                    atoms[axnum],
1545                                    abs->minimum,
1546                                    abs->maximum,
1547                                    resolution, 0, resolution,
1548                                    Absolute);
1549     }
1550 
1551     if (num_scroll_axes)
1552     {
1553         int idx;
1554         if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
1555         {
1556             idx = REL_WHEEL;
1557             xf86InitValuatorAxisStruct(device,
1558                                        pEvdev->rel_axis_map[idx],
1559                                        atoms[pEvdev->rel_axis_map[idx]],
1560                                        NO_AXIS_LIMITS, NO_AXIS_LIMITS,
1561                                        0, 0, 0, Relative);
1562             SetScrollValuator(device, pEvdev->rel_axis_map[idx],
1563                               SCROLL_TYPE_VERTICAL,
1564                               -pEvdev->smoothScroll.vert_delta,
1565                               SCROLL_FLAG_PREFERRED);
1566         }
1567 
1568         if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
1569         {
1570             idx = REL_HWHEEL;
1571             xf86InitValuatorAxisStruct(device,
1572                                        pEvdev->rel_axis_map[idx],
1573                                        atoms[pEvdev->rel_axis_map[idx]],
1574                                        NO_AXIS_LIMITS, NO_AXIS_LIMITS,
1575                                        0, 0, 0, Relative);
1576             SetScrollValuator(device, pEvdev->rel_axis_map[idx],
1577                               SCROLL_TYPE_HORIZONTAL,
1578                               pEvdev->smoothScroll.horiz_delta,
1579                               SCROLL_FLAG_NONE);
1580         }
1581 
1582         if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
1583         {
1584             idx = REL_DIAL;
1585             xf86InitValuatorAxisStruct(device,
1586                                        pEvdev->rel_axis_map[idx],
1587                                        atoms[pEvdev->rel_axis_map[idx]],
1588                                        NO_AXIS_LIMITS, NO_AXIS_LIMITS,
1589                                        0, 0, 0, Relative);
1590             SetScrollValuator(device, pEvdev->rel_axis_map[idx],
1591                               SCROLL_TYPE_HORIZONTAL,
1592                               pEvdev->smoothScroll.dial_delta,
1593                               SCROLL_FLAG_NONE);
1594         }
1595     }
1596 
1597     free(atoms);
1598 
1599     for (i = 0; i < ArrayLength(proximity_bits); i++)
1600     {
1601         if (!pEvdev->use_proximity)
1602             break;
1603 
1604         if (libevdev_has_event_code(pEvdev->dev, EV_KEY, proximity_bits[i]))
1605         {
1606             InitProximityClassDeviceStruct(device);
1607             pEvdev->prox = valuator_mask_new(num_axes);
1608             if (!pEvdev->prox) {
1609                 xf86IDrvMsg(pInfo, X_ERROR,
1610                             "failed to allocate proximity valuator " "mask.\n");
1611                 goto out;
1612             }
1613             break;
1614         }
1615     }
1616 
1617     if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc)) {
1618         xf86IDrvMsg(pInfo, X_ERROR,
1619                     "failed to initialize pointer feedback class device.\n");
1620         goto out;
1621     }
1622 
1623     if (pEvdev->flags & EVDEV_TOUCHPAD)
1624         pEvdev->flags |= EVDEV_RELATIVE_MODE;
1625     else
1626         pEvdev->flags &= ~EVDEV_RELATIVE_MODE;
1627 
1628     if (xf86FindOption(pInfo->options, "Mode"))
1629     {
1630         char *mode;
1631         mode = xf86SetStrOption(pInfo->options, "Mode", NULL);
1632         if (!strcasecmp("absolute", mode))
1633             pEvdev->flags &= ~EVDEV_RELATIVE_MODE;
1634         else if (!strcasecmp("relative", mode))
1635             pEvdev->flags |= EVDEV_RELATIVE_MODE;
1636         else
1637             xf86IDrvMsg(pInfo, X_INFO, "unknown mode, use default\n");
1638         free(mode);
1639     }
1640 
1641     return Success;
1642 
1643 out:
1644     EvdevFreeMasks(pEvdev);
1645     return !Success;
1646 }
1647 
1648 static int
EvdevSetScrollValuators(DeviceIntPtr device)1649 EvdevSetScrollValuators(DeviceIntPtr device)
1650 {
1651     InputInfoPtr pInfo;
1652     EvdevPtr pEvdev;
1653     int axnum;
1654 
1655     pInfo = device->public.devicePrivate;
1656     pEvdev = pInfo->private;
1657 
1658     axnum = pEvdev->rel_axis_map[REL_WHEEL];
1659     if (axnum != -1) {
1660         SetScrollValuator(device, axnum, SCROLL_TYPE_VERTICAL,
1661                           -pEvdev->smoothScroll.vert_delta,
1662                           SCROLL_FLAG_PREFERRED);
1663     }
1664 
1665     axnum = pEvdev->rel_axis_map[REL_DIAL];
1666     if (axnum != -1) {
1667         SetScrollValuator(device, axnum, SCROLL_TYPE_HORIZONTAL,
1668                           pEvdev->smoothScroll.dial_delta,
1669                           SCROLL_FLAG_NONE);
1670     }
1671 
1672     axnum = pEvdev->rel_axis_map[REL_HWHEEL];
1673     if (axnum != -1) {
1674         SetScrollValuator(device, axnum, SCROLL_TYPE_HORIZONTAL,
1675                           pEvdev->smoothScroll.horiz_delta,
1676                           SCROLL_FLAG_NONE);
1677     }
1678 
1679     return Success;
1680 }
1681 
1682 static int
EvdevAddRelValuatorClass(DeviceIntPtr device,int num_scroll_axes)1683 EvdevAddRelValuatorClass(DeviceIntPtr device, int num_scroll_axes)
1684 {
1685     InputInfoPtr pInfo;
1686     EvdevPtr pEvdev;
1687     int num_axes = 0, axis, map, i = 0;
1688     Atom *atoms;
1689 
1690     pInfo = device->public.devicePrivate;
1691     pEvdev = pInfo->private;
1692 
1693     if (!libevdev_has_event_type(pEvdev->dev, EV_REL))
1694         goto out;
1695 
1696     for (i = 0; i <= REL_MAX; i++) {
1697         if (i == REL_WHEEL || i == REL_HWHEEL || i == REL_DIAL)
1698             continue;
1699 
1700         if (libevdev_has_event_code(pEvdev->dev, EV_REL, i))
1701             num_axes++;
1702     }
1703 
1704     /* If we have only relative scroll axes, then we punt axis init to
1705        EvdevInitAbsValuators if possible */
1706     if (num_axes < 1 &&
1707         (num_scroll_axes == 0 || pEvdev->flags & EVDEV_ABSOLUTE_EVENTS))
1708             goto out;
1709 
1710     num_axes += num_scroll_axes;
1711 
1712     if (num_axes > MAX_VALUATORS) {
1713         xf86IDrvMsg(pInfo, X_WARNING, "found %d axes, limiting to %d.\n", num_axes, MAX_VALUATORS);
1714         num_axes = MAX_VALUATORS;
1715     }
1716 
1717     pEvdev->num_vals = num_axes;
1718     if (num_axes > 0) {
1719         pEvdev->rel_vals = valuator_mask_new(num_axes);
1720         if (!pEvdev->rel_vals)
1721             goto out;
1722     }
1723     atoms = malloc(pEvdev->num_vals * sizeof(Atom));
1724 
1725     for (axis = REL_X, map = 0; map < MAX_VALUATORS && axis <= REL_MAX; axis++)
1726     {
1727         pEvdev->rel_axis_map[axis] = -1;
1728         if (!libevdev_has_event_code(pEvdev->dev, EV_REL, axis))
1729             continue;
1730         pEvdev->rel_axis_map[axis] = map;
1731         map++;
1732     }
1733 
1734     EvdevInitAxesLabels(pEvdev, Relative, pEvdev->num_vals, atoms);
1735 
1736     if (!InitValuatorClassDeviceStruct(device, num_axes, atoms,
1737                                        GetMotionHistorySize(), Relative)) {
1738         xf86IDrvMsg(pInfo, X_ERROR, "failed to initialize valuator class device.\n");
1739         goto out;
1740     }
1741 
1742     if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc)) {
1743         xf86IDrvMsg(pInfo, X_ERROR, "failed to initialize pointer feedback class "
1744                 "device.\n");
1745         goto out;
1746     }
1747 
1748     for (axis = REL_X; axis <= REL_MAX; axis++)
1749     {
1750         int axnum = pEvdev->rel_axis_map[axis];
1751 
1752         if (axnum == -1)
1753             continue;
1754         xf86InitValuatorAxisStruct(device, axnum, atoms[axnum], -1, -1, 1, 0, 1,
1755                                    Relative);
1756         xf86InitValuatorDefaults(device, axnum);
1757     }
1758 
1759     EvdevSetScrollValuators(device);
1760 
1761     free(atoms);
1762 
1763     return Success;
1764 
1765 out:
1766     valuator_mask_free(&pEvdev->rel_vals);
1767     return !Success;
1768 }
1769 
1770 static int
EvdevAddButtonClass(DeviceIntPtr device)1771 EvdevAddButtonClass(DeviceIntPtr device)
1772 {
1773     InputInfoPtr pInfo;
1774     EvdevPtr pEvdev;
1775     Atom *labels;
1776 
1777     pInfo = device->public.devicePrivate;
1778     pEvdev = pInfo->private;
1779 
1780     labels = malloc(pEvdev->num_buttons * sizeof(Atom));
1781     EvdevInitButtonLabels(pEvdev, pEvdev->num_buttons, labels);
1782 
1783     if (!InitButtonClassDeviceStruct(device, pEvdev->num_buttons, labels,
1784                                      pEvdev->btnmap))
1785         return !Success;
1786 
1787     free(labels);
1788     return Success;
1789 }
1790 
1791 /**
1792  * Init the button mapping for the device. By default, this is a 1:1 mapping,
1793  * i.e. Button 1 maps to Button 1, Button 2 to 2, etc.
1794  *
1795  * If a mapping has been specified, the mapping is the default, with the
1796  * user-defined ones overwriting the defaults.
1797  * i.e. a user-defined mapping of "3 2 1" results in a mapping of 3 2 1 4 5 6 ...
1798  *
1799  * Invalid button mappings revert to the default.
1800  *
1801  * Note that index 0 is unused, button 0 does not exist.
1802  * This mapping is initialised for all devices, but only applied if the device
1803  * has buttons (in EvdevAddButtonClass).
1804  */
1805 static void
EvdevInitButtonMapping(InputInfoPtr pInfo)1806 EvdevInitButtonMapping(InputInfoPtr pInfo)
1807 {
1808     int         i, nbuttons     = 1;
1809     char       *mapping         = NULL;
1810     EvdevPtr    pEvdev          = pInfo->private;
1811 
1812     /* Check for user-defined button mapping */
1813     if ((mapping = xf86CheckStrOption(pInfo->options, "ButtonMapping", NULL)))
1814     {
1815         char    *map, *s = NULL;
1816         int     btn = 0;
1817 
1818         xf86IDrvMsg(pInfo, X_CONFIG, "ButtonMapping '%s'\n", mapping);
1819         map = mapping;
1820         do
1821         {
1822             btn = strtol(map, &s, 10);
1823 
1824             if (s == map || btn < 0 || btn > EVDEV_MAXBUTTONS)
1825             {
1826                 xf86IDrvMsg(pInfo, X_ERROR,
1827                             "... Invalid button mapping. Using defaults\n");
1828                 nbuttons = 1; /* ensure defaults start at 1 */
1829                 break;
1830             }
1831 
1832             pEvdev->btnmap[nbuttons++] = btn;
1833             map = s;
1834         } while (s && *s != '\0' && nbuttons < EVDEV_MAXBUTTONS);
1835         free(mapping);
1836     }
1837 
1838     for (i = nbuttons; i < ArrayLength(pEvdev->btnmap); i++)
1839         pEvdev->btnmap[i] = i;
1840 
1841 }
1842 
1843 static int
EvdevCountScrollAxes(EvdevPtr pEvdev)1844 EvdevCountScrollAxes(EvdevPtr pEvdev)
1845 {
1846     int num_scroll_axes = 0;
1847 
1848     if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
1849         num_scroll_axes++;
1850     if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
1851         num_scroll_axes++;
1852     if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
1853         num_scroll_axes++;
1854 
1855     return num_scroll_axes;
1856 }
1857 
1858 static void
EvdevInitAnyValuators(DeviceIntPtr device,EvdevPtr pEvdev)1859 EvdevInitAnyValuators(DeviceIntPtr device, EvdevPtr pEvdev)
1860 {
1861     InputInfoPtr pInfo = device->public.devicePrivate;
1862     int num_scroll_axes = EvdevCountScrollAxes(pEvdev);
1863 
1864     if (pEvdev->flags & EVDEV_RELATIVE_EVENTS &&
1865         EvdevAddRelValuatorClass(device, num_scroll_axes) == Success)
1866         xf86IDrvMsg(pInfo, X_INFO, "initialized for relative axes.\n");
1867     /* FIXME: EvdevAddAbsValuatorClass overwrites the valuators initialized
1868        in EvdevAddRelValuatorClass and leaks the latter's memory */
1869     if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS &&
1870         EvdevAddAbsValuatorClass(device, num_scroll_axes) == Success)
1871         xf86IDrvMsg(pInfo, X_INFO, "initialized for absolute axes.\n");
1872 }
1873 
1874 static void
EvdevInitAbsValuators(DeviceIntPtr device,EvdevPtr pEvdev)1875 EvdevInitAbsValuators(DeviceIntPtr device, EvdevPtr pEvdev)
1876 {
1877     InputInfoPtr pInfo = device->public.devicePrivate;
1878     int num_scroll_axes = EvdevCountScrollAxes(pEvdev);
1879 
1880     if (EvdevAddAbsValuatorClass(device, num_scroll_axes) == Success) {
1881         xf86IDrvMsg(pInfo, X_INFO,"initialized for absolute axes.\n");
1882     } else {
1883         xf86IDrvMsg(pInfo, X_ERROR,"failed to initialize for absolute axes.\n");
1884         pEvdev->flags &= ~EVDEV_ABSOLUTE_EVENTS;
1885     }
1886 }
1887 
1888 static void
EvdevInitRelValuators(DeviceIntPtr device,EvdevPtr pEvdev)1889 EvdevInitRelValuators(DeviceIntPtr device, EvdevPtr pEvdev)
1890 {
1891     InputInfoPtr pInfo = device->public.devicePrivate;
1892     int has_abs_axes = pEvdev->flags & EVDEV_ABSOLUTE_EVENTS;
1893     int num_scroll_axes = EvdevCountScrollAxes(pEvdev);
1894 
1895     if (EvdevAddRelValuatorClass(device, num_scroll_axes) == Success) {
1896 
1897         xf86IDrvMsg(pInfo, X_INFO,"initialized for relative axes.\n");
1898 
1899         if (has_abs_axes) {
1900             xf86IDrvMsg(pInfo, X_WARNING,"ignoring absolute axes.\n");
1901             pEvdev->flags &= ~EVDEV_ABSOLUTE_EVENTS;
1902         }
1903 
1904     } else {
1905         xf86IDrvMsg(pInfo, X_ERROR,"failed to initialize for relative axes.\n");
1906 
1907         pEvdev->flags &= ~EVDEV_RELATIVE_EVENTS;
1908 
1909         if (has_abs_axes)
1910             EvdevInitAbsValuators(device, pEvdev);
1911     }
1912 }
1913 
1914 static void
EvdevInitTouchDevice(DeviceIntPtr device,EvdevPtr pEvdev)1915 EvdevInitTouchDevice(DeviceIntPtr device, EvdevPtr pEvdev)
1916 {
1917     InputInfoPtr pInfo = device->public.devicePrivate;
1918 
1919     if (pEvdev->flags & EVDEV_RELATIVE_EVENTS) {
1920         xf86IDrvMsg(pInfo, X_WARNING, "touchpads, tablets and touchscreens "
1921                     "ignore relative axes.\n");
1922         pEvdev->flags &= ~EVDEV_RELATIVE_EVENTS;
1923     }
1924 
1925     EvdevInitAbsValuators(device, pEvdev);
1926 }
1927 
1928 static int
EvdevInit(DeviceIntPtr device)1929 EvdevInit(DeviceIntPtr device)
1930 {
1931     InputInfoPtr pInfo;
1932     EvdevPtr pEvdev;
1933 
1934     pInfo = device->public.devicePrivate;
1935     pEvdev = pInfo->private;
1936 
1937     if (pEvdev->flags & EVDEV_KEYBOARD_EVENTS)
1938 	EvdevAddKeyClass(device);
1939     if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
1940 	EvdevAddButtonClass(device);
1941 
1942     /* We don't allow relative and absolute axes on the same device. The
1943      * reason is that some devices (MS Optical Desktop 2000) register both
1944      * rel and abs axes for x/y.
1945      *
1946      * The abs axes register min/max; this min/max then also applies to the
1947      * relative device (the mouse) and caps it at 0..255 for both axes.
1948      * So, unless you have a small screen, you won't be enjoying it much;
1949      * consequently, absolute axes are generally ignored.
1950      *
1951      * However, currenly only a device with absolute axes can be registered
1952      * as a touch{pad,screen}. Thus, given such a device, absolute axes are
1953      * used and relative axes are ignored.
1954      */
1955 
1956     if ((pEvdev->flags & (EVDEV_UNIGNORE_RELATIVE|EVDEV_UNIGNORE_ABSOLUTE)) == EVDEV_UNIGNORE_RELATIVE)
1957         EvdevInitRelValuators(device, pEvdev);
1958     else if (pEvdev->flags & EVDEV_UNIGNORE_ABSOLUTE)
1959         EvdevInitAnyValuators(device, pEvdev);
1960     else if (pEvdev->flags & (EVDEV_TOUCHPAD | EVDEV_TOUCHSCREEN | EVDEV_TABLET))
1961         EvdevInitTouchDevice(device, pEvdev);
1962     else if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
1963         EvdevInitRelValuators(device, pEvdev);
1964     else if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
1965         EvdevInitAbsValuators(device, pEvdev);
1966 
1967     /* We drop the return value, the only time we ever want the handlers to
1968      * unregister is when the device dies. In which case we don't have to
1969      * unregister anyway */
1970     EvdevInitProperty(device);
1971     XIRegisterPropertyHandler(device, EvdevSetProperty, NULL, NULL);
1972     EvdevMBEmuInitProperty(device);
1973     Evdev3BEmuInitProperty(device);
1974     EvdevWheelEmuInitProperty(device);
1975     EvdevDragLockInitProperty(device);
1976     EvdevAppleInitProperty(device);
1977 
1978     return Success;
1979 }
1980 
1981 /**
1982  * Init all extras (wheel emulation, etc.) and grab the device.
1983  */
1984 static int
EvdevOn(DeviceIntPtr device)1985 EvdevOn(DeviceIntPtr device)
1986 {
1987     InputInfoPtr pInfo;
1988     EvdevPtr pEvdev;
1989     int rc = Success;
1990 
1991     pInfo = device->public.devicePrivate;
1992     pEvdev = pInfo->private;
1993     /* after PreInit fd is still open */
1994     rc = EvdevOpenDevice(pInfo);
1995     if (rc != Success)
1996         return rc;
1997 
1998     EvdevGrabDevice(pInfo, 1, 0);
1999 
2000     xf86FlushInput(pInfo->fd);
2001     xf86AddEnabledDevice(pInfo);
2002     EvdevMBEmuOn(pInfo);
2003     Evdev3BEmuOn(pInfo);
2004     pEvdev->flags |= EVDEV_INITIALIZED;
2005     device->public.on = TRUE;
2006 
2007     return Success;
2008 }
2009 
2010 
2011 static int
EvdevProc(DeviceIntPtr device,int what)2012 EvdevProc(DeviceIntPtr device, int what)
2013 {
2014     InputInfoPtr pInfo;
2015     EvdevPtr pEvdev;
2016 
2017     pInfo = device->public.devicePrivate;
2018     pEvdev = pInfo->private;
2019 
2020     switch (what)
2021     {
2022     case DEVICE_INIT:
2023 	return EvdevInit(device);
2024 
2025     case DEVICE_ON:
2026         return EvdevOn(device);
2027 
2028     case DEVICE_OFF:
2029         if (pEvdev->flags & EVDEV_INITIALIZED)
2030         {
2031             EvdevMBEmuFinalize(pInfo);
2032             Evdev3BEmuFinalize(pInfo);
2033         }
2034         if (pInfo->fd != -1)
2035         {
2036             EvdevGrabDevice(pInfo, 0, 1);
2037             xf86RemoveEnabledDevice(pInfo);
2038             EvdevCloseDevice(pInfo);
2039         }
2040         pEvdev->min_maj = 0;
2041         pEvdev->flags &= ~EVDEV_INITIALIZED;
2042 	device->public.on = FALSE;
2043 	break;
2044 
2045     case DEVICE_CLOSE:
2046 	xf86IDrvMsg(pInfo, X_INFO, "Close\n");
2047         EvdevCloseDevice(pInfo);
2048         EvdevFreeMasks(pEvdev);
2049         pEvdev->min_maj = 0;
2050 	break;
2051 
2052     default:
2053         return BadValue;
2054     }
2055 
2056     return Success;
2057 }
2058 
2059 /**
2060  * Get as much information as we can from the fd and cache it.
2061  *
2062  * @return Success if the information was cached, or !Success otherwise.
2063  */
2064 static int
EvdevCache(InputInfoPtr pInfo)2065 EvdevCache(InputInfoPtr pInfo)
2066 {
2067     EvdevPtr pEvdev = pInfo->private;
2068     int i;
2069 
2070     /*
2071      * Do not try to validate absinfo data since it is not expected
2072      * to be static, always refresh it in evdev structure.
2073      */
2074     for (i = ABS_X; i <= ABS_MAX; i++) {
2075         if (libevdev_has_event_code(pEvdev->dev, EV_ABS, i)) {
2076             const struct input_absinfo *abs = libevdev_get_abs_info(pEvdev->dev, i);
2077             xf86IDrvMsgVerb(pInfo, X_PROBED, 6, "absolute axis %#x [%d..%d]\n",
2078                             i, abs->minimum, abs->maximum);
2079         }
2080     }
2081 
2082     return Success;
2083 }
2084 
2085 /**
2086  * Issue an EVIOCGRAB on the device file, either as a grab or to ungrab, or
2087  * both. Return TRUE on success, otherwise FALSE. Failing the release is a
2088  * still considered a success, because it's not as if you could do anything
2089  * about it.
2090  */
2091 static BOOL
EvdevGrabDevice(InputInfoPtr pInfo,int grab,int ungrab)2092 EvdevGrabDevice(InputInfoPtr pInfo, int grab, int ungrab)
2093 {
2094     EvdevPtr pEvdev = pInfo->private;
2095 
2096     if (pEvdev->grabDevice)
2097     {
2098         int rc;
2099         if (grab && (rc = libevdev_grab(pEvdev->dev, LIBEVDEV_GRAB)) < 0) {
2100             xf86IDrvMsg(pInfo, X_WARNING, "Grab failed (%s)\n",
2101                         strerror(-rc));
2102             return FALSE;
2103         } else if (ungrab && (rc = libevdev_grab(pEvdev->dev, LIBEVDEV_UNGRAB)) < 0)
2104             xf86IDrvMsg(pInfo, X_WARNING, "Release failed (%s)\n",
2105                         strerror(-rc));
2106     }
2107 
2108     return TRUE;
2109 }
2110 
2111 /**
2112  * Some devices only have other axes (e.g. wheels), but we
2113  * still need x/y for these. The server relies on devices having
2114  * x/y as axes 0/1 and core/XI 1.x clients expect it too (#44655)
2115  */
2116 static void
EvdevForceXY(InputInfoPtr pInfo,int mode)2117 EvdevForceXY(InputInfoPtr pInfo, int mode)
2118 {
2119     EvdevPtr pEvdev = pInfo->private;
2120 
2121     xf86IDrvMsg(pInfo, X_INFO, "Forcing %s x/y axes to exist.\n",
2122                 (mode == Relative) ? "relative" : "absolute");
2123 
2124     if (mode == Relative)
2125     {
2126         libevdev_enable_event_code(pEvdev->dev, EV_REL, REL_X, NULL);
2127         libevdev_enable_event_code(pEvdev->dev, EV_REL, REL_Y, NULL);
2128     } else if (mode == Absolute)
2129     {
2130         struct input_absinfo abs;
2131 
2132         abs.minimum = 0;
2133         abs.maximum = 1000;
2134         abs.value = 0;
2135         abs.fuzz = 0;
2136         abs.flat = 0;
2137         abs.resolution = 0;
2138 
2139         libevdev_enable_event_code(pEvdev->dev, EV_ABS, ABS_X, &abs);
2140         libevdev_enable_event_code(pEvdev->dev, EV_ABS, ABS_Y, &abs);
2141     }
2142 }
2143 
2144 static int
EvdevProbe(InputInfoPtr pInfo)2145 EvdevProbe(InputInfoPtr pInfo)
2146 {
2147     int i, has_rel_axes, has_abs_axes, has_keys, num_buttons, has_scroll;
2148     int has_lmr; /* left middle right */
2149     int has_mt; /* multitouch */
2150     int ignore_abs = 0, ignore_rel = 0;
2151     EvdevPtr pEvdev = pInfo->private;
2152     int rc = 1;
2153 
2154     xf86IDrvMsg(pInfo, X_PROBED, "Vendor %#hx Product %#hx\n",
2155                 libevdev_get_id_vendor(pEvdev->dev),
2156                 libevdev_get_id_product(pEvdev->dev));
2157 
2158     /* Trinary state for ignoring axes:
2159        - unset: do the normal thing.
2160        - TRUE: explicitly ignore them.
2161        - FALSE: unignore axes, use them at all cost if they're present.
2162      */
2163     if (xf86FindOption(pInfo->options, "IgnoreRelativeAxes"))
2164     {
2165         if (xf86SetBoolOption(pInfo->options, "IgnoreRelativeAxes", FALSE))
2166             ignore_rel = TRUE;
2167         else
2168             pEvdev->flags |= EVDEV_UNIGNORE_RELATIVE;
2169 
2170     }
2171     if (xf86FindOption(pInfo->options, "IgnoreAbsoluteAxes"))
2172     {
2173         if (xf86SetBoolOption(pInfo->options, "IgnoreAbsoluteAxes", FALSE))
2174            ignore_abs = TRUE;
2175         else
2176             pEvdev->flags |= EVDEV_UNIGNORE_ABSOLUTE;
2177     }
2178 
2179     has_rel_axes = FALSE;
2180     has_abs_axes = FALSE;
2181     has_keys = FALSE;
2182     has_scroll = FALSE;
2183     has_lmr = FALSE;
2184     has_mt = FALSE;
2185     num_buttons = 0;
2186 
2187     /* count all buttons */
2188     for (i = BTN_MISC; i < BTN_JOYSTICK; i++)
2189     {
2190         int mapping = 0;
2191         if (libevdev_has_event_code(pEvdev->dev, EV_KEY, i))
2192         {
2193             mapping = EvdevUtilButtonEventToButtonNumber(pEvdev, i);
2194             if (mapping > num_buttons)
2195                 num_buttons = mapping;
2196         }
2197     }
2198 
2199     has_lmr = libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_LEFT) ||
2200               libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_MIDDLE) ||
2201               libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_RIGHT);
2202 
2203     if (num_buttons)
2204     {
2205         pEvdev->flags |= EVDEV_BUTTON_EVENTS;
2206         pEvdev->num_buttons = num_buttons;
2207         xf86IDrvMsg(pInfo, X_PROBED, "Found %d mouse buttons\n", num_buttons);
2208     }
2209 
2210     for (i = 0; i < REL_MAX; i++) {
2211         if (libevdev_has_event_code(pEvdev->dev, EV_REL, i)) {
2212             has_rel_axes = TRUE;
2213             break;
2214         }
2215     }
2216 
2217     if (has_rel_axes) {
2218         if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL) ||
2219             libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL) ||
2220             libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL)) {
2221             xf86IDrvMsg(pInfo, X_PROBED, "Found scroll wheel(s)\n");
2222             has_scroll = TRUE;
2223             if (!num_buttons)
2224                 xf86IDrvMsg(pInfo, X_INFO,
2225                             "Forcing buttons for scroll wheel(s)\n");
2226             num_buttons = (num_buttons < 3) ? 7 : num_buttons + 4;
2227             pEvdev->num_buttons = num_buttons;
2228         }
2229 
2230         if (!ignore_rel)
2231         {
2232             xf86IDrvMsg(pInfo, X_PROBED, "Found relative axes\n");
2233             pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
2234 
2235             if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_X) &&
2236                 libevdev_has_event_code(pEvdev->dev, EV_REL, REL_Y)) {
2237                 xf86IDrvMsg(pInfo, X_PROBED, "Found x and y relative axes\n");
2238             } else if (!libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_X) ||
2239                        !libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_Y))
2240                 EvdevForceXY(pInfo, Relative);
2241         } else {
2242             xf86IDrvMsg(pInfo, X_INFO, "Relative axes present but ignored.\n");
2243             has_rel_axes = FALSE;
2244         }
2245     }
2246 
2247     for (i = 0; i < ABS_MAX; i++) {
2248         if (libevdev_has_event_code(pEvdev->dev, EV_ABS, i)) {
2249             has_abs_axes = TRUE;
2250             break;
2251         }
2252     }
2253 
2254     for (i = ABS_MT_SLOT; i < ABS_MAX; i++) {
2255         if (libevdev_has_event_code(pEvdev->dev, EV_ABS, i)) {
2256             has_mt = TRUE;
2257             break;
2258         }
2259     }
2260 
2261     if (libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_SLOT) &&
2262         libevdev_get_num_slots(pEvdev->dev) == -1)
2263         pEvdev->fake_mt = TRUE;
2264 
2265     if (ignore_abs && has_abs_axes)
2266     {
2267         xf86IDrvMsg(pInfo, X_INFO, "Absolute axes present but ignored.\n");
2268         has_abs_axes = FALSE;
2269     } else if (has_abs_axes) {
2270         xf86IDrvMsg(pInfo, X_PROBED, "Found absolute axes\n");
2271         pEvdev->flags |= EVDEV_ABSOLUTE_EVENTS;
2272 
2273         if (has_mt) {
2274             xf86IDrvMsg(pInfo, X_PROBED, "Found absolute multitouch axes\n");
2275             if (num_buttons == 0) {
2276                 if (libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_JOYSTICK)) {
2277                     xf86IDrvMsg(pInfo, X_INFO, "Device is a Joystick with MT without buttons. Ignoring it.\n");
2278                     goto out;
2279                 } else {
2280                     xf86IDrvMsg(pInfo, X_INFO, "No buttons found, faking one.\n");
2281                     num_buttons = 1;
2282                     pEvdev->num_buttons = num_buttons;
2283                     pEvdev->flags |= EVDEV_BUTTON_EVENTS;
2284                 }
2285             }
2286             if (pEvdev->fake_mt)
2287                 xf86IDrvMsg(pInfo, X_PROBED, "Fake MT device detected\n");
2288         }
2289 
2290         if ((libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_X) &&
2291              libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_Y))) {
2292             xf86IDrvMsg(pInfo, X_PROBED, "Found x and y absolute axes\n");
2293             if (libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_TOOL_PEN) ||
2294                 libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_STYLUS) ||
2295                 libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_STYLUS2))
2296             {
2297                 xf86IDrvMsg(pInfo, X_PROBED, "Found absolute tablet.\n");
2298                 pEvdev->flags |= EVDEV_TABLET;
2299                 if (!pEvdev->num_buttons)
2300                 {
2301                     pEvdev->num_buttons = 7; /* LMR + scroll wheels */
2302                     pEvdev->flags |= EVDEV_BUTTON_EVENTS;
2303                 }
2304             } else if (libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_PRESSURE) ||
2305                        libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_TOUCH)) {
2306                 if (has_lmr || libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_TOOL_FINGER)) {
2307                     xf86IDrvMsg(pInfo, X_PROBED, "Found absolute touchpad.\n");
2308                     pEvdev->flags |= EVDEV_TOUCHPAD;
2309                 } else {
2310                     xf86IDrvMsg(pInfo, X_PROBED, "Found absolute touchscreen\n");
2311                     pEvdev->flags |= EVDEV_TOUCHSCREEN;
2312                     pEvdev->flags |= EVDEV_BUTTON_EVENTS;
2313                 }
2314             } else if (!(libevdev_has_event_code(pEvdev->dev, EV_REL, REL_X) &&
2315                          libevdev_has_event_code(pEvdev->dev, EV_REL, REL_Y)) && has_lmr) {
2316                     /* some touchscreens use BTN_LEFT rather than BTN_TOUCH */
2317                     xf86IDrvMsg(pInfo, X_PROBED, "Found absolute touchscreen\n");
2318                     pEvdev->flags |= EVDEV_TOUCHSCREEN;
2319                     pEvdev->flags |= EVDEV_BUTTON_EVENTS;
2320             }
2321         } else {
2322             if (!libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_POSITION_X) ||
2323                 !libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_POSITION_Y))
2324                 EvdevForceXY(pInfo, Absolute);
2325         }
2326     }
2327 
2328     for (i = 0; i < BTN_MISC; i++) {
2329         if (libevdev_has_event_code(pEvdev->dev, EV_KEY, i)) {
2330             xf86IDrvMsg(pInfo, X_PROBED, "Found keys\n");
2331             pEvdev->flags |= EVDEV_KEYBOARD_EVENTS;
2332             has_keys = TRUE;
2333             break;
2334         }
2335     }
2336 
2337     if (has_rel_axes || has_abs_axes)
2338     {
2339         char *str;
2340         int num_calibration = 0, calibration[4] = { 0, 0, 0, 0 };
2341 
2342         pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE);
2343         pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
2344         pEvdev->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE);
2345 
2346         pEvdev->resolution = xf86SetIntOption(pInfo->options, "Resolution", 0);
2347         if (pEvdev->resolution < 0) {
2348             xf86IDrvMsg(pInfo, X_ERROR, "Resolution must be a positive number");
2349             pEvdev->resolution = 0;
2350         }
2351 
2352         str = xf86CheckStrOption(pInfo->options, "Calibration", NULL);
2353         if (str) {
2354             num_calibration = sscanf(str, "%d %d %d %d",
2355                     &calibration[0], &calibration[1],
2356                     &calibration[2], &calibration[3]);
2357             free(str);
2358             if (num_calibration == 4)
2359                 EvdevSetCalibration(pInfo, num_calibration, calibration);
2360             else
2361                 xf86IDrvMsg(pInfo, X_ERROR,
2362                             "Insufficient calibration factors (%d). Ignoring calibration\n",
2363                             num_calibration);
2364         }
2365     }
2366 
2367     if (has_rel_axes || has_abs_axes || num_buttons) {
2368         pInfo->flags |= XI86_SEND_DRAG_EVENTS;
2369 	if (pEvdev->flags & EVDEV_TOUCHPAD) {
2370 	    xf86IDrvMsg(pInfo, X_INFO, "Configuring as touchpad\n");
2371 	    pInfo->type_name = XI_TOUCHPAD;
2372 	    pEvdev->use_proximity = 0;
2373 	} else if (pEvdev->flags & EVDEV_TABLET) {
2374 	    xf86IDrvMsg(pInfo, X_INFO, "Configuring as tablet\n");
2375 	    pInfo->type_name = XI_TABLET;
2376         } else if (pEvdev->flags & EVDEV_TOUCHSCREEN) {
2377             xf86IDrvMsg(pInfo, X_INFO, "Configuring as touchscreen\n");
2378             pInfo->type_name = XI_TOUCHSCREEN;
2379 	} else {
2380             if (!libevdev_has_event_code(pEvdev->dev, EV_REL, REL_X) ||
2381                 !libevdev_has_event_code(pEvdev->dev, EV_REL, REL_Y)) {
2382                 pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
2383                 EvdevForceXY(pInfo, Relative);
2384             }
2385 	    xf86IDrvMsg(pInfo, X_INFO, "Configuring as mouse\n");
2386 	    pInfo->type_name = XI_MOUSE;
2387 	}
2388 
2389         rc = 0;
2390     }
2391 
2392     if (has_keys) {
2393         xf86IDrvMsg(pInfo, X_INFO, "Configuring as keyboard\n");
2394         pInfo->type_name = XI_KEYBOARD;
2395         rc = 0;
2396     }
2397 
2398     if (has_scroll &&
2399         (has_rel_axes || has_abs_axes || num_buttons || has_keys))
2400     {
2401         xf86IDrvMsg(pInfo, X_INFO, "Adding scrollwheel support\n");
2402         pEvdev->flags |= EVDEV_BUTTON_EVENTS;
2403         pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
2404 
2405         pEvdev->smoothScroll.vert_delta =
2406             xf86SetIntOption(pInfo->options, "VertScrollDelta", 1);
2407         pEvdev->smoothScroll.horiz_delta =
2408             xf86SetIntOption(pInfo->options, "HorizScrollDelta", 1);
2409         pEvdev->smoothScroll.dial_delta =
2410             xf86SetIntOption(pInfo->options, "DialDelta", 1);
2411     }
2412 
2413 out:
2414     if (rc)
2415         xf86IDrvMsg(pInfo, X_WARNING, "Don't know how to use device\n");
2416 
2417     return rc;
2418 }
2419 
2420 static void
EvdevSetCalibration(InputInfoPtr pInfo,int num_calibration,int calibration[4])2421 EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4])
2422 {
2423     EvdevPtr pEvdev = pInfo->private;
2424 
2425     if (num_calibration == 0) {
2426         pEvdev->flags &= ~EVDEV_CALIBRATED;
2427         pEvdev->calibration.min_x = 0;
2428         pEvdev->calibration.max_x = 0;
2429         pEvdev->calibration.min_y = 0;
2430         pEvdev->calibration.max_y = 0;
2431     } else if (num_calibration == 4) {
2432         pEvdev->flags |= EVDEV_CALIBRATED;
2433         pEvdev->calibration.min_x = calibration[0];
2434         pEvdev->calibration.max_x = calibration[1];
2435         pEvdev->calibration.min_y = calibration[2];
2436         pEvdev->calibration.max_y = calibration[3];
2437     }
2438 }
2439 
2440 /**
2441  * Open an mtdev device for this device. mtdev is a bit too generous with
2442  * memory usage, so only do so for multitouch protocol A devices.
2443  *
2444  * @return FALSE on error, TRUE if mtdev was initiated or the device doesn't
2445  * need it
2446  */
2447 static Bool
EvdevOpenMTDev(InputInfoPtr pInfo)2448 EvdevOpenMTDev(InputInfoPtr pInfo)
2449 {
2450     EvdevPtr pEvdev = pInfo->private;
2451 
2452     if (pEvdev->mtdev) {
2453         pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
2454         return TRUE;
2455     } else if (libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_SLOT)) {
2456         pEvdev->cur_slot = libevdev_get_current_slot(pEvdev->dev);
2457         return TRUE;
2458     }
2459 
2460     if (pInfo->fd < 0) {
2461         xf86Msg(X_ERROR, "%s: Bug. fd < 0\n", pInfo->name);
2462         return FALSE;
2463     }
2464 
2465     if (!libevdev_has_event_type(pEvdev->dev, EV_ABS))
2466         return TRUE;
2467 
2468     /* don't need mtdev for protocol B devices */
2469     if (libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_SLOT))
2470         return TRUE;
2471 
2472     if (!libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_POSITION_X) ||
2473         !libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_POSITION_Y))
2474         return TRUE;
2475 
2476     xf86IDrvMsg(pInfo, X_INFO, "Using mtdev for this device\n");
2477     pEvdev->mtdev = mtdev_new_open(pInfo->fd);
2478     if (pEvdev->mtdev)
2479         pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
2480     else {
2481         xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
2482         EvdevCloseDevice(pInfo);
2483         return FALSE;
2484     }
2485 
2486     return TRUE;
2487 }
2488 
2489 static int
EvdevOpenDevice(InputInfoPtr pInfo)2490 EvdevOpenDevice(InputInfoPtr pInfo)
2491 {
2492     EvdevPtr pEvdev = pInfo->private;
2493     char *device = pEvdev->device;
2494 
2495     if (!device)
2496     {
2497         device = xf86CheckStrOption(pInfo->options, "Device", NULL);
2498         if (!device) {
2499             xf86IDrvMsg(pInfo, X_ERROR, "No device specified.\n");
2500             return BadValue;
2501         }
2502 
2503         pEvdev->device = device;
2504         xf86IDrvMsg(pInfo, X_CONFIG, "Device: \"%s\"\n", device);
2505     }
2506 
2507     if (!(pInfo->flags & XI86_SERVER_FD) && pInfo->fd < 0)
2508     {
2509         do {
2510             pInfo->fd = open(device, O_RDWR | O_NONBLOCK, 0);
2511         } while (pInfo->fd < 0 && errno == EINTR);
2512     }
2513 
2514     if (pInfo->fd < 0) {
2515         xf86IDrvMsg(pInfo, X_ERROR, "Unable to open evdev device \"%s\" (%s).\n", device, strerror(errno));
2516         return BadValue;
2517     }
2518 
2519     if (libevdev_get_fd(pEvdev->dev) != -1) {
2520         struct input_event ev;
2521 
2522         libevdev_change_fd(pEvdev->dev, pInfo->fd);
2523         /* re-sync libevdev's view of the device, but
2524            we don't care about the actual events here */
2525         libevdev_next_event(pEvdev->dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
2526         while (libevdev_next_event(pEvdev->dev, LIBEVDEV_READ_FLAG_SYNC, &ev) == LIBEVDEV_READ_STATUS_SYNC)
2527             ;
2528     } else {
2529         int rc = libevdev_set_fd(pEvdev->dev, pInfo->fd);
2530         if (rc < 0) {
2531             xf86IDrvMsg(pInfo, X_ERROR, "Unable to query fd: %s\n", strerror(-rc));
2532             return BadValue;
2533         }
2534     }
2535 
2536     /* Check major/minor of device node to avoid adding duplicate devices. */
2537     pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
2538     if (EvdevIsDuplicate(pInfo))
2539     {
2540         xf86IDrvMsg(pInfo, X_WARNING, "device file is duplicate. Ignoring.\n");
2541         EvdevCloseDevice(pInfo);
2542         return BadMatch;
2543     }
2544 
2545     if (!EvdevOpenMTDev(pInfo)) {
2546         xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
2547         EvdevCloseDevice(pInfo);
2548         return BadValue;
2549     }
2550 
2551     return Success;
2552 }
2553 
2554 static void
EvdevCloseDevice(InputInfoPtr pInfo)2555 EvdevCloseDevice(InputInfoPtr pInfo)
2556 {
2557     EvdevPtr pEvdev = pInfo->private;
2558     if (!(pInfo->flags & XI86_SERVER_FD) && pInfo->fd >= 0)
2559     {
2560         close(pInfo->fd);
2561         pInfo->fd = -1;
2562     }
2563 
2564     if (pEvdev->mtdev)
2565     {
2566         mtdev_close_delete(pEvdev->mtdev);
2567         pEvdev->mtdev = NULL;
2568     }
2569 
2570 }
2571 
2572 
2573 static void
EvdevUnInit(InputDriverPtr drv,InputInfoPtr pInfo,int flags)2574 EvdevUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2575 {
2576     EvdevPtr pEvdev = pInfo ? pInfo->private : NULL;
2577     if (pEvdev)
2578     {
2579         /* Release string allocated in EvdevOpenDevice. */
2580         free(pEvdev->device);
2581         pEvdev->device = NULL;
2582 
2583         free(pEvdev->type_name);
2584         pEvdev->type_name = NULL;
2585 
2586         libevdev_free(pEvdev->dev);
2587     }
2588     xf86DeleteInput(pInfo, flags);
2589 }
2590 
2591 static EvdevPtr
EvdevAlloc(InputInfoPtr pInfo)2592 EvdevAlloc(InputInfoPtr pInfo)
2593 {
2594     int i;
2595     EvdevPtr pEvdev = calloc(sizeof(EvdevRec), 1);
2596 
2597     if (!pEvdev)
2598         return NULL;
2599 
2600     pEvdev->dev = libevdev_new();
2601     if (!pEvdev->dev) {
2602         free(pEvdev);
2603         return NULL;
2604     }
2605 
2606     /*
2607      * We initialize pEvdev->in_proximity to 1 so that device that doesn't use
2608      * proximity will still report events.
2609      */
2610     pEvdev->in_proximity = 1;
2611     pEvdev->use_proximity = 1;
2612 
2613     pEvdev->cur_slot = -1;
2614 
2615     for (i = 0; i < ArrayLength(pEvdev->rel_axis_map); i++)
2616         pEvdev->rel_axis_map[i] = -1;
2617     for (i = 0; i < ArrayLength(pEvdev->abs_axis_map); i++)
2618         pEvdev->abs_axis_map[i] = -1;
2619 
2620     pEvdev->rel_axis_map[0] = 0;
2621     pEvdev->rel_axis_map[1] = 1;
2622 
2623     pEvdev->type_name = NULL;
2624 
2625     return pEvdev;
2626 }
2627 
2628 static int
EvdevPreInit(InputDriverPtr drv,InputInfoPtr pInfo,int flags)2629 EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2630 {
2631     EvdevPtr pEvdev;
2632     int rc = BadAlloc;
2633 
2634     if (!(pEvdev = EvdevAlloc(pInfo)))
2635         goto error;
2636 
2637     pInfo->private = pEvdev;
2638     pInfo->type_name = "UNKNOWN";
2639     pInfo->device_control = EvdevProc;
2640     pInfo->read_input = EvdevReadInput;
2641     pInfo->switch_mode = EvdevSwitchMode;
2642 
2643     rc = EvdevOpenDevice(pInfo);
2644     if (rc != Success)
2645         goto error;
2646 
2647     /* Grabbing the event device stops in-kernel event forwarding. In other
2648        words, it disables rfkill and the "Macintosh mouse button emulation".
2649        Note that this needs a server that sets the console to RAW mode. */
2650     pEvdev->grabDevice = xf86CheckBoolOption(pInfo->options, "GrabDevice", 0);
2651 
2652     /* If grabDevice is set, ungrab immediately since we only want to grab
2653      * between DEVICE_ON and DEVICE_OFF. If we never get DEVICE_ON, don't
2654      * hold a grab. */
2655 
2656     if (!EvdevGrabDevice(pInfo, 1, 1))
2657     {
2658         xf86IDrvMsg(pInfo, X_WARNING, "Device may already be configured.\n");
2659         rc = BadMatch;
2660         goto error;
2661     }
2662 
2663     EvdevInitButtonMapping(pInfo);
2664 
2665     if (EvdevCache(pInfo) || EvdevProbe(pInfo)) {
2666         rc = BadMatch;
2667         goto error;
2668     }
2669 
2670     /* Overwrite type_name with custom-defined one (#62831).
2671        Note: pInfo->type_name isn't freed so we need to manually do this
2672      */
2673     pEvdev->type_name = xf86SetStrOption(pInfo->options,
2674                                          "TypeName",
2675                                          pInfo->type_name);
2676     pInfo->type_name = pEvdev->type_name;
2677 
2678     if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
2679     {
2680         EvdevMBEmuPreInit(pInfo);
2681         Evdev3BEmuPreInit(pInfo);
2682         EvdevWheelEmuPreInit(pInfo);
2683         EvdevDragLockPreInit(pInfo);
2684     }
2685 
2686     return Success;
2687 
2688 error:
2689     EvdevCloseDevice(pInfo);
2690     return rc;
2691 }
2692 
2693 _X_EXPORT InputDriverRec EVDEV = {
2694     1,
2695     "evdev",
2696     NULL,
2697     EvdevPreInit,
2698     EvdevUnInit,
2699     NULL,
2700     NULL,
2701 #ifdef XI86_DRV_CAP_SERVER_FD
2702     XI86_DRV_CAP_SERVER_FD
2703 #endif
2704 };
2705 
2706 static void
EvdevUnplug(pointer p)2707 EvdevUnplug(pointer	p)
2708 {
2709 }
2710 
2711 static pointer
EvdevPlug(pointer module,pointer options,int * errmaj,int * errmin)2712 EvdevPlug(pointer	module,
2713           pointer	options,
2714           int		*errmaj,
2715           int		*errmin)
2716 {
2717     xf86AddInputDriver(&EVDEV, module, 0);
2718     return module;
2719 }
2720 
2721 static XF86ModuleVersionInfo EvdevVersionRec =
2722 {
2723     "evdev",
2724     MODULEVENDORSTRING,
2725     MODINFOSTRING1,
2726     MODINFOSTRING2,
2727     XORG_VERSION_CURRENT,
2728     PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
2729     ABI_CLASS_XINPUT,
2730     ABI_XINPUT_VERSION,
2731     MOD_CLASS_XINPUT,
2732     {0, 0, 0, 0}
2733 };
2734 
2735 _X_EXPORT XF86ModuleData evdevModuleData =
2736 {
2737     &EvdevVersionRec,
2738     EvdevPlug,
2739     EvdevUnplug
2740 };
2741 
2742 
2743 /* Return an index value for a given button event code
2744  * returns 0 on non-button event.
2745  */
2746 unsigned int
EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev,int code)2747 EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code)
2748 {
2749     switch (code)
2750     {
2751         /* Mouse buttons */
2752         case BTN_LEFT:
2753             return 1;
2754         case BTN_MIDDLE:
2755             return 2;
2756         case BTN_RIGHT:
2757             return 3;
2758         case BTN_SIDE ... BTN_JOYSTICK - 1:
2759             return 8 + code - BTN_SIDE;
2760 
2761         /* Generic buttons */
2762         case BTN_0 ... BTN_2:
2763             return 1 + code - BTN_0;
2764         case BTN_3 ... BTN_MOUSE - 1:
2765             return 8 + code - BTN_3;
2766 
2767         /* Tablet stylus buttons */
2768         case BTN_TOUCH ... BTN_STYLUS2:
2769             return 1 + code - BTN_TOUCH;
2770 
2771         /* The rest */
2772         default:
2773             /* Ignore */
2774             return 0;
2775     }
2776 }
2777 
EvdevInitOneAxisLabel(EvdevPtr pEvdev,int mapped_axis,const char ** labels,int label_idx,Atom * atoms)2778 static void EvdevInitOneAxisLabel(EvdevPtr pEvdev, int mapped_axis,
2779                                   const char **labels, int label_idx, Atom *atoms)
2780 {
2781     Atom atom;
2782 
2783     if (mapped_axis == -1)
2784         return;
2785 
2786     atom = XIGetKnownProperty(labels[label_idx]);
2787     if (!atom) /* Should not happen */
2788         return;
2789 
2790     atoms[mapped_axis] = atom;
2791 }
2792 
EvdevInitAxesLabels(EvdevPtr pEvdev,int mode,int natoms,Atom * atoms)2793 static void EvdevInitAxesLabels(EvdevPtr pEvdev, int mode, int natoms, Atom *atoms)
2794 {
2795     int axis;
2796 
2797     memset(atoms, 0, natoms * sizeof(Atom));
2798 
2799     /* rel[0] and [1] are always mapped, so we get the rel labels. if we
2800        have abs x/y, the labels will be overwritten with the right one */
2801     for (axis = 0; axis < ArrayLength(rel_labels); axis++)
2802         EvdevInitOneAxisLabel(pEvdev, pEvdev->rel_axis_map[axis], rel_labels, axis, atoms);
2803 
2804     for (axis = 0; axis < ArrayLength(abs_labels); axis++)
2805         EvdevInitOneAxisLabel(pEvdev, pEvdev->abs_axis_map[axis], abs_labels, axis, atoms);
2806 }
2807 
EvdevInitButtonLabels(EvdevPtr pEvdev,int natoms,Atom * atoms)2808 static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms)
2809 {
2810     Atom atom;
2811     int button, bmap;
2812 
2813     /* First, make sure all atoms are initialized */
2814     atom = XIGetKnownProperty(BTN_LABEL_PROP_BTN_UNKNOWN);
2815     for (button = 0; button < natoms; button++)
2816         atoms[button] = atom;
2817 
2818     for (button = BTN_MISC; button < BTN_JOYSTICK; button++)
2819     {
2820         int group = (button % 0x100)/16;
2821         int idx = button - ((button/16) * 16);
2822 
2823         if (group >= ArrayLength(btn_labels))
2824             break;
2825 
2826         if (!libevdev_has_event_code(pEvdev->dev, EV_KEY, button))
2827             continue;
2828 
2829         if (!btn_labels[group][idx])
2830             continue;
2831 
2832         atom = XIGetKnownProperty(btn_labels[group][idx]);
2833         if (!atom)
2834             continue;
2835 
2836         /* Props are 0-indexed, button numbers start with 1 */
2837         bmap = EvdevUtilButtonEventToButtonNumber(pEvdev, button) - 1;
2838         atoms[bmap] = atom;
2839     }
2840 
2841     /* wheel buttons, hardcoded anyway */
2842     if (natoms > 3)
2843         atoms[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
2844     if (natoms > 4)
2845         atoms[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
2846     if (natoms > 5)
2847         atoms[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
2848     if (natoms > 6)
2849         atoms[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
2850 }
2851 
2852 static void
EvdevInitProperty(DeviceIntPtr dev)2853 EvdevInitProperty(DeviceIntPtr dev)
2854 {
2855     InputInfoPtr pInfo  = dev->public.devicePrivate;
2856     EvdevPtr     pEvdev = pInfo->private;
2857     int          rc;
2858     char         *device_node;
2859 
2860     CARD32       product[2];
2861 
2862     prop_product_id = MakeAtom(XI_PROP_PRODUCT_ID, strlen(XI_PROP_PRODUCT_ID), TRUE);
2863     product[0] = libevdev_get_id_vendor(pEvdev->dev);
2864     product[1] = libevdev_get_id_product(pEvdev->dev);
2865     rc = XIChangeDeviceProperty(dev, prop_product_id, XA_INTEGER, 32,
2866                                 PropModeReplace, 2, product, FALSE);
2867     if (rc != Success)
2868         return;
2869 
2870     XISetDevicePropertyDeletable(dev, prop_product_id, FALSE);
2871 
2872     /* Device node property */
2873     device_node = strdup(pEvdev->device);
2874     prop_device = MakeAtom(XI_PROP_DEVICE_NODE,
2875                            strlen(XI_PROP_DEVICE_NODE), TRUE);
2876     rc = XIChangeDeviceProperty(dev, prop_device, XA_STRING, 8,
2877                                 PropModeReplace,
2878                                 strlen(device_node), device_node,
2879                                 FALSE);
2880     free(device_node);
2881 
2882     if (rc != Success)
2883         return;
2884 
2885     if (EvdevDeviceIsVirtual(pEvdev->device))
2886     {
2887         BOOL virtual = 1;
2888         prop_virtual = MakeAtom(XI_PROP_VIRTUAL_DEVICE,
2889                                 strlen(XI_PROP_VIRTUAL_DEVICE), TRUE);
2890         rc = XIChangeDeviceProperty(dev, prop_virtual, XA_INTEGER, 8,
2891                                     PropModeReplace, 1, &virtual, FALSE);
2892         if (rc != Success)
2893             return;
2894 
2895         XISetDevicePropertyDeletable(dev, prop_virtual, FALSE);
2896     }
2897 
2898 
2899     XISetDevicePropertyDeletable(dev, prop_device, FALSE);
2900 
2901     if (pEvdev->flags & (EVDEV_RELATIVE_EVENTS | EVDEV_ABSOLUTE_EVENTS))
2902     {
2903         BOOL invert[2];
2904         invert[0] = pEvdev->invert_x;
2905         invert[1] = pEvdev->invert_y;
2906 
2907         prop_invert = MakeAtom(EVDEV_PROP_INVERT_AXES, strlen(EVDEV_PROP_INVERT_AXES), TRUE);
2908 
2909         rc = XIChangeDeviceProperty(dev, prop_invert, XA_INTEGER, 8,
2910                 PropModeReplace, 2,
2911                 invert, FALSE);
2912         if (rc != Success)
2913             return;
2914 
2915         XISetDevicePropertyDeletable(dev, prop_invert, FALSE);
2916 
2917         prop_calibration = MakeAtom(EVDEV_PROP_CALIBRATION,
2918                 strlen(EVDEV_PROP_CALIBRATION), TRUE);
2919         if (pEvdev->flags & EVDEV_CALIBRATED) {
2920             int calibration[4];
2921 
2922             calibration[0] = pEvdev->calibration.min_x;
2923             calibration[1] = pEvdev->calibration.max_x;
2924             calibration[2] = pEvdev->calibration.min_y;
2925             calibration[3] = pEvdev->calibration.max_y;
2926 
2927             rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER,
2928                     32, PropModeReplace, 4, calibration,
2929                     FALSE);
2930         } else if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) {
2931             rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER,
2932                     32, PropModeReplace, 0, NULL,
2933                     FALSE);
2934         }
2935         if (rc != Success)
2936             return;
2937 
2938         XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
2939 
2940         prop_swap = MakeAtom(EVDEV_PROP_SWAP_AXES,
2941                 strlen(EVDEV_PROP_SWAP_AXES), TRUE);
2942 
2943         rc = XIChangeDeviceProperty(dev, prop_swap, XA_INTEGER, 8,
2944                 PropModeReplace, 1, &pEvdev->swap_axes, FALSE);
2945         if (rc != Success)
2946             return;
2947 
2948         XISetDevicePropertyDeletable(dev, prop_swap, FALSE);
2949 
2950         /* Axis labelling */
2951         if ((pEvdev->num_vals > 0) && (prop_axis_label = XIGetKnownProperty(AXIS_LABEL_PROP)))
2952         {
2953             int mode;
2954             int num_axes = pEvdev->num_vals + pEvdev->num_mt_vals;
2955             Atom atoms[num_axes];
2956 
2957             if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
2958                 mode = Absolute;
2959             else if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
2960                 mode = Relative;
2961             else {
2962                 xf86IDrvMsg(pInfo, X_ERROR, "BUG: mode is neither absolute nor relative\n");
2963                 mode = Absolute;
2964             }
2965 
2966             EvdevInitAxesLabels(pEvdev, mode, num_axes, atoms);
2967             rc = XIChangeDeviceProperty(dev, prop_axis_label, XA_ATOM, 32,
2968                                         PropModeReplace, num_axes, atoms, FALSE);
2969             if (rc != Success)
2970                 return;
2971 
2972             XISetDevicePropertyDeletable(dev, prop_axis_label, FALSE);
2973         }
2974         /* Button labelling */
2975         if ((pEvdev->num_buttons > 0) && (prop_btn_label = XIGetKnownProperty(BTN_LABEL_PROP)))
2976         {
2977             Atom atoms[EVDEV_MAXBUTTONS];
2978             EvdevInitButtonLabels(pEvdev, EVDEV_MAXBUTTONS, atoms);
2979             rc = XIChangeDeviceProperty(dev, prop_btn_label, XA_ATOM, 32,
2980                                         PropModeReplace, pEvdev->num_buttons, atoms, FALSE);
2981             if (rc != Success)
2982                 return;
2983 
2984             XISetDevicePropertyDeletable(dev, prop_btn_label, FALSE);
2985         }
2986 
2987         {
2988             int smooth_scroll_values[3] = {
2989                 pEvdev->smoothScroll.vert_delta,
2990                 pEvdev->smoothScroll.horiz_delta,
2991                 pEvdev->smoothScroll.dial_delta
2992             };
2993             prop_scroll_dist = MakeAtom(EVDEV_PROP_SCROLL_DISTANCE,
2994                                         strlen(EVDEV_PROP_SCROLL_DISTANCE), TRUE);
2995             rc = XIChangeDeviceProperty(dev, prop_scroll_dist, XA_INTEGER, 32,
2996                                         PropModeReplace, 3, smooth_scroll_values, FALSE);
2997             if (rc != Success)
2998                 return;
2999 
3000             XISetDevicePropertyDeletable(dev, prop_scroll_dist, FALSE);
3001         }
3002 
3003     }
3004 
3005 }
3006 
3007 static int
EvdevSetProperty(DeviceIntPtr dev,Atom atom,XIPropertyValuePtr val,BOOL checkonly)3008 EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
3009                  BOOL checkonly)
3010 {
3011     InputInfoPtr pInfo  = dev->public.devicePrivate;
3012     EvdevPtr     pEvdev = pInfo->private;
3013 
3014     if (atom == prop_invert)
3015     {
3016         BOOL* data;
3017         if (val->format != 8 || val->size != 2 || val->type != XA_INTEGER)
3018             return BadMatch;
3019 
3020         if (!checkonly)
3021         {
3022             data = (BOOL*)val->data;
3023             pEvdev->invert_x = data[0];
3024             pEvdev->invert_y = data[1];
3025         }
3026     } else if (atom == prop_calibration)
3027     {
3028         if (val->format != 32 || val->type != XA_INTEGER)
3029             return BadMatch;
3030         if (val->size != 4 && val->size != 0)
3031             return BadMatch;
3032 
3033         if (!checkonly)
3034             EvdevSetCalibration(pInfo, val->size, val->data);
3035     } else if (atom == prop_swap)
3036     {
3037         if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
3038             return BadMatch;
3039 
3040         if (!checkonly)
3041             pEvdev->swap_axes = *((BOOL*)val->data);
3042     } else if (atom == prop_scroll_dist)
3043     {
3044         if (val->format != 32 || val->type != XA_INTEGER || val->size != 3)
3045             return BadMatch;
3046 
3047         if (!checkonly) {
3048             int *data = (int *)val->data;
3049             pEvdev->smoothScroll.vert_delta = data[0];
3050             pEvdev->smoothScroll.horiz_delta = data[1];
3051             pEvdev->smoothScroll.dial_delta = data[2];
3052             EvdevSetScrollValuators(dev);
3053         }
3054     } else if (atom == prop_axis_label || atom == prop_btn_label ||
3055                atom == prop_product_id || atom == prop_device ||
3056                atom == prop_virtual)
3057         return BadAccess; /* Read-only properties */
3058 
3059     return Success;
3060 }
3061