2 * Copyright © 2004-2008 Red Hat, Inc.
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
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.
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)
34 #include <X11/keysym.h>
42 #include <xf86Xinput.h>
44 #include <xorgVersion.h>
49 #ifdef HAVE_PROPERTIES
50 #include <X11/Xatom.h>
51 #include <evdev-properties.h>
52 #include <xserver-properties.h>
53 /* 1.6 has properties, but no labels */
54 #ifdef AXIS_LABEL_PROP
63 #include <inputstr.h> /* for MAX_DEVICES */
64 #define MAXDEVICES MAX_DEVICES
67 /* 2.4 compatibility */
69 #define EVIOCGRAB _IOW('E', 0x90, int)
73 #define BTN_TASK 0x117
81 #define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
84 #define EVDEV_KEYBOARD_EVENTS (1 << 0)
85 #define EVDEV_BUTTON_EVENTS (1 << 1)
86 #define EVDEV_RELATIVE_EVENTS (1 << 2)
87 #define EVDEV_ABSOLUTE_EVENTS (1 << 3)
88 #define EVDEV_TOUCHPAD (1 << 4)
89 #define EVDEV_INITIALIZED (1 << 5) /* WheelInit etc. called already? */
90 #define EVDEV_TOUCHSCREEN (1 << 6)
91 #define EVDEV_CALIBRATED (1 << 7) /* run-time calibrated? */
92 #define EVDEV_TABLET (1 << 8) /* device looks like a tablet? */
93 #define EVDEV_UNIGNORE_ABSOLUTE (1 << 9) /* explicitly unignore abs axes */
94 #define EVDEV_UNIGNORE_RELATIVE (1 << 10) /* explicitly unignore rel axes */
95 #define EVDEV_RESOLUTION (1 << 12) /* device looks like a multi-touch screen? */
98 #define GLYPHS_PER_KEY 2
99 #define AltMask Mod1Mask
100 #define NumLockMask Mod2Mask
101 #define AltLangMask Mod3Mask
102 #define KanaMask Mod4Mask
103 #define ScrollLockMask Mod5Mask
109 #define COMPOSEFLAG 16
111 static const char *evdevDefaults[] = {
118 static int EvdevOn(DeviceIntPtr);
119 static int EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare);
120 static void EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl);
121 static void EvdevSwapAxes(EvdevPtr pEvdev);
122 static void EvdevSetResolution(InputInfoPtr pInfo, int num_resolution, int resolution[4]);
124 #ifdef HAVE_PROPERTIES
125 static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
126 static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
127 static void EvdevInitProperty(DeviceIntPtr dev);
128 static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
129 XIPropertyValuePtr val, BOOL checkonly);
130 static void EvdevSetMouseExist(int value);
131 static void EvdevSetExtKeyboardExist(int value);
132 static Atom prop_invert = 0;
133 static Atom prop_reopen = 0;
134 static Atom prop_calibration = 0;
135 static Atom prop_swap = 0;
136 static Atom prop_axis_label = 0;
137 static Atom prop_btn_label = 0;
140 /* All devices the evdev driver has allocated and knows about.
141 * MAXDEVICES is safe as null-terminated array, as two devices (VCP and VCK)
142 * cannot be used by evdev, leaving us with a space of 2 at the end. */
143 static EvdevPtr evdev_devices[MAXDEVICES] = {NULL};
145 static size_t CountBits(unsigned long *array, size_t nlongs)
150 for (i = 0; i < nlongs; i++) {
151 unsigned long x = array[i];
163 EvdevGetMajorMinor(InputInfoPtr pInfo)
167 if (fstat(pInfo->fd, &st) == -1)
169 xf86Msg(X_ERROR, "%s: stat failed (%s). cannot check for duplicates.\n",
170 pInfo->name, strerror(errno));
178 * Return TRUE if one of the devices we know about has the same min/maj
182 EvdevIsDuplicate(InputInfoPtr pInfo)
184 EvdevPtr pEvdev = pInfo->private;
185 EvdevPtr* dev = evdev_devices;
191 if ((*dev) != pEvdev &&
193 (*dev)->min_maj == pEvdev->min_maj)
202 * Add to internal device list.
205 EvdevAddDevice(InputInfoPtr pInfo)
207 EvdevPtr pEvdev = pInfo->private;
208 EvdevPtr* dev = evdev_devices;
217 * Remove from internal device list.
220 EvdevRemoveDevice(InputInfoPtr pInfo)
222 EvdevPtr pEvdev = pInfo->private;
223 EvdevPtr *dev = evdev_devices;
231 memmove(dev, dev + 1,
232 sizeof(evdev_devices) - (count * sizeof(EvdevPtr)));
241 SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
245 if ((s = xf86SetStrOption(pInfo->options, name, NULL))) {
255 static int wheel_up_button = 4;
256 static int wheel_down_button = 5;
257 static int wheel_left_button = 6;
258 static int wheel_right_button = 7;
261 EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
263 int code = ev->code + MIN_KEYCODE;
264 static char warned[KEY_CNT];
265 EventQueuePtr pQueue;
266 EvdevPtr pEvdev = pInfo->private;
268 /* Filter all repeated events from device.
269 We'll do softrepeat in the server, but only since 1.6 */
271 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) <= 2
272 && (ev->code == KEY_LEFTCTRL || ev->code == KEY_RIGHTCTRL ||
273 ev->code == KEY_LEFTSHIFT || ev->code == KEY_RIGHTSHIFT ||
274 ev->code == KEY_LEFTALT || ev->code == KEY_RIGHTALT ||
275 ev->code == KEY_LEFTMETA || ev->code == KEY_RIGHTMETA ||
276 ev->code == KEY_CAPSLOCK || ev->code == KEY_NUMLOCK ||
277 ev->code == KEY_SCROLLLOCK) /* XXX windows keys? */
284 if (ev->code <= KEY_MAX && !warned[ev->code])
286 xf86Msg(X_WARNING, "%s: unable to handle keycode %d\n",
287 pInfo->name, ev->code);
288 warned[ev->code] = 1;
291 /* The X server can't handle keycodes > 255. */
295 if (pEvdev->num_queue >= EVDEV_MAXQUEUE)
297 xf86Msg(X_NONE, "%s: dropping event due to full queue!\n", pInfo->name);
301 pQueue = &pEvdev->queue[pEvdev->num_queue];
302 pQueue->type = EV_QUEUE_KEY;
309 EvdevQueueButtonEvent(InputInfoPtr pInfo, int button, int value)
311 EventQueuePtr pQueue;
312 EvdevPtr pEvdev = pInfo->private;
314 if (pEvdev->num_queue >= EVDEV_MAXQUEUE)
316 xf86Msg(X_NONE, "%s: dropping event due to full queue!\n", pInfo->name);
320 pQueue = &pEvdev->queue[pEvdev->num_queue];
321 pQueue->type = EV_QUEUE_BTN;
322 pQueue->key = button;
328 * Post button event right here, right now.
329 * Interface for MB emulation since these need to post immediately.
332 EvdevPostButtonEvent(InputInfoPtr pInfo, int button, int value)
334 xf86PostButtonEvent(pInfo->dev, 0, button, value, 0, 0);
338 EvdevQueueButtonClicks(InputInfoPtr pInfo, int button, int count)
342 for (i = 0; i < count; i++) {
343 EvdevQueueButtonEvent(pInfo, button, 1);
344 EvdevQueueButtonEvent(pInfo, button, 0);
349 * Coming back from resume may leave us with a file descriptor that can be
350 * opened but fails on the first read (ENODEV).
351 * In this case, try to open the device until it becomes available or until
352 * the predefined count expires.
355 EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
357 InputInfoPtr pInfo = (InputInfoPtr)arg;
358 EvdevPtr pEvdev = pInfo->private;
361 pInfo->fd = open(pEvdev->device, O_RDWR | O_NONBLOCK, 0);
362 } while (pInfo->fd < 0 && errno == EINTR);
366 if (EvdevCacheCompare(pInfo, TRUE) == Success)
368 xf86Msg(X_INFO, "%s: Device reopened after %d attempts.\n", pInfo->name,
369 pEvdev->reopen_attempts - pEvdev->reopen_left + 1);
373 xf86Msg(X_ERROR, "%s: Device has changed - disabling.\n",
375 xf86DisableDevice(pInfo->dev, FALSE);
378 pEvdev->min_maj = 0; /* don't hog the device */
380 pEvdev->reopen_left = 0;
384 pEvdev->reopen_left--;
386 if (!pEvdev->reopen_left)
388 xf86Msg(X_ERROR, "%s: Failed to reopen device after %d attempts.\n",
389 pInfo->name, pEvdev->reopen_attempts);
390 xf86DisableDevice(pInfo->dev, FALSE);
391 pEvdev->min_maj = 0; /* don't hog the device */
395 return 100; /* come back in 100 ms */
398 #define ABS_X_VALUE 0x1
399 #define ABS_Y_VALUE 0x2
400 #define ABS_VALUE 0x4
402 * Take the valuators and process them accordingly.
405 EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
409 EvdevPtr pEvdev = pInfo->private;
411 *num_v = *first_v = 0;
413 /* convert to relative motion for touchpads */
414 if (pEvdev->abs && (pEvdev->flags & EVDEV_TOUCHPAD)) {
415 if (pEvdev->tool) { /* meaning, touch is active */
416 if (pEvdev->old_vals[0] != -1)
417 pEvdev->delta[REL_X] = pEvdev->vals[0] - pEvdev->old_vals[0];
418 if (pEvdev->old_vals[1] != -1)
419 pEvdev->delta[REL_Y] = pEvdev->vals[1] - pEvdev->old_vals[1];
420 if (pEvdev->abs & ABS_X_VALUE)
421 pEvdev->old_vals[0] = pEvdev->vals[0];
422 if (pEvdev->abs & ABS_Y_VALUE)
423 pEvdev->old_vals[1] = pEvdev->vals[1];
425 pEvdev->old_vals[0] = pEvdev->old_vals[1] = -1;
432 int first = REL_CNT, last = 0;
435 if (pEvdev->swap_axes) {
436 tmp = pEvdev->delta[REL_X];
437 pEvdev->delta[REL_X] = pEvdev->delta[REL_Y];
438 pEvdev->delta[REL_Y] = tmp;
440 if (pEvdev->invert_x)
441 pEvdev->delta[REL_X] *= -1;
442 if (pEvdev->invert_y)
443 pEvdev->delta[REL_Y] *= -1;
445 for (i = 0; i < REL_CNT; i++)
447 int map = pEvdev->axis_map[i];
450 v[map] = pEvdev->delta[i];
458 *num_v = (last - first + 1);
462 * Some devices only generate valid abs coords when BTN_DIGI is
463 * pressed. On wacom tablets, this means that the pen is in
464 * proximity of the tablet. After the pen is removed, BTN_DIGI is
465 * released, and a (0, 0) absolute event is generated. Checking
466 * pEvdev->digi here, lets us ignore that event. pEvdev is
467 * initialized to 1 so devices that doesn't use this scheme still
470 else if (pEvdev->abs && pEvdev->tool) {
471 memcpy(v, pEvdev->vals, sizeof(int) * pEvdev->num_vals);
473 if (pEvdev->swap_axes) {
479 if (pEvdev->flags & EVDEV_CALIBRATED)
481 v[0] = xf86ScaleAxis(v[0],
482 pEvdev->absinfo[ABS_X].maximum,
483 pEvdev->absinfo[ABS_X].minimum,
484 pEvdev->calibration.max_x, pEvdev->calibration.min_x);
485 v[1] = xf86ScaleAxis(v[1],
486 pEvdev->absinfo[ABS_Y].maximum,
487 pEvdev->absinfo[ABS_Y].minimum,
488 pEvdev->calibration.max_y, pEvdev->calibration.min_y);
491 if (pEvdev->invert_x)
492 v[0] = (pEvdev->absinfo[ABS_X].maximum - v[0] +
493 pEvdev->absinfo[ABS_X].minimum);
494 if (pEvdev->invert_y)
495 v[1] = (pEvdev->absinfo[ABS_Y].maximum - v[1] +
496 pEvdev->absinfo[ABS_Y].minimum);
498 *num_v = pEvdev->num_vals;
504 * Take a button input event and process it accordingly.
507 EvdevProcessButtonEvent(InputInfoPtr pInfo, struct input_event *ev)
511 EvdevPtr pEvdev = pInfo->private;
513 button = EvdevUtilButtonEventToButtonNumber(pEvdev, ev->code);
515 /* Get the signed value, earlier kernels had this as unsigned */
518 /* Handle drag lock */
519 if (EvdevDragLockFilterEvent(pInfo, button, value))
522 if (EvdevWheelEmuFilterButton(pInfo, button, value))
525 if (EvdevMBEmuFilterEvent(pInfo, button, value))
529 EvdevQueueButtonEvent(pInfo, button, value);
531 EvdevQueueKbdEvent(pInfo, ev, value);
535 * Take the relative motion input event and process it accordingly.
538 EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
541 EvdevPtr pEvdev = pInfo->private;
543 /* Get the signed value, earlier kernels had this as unsigned */
551 EvdevQueueButtonClicks(pInfo, wheel_up_button, value);
553 EvdevQueueButtonClicks(pInfo, wheel_down_button, -value);
559 EvdevQueueButtonClicks(pInfo, wheel_right_button, value);
561 EvdevQueueButtonClicks(pInfo, wheel_left_button, -value);
564 /* We don't post wheel events as axis motion. */
566 /* Ignore EV_REL events if we never set up for them. */
567 if (!(pEvdev->flags & EVDEV_RELATIVE_EVENTS))
570 /* Handle mouse wheel emulation */
571 if (EvdevWheelEmuFilterMotion(pInfo, ev))
574 pEvdev->delta[ev->code] += value;
580 * Take the absolute motion input event and process it accordingly.
583 EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
586 EvdevPtr pEvdev = pInfo->private;
588 /* Get the signed value, earlier kernels had this as unsigned */
591 /* Ignore EV_ABS events if we never set up for them. */
592 if (!(pEvdev->flags & EVDEV_ABSOLUTE_EVENTS))
595 if (ev->code > ABS_MAX)
598 pEvdev->vals[pEvdev->axis_map[ev->code]] = value;
599 if (ev->code == ABS_X)
600 pEvdev->abs |= ABS_X_VALUE;
601 else if (ev->code == ABS_Y)
602 pEvdev->abs |= ABS_Y_VALUE;
604 pEvdev->abs |= ABS_VALUE;
608 * Take the key press/release input event and process it accordingly.
611 EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev)
614 EvdevPtr pEvdev = pInfo->private;
616 /* Get the signed value, earlier kernels had this as unsigned */
619 /* don't repeat mouse buttons */
620 if (ev->code >= BTN_MOUSE && ev->code < KEY_OK)
626 case BTN_TOOL_RUBBER:
628 case BTN_TOOL_PENCIL:
629 case BTN_TOOL_AIRBRUSH:
630 case BTN_TOOL_FINGER:
633 pEvdev->tool = value ? ev->code : 0;
637 pEvdev->tool = value ? ev->code : 0;
638 if (!(pEvdev->flags & (EVDEV_TOUCHSCREEN | EVDEV_TABLET)))
640 /* Treat BTN_TOUCH from devices that only have BTN_TOUCH as
643 /* Intentional fallthrough! */
646 EvdevProcessButtonEvent(pInfo, ev);
652 * Post the relative motion events.
655 EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
656 int v[MAX_VALUATORS])
658 EvdevPtr pEvdev = pInfo->private;
661 xf86PostMotionEventP(pInfo->dev, FALSE, *first_v, *num_v, v + *first_v);
666 * Post the absolute motion events.
669 EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
670 int v[MAX_VALUATORS])
672 EvdevPtr pEvdev = pInfo->private;
675 * Some devices only generate valid abs coords when BTN_DIGI is
676 * pressed. On wacom tablets, this means that the pen is in
677 * proximity of the tablet. After the pen is removed, BTN_DIGI is
678 * released, and a (0, 0) absolute event is generated. Checking
679 * pEvdev->digi here, lets us ignore that event. pEvdev is
680 * initialized to 1 so devices that doesn't use this scheme still
683 if (pEvdev->abs && pEvdev->tool) {
684 xf86PostMotionEventP(pInfo->dev, TRUE, *first_v, *num_v, v);
689 * Post the queued key/button events.
691 static void EvdevPostQueuedEvents(InputInfoPtr pInfo, int *num_v, int *first_v,
692 int v[MAX_VALUATORS])
695 EvdevPtr pEvdev = pInfo->private;
697 for (i = 0; i < pEvdev->num_queue; i++) {
698 switch (pEvdev->queue[i].type) {
700 xf86PostKeyboardEvent(pInfo->dev, pEvdev->queue[i].key,
701 pEvdev->queue[i].val);
704 /* FIXME: Add xf86PostButtonEventP to the X server so that we may
705 * pass the valuators on ButtonPress/Release events, too. Currently
706 * only MotionNotify events contain the pointer position. */
707 xf86PostButtonEvent(pInfo->dev, 0, pEvdev->queue[i].key,
708 pEvdev->queue[i].val, 0, 0);
715 * Take the synchronization input event and process it accordingly; the motion
716 * notify events are sent first, then any button/key press/release events.
719 EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
721 int num_v = 0, first_v = 0;
722 int v[MAX_VALUATORS];
723 EvdevPtr pEvdev = pInfo->private;
725 EvdevProcessValuators(pInfo, v, &num_v, &first_v);
727 EvdevPostRelativeMotionEvents(pInfo, &num_v, &first_v, v);
728 EvdevPostAbsoluteMotionEvents(pInfo, &num_v, &first_v, v);
729 EvdevPostQueuedEvents(pInfo, &num_v, &first_v, v);
731 memset(pEvdev->delta, 0, sizeof(pEvdev->delta));
732 memset(pEvdev->queue, 0, sizeof(pEvdev->queue));
733 pEvdev->num_queue = 0;
739 * Process the events from the device; nothing is actually posted to the server
740 * until an EV_SYN event is received.
743 EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
747 EvdevProcessRelativeMotionEvent(pInfo, ev);
750 EvdevProcessAbsoluteMotionEvent(pInfo, ev);
753 EvdevProcessKeyEvent(pInfo, ev);
756 EvdevProcessSyncEvent(pInfo, ev);
765 /* just a magic number to reduce the number of reads */
766 #define NUM_EVENTS 16
769 EvdevReadInput(InputInfoPtr pInfo)
771 struct input_event ev[NUM_EVENTS];
772 int i, len = sizeof(ev);
773 EvdevPtr pEvdev = pInfo->private;
775 while (len == sizeof(ev))
777 len = read(pInfo->fd, &ev, sizeof(ev));
780 if (errno == ENODEV) /* May happen after resume */
782 EvdevMBEmuFinalize(pInfo);
783 xf86RemoveEnabledDevice(pInfo);
786 if (pEvdev->reopen_timer)
788 pEvdev->reopen_left = pEvdev->reopen_attempts;
789 pEvdev->reopen_timer = TimerSet(pEvdev->reopen_timer, 0, 100, EvdevReopenTimer, pInfo);
791 } else if (errno != EAGAIN)
793 /* We use X_NONE here because it doesn't alloc */
794 xf86MsgVerb(X_NONE, 0, "%s: Read error: %s\n", pInfo->name,
800 /* The kernel promises that we always only read a complete
801 * event, so len != sizeof ev is an error. */
802 if (len % sizeof(ev[0])) {
803 /* We use X_NONE here because it doesn't alloc */
804 xf86MsgVerb(X_NONE, 0, "%s: Read error: %s\n", pInfo->name, strerror(errno));
808 for (i = 0; i < len/sizeof(ev[0]); i++)
809 EvdevProcessEvent(pInfo, &ev[i]);
813 #define TestBit(bit, array) ((array[(bit) / LONG_BITS]) & (1L << ((bit) % LONG_BITS)))
816 EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
818 /* Nothing to do, dix handles all settings */
821 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 5
822 static KeySym map[] = {
823 /* 0x00 */ NoSymbol, NoSymbol,
824 /* 0x01 */ XK_Escape, NoSymbol,
825 /* 0x02 */ XK_1, XK_exclam,
826 /* 0x03 */ XK_2, XK_at,
827 /* 0x04 */ XK_3, XK_numbersign,
828 /* 0x05 */ XK_4, XK_dollar,
829 /* 0x06 */ XK_5, XK_percent,
830 /* 0x07 */ XK_6, XK_asciicircum,
831 /* 0x08 */ XK_7, XK_ampersand,
832 /* 0x09 */ XK_8, XK_asterisk,
833 /* 0x0a */ XK_9, XK_parenleft,
834 /* 0x0b */ XK_0, XK_parenright,
835 /* 0x0c */ XK_minus, XK_underscore,
836 /* 0x0d */ XK_equal, XK_plus,
837 /* 0x0e */ XK_BackSpace, NoSymbol,
838 /* 0x0f */ XK_Tab, XK_ISO_Left_Tab,
839 /* 0x10 */ XK_Q, NoSymbol,
840 /* 0x11 */ XK_W, NoSymbol,
841 /* 0x12 */ XK_E, NoSymbol,
842 /* 0x13 */ XK_R, NoSymbol,
843 /* 0x14 */ XK_T, NoSymbol,
844 /* 0x15 */ XK_Y, NoSymbol,
845 /* 0x16 */ XK_U, NoSymbol,
846 /* 0x17 */ XK_I, NoSymbol,
847 /* 0x18 */ XK_O, NoSymbol,
848 /* 0x19 */ XK_P, NoSymbol,
849 /* 0x1a */ XK_bracketleft, XK_braceleft,
850 /* 0x1b */ XK_bracketright,XK_braceright,
851 /* 0x1c */ XK_Return, NoSymbol,
852 /* 0x1d */ XK_Control_L, NoSymbol,
853 /* 0x1e */ XK_A, NoSymbol,
854 /* 0x1f */ XK_S, NoSymbol,
855 /* 0x20 */ XK_D, NoSymbol,
856 /* 0x21 */ XK_F, NoSymbol,
857 /* 0x22 */ XK_G, NoSymbol,
858 /* 0x23 */ XK_H, NoSymbol,
859 /* 0x24 */ XK_J, NoSymbol,
860 /* 0x25 */ XK_K, NoSymbol,
861 /* 0x26 */ XK_L, NoSymbol,
862 /* 0x27 */ XK_semicolon, XK_colon,
863 /* 0x28 */ XK_quoteright, XK_quotedbl,
864 /* 0x29 */ XK_quoteleft, XK_asciitilde,
865 /* 0x2a */ XK_Shift_L, NoSymbol,
866 /* 0x2b */ XK_backslash, XK_bar,
867 /* 0x2c */ XK_Z, NoSymbol,
868 /* 0x2d */ XK_X, NoSymbol,
869 /* 0x2e */ XK_C, NoSymbol,
870 /* 0x2f */ XK_V, NoSymbol,
871 /* 0x30 */ XK_B, NoSymbol,
872 /* 0x31 */ XK_N, NoSymbol,
873 /* 0x32 */ XK_M, NoSymbol,
874 /* 0x33 */ XK_comma, XK_less,
875 /* 0x34 */ XK_period, XK_greater,
876 /* 0x35 */ XK_slash, XK_question,
877 /* 0x36 */ XK_Shift_R, NoSymbol,
878 /* 0x37 */ XK_KP_Multiply, NoSymbol,
879 /* 0x38 */ XK_Alt_L, XK_Meta_L,
880 /* 0x39 */ XK_space, NoSymbol,
881 /* 0x3a */ XK_Caps_Lock, NoSymbol,
882 /* 0x3b */ XK_F1, NoSymbol,
883 /* 0x3c */ XK_F2, NoSymbol,
884 /* 0x3d */ XK_F3, NoSymbol,
885 /* 0x3e */ XK_F4, NoSymbol,
886 /* 0x3f */ XK_F5, NoSymbol,
887 /* 0x40 */ XK_F6, NoSymbol,
888 /* 0x41 */ XK_F7, NoSymbol,
889 /* 0x42 */ XK_F8, NoSymbol,
890 /* 0x43 */ XK_F9, NoSymbol,
891 /* 0x44 */ XK_F10, NoSymbol,
892 /* 0x45 */ XK_Num_Lock, NoSymbol,
893 /* 0x46 */ XK_Scroll_Lock, NoSymbol,
894 /* These KP keys should have the KP_7 keysyms in the numlock
896 /* 0x47 */ XK_KP_Home, XK_KP_7,
897 /* 0x48 */ XK_KP_Up, XK_KP_8,
898 /* 0x49 */ XK_KP_Prior, XK_KP_9,
899 /* 0x4a */ XK_KP_Subtract, NoSymbol,
900 /* 0x4b */ XK_KP_Left, XK_KP_4,
901 /* 0x4c */ XK_KP_Begin, XK_KP_5,
902 /* 0x4d */ XK_KP_Right, XK_KP_6,
903 /* 0x4e */ XK_KP_Add, NoSymbol,
904 /* 0x4f */ XK_KP_End, XK_KP_1,
905 /* 0x50 */ XK_KP_Down, XK_KP_2,
906 /* 0x51 */ XK_KP_Next, XK_KP_3,
907 /* 0x52 */ XK_KP_Insert, XK_KP_0,
908 /* 0x53 */ XK_KP_Delete, XK_KP_Decimal,
909 /* 0x54 */ NoSymbol, NoSymbol,
910 /* 0x55 */ XK_F13, NoSymbol,
911 /* 0x56 */ XK_less, XK_greater,
912 /* 0x57 */ XK_F11, NoSymbol,
913 /* 0x58 */ XK_F12, NoSymbol,
914 /* 0x59 */ XK_F14, NoSymbol,
915 /* 0x5a */ XK_F15, NoSymbol,
916 /* 0x5b */ XK_F16, NoSymbol,
917 /* 0x5c */ XK_F17, NoSymbol,
918 /* 0x5d */ XK_F18, NoSymbol,
919 /* 0x5e */ XK_F19, NoSymbol,
920 /* 0x5f */ XK_F20, NoSymbol,
921 /* 0x60 */ XK_KP_Enter, NoSymbol,
922 /* 0x61 */ XK_Control_R, NoSymbol,
923 /* 0x62 */ XK_KP_Divide, NoSymbol,
924 /* 0x63 */ XK_Print, XK_Sys_Req,
925 /* 0x64 */ XK_Alt_R, XK_Meta_R,
926 /* 0x65 */ NoSymbol, NoSymbol, /* KEY_LINEFEED */
927 /* 0x66 */ XK_Home, NoSymbol,
928 /* 0x67 */ XK_Up, NoSymbol,
929 /* 0x68 */ XK_Prior, NoSymbol,
930 /* 0x69 */ XK_Left, NoSymbol,
931 /* 0x6a */ XK_Right, NoSymbol,
932 /* 0x6b */ XK_End, NoSymbol,
933 /* 0x6c */ XK_Down, NoSymbol,
934 /* 0x6d */ XK_Next, NoSymbol,
935 /* 0x6e */ XK_Insert, NoSymbol,
936 /* 0x6f */ XK_Delete, NoSymbol,
937 /* 0x70 */ NoSymbol, NoSymbol, /* KEY_MACRO */
938 /* 0x71 */ NoSymbol, NoSymbol,
939 /* 0x72 */ NoSymbol, NoSymbol,
940 /* 0x73 */ NoSymbol, NoSymbol,
941 /* 0x74 */ NoSymbol, NoSymbol,
942 /* 0x75 */ XK_KP_Equal, NoSymbol,
943 /* 0x76 */ NoSymbol, NoSymbol,
944 /* 0x77 */ NoSymbol, NoSymbol,
945 /* 0x78 */ XK_F21, NoSymbol,
946 /* 0x79 */ XK_F22, NoSymbol,
947 /* 0x7a */ XK_F23, NoSymbol,
948 /* 0x7b */ XK_F24, NoSymbol,
949 /* 0x7c */ XK_KP_Separator, NoSymbol,
950 /* 0x7d */ XK_Meta_L, NoSymbol,
951 /* 0x7e */ XK_Meta_R, NoSymbol,
952 /* 0x7f */ XK_Multi_key, NoSymbol,
953 /* 0x80 */ NoSymbol, NoSymbol,
954 /* 0x81 */ NoSymbol, NoSymbol,
955 /* 0x82 */ NoSymbol, NoSymbol,
956 /* 0x83 */ NoSymbol, NoSymbol,
957 /* 0x84 */ NoSymbol, NoSymbol,
958 /* 0x85 */ NoSymbol, NoSymbol,
959 /* 0x86 */ NoSymbol, NoSymbol,
960 /* 0x87 */ NoSymbol, NoSymbol,
961 /* 0x88 */ NoSymbol, NoSymbol,
962 /* 0x89 */ NoSymbol, NoSymbol,
963 /* 0x8a */ NoSymbol, NoSymbol,
964 /* 0x8b */ NoSymbol, NoSymbol,
965 /* 0x8c */ NoSymbol, NoSymbol,
966 /* 0x8d */ NoSymbol, NoSymbol,
967 /* 0x8e */ NoSymbol, NoSymbol,
968 /* 0x8f */ NoSymbol, NoSymbol,
969 /* 0x90 */ NoSymbol, NoSymbol,
970 /* 0x91 */ NoSymbol, NoSymbol,
971 /* 0x92 */ NoSymbol, NoSymbol,
972 /* 0x93 */ NoSymbol, NoSymbol,
973 /* 0x94 */ NoSymbol, NoSymbol,
974 /* 0x95 */ NoSymbol, NoSymbol,
975 /* 0x96 */ NoSymbol, NoSymbol,
976 /* 0x97 */ NoSymbol, NoSymbol,
977 /* 0x98 */ NoSymbol, NoSymbol,
978 /* 0x99 */ NoSymbol, NoSymbol,
979 /* 0x9a */ NoSymbol, NoSymbol,
980 /* 0x9b */ NoSymbol, NoSymbol,
981 /* 0x9c */ NoSymbol, NoSymbol,
982 /* 0x9d */ NoSymbol, NoSymbol,
983 /* 0x9e */ NoSymbol, NoSymbol,
984 /* 0x9f */ NoSymbol, NoSymbol,
985 /* 0xa0 */ NoSymbol, NoSymbol,
986 /* 0xa1 */ NoSymbol, NoSymbol,
987 /* 0xa2 */ NoSymbol, NoSymbol,
988 /* 0xa3 */ NoSymbol, NoSymbol,
989 /* 0xa4 */ NoSymbol, NoSymbol,
990 /* 0xa5 */ NoSymbol, NoSymbol,
991 /* 0xa6 */ NoSymbol, NoSymbol,
992 /* 0xa7 */ NoSymbol, NoSymbol,
993 /* 0xa8 */ NoSymbol, NoSymbol,
994 /* 0xa9 */ NoSymbol, NoSymbol,
995 /* 0xaa */ NoSymbol, NoSymbol,
996 /* 0xab */ NoSymbol, NoSymbol,
997 /* 0xac */ NoSymbol, NoSymbol,
998 /* 0xad */ NoSymbol, NoSymbol,
999 /* 0xae */ NoSymbol, NoSymbol,
1000 /* 0xaf */ NoSymbol, NoSymbol,
1001 /* 0xb0 */ NoSymbol, NoSymbol,
1002 /* 0xb1 */ NoSymbol, NoSymbol,
1003 /* 0xb2 */ NoSymbol, NoSymbol,
1004 /* 0xb3 */ NoSymbol, NoSymbol,
1005 /* 0xb4 */ NoSymbol, NoSymbol,
1006 /* 0xb5 */ NoSymbol, NoSymbol,
1007 /* 0xb6 */ NoSymbol, NoSymbol,
1008 /* 0xb7 */ NoSymbol, NoSymbol,
1009 /* 0xb8 */ NoSymbol, NoSymbol,
1010 /* 0xb9 */ NoSymbol, NoSymbol,
1011 /* 0xba */ NoSymbol, NoSymbol,
1012 /* 0xbb */ NoSymbol, NoSymbol,
1013 /* 0xbc */ NoSymbol, NoSymbol,
1014 /* 0xbd */ NoSymbol, NoSymbol,
1015 /* 0xbe */ NoSymbol, NoSymbol,
1016 /* 0xbf */ NoSymbol, NoSymbol,
1017 /* 0xc0 */ NoSymbol, NoSymbol,
1018 /* 0xc1 */ NoSymbol, NoSymbol,
1019 /* 0xc2 */ NoSymbol, NoSymbol,
1020 /* 0xc3 */ NoSymbol, NoSymbol,
1021 /* 0xc4 */ NoSymbol, NoSymbol,
1022 /* 0xc5 */ NoSymbol, NoSymbol,
1023 /* 0xc6 */ NoSymbol, NoSymbol,
1024 /* 0xc7 */ NoSymbol, NoSymbol,
1025 /* 0xc8 */ NoSymbol, NoSymbol,
1026 /* 0xc9 */ NoSymbol, NoSymbol,
1027 /* 0xca */ NoSymbol, NoSymbol,
1028 /* 0xcb */ NoSymbol, NoSymbol,
1029 /* 0xcc */ NoSymbol, NoSymbol,
1030 /* 0xcd */ NoSymbol, NoSymbol,
1031 /* 0xce */ NoSymbol, NoSymbol,
1032 /* 0xcf */ NoSymbol, NoSymbol,
1033 /* 0xd0 */ NoSymbol, NoSymbol,
1034 /* 0xd1 */ NoSymbol, NoSymbol,
1035 /* 0xd2 */ NoSymbol, NoSymbol,
1036 /* 0xd3 */ NoSymbol, NoSymbol,
1037 /* 0xd4 */ NoSymbol, NoSymbol,
1038 /* 0xd5 */ NoSymbol, NoSymbol,
1039 /* 0xd6 */ NoSymbol, NoSymbol,
1040 /* 0xd7 */ NoSymbol, NoSymbol,
1041 /* 0xd8 */ NoSymbol, NoSymbol,
1042 /* 0xd9 */ NoSymbol, NoSymbol,
1043 /* 0xda */ NoSymbol, NoSymbol,
1044 /* 0xdb */ NoSymbol, NoSymbol,
1045 /* 0xdc */ NoSymbol, NoSymbol,
1046 /* 0xdd */ NoSymbol, NoSymbol,
1047 /* 0xde */ NoSymbol, NoSymbol,
1048 /* 0xdf */ NoSymbol, NoSymbol,
1049 /* 0xe0 */ NoSymbol, NoSymbol,
1050 /* 0xe1 */ NoSymbol, NoSymbol,
1051 /* 0xe2 */ NoSymbol, NoSymbol,
1052 /* 0xe3 */ NoSymbol, NoSymbol,
1053 /* 0xe4 */ NoSymbol, NoSymbol,
1054 /* 0xe5 */ NoSymbol, NoSymbol,
1055 /* 0xe6 */ NoSymbol, NoSymbol,
1056 /* 0xe7 */ NoSymbol, NoSymbol,
1057 /* 0xe8 */ NoSymbol, NoSymbol,
1058 /* 0xe9 */ NoSymbol, NoSymbol,
1059 /* 0xea */ NoSymbol, NoSymbol,
1060 /* 0xeb */ NoSymbol, NoSymbol,
1061 /* 0xec */ NoSymbol, NoSymbol,
1062 /* 0xed */ NoSymbol, NoSymbol,
1063 /* 0xee */ NoSymbol, NoSymbol,
1064 /* 0xef */ NoSymbol, NoSymbol,
1065 /* 0xf0 */ NoSymbol, NoSymbol,
1066 /* 0xf1 */ NoSymbol, NoSymbol,
1067 /* 0xf2 */ NoSymbol, NoSymbol,
1068 /* 0xf3 */ NoSymbol, NoSymbol,
1069 /* 0xf4 */ NoSymbol, NoSymbol,
1070 /* 0xf5 */ NoSymbol, NoSymbol,
1071 /* 0xf6 */ NoSymbol, NoSymbol,
1072 /* 0xf7 */ NoSymbol, NoSymbol,
1075 static struct { KeySym keysym; CARD8 mask; } modifiers[] = {
1076 { XK_Shift_L, ShiftMask },
1077 { XK_Shift_R, ShiftMask },
1078 { XK_Control_L, ControlMask },
1079 { XK_Control_R, ControlMask },
1080 { XK_Caps_Lock, LockMask },
1081 { XK_Alt_L, AltMask },
1082 { XK_Alt_R, AltMask },
1083 { XK_Meta_L, Mod4Mask },
1084 { XK_Meta_R, Mod4Mask },
1085 { XK_Num_Lock, NumLockMask },
1086 { XK_Scroll_Lock, ScrollLockMask },
1087 { XK_Mode_switch, AltLangMask }
1090 /* Server 1.6 and earlier */
1092 EvdevInitKeysyms(DeviceIntPtr device)
1097 CARD8 modMap[MAP_LENGTH];
1101 pInfo = device->public.devicePrivate;
1102 pEvdev = pInfo->private;
1104 /* Compute the modifier map */
1105 memset(modMap, 0, sizeof modMap);
1107 for (i = 0; i < ArrayLength(map) / GLYPHS_PER_KEY; i++) {
1108 sym = map[i * GLYPHS_PER_KEY];
1109 for (j = 0; j < ArrayLength(modifiers); j++) {
1110 if (modifiers[j].keysym == sym)
1111 modMap[i + MIN_KEYCODE] = modifiers[j].mask;
1116 keySyms.mapWidth = GLYPHS_PER_KEY;
1117 keySyms.minKeyCode = MIN_KEYCODE;
1118 keySyms.maxKeyCode = MIN_KEYCODE + ArrayLength(map) / GLYPHS_PER_KEY - 1;
1120 XkbSetRulesDflts(pEvdev->rmlvo.rules, pEvdev->rmlvo.model,
1121 pEvdev->rmlvo.layout, pEvdev->rmlvo.variant,
1122 pEvdev->rmlvo.options);
1123 if (!XkbInitKeyboardDeviceStruct(device, &pEvdev->xkbnames,
1124 &keySyms, modMap, NULL,
1133 EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl)
1135 static struct { int xbit, code; } bits[] = {
1136 { CAPSFLAG, LED_CAPSL },
1137 { NUMFLAG, LED_NUML },
1138 { SCROLLFLAG, LED_SCROLLL },
1139 { MODEFLAG, LED_KANA },
1140 { COMPOSEFLAG, LED_COMPOSE }
1144 struct input_event ev[ArrayLength(bits)];
1147 memset(ev, 0, sizeof(ev));
1149 pInfo = device->public.devicePrivate;
1150 for (i = 0; i < ArrayLength(bits); i++) {
1151 ev[i].type = EV_LED;
1152 ev[i].code = bits[i].code;
1153 ev[i].value = (ctrl->leds & bits[i].xbit) > 0;
1156 write(pInfo->fd, ev, sizeof ev);
1160 EvdevAddKeyClass(DeviceIntPtr device)
1165 pInfo = device->public.devicePrivate;
1166 pEvdev = pInfo->private;
1168 /* sorry, no rules change allowed for you */
1169 xf86ReplaceStrOption(pInfo->options, "xkb_rules", "evdev");
1170 SetXkbOption(pInfo, "xkb_rules", &pEvdev->rmlvo.rules);
1171 SetXkbOption(pInfo, "xkb_model", &pEvdev->rmlvo.model);
1172 if (!pEvdev->rmlvo.model)
1173 SetXkbOption(pInfo, "XkbModel", &pEvdev->rmlvo.model);
1174 SetXkbOption(pInfo, "xkb_layout", &pEvdev->rmlvo.layout);
1175 if (!pEvdev->rmlvo.layout)
1176 SetXkbOption(pInfo, "XkbLayout", &pEvdev->rmlvo.layout);
1177 SetXkbOption(pInfo, "xkb_variant", &pEvdev->rmlvo.variant);
1178 if (!pEvdev->rmlvo.variant)
1179 SetXkbOption(pInfo, "XkbVariant", &pEvdev->rmlvo.variant);
1180 SetXkbOption(pInfo, "xkb_options", &pEvdev->rmlvo.options);
1181 if (!pEvdev->rmlvo.options)
1182 SetXkbOption(pInfo, "XkbOptions", &pEvdev->rmlvo.options);
1184 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 5
1185 if (!InitKeyboardDeviceStruct(device, &pEvdev->rmlvo, NULL, EvdevKbdCtrl))
1188 if (!EvdevInitKeysyms(device))
1193 pInfo->flags |= XI86_KEYBOARD_CAPABLE;
1199 EvdevAddAbsClass(DeviceIntPtr device)
1203 int num_axes, axis, i = 0;
1206 pInfo = device->public.devicePrivate;
1207 pEvdev = pInfo->private;
1209 if (!TestBit(EV_ABS, pEvdev->bitmask))
1212 num_axes = CountBits(pEvdev->abs_bitmask, NLONGS(ABS_MAX));
1215 pEvdev->num_vals = num_axes;
1216 memset(pEvdev->vals, 0, num_axes * sizeof(int));
1217 memset(pEvdev->old_vals, -1, num_axes * sizeof(int));
1218 atoms = malloc(pEvdev->num_vals * sizeof(Atom));
1220 for (axis = ABS_X; axis <= ABS_MAX; axis++) {
1221 pEvdev->axis_map[axis] = -1;
1222 if (!TestBit(axis, pEvdev->abs_bitmask))
1224 pEvdev->axis_map[axis] = i;
1228 EvdevInitAxesLabels(pEvdev, pEvdev->num_vals, atoms);
1230 if (!InitValuatorClassDeviceStruct(device, num_axes,
1231 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
1234 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
1237 GetMotionHistorySize(), Absolute))
1240 for (axis = ABS_X; axis <= ABS_MAX; axis++) {
1241 int axnum = pEvdev->axis_map[axis];
1244 xf86InitValuatorAxisStruct(device, axnum,
1245 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
1248 pEvdev->absinfo[axis].minimum,
1249 pEvdev->absinfo[axis].maximum,
1251 xf86InitValuatorDefaults(device, axnum);
1252 pEvdev->old_vals[axnum] = -1;
1257 if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
1260 if ((TestBit(ABS_X, pEvdev->abs_bitmask) &&
1261 TestBit(ABS_Y, pEvdev->abs_bitmask)) ||
1262 (TestBit(ABS_RX, pEvdev->abs_bitmask) &&
1263 TestBit(ABS_RY, pEvdev->abs_bitmask)) ||
1264 (TestBit(ABS_HAT0X, pEvdev->abs_bitmask) &&
1265 TestBit(ABS_HAT0Y, pEvdev->abs_bitmask)) ||
1266 (TestBit(ABS_HAT1X, pEvdev->abs_bitmask) &&
1267 TestBit(ABS_HAT1Y, pEvdev->abs_bitmask)) ||
1268 (TestBit(ABS_HAT2X, pEvdev->abs_bitmask) &&
1269 TestBit(ABS_HAT2Y, pEvdev->abs_bitmask)) ||
1270 (TestBit(ABS_HAT3X, pEvdev->abs_bitmask) &&
1271 TestBit(ABS_HAT3Y, pEvdev->abs_bitmask)) ||
1272 (TestBit(ABS_TILT_X, pEvdev->abs_bitmask) &&
1273 TestBit(ABS_TILT_Y, pEvdev->abs_bitmask)))
1274 pInfo->flags |= XI86_POINTER_CAPABLE;
1280 EvdevAddRelClass(DeviceIntPtr device)
1284 int num_axes, axis, i = 0;
1287 pInfo = device->public.devicePrivate;
1288 pEvdev = pInfo->private;
1290 if (!TestBit(EV_REL, pEvdev->bitmask))
1293 num_axes = CountBits(pEvdev->rel_bitmask, NLONGS(REL_MAX));
1297 /* Wheels are special, we post them as button events. So let's ignore them
1298 * in the axes list too */
1299 if (TestBit(REL_WHEEL, pEvdev->rel_bitmask))
1301 if (TestBit(REL_HWHEEL, pEvdev->rel_bitmask))
1303 if (TestBit(REL_DIAL, pEvdev->rel_bitmask))
1309 pEvdev->num_vals = num_axes;
1310 memset(pEvdev->vals, 0, num_axes * sizeof(int));
1311 atoms = malloc(pEvdev->num_vals * sizeof(Atom));
1313 for (axis = REL_X; axis <= REL_MAX; axis++)
1315 pEvdev->axis_map[axis] = -1;
1316 /* We don't post wheel events, so ignore them here too */
1317 if (axis == REL_WHEEL || axis == REL_HWHEEL || axis == REL_DIAL)
1319 if (!TestBit(axis, pEvdev->rel_bitmask))
1321 pEvdev->axis_map[axis] = i;
1325 EvdevInitAxesLabels(pEvdev, pEvdev->num_vals, atoms);
1327 if (!InitValuatorClassDeviceStruct(device, num_axes,
1328 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
1331 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
1334 GetMotionHistorySize(), Relative))
1337 for (axis = REL_X; axis <= REL_MAX; axis++)
1339 int axnum = pEvdev->axis_map[axis];
1343 xf86InitValuatorAxisStruct(device, axnum,
1344 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
1348 xf86InitValuatorDefaults(device, axnum);
1353 if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
1356 pInfo->flags |= XI86_POINTER_CAPABLE;
1362 EvdevAddButtonClass(DeviceIntPtr device)
1368 pInfo = device->public.devicePrivate;
1369 pEvdev = pInfo->private;
1371 labels = malloc(pEvdev->num_buttons * sizeof(Atom));
1372 EvdevInitButtonLabels(pEvdev, pEvdev->num_buttons, labels);
1374 if (!InitButtonClassDeviceStruct(device, pEvdev->num_buttons,
1375 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
1386 * Init the button mapping for the device. By default, this is a 1:1 mapping,
1387 * i.e. Button 1 maps to Button 1, Button 2 to 2, etc.
1389 * If a mapping has been specified, the mapping is the default, with the
1390 * user-defined ones overwriting the defaults.
1391 * i.e. a user-defined mapping of "3 2 1" results in a mapping of 3 2 1 4 5 6 ...
1393 * Invalid button mappings revert to the default.
1395 * Note that index 0 is unused, button 0 does not exist.
1396 * This mapping is initialised for all devices, but only applied if the device
1397 * has buttons (in EvdevAddButtonClass).
1400 EvdevInitButtonMapping(InputInfoPtr pInfo)
1402 int i, nbuttons = 1;
1403 char *mapping = NULL;
1404 EvdevPtr pEvdev = pInfo->private;
1406 /* Check for user-defined button mapping */
1407 if ((mapping = xf86CheckStrOption(pInfo->options, "ButtonMapping", NULL)))
1412 xf86Msg(X_CONFIG, "%s: ButtonMapping '%s'\n", pInfo->name, mapping);
1413 while (s && *s != '\0' && nbuttons < EVDEV_MAXBUTTONS)
1415 btn = strtol(mapping, &s, 10);
1417 if (s == mapping || btn < 0 || btn > EVDEV_MAXBUTTONS)
1420 "%s: ... Invalid button mapping. Using defaults\n",
1422 nbuttons = 1; /* ensure defaults start at 1 */
1426 pEvdev->btnmap[nbuttons++] = btn;
1431 for (i = nbuttons; i < ArrayLength(pEvdev->btnmap); i++)
1432 pEvdev->btnmap[i] = i;
1437 EvdevInitAnyClass(DeviceIntPtr device, EvdevPtr pEvdev)
1439 if (pEvdev->flags & EVDEV_RELATIVE_EVENTS &&
1440 EvdevAddRelClass(device) == Success)
1441 xf86Msg(X_INFO, "%s: initialized for relative axes.\n", device->name);
1442 if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS &&
1443 EvdevAddAbsClass(device) == Success)
1444 xf86Msg(X_INFO, "%s: initialized for absolute axes.\n", device->name);
1448 EvdevInitAbsClass(DeviceIntPtr device, EvdevPtr pEvdev)
1450 if (EvdevAddAbsClass(device) == Success) {
1452 xf86Msg(X_INFO,"%s: initialized for absolute axes.\n", device->name);
1456 xf86Msg(X_ERROR,"%s: failed to initialize for absolute axes.\n",
1459 pEvdev->flags &= ~EVDEV_ABSOLUTE_EVENTS;
1465 EvdevInitRelClass(DeviceIntPtr device, EvdevPtr pEvdev)
1467 int has_abs_axes = pEvdev->flags & EVDEV_ABSOLUTE_EVENTS;
1469 if (EvdevAddRelClass(device) == Success) {
1471 xf86Msg(X_INFO,"%s: initialized for relative axes.\n", device->name);
1475 xf86Msg(X_WARNING,"%s: ignoring absolute axes.\n", device->name);
1476 pEvdev->flags &= ~EVDEV_ABSOLUTE_EVENTS;
1481 xf86Msg(X_ERROR,"%s: failed to initialize for relative axes.\n",
1484 pEvdev->flags &= ~EVDEV_RELATIVE_EVENTS;
1487 EvdevInitAbsClass(device, pEvdev);
1492 EvdevInitTouchDevice(DeviceIntPtr device, EvdevPtr pEvdev)
1494 if (pEvdev->flags & EVDEV_RELATIVE_EVENTS) {
1496 xf86Msg(X_WARNING,"%s: touchpads, tablets and touchscreens ignore "
1497 "relative axes.\n", device->name);
1499 pEvdev->flags &= ~EVDEV_RELATIVE_EVENTS;
1502 EvdevInitAbsClass(device, pEvdev);
1506 EvdevInit(DeviceIntPtr device)
1512 pInfo = device->public.devicePrivate;
1513 pEvdev = pInfo->private;
1515 /* clear all axis_map entries */
1516 for(i = 0; i < max(ABS_CNT,REL_CNT); i++)
1517 pEvdev->axis_map[i]=-1;
1519 if (pEvdev->flags & EVDEV_KEYBOARD_EVENTS)
1520 EvdevAddKeyClass(device);
1521 if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
1522 EvdevAddButtonClass(device);
1524 /* We don't allow relative and absolute axes on the same device. The
1525 * reason is that some devices (MS Optical Desktop 2000) register both
1526 * rel and abs axes for x/y.
1528 * The abs axes register min/max; this min/max then also applies to the
1529 * relative device (the mouse) and caps it at 0..255 for both axes.
1530 * So, unless you have a small screen, you won't be enjoying it much;
1531 * consequently, absolute axes are generally ignored.
1533 * However, currenly only a device with absolute axes can be registered
1534 * as a touch{pad,screen}. Thus, given such a device, absolute axes are
1535 * used and relative axes are ignored.
1538 if (pEvdev->flags & (EVDEV_UNIGNORE_RELATIVE | EVDEV_UNIGNORE_ABSOLUTE))
1539 EvdevInitAnyClass(device, pEvdev);
1540 else if (pEvdev->flags & (EVDEV_TOUCHPAD | EVDEV_TOUCHSCREEN | EVDEV_TABLET))
1541 EvdevInitTouchDevice(device, pEvdev);
1542 else if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
1543 EvdevInitRelClass(device, pEvdev);
1544 #ifdef _F_INIT_ABS_ONLY_FOR_POINTER_
1545 else if ( !(pEvdev->flags & EVDEV_KEYBOARD_EVENTS) && (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) )
1547 else if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
1549 EvdevInitAbsClass(device, pEvdev);
1551 #ifdef HAVE_PROPERTIES
1552 /* We drop the return value, the only time we ever want the handlers to
1553 * unregister is when the device dies. In which case we don't have to
1554 * unregister anyway */
1555 EvdevInitProperty(device);
1556 XIRegisterPropertyHandler(device, EvdevSetProperty, NULL, NULL);
1557 EvdevMBEmuInitProperty(device);
1558 EvdevWheelEmuInitProperty(device);
1559 EvdevDragLockInitProperty(device);
1566 * Init all extras (wheel emulation, etc.) and grab the device.
1568 * Coming from a resume, the grab may fail with ENODEV. In this case, we set a
1569 * timer to wake up and try to reopen the device later.
1572 EvdevOn(DeviceIntPtr device)
1578 pInfo = device->public.devicePrivate;
1579 pEvdev = pInfo->private;
1581 if (pInfo->fd != -1 && pEvdev->grabDevice &&
1582 (rc = ioctl(pInfo->fd, EVIOCGRAB, (void *)1)))
1584 xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name,
1587 /* ENODEV - device has disappeared after resume */
1588 if (rc && errno == ENODEV)
1595 if (pInfo->fd == -1)
1597 pEvdev->reopen_left = pEvdev->reopen_attempts;
1598 pEvdev->reopen_timer = TimerSet(pEvdev->reopen_timer, 0, 100, EvdevReopenTimer, pInfo);
1601 pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
1602 if (EvdevIsDuplicate(pInfo))
1604 xf86Msg(X_WARNING, "%s: Refusing to enable duplicate device.\n",
1609 pEvdev->reopen_timer = TimerSet(pEvdev->reopen_timer, 0, 0, NULL, NULL);
1611 xf86FlushInput(pInfo->fd);
1612 xf86AddEnabledDevice(pInfo);
1613 EvdevMBEmuOn(pInfo);
1614 pEvdev->flags |= EVDEV_INITIALIZED;
1615 device->public.on = TRUE;
1623 EvdevProc(DeviceIntPtr device, int what)
1628 pInfo = device->public.devicePrivate;
1629 pEvdev = pInfo->private;
1634 return EvdevInit(device);
1637 return EvdevOn(device);
1640 if (pEvdev->flags & EVDEV_INITIALIZED)
1641 EvdevMBEmuFinalize(pInfo);
1643 if (pInfo->fd != -1)
1645 if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
1646 xf86Msg(X_WARNING, "%s: Release failed (%s)\n", pInfo->name,
1648 xf86RemoveEnabledDevice(pInfo);
1652 pEvdev->min_maj = 0;
1653 pEvdev->flags &= ~EVDEV_INITIALIZED;
1654 device->public.on = FALSE;
1655 if (pEvdev->reopen_timer)
1657 TimerFree(pEvdev->reopen_timer);
1658 pEvdev->reopen_timer = NULL;
1663 xf86Msg(X_INFO, "%s: Close\n", pInfo->name);
1664 if (pInfo->fd != -1) {
1668 EvdevRemoveDevice(pInfo);
1669 pEvdev->min_maj = 0;
1677 * Get as much information as we can from the fd and cache it.
1678 * If compare is True, then the information retrieved will be compared to the
1679 * one already cached. If the information does not match, then this function
1682 * @return Success if the information was cached, or !Success otherwise.
1685 EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
1687 EvdevPtr pEvdev = pInfo->private;
1691 char name[1024] = {0};
1692 unsigned long bitmask[NLONGS(EV_CNT)] = {0};
1693 unsigned long key_bitmask[NLONGS(KEY_CNT)] = {0};
1694 unsigned long rel_bitmask[NLONGS(REL_CNT)] = {0};
1695 unsigned long abs_bitmask[NLONGS(ABS_CNT)] = {0};
1696 unsigned long led_bitmask[NLONGS(LED_CNT)] = {0};
1698 if (ioctl(pInfo->fd, EVIOCGNAME(sizeof(name) - 1), name) < 0) {
1699 xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
1704 strcpy(pEvdev->name, name);
1705 } else if (strcmp(pEvdev->name, name)) {
1706 xf86Msg(X_ERROR, "%s: device name changed: %s != %s\n",
1707 pInfo->name, pEvdev->name, name);
1711 len = ioctl(pInfo->fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask);
1713 xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
1714 pInfo->name, strerror(errno));
1719 memcpy(pEvdev->bitmask, bitmask, len);
1720 } else if (memcmp(pEvdev->bitmask, bitmask, len)) {
1721 xf86Msg(X_ERROR, "%s: device bitmask has changed\n", pInfo->name);
1725 len = ioctl(pInfo->fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask);
1727 xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
1728 pInfo->name, strerror(errno));
1733 memcpy(pEvdev->rel_bitmask, rel_bitmask, len);
1734 } else if (memcmp(pEvdev->rel_bitmask, rel_bitmask, len)) {
1735 xf86Msg(X_ERROR, "%s: device rel_bitmask has changed\n", pInfo->name);
1739 len = ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
1741 xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
1742 pInfo->name, strerror(errno));
1747 memcpy(pEvdev->abs_bitmask, abs_bitmask, len);
1748 } else if (memcmp(pEvdev->abs_bitmask, abs_bitmask, len)) {
1749 xf86Msg(X_ERROR, "%s: device abs_bitmask has changed\n", pInfo->name);
1753 len = ioctl(pInfo->fd, EVIOCGBIT(EV_LED, sizeof(led_bitmask)), led_bitmask);
1755 xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
1756 pInfo->name, strerror(errno));
1761 memcpy(pEvdev->led_bitmask, led_bitmask, len);
1762 } else if (memcmp(pEvdev->led_bitmask, led_bitmask, len)) {
1763 xf86Msg(X_ERROR, "%s: device led_bitmask has changed\n", pInfo->name);
1768 * Do not try to validate absinfo data since it is not expected
1769 * to be static, always refresh it in evdev structure.
1771 for (i = ABS_X; i <= ABS_MAX; i++) {
1772 if (TestBit(i, abs_bitmask)) {
1773 len = ioctl(pInfo->fd, EVIOCGABS(i), &pEvdev->absinfo[i]);
1775 xf86Msg(X_ERROR, "%s: ioctl EVIOCGABSi(%d) failed: %s\n",
1776 pInfo->name, i, strerror(errno));
1782 len = ioctl(pInfo->fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask);
1784 xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n",
1785 pInfo->name, strerror(errno));
1791 * Keys are special as user can adjust keymap at any time (on
1792 * devices that support EVIOCSKEYCODE. However we do not expect
1793 * buttons reserved for mice/tablets/digitizers and so on to
1794 * appear/disappear so we will check only those in
1795 * [BTN_MISC, KEY_OK) range.
1797 size_t start_word = BTN_MISC / LONG_BITS;
1798 size_t start_byte = start_word * sizeof(unsigned long);
1799 size_t end_word = KEY_OK / LONG_BITS;
1800 size_t end_byte = end_word * sizeof(unsigned long);
1802 if (len >= start_byte &&
1803 memcmp(&pEvdev->key_bitmask[start_word], &key_bitmask[start_word],
1804 min(len, end_byte) - start_byte + 1)) {
1805 xf86Msg(X_ERROR, "%s: device key_bitmask has changed\n", pInfo->name);
1810 /* Copy the data so we have reasonably up-to-date info */
1811 memcpy(pEvdev->key_bitmask, key_bitmask, len);
1821 EvdevProbe(InputInfoPtr pInfo)
1823 int i, has_rel_axes, has_abs_axes, has_keys, num_buttons, has_scroll;
1825 int ignore_abs = 0, ignore_rel = 0;
1826 EvdevPtr pEvdev = pInfo->private;
1828 if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
1829 if (errno == EINVAL) {
1830 /* keyboards are unsafe in 2.4 */
1832 pEvdev->grabDevice = 0;
1834 xf86Msg(X_ERROR, "Grab failed. Device already configured?\n");
1837 } else if (pEvdev->grabDevice) {
1838 ioctl(pInfo->fd, EVIOCGRAB, (void *)0);
1841 /* Trinary state for ignoring axes:
1842 - unset: do the normal thing.
1843 - TRUE: explicitly ignore them.
1844 - FALSE: unignore axes, use them at all cost if they're present.
1846 if (xf86FindOption(pInfo->options, "IgnoreRelativeAxes"))
1848 if (xf86SetBoolOption(pInfo->options, "IgnoreRelativeAxes", FALSE))
1851 pEvdev->flags |= EVDEV_UNIGNORE_RELATIVE;
1854 if (xf86FindOption(pInfo->options, "IgnoreAbsoluteAxes"))
1856 if (xf86SetBoolOption(pInfo->options, "IgnoreAbsoluteAxes", FALSE))
1859 pEvdev->flags |= EVDEV_UNIGNORE_ABSOLUTE;
1862 has_rel_axes = FALSE;
1863 has_abs_axes = FALSE;
1868 /* count all buttons */
1869 for (i = BTN_MISC; i < BTN_JOYSTICK; i++)
1872 if (TestBit(i, pEvdev->key_bitmask))
1874 mapping = EvdevUtilButtonEventToButtonNumber(pEvdev, i);
1875 if (mapping > num_buttons)
1876 num_buttons = mapping;
1882 pEvdev->flags |= EVDEV_BUTTON_EVENTS;
1883 pEvdev->num_buttons = num_buttons;
1884 xf86Msg(X_INFO, "%s: Found %d mouse buttons\n", pInfo->name,
1888 for (i = 0; i < REL_MAX; i++) {
1889 if (TestBit(i, pEvdev->rel_bitmask)) {
1890 has_rel_axes = TRUE;
1896 if (TestBit(REL_WHEEL, pEvdev->rel_bitmask) ||
1897 TestBit(REL_HWHEEL, pEvdev->rel_bitmask) ||
1898 TestBit(REL_DIAL, pEvdev->rel_bitmask)) {
1899 xf86Msg(X_INFO, "%s: Found scroll wheel(s)\n", pInfo->name);
1902 xf86Msg(X_INFO, "%s: Forcing buttons for scroll wheel(s)\n",
1904 num_buttons = (num_buttons < 3) ? 7 : num_buttons + 4;
1905 pEvdev->num_buttons = num_buttons;
1910 xf86Msg(X_INFO, "%s: Found relative axes\n", pInfo->name);
1911 pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
1913 if (TestBit(REL_X, pEvdev->rel_bitmask) &&
1914 TestBit(REL_Y, pEvdev->rel_bitmask)) {
1915 xf86Msg(X_INFO, "%s: Found x and y relative axes\n", pInfo->name);
1918 xf86Msg(X_INFO, "%s: Relative axes present but ignored.\n", pInfo->name);
1919 has_rel_axes = FALSE;
1923 for (i = 0; i < ABS_MAX; i++) {
1924 if (TestBit(i, pEvdev->abs_bitmask)) {
1925 has_abs_axes = TRUE;
1930 if (ignore_abs && has_abs_axes)
1932 xf86Msg(X_INFO, "%s: Absolute axes present but ignored.\n", pInfo->name);
1933 has_abs_axes = FALSE;
1934 } else if (has_abs_axes) {
1935 xf86Msg(X_INFO, "%s: Found absolute axes\n", pInfo->name);
1936 pEvdev->flags |= EVDEV_ABSOLUTE_EVENTS;
1938 if ((TestBit(ABS_X, pEvdev->abs_bitmask) &&
1939 TestBit(ABS_Y, pEvdev->abs_bitmask))) {
1940 xf86Msg(X_INFO, "%s: Found x and y absolute axes\n", pInfo->name);
1941 if (TestBit(BTN_TOOL_PEN, pEvdev->key_bitmask))
1943 xf86Msg(X_INFO, "%s: Found absolute tablet.\n", pInfo->name);
1944 pEvdev->flags |= EVDEV_TABLET;
1945 if (!pEvdev->num_buttons)
1947 pEvdev->num_buttons = 7; /* LMR + scroll wheels */
1948 pEvdev->flags |= EVDEV_BUTTON_EVENTS;
1950 } else if (TestBit(ABS_PRESSURE, pEvdev->abs_bitmask) ||
1951 TestBit(BTN_TOUCH, pEvdev->key_bitmask)) {
1952 if (num_buttons || TestBit(BTN_TOOL_FINGER, pEvdev->key_bitmask)) {
1953 xf86Msg(X_INFO, "%s: Found absolute touchpad.\n", pInfo->name);
1954 pEvdev->flags |= EVDEV_TOUCHPAD;
1955 memset(pEvdev->old_vals, -1, sizeof(int) * pEvdev->num_vals);
1957 xf86Msg(X_INFO, "%s: Found absolute touchscreen\n", pInfo->name);
1958 pEvdev->flags |= EVDEV_TOUCHSCREEN;
1959 pEvdev->flags |= EVDEV_BUTTON_EVENTS;
1965 for (i = 0; i < BTN_MISC; i++) {
1966 if (TestBit(i, pEvdev->key_bitmask)) {
1967 xf86Msg(X_INFO, "%s: Found keys\n", pInfo->name);
1968 pEvdev->flags |= EVDEV_KEYBOARD_EVENTS;
1974 if (has_rel_axes || has_abs_axes || num_buttons) {
1975 pInfo->flags |= XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS |
1977 if (pEvdev->flags & EVDEV_TOUCHPAD) {
1978 xf86Msg(X_INFO, "%s: Configuring as touchpad\n", pInfo->name);
1979 pInfo->type_name = XI_TOUCHPAD;
1980 } else if (pEvdev->flags & EVDEV_TABLET) {
1981 xf86Msg(X_INFO, "%s: Configuring as tablet\n", pInfo->name);
1982 pInfo->type_name = XI_TABLET;
1983 } else if (pEvdev->flags & EVDEV_TOUCHSCREEN) {
1984 xf86Msg(X_INFO, "%s: Configuring as touchscreen\n", pInfo->name);
1985 pInfo->type_name = XI_TOUCHSCREEN;
1987 xf86Msg(X_INFO, "%s: Configuring as mouse\n", pInfo->name);
1988 pInfo->type_name = XI_MOUSE;
1994 xf86Msg(X_INFO, "%s: Kernel < 2.6 is too old, ignoring keyboard\n",
1997 xf86Msg(X_INFO, "%s: Configuring as keyboard\n", pInfo->name);
1998 pInfo->flags |= XI86_KEYBOARD_CAPABLE | XI86_CONFIGURED;
1999 pInfo->type_name = XI_KEYBOARD;
2003 if (has_scroll && (pInfo->flags & XI86_CONFIGURED) &&
2004 (pInfo->flags & XI86_POINTER_CAPABLE) == 0)
2006 xf86Msg(X_INFO, "%s: Adding scrollwheel support\n", pInfo->name);
2007 pInfo->flags |= XI86_POINTER_CAPABLE;
2008 pEvdev->flags |= EVDEV_BUTTON_EVENTS;
2009 pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
2012 if ((pInfo->flags & XI86_CONFIGURED) == 0) {
2013 xf86Msg(X_WARNING, "%s: Don't know how to use device\n",
2022 EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4])
2024 EvdevPtr pEvdev = pInfo->private;
2026 if (num_calibration == 0) {
2027 pEvdev->flags &= ~EVDEV_CALIBRATED;
2028 pEvdev->calibration.min_x = 0;
2029 pEvdev->calibration.max_x = 0;
2030 pEvdev->calibration.min_y = 0;
2031 pEvdev->calibration.max_y = 0;
2032 } else if (num_calibration == 4) {
2033 pEvdev->flags |= EVDEV_CALIBRATED;
2034 pEvdev->calibration.min_x = calibration[0];
2035 pEvdev->calibration.max_x = calibration[1];
2036 pEvdev->calibration.min_y = calibration[2];
2037 pEvdev->calibration.max_y = calibration[3];
2042 EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
2045 const char *device, *str;
2046 int num_calibration = 0, calibration[4] = { 0, 0, 0, 0 };
2047 int num_resolution = 0, resolution[4] = { 0, 0, 0, 0 };
2050 if (!(pInfo = xf86AllocateInput(drv, 0)))
2053 /* Initialise the InputInfoRec. */
2054 pInfo->name = dev->identifier;
2056 pInfo->type_name = "UNKNOWN";
2057 pInfo->device_control = EvdevProc;
2058 pInfo->read_input = EvdevReadInput;
2059 pInfo->history_size = 0;
2060 pInfo->control_proc = NULL;
2061 pInfo->close_proc = NULL;
2062 pInfo->switch_mode = NULL;
2063 pInfo->conversion_proc = NULL;
2064 pInfo->reverse_conversion_proc = NULL;
2066 pInfo->private_flags = 0;
2067 pInfo->always_core_feedback = NULL;
2068 pInfo->conf_idev = dev;
2070 if (!(pEvdev = xcalloc(sizeof(EvdevRec), 1)))
2073 pInfo->private = pEvdev;
2075 xf86CollectInputOptions(pInfo, evdevDefaults, NULL);
2076 xf86ProcessCommonOptions(pInfo, pInfo->options);
2079 * We initialize pEvdev->tool to 1 so that device that doesn't use
2080 * proximity will still report events.
2084 device = xf86CheckStrOption(dev->commonOptions, "Device", NULL);
2086 xf86Msg(X_ERROR, "%s: No device specified.\n", pInfo->name);
2087 xf86DeleteInput(pInfo, 0);
2091 pEvdev->device = device;
2093 xf86Msg(X_CONFIG, "%s: Device: \"%s\"\n", pInfo->name, device);
2095 pInfo->fd = open(device, O_RDWR | O_NONBLOCK, 0);
2096 } while (pInfo->fd < 0 && errno == EINTR);
2098 if (pInfo->fd < 0) {
2099 xf86Msg(X_ERROR, "Unable to open evdev device \"%s\".\n", device);
2100 xf86DeleteInput(pInfo, 0);
2104 /* Check major/minor of device node to avoid adding duplicate devices. */
2105 pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
2106 if (EvdevIsDuplicate(pInfo))
2108 xf86Msg(X_WARNING, "%s: device file already in use. Ignoring.\n",
2111 xf86DeleteInput(pInfo, 0);
2115 pEvdev->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10);
2116 pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE);
2117 pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
2118 pEvdev->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE);
2120 str = xf86CheckStrOption(pInfo->options, "Calibration", NULL);
2122 num_calibration = sscanf(str, "%d %d %d %d",
2123 &calibration[0], &calibration[1],
2124 &calibration[2], &calibration[3]);
2125 if (num_calibration == 4)
2126 EvdevSetCalibration(pInfo, num_calibration, calibration);
2129 "%s: Insufficient calibration factors (%d). Ignoring calibration\n",
2130 pInfo->name, num_calibration);
2133 str = xf86CheckStrOption(pInfo->options, "Resolution", NULL);
2135 num_resolution = sscanf(str, "%d %d %d %d",
2136 &resolution[0], &resolution[1],
2137 &resolution[2], &resolution[3]);
2138 if (num_resolution == 4)
2139 EvdevSetResolution(pInfo, num_resolution, resolution);
2142 "%s: Insufficient resolution factors (%d). Ignoring resolution\n",
2143 pInfo->name, num_resolution);
2146 /* Grabbing the event device stops in-kernel event forwarding. In other
2147 words, it disables rfkill and the "Macintosh mouse button emulation".
2148 Note that this needs a server that sets the console to RAW mode. */
2149 pEvdev->grabDevice = xf86CheckBoolOption(dev->commonOptions, "GrabDevice", 0);
2151 EvdevInitButtonMapping(pInfo);
2153 if (EvdevCacheCompare(pInfo, FALSE) ||
2154 EvdevProbe(pInfo)) {
2156 xf86DeleteInput(pInfo, 0);
2160 if(pEvdev->flags & EVDEV_RESOLUTION)
2162 EvdevSwapAxes(pEvdev);
2166 pEvdev->absinfo[ABS_X].maximum = 0;
2167 pEvdev->absinfo[ABS_X].minimum = 0;
2168 pEvdev->absinfo[ABS_Y].maximum = 0;
2169 pEvdev->absinfo[ABS_Y].minimum = 0;
2172 EvdevAddDevice(pInfo);
2174 if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
2176 EvdevMBEmuPreInit(pInfo);
2177 EvdevWheelEmuPreInit(pInfo);
2178 EvdevDragLockPreInit(pInfo);
2184 _X_EXPORT InputDriverRec EVDEV = {
2195 EvdevUnplug(pointer p)
2200 EvdevPlug(pointer module,
2205 xf86AddInputDriver(&EVDEV, module, 0);
2209 static XF86ModuleVersionInfo EvdevVersionRec =
2215 XORG_VERSION_CURRENT,
2216 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
2223 _X_EXPORT XF86ModuleData evdevModuleData =
2231 /* Return an index value for a given button event code
2232 * returns 0 on non-button event.
2235 EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code)
2237 unsigned int button = 0;
2252 /* Treat BTN_[0-2] as LMR buttons on devices that do not advertise
2253 BTN_LEFT, BTN_MIDDLE, BTN_RIGHT.
2254 Otherwise, treat BTN_[0+n] as button 5+n.
2255 XXX: This causes duplicate mappings for BTN_0 + n and BTN_SIDE + n
2258 button = (TestBit(BTN_LEFT, pEvdev->key_bitmask)) ? 8 : 1;
2261 button = (TestBit(BTN_MIDDLE, pEvdev->key_bitmask)) ? 9 : 2;
2264 button = (TestBit(BTN_RIGHT, pEvdev->key_bitmask)) ? 10 : 3;
2267 /* FIXME: BTN_3.. and BTN_SIDE.. have the same button mapping */
2275 button = (code - BTN_0 + 5);
2283 button = (code - BTN_LEFT + 5);
2287 if ((code > BTN_TASK) && (code < KEY_OK)) {
2288 if (code < BTN_JOYSTICK) {
2289 if (code < BTN_MOUSE)
2290 button = (code - BTN_0 + 5);
2292 button = (code - BTN_LEFT + 5);
2297 if (button > EVDEV_MAXBUTTONS)
2303 #ifdef HAVE_PROPERTIES
2305 /* Aligned with linux/input.h.
2306 Note that there are holes in the ABS_ range, these are simply replaced with
2308 static char* abs_labels[] = {
2309 AXIS_LABEL_PROP_ABS_X, /* 0x00 */
2310 AXIS_LABEL_PROP_ABS_Y, /* 0x01 */
2311 AXIS_LABEL_PROP_ABS_Z, /* 0x02 */
2312 AXIS_LABEL_PROP_ABS_RX, /* 0x03 */
2313 AXIS_LABEL_PROP_ABS_RY, /* 0x04 */
2314 AXIS_LABEL_PROP_ABS_RZ, /* 0x05 */
2315 AXIS_LABEL_PROP_ABS_THROTTLE, /* 0x06 */
2316 AXIS_LABEL_PROP_ABS_RUDDER, /* 0x07 */
2317 AXIS_LABEL_PROP_ABS_WHEEL, /* 0x08 */
2318 AXIS_LABEL_PROP_ABS_GAS, /* 0x09 */
2319 AXIS_LABEL_PROP_ABS_BRAKE, /* 0x0a */
2320 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
2321 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
2322 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
2323 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
2324 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
2325 AXIS_LABEL_PROP_ABS_HAT0X, /* 0x10 */
2326 AXIS_LABEL_PROP_ABS_HAT0Y, /* 0x11 */
2327 AXIS_LABEL_PROP_ABS_HAT1X, /* 0x12 */
2328 AXIS_LABEL_PROP_ABS_HAT1Y, /* 0x13 */
2329 AXIS_LABEL_PROP_ABS_HAT2X, /* 0x14 */
2330 AXIS_LABEL_PROP_ABS_HAT2Y, /* 0x15 */
2331 AXIS_LABEL_PROP_ABS_HAT3X, /* 0x16 */
2332 AXIS_LABEL_PROP_ABS_HAT3Y, /* 0x17 */
2333 AXIS_LABEL_PROP_ABS_PRESSURE, /* 0x18 */
2334 AXIS_LABEL_PROP_ABS_DISTANCE, /* 0x19 */
2335 AXIS_LABEL_PROP_ABS_TILT_X, /* 0x1a */
2336 AXIS_LABEL_PROP_ABS_TILT_Y, /* 0x1b */
2337 AXIS_LABEL_PROP_ABS_TOOL_WIDTH, /* 0x1c */
2338 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
2339 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
2340 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
2341 AXIS_LABEL_PROP_ABS_VOLUME /* 0x20 */
2344 static char* rel_labels[] = {
2345 AXIS_LABEL_PROP_REL_X,
2346 AXIS_LABEL_PROP_REL_Y,
2347 AXIS_LABEL_PROP_REL_Z,
2348 AXIS_LABEL_PROP_REL_RX,
2349 AXIS_LABEL_PROP_REL_RY,
2350 AXIS_LABEL_PROP_REL_RZ,
2351 AXIS_LABEL_PROP_REL_HWHEEL,
2352 AXIS_LABEL_PROP_REL_DIAL,
2353 AXIS_LABEL_PROP_REL_WHEEL,
2354 AXIS_LABEL_PROP_REL_MISC
2357 static char* btn_labels[][16] = {
2358 { /* BTN_MISC group offset 0x100*/
2359 BTN_LABEL_PROP_BTN_0, /* 0x00 */
2360 BTN_LABEL_PROP_BTN_1, /* 0x01 */
2361 BTN_LABEL_PROP_BTN_2, /* 0x02 */
2362 BTN_LABEL_PROP_BTN_3, /* 0x03 */
2363 BTN_LABEL_PROP_BTN_4, /* 0x04 */
2364 BTN_LABEL_PROP_BTN_5, /* 0x05 */
2365 BTN_LABEL_PROP_BTN_6, /* 0x06 */
2366 BTN_LABEL_PROP_BTN_7, /* 0x07 */
2367 BTN_LABEL_PROP_BTN_8, /* 0x08 */
2368 BTN_LABEL_PROP_BTN_9 /* 0x09 */
2370 { /* BTN_MOUSE group offset 0x110 */
2371 BTN_LABEL_PROP_BTN_LEFT, /* 0x00 */
2372 BTN_LABEL_PROP_BTN_RIGHT, /* 0x01 */
2373 BTN_LABEL_PROP_BTN_MIDDLE, /* 0x02 */
2374 BTN_LABEL_PROP_BTN_SIDE, /* 0x03 */
2375 BTN_LABEL_PROP_BTN_EXTRA, /* 0x04 */
2376 BTN_LABEL_PROP_BTN_FORWARD, /* 0x05 */
2377 BTN_LABEL_PROP_BTN_BACK, /* 0x06 */
2378 BTN_LABEL_PROP_BTN_TASK /* 0x07 */
2380 { /* BTN_JOYSTICK group offset 0x120 */
2381 BTN_LABEL_PROP_BTN_TRIGGER, /* 0x00 */
2382 BTN_LABEL_PROP_BTN_THUMB, /* 0x01 */
2383 BTN_LABEL_PROP_BTN_THUMB2, /* 0x02 */
2384 BTN_LABEL_PROP_BTN_TOP, /* 0x03 */
2385 BTN_LABEL_PROP_BTN_TOP2, /* 0x04 */
2386 BTN_LABEL_PROP_BTN_PINKIE, /* 0x05 */
2387 BTN_LABEL_PROP_BTN_BASE, /* 0x06 */
2388 BTN_LABEL_PROP_BTN_BASE2, /* 0x07 */
2389 BTN_LABEL_PROP_BTN_BASE3, /* 0x08 */
2390 BTN_LABEL_PROP_BTN_BASE4, /* 0x09 */
2391 BTN_LABEL_PROP_BTN_BASE5, /* 0x0a */
2392 BTN_LABEL_PROP_BTN_BASE6, /* 0x0b */
2396 BTN_LABEL_PROP_BTN_DEAD /* 0x0f */
2398 { /* BTN_GAMEPAD group offset 0x130 */
2399 BTN_LABEL_PROP_BTN_A, /* 0x00 */
2400 BTN_LABEL_PROP_BTN_B, /* 0x01 */
2401 BTN_LABEL_PROP_BTN_C, /* 0x02 */
2402 BTN_LABEL_PROP_BTN_X, /* 0x03 */
2403 BTN_LABEL_PROP_BTN_Y, /* 0x04 */
2404 BTN_LABEL_PROP_BTN_Z, /* 0x05 */
2405 BTN_LABEL_PROP_BTN_TL, /* 0x06 */
2406 BTN_LABEL_PROP_BTN_TR, /* 0x07 */
2407 BTN_LABEL_PROP_BTN_TL2, /* 0x08 */
2408 BTN_LABEL_PROP_BTN_TR2, /* 0x09 */
2409 BTN_LABEL_PROP_BTN_SELECT, /* 0x0a */
2410 BTN_LABEL_PROP_BTN_START, /* 0x0b */
2411 BTN_LABEL_PROP_BTN_MODE, /* 0x0c */
2412 BTN_LABEL_PROP_BTN_THUMBL, /* 0x0d */
2413 BTN_LABEL_PROP_BTN_THUMBR /* 0x0e */
2415 { /* BTN_DIGI group offset 0x140 */
2416 BTN_LABEL_PROP_BTN_TOOL_PEN, /* 0x00 */
2417 BTN_LABEL_PROP_BTN_TOOL_RUBBER, /* 0x01 */
2418 BTN_LABEL_PROP_BTN_TOOL_BRUSH, /* 0x02 */
2419 BTN_LABEL_PROP_BTN_TOOL_PENCIL, /* 0x03 */
2420 BTN_LABEL_PROP_BTN_TOOL_AIRBRUSH, /* 0x04 */
2421 BTN_LABEL_PROP_BTN_TOOL_FINGER, /* 0x05 */
2422 BTN_LABEL_PROP_BTN_TOOL_MOUSE, /* 0x06 */
2423 BTN_LABEL_PROP_BTN_TOOL_LENS, /* 0x07 */
2426 BTN_LABEL_PROP_BTN_TOUCH, /* 0x0a */
2427 BTN_LABEL_PROP_BTN_STYLUS, /* 0x0b */
2428 BTN_LABEL_PROP_BTN_STYLUS2, /* 0x0c */
2429 BTN_LABEL_PROP_BTN_TOOL_DOUBLETAP, /* 0x0d */
2430 BTN_LABEL_PROP_BTN_TOOL_TRIPLETAP /* 0x0e */
2432 { /* BTN_WHEEL group offset 0x150 */
2433 BTN_LABEL_PROP_BTN_GEAR_DOWN, /* 0x00 */
2434 BTN_LABEL_PROP_BTN_GEAR_UP /* 0x01 */
2438 #endif /* HAVE_LABELS */
2440 static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms)
2449 if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
2451 labels = abs_labels;
2452 labels_len = ArrayLength(abs_labels);
2453 misc_label = AXIS_LABEL_PROP_ABS_MISC;
2454 } else if ((pEvdev->flags & EVDEV_RELATIVE_EVENTS))
2456 labels = rel_labels;
2457 labels_len = ArrayLength(rel_labels);
2458 misc_label = AXIS_LABEL_PROP_REL_MISC;
2461 memset(atoms, 0, natoms * sizeof(Atom));
2463 /* Now fill the ones we know */
2464 for (axis = 0; axis < labels_len; axis++)
2466 if (pEvdev->axis_map[axis] == -1)
2469 atom = XIGetKnownProperty(labels[axis]);
2470 if (!atom) /* Should not happen */
2473 atoms[pEvdev->axis_map[axis]] = atom;
2478 static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms)
2484 /* First, make sure all atoms are initialized */
2485 atom = XIGetKnownProperty(BTN_LABEL_PROP_BTN_UNKNOWN);
2486 for (button = 0; button < natoms; button++)
2487 atoms[button] = atom;
2489 for (button = BTN_MISC; button < BTN_JOYSTICK; button++)
2491 if (TestBit(button, pEvdev->key_bitmask))
2493 int group = (button % 0x100)/16;
2494 int idx = button - ((button/16) * 16);
2496 if (!btn_labels[group][idx])
2499 atom = XIGetKnownProperty(btn_labels[group][idx]);
2503 /* Props are 0-indexed, button numbers start with 1 */
2504 bmap = EvdevUtilButtonEventToButtonNumber(pEvdev, button) - 1;
2509 /* wheel buttons, hardcoded anyway */
2511 atoms[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
2513 atoms[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
2515 atoms[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
2517 atoms[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
2522 EvdevInitProperty(DeviceIntPtr dev)
2524 InputInfoPtr pInfo = dev->public.devicePrivate;
2525 EvdevPtr pEvdev = pInfo->private;
2530 prop_reopen = MakeAtom(EVDEV_PROP_REOPEN, strlen(EVDEV_PROP_REOPEN),
2533 reopen = pEvdev->reopen_attempts;
2534 rc = XIChangeDeviceProperty(dev, prop_reopen, XA_INTEGER, 8,
2535 PropModeReplace, 1, &reopen, FALSE);
2539 XISetDevicePropertyDeletable(dev, prop_reopen, FALSE);
2541 if (pEvdev->flags & (EVDEV_RELATIVE_EVENTS | EVDEV_ABSOLUTE_EVENTS))
2543 invert[0] = pEvdev->invert_x;
2544 invert[1] = pEvdev->invert_y;
2546 prop_invert = MakeAtom(EVDEV_PROP_INVERT_AXES, strlen(EVDEV_PROP_INVERT_AXES), TRUE);
2548 rc = XIChangeDeviceProperty(dev, prop_invert, XA_INTEGER, 8,
2554 XISetDevicePropertyDeletable(dev, prop_invert, FALSE);
2556 prop_calibration = MakeAtom(EVDEV_PROP_CALIBRATION,
2557 strlen(EVDEV_PROP_CALIBRATION), TRUE);
2558 if (pEvdev->flags & EVDEV_CALIBRATED) {
2561 calibration[0] = pEvdev->calibration.min_x;
2562 calibration[1] = pEvdev->calibration.max_x;
2563 calibration[2] = pEvdev->calibration.min_y;
2564 calibration[3] = pEvdev->calibration.max_y;
2566 rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER,
2567 32, PropModeReplace, 4, calibration,
2569 } else if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) {
2570 rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER,
2571 32, PropModeReplace, 0, NULL,
2577 XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
2579 prop_swap = MakeAtom(EVDEV_PROP_SWAP_AXES,
2580 strlen(EVDEV_PROP_SWAP_AXES), TRUE);
2582 rc = XIChangeDeviceProperty(dev, prop_swap, XA_INTEGER, 8,
2583 PropModeReplace, 1, &pEvdev->swap_axes, FALSE);
2587 XISetDevicePropertyDeletable(dev, prop_swap, FALSE);
2590 /* Axis labelling */
2591 if ((pEvdev->num_vals > 0) && (prop_axis_label = XIGetKnownProperty(AXIS_LABEL_PROP)))
2593 Atom atoms[pEvdev->num_vals];
2594 EvdevInitAxesLabels(pEvdev, pEvdev->num_vals, atoms);
2595 XIChangeDeviceProperty(dev, prop_axis_label, XA_ATOM, 32,
2596 PropModeReplace, pEvdev->num_vals, atoms, FALSE);
2597 XISetDevicePropertyDeletable(dev, prop_axis_label, FALSE);
2599 /* Button labelling */
2600 if ((pEvdev->num_buttons > 0) && (prop_btn_label = XIGetKnownProperty(BTN_LABEL_PROP)))
2602 Atom atoms[EVDEV_MAXBUTTONS];
2603 EvdevInitButtonLabels(pEvdev, EVDEV_MAXBUTTONS, atoms);
2604 XIChangeDeviceProperty(dev, prop_btn_label, XA_ATOM, 32,
2605 PropModeReplace, pEvdev->num_buttons, atoms, FALSE);
2606 XISetDevicePropertyDeletable(dev, prop_btn_label, FALSE);
2608 #endif /* HAVE_LABELS */
2613 static void EvdevSwapAxes(EvdevPtr pEvdev)
2615 if(pEvdev->swap_axes)
2617 pEvdev->absinfo[ABS_Y].maximum = pEvdev->resolution.min_x;
2618 pEvdev->absinfo[ABS_Y].minimum = pEvdev->resolution.max_x;
2619 pEvdev->absinfo[ABS_X].maximum = pEvdev->resolution.min_y;
2620 pEvdev->absinfo[ABS_X].minimum = pEvdev->resolution.max_y;
2624 pEvdev->absinfo[ABS_X].maximum = pEvdev->resolution.min_x;
2625 pEvdev->absinfo[ABS_X].minimum = pEvdev->resolution.max_x;
2626 pEvdev->absinfo[ABS_Y].maximum = pEvdev->resolution.min_y;
2627 pEvdev->absinfo[ABS_Y].minimum = pEvdev->resolution.max_y;
2632 EvdevSetResolution(InputInfoPtr pInfo, int num_resolution, int resolution[4])
2634 EvdevPtr pEvdev = pInfo->private;
2636 if (num_resolution == 0) {
2637 pEvdev->flags &= ~EVDEV_RESOLUTION;
2638 pEvdev->resolution.min_x = 0;
2639 pEvdev->resolution.max_x = 0;
2640 pEvdev->resolution.min_y = 0;
2641 pEvdev->resolution.max_y = 0;
2642 } else if (num_resolution == 4) {
2643 pEvdev->flags |= EVDEV_RESOLUTION;
2644 pEvdev->resolution.min_x = resolution[0];
2645 pEvdev->resolution.max_x = resolution[1];
2646 pEvdev->resolution.min_y = resolution[2];
2647 pEvdev->resolution.max_y = resolution[3];
2652 EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
2655 InputInfoPtr pInfo = dev->public.devicePrivate;
2656 EvdevPtr pEvdev = pInfo->private;
2658 if (atom == prop_invert)
2661 if (val->format != 8 || val->size != 2 || val->type != XA_INTEGER)
2666 data = (BOOL*)val->data;
2667 pEvdev->invert_x = data[0];
2668 pEvdev->invert_y = data[1];
2670 } else if (atom == prop_reopen)
2672 if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
2676 pEvdev->reopen_attempts = *((CARD8*)val->data);
2677 } else if (atom == prop_calibration)
2679 if (val->format != 32 || val->type != XA_INTEGER)
2681 if (val->size != 4 && val->size != 0)
2685 EvdevSetCalibration(pInfo, val->size, val->data);
2686 } else if (atom == prop_swap)
2688 if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
2692 pEvdev->swap_axes = *((BOOL*)val->data);
2693 EvdevSwapAxes(pEvdev);
2694 } else if (atom == prop_axis_label || atom == prop_btn_label)
2695 return BadAccess; /* Axis/Button labels can't be changed */