[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-input-evdev: Changes to 'upstream-unstable'



Rebased ref, commits from common ancestor:
commit 11d506dce6363525e80eda219aee8af429fb302e
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Tue Jan 13 11:32:05 2009 +1000

    evdev 2.1.1

diff --git a/configure.ac b/configure.ac
index f668d1e..28294e6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-input-evdev],
-        2.1.0,
+        2.1.1,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-input-evdev)
 

commit a34a2cd3476441f29c9faa79ffa9289dbf2eebf4
Author: Michael Chapman <mike@very.puzzling.org>
Date:   Fri Jan 9 19:07:10 2009 +1100

    Disable middle mouse button emulation when a middle mouse button event is registered
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    (cherry picked from commit 0592d97fbb5a1241ee79397ce9203346d050a9f9)

diff --git a/src/emuMB.c b/src/emuMB.c
index e5a767a..028d27f 100644
--- a/src/emuMB.c
+++ b/src/emuMB.c
@@ -231,6 +231,11 @@ EvdevMBEmuFilterEvent(InputInfoPtr pInfo, int button, BOOL press)
     if (!pEvdev->emulateMB.enabled)
         return ret;
 
+    if (button == 2) {
+        EvdevMBEmuEnable(pInfo, FALSE);
+        return ret;
+    }
+
     /* don't care about other buttons */
     if (button != 1 && button != 3)
         return ret;

commit 78c00bd77f983aa22611c9966fbcb7e22453b588
Author: Matt Helsley <matt.helsley@gmail.com>
Date:   Tue Jan 13 11:03:04 2009 +1000

    Fix FOO_MAX off-by-one
    
    In linux/input.h each section's (e.g. ABS) FOO_MAX is the maximum FOO
    value. Recent kernels define FOO_CNT as the maximum number of FOO there
    will ever be. Hence using FOO_MAX to size the bit vectors representing
    the capabilities of an evdev device is off by one.
    
    Define FOO_CNT values for use with Linux kernels which lack them. Use
    FOO_CNT whenever we need to know the number of bits needed -- usually to
    calculate the number of longs needed.
    
    When iterating over the values FOO_MAX still seems appropriate however
    the loop test should include FOO_MAX rather than skip it.
    
    Signed-off-by: Matt Helsley <matt.helsley@gmail.com>
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    (cherry picked from commit 4dfd86b2201b2b19761a1abb3c580cecf0060224)
    
    Conflicts:
    
    	src/evdev.c

diff --git a/src/evdev.c b/src/evdev.c
index e48edd9..5601caa 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -236,7 +236,7 @@ static void
 PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
 {
     int code = ev->code + MIN_KEYCODE;
-    static char warned[KEY_MAX];
+    static char warned[KEY_CNT];
 
     /* filter repeat events for chording keys */
     if (value == 2 &&
@@ -248,7 +248,7 @@ PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
          ev->code == KEY_SCROLLLOCK)) /* XXX windows keys? */
         return;
 
-    if (code > 255 && ev->code < KEY_MAX) {
+    if (code > 255 && ev->code <= KEY_MAX) {
 	if (!warned[ev->code])
 	    xf86Msg(X_WARNING, "%s: unable to handle keycode %d\n",
 		    pInfo->name, ev->code);
@@ -1202,12 +1202,12 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
     int i;
 
     char name[1024]                  = {0};
-    long bitmask[NLONGS(EV_MAX)]      = {0};
-    long key_bitmask[NLONGS(KEY_MAX)] = {0};
-    long rel_bitmask[NLONGS(REL_MAX)] = {0};
-    long abs_bitmask[NLONGS(ABS_MAX)] = {0};
-    long led_bitmask[NLONGS(LED_MAX)] = {0};
-    struct input_absinfo absinfo[ABS_MAX];
+    long bitmask[NLONGS(EV_CNT)]      = {0};
+    long key_bitmask[NLONGS(KEY_CNT)] = {0};
+    long rel_bitmask[NLONGS(REL_CNT)] = {0};
+    long abs_bitmask[NLONGS(ABS_CNT)] = {0};
+    long led_bitmask[NLONGS(LED_CNT)] = {0};
+    struct input_absinfo absinfo[ABS_CNT];
 
     if (ioctl(pInfo->fd,
               EVIOCGNAME(sizeof(name) - 1), name) < 0) {
@@ -1266,7 +1266,7 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
 
     memset(absinfo, 0, sizeof(absinfo));
 
-    for (i = 0; i < ABS_MAX; i++)
+    for (i = ABS_X; i <= ABS_MAX; i++)
     {
         if (TestBit(i, abs_bitmask))
         {
@@ -1302,9 +1302,9 @@ error:
 static int
 EvdevProbe(InputInfoPtr pInfo)
 {
-    long key_bitmask[NLONGS(KEY_MAX)] = {0};
-    long rel_bitmask[NLONGS(REL_MAX)] = {0};
-    long abs_bitmask[NLONGS(ABS_MAX)] = {0};
+    long key_bitmask[NLONGS(KEY_CNT)] = {0};
+    long rel_bitmask[NLONGS(REL_CNT)] = {0};
+    long abs_bitmask[NLONGS(ABS_CNT)] = {0};
     int i, has_axes, has_keys, num_buttons;
     int kernel24 = 0;
     EvdevPtr pEvdev = pInfo->private;
diff --git a/src/evdev.h b/src/evdev.h
index 107dc77..cdbc87d 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -40,6 +40,22 @@
 #include <xkbstr.h>
 #endif
 
+#ifndef EV_CNT /* linux 2.4 kernels and earlier lack _CNT defines */
+#define EV_CNT (EV_MAX+1)
+#endif
+#ifndef KEY_CNT
+#define KEY_CNT (KEY_MAX+1)
+#endif
+#ifndef REL_CNT
+#define REL_CNT (REL_MAX+1)
+#endif
+#ifndef ABS_CNT
+#define ABS_CNT (ABS_MAX+1)
+#endif
+#ifndef LED_CNT
+#define LED_CNT (LED_MAX+1)
+#endif
+
 #define EVDEV_MAXBUTTONS 32
 
 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
@@ -122,12 +138,12 @@ typedef struct {
 
     /* Cached info from device. */
     char name[1024];
-    long bitmask[NLONGS(EV_MAX)];
-    long key_bitmask[NLONGS(KEY_MAX)];
-    long rel_bitmask[NLONGS(REL_MAX)];
-    long abs_bitmask[NLONGS(ABS_MAX)];
-    long led_bitmask[NLONGS(LED_MAX)];
-    struct input_absinfo absinfo[ABS_MAX];
+    long bitmask[NLONGS(EV_CNT)];
+    long key_bitmask[NLONGS(KEY_CNT)];
+    long rel_bitmask[NLONGS(REL_CNT)];
+    long abs_bitmask[NLONGS(ABS_CNT)];
+    long led_bitmask[NLONGS(LED_CNT)];
+    struct input_absinfo absinfo[ABS_CNT];
 
     /* minor/major number */
     dev_t min_maj;

commit 760f1c6bb184e3b48ca6a6bfe8942d306f378148
Author: Matt Helsley <matt.helsley@gmail.com>
Date:   Sun Jan 11 18:04:40 2009 -0800

    rename NBITS to NLONGS to reflect its actual meaning
    
    NBITS really convers the number of bits passed as its argument
    into a number of longs. This is somewhat atypical of many
    function-like-macro names. Rename it to NLONGS.
    
    Signed-off-by: Matt Helsley <matt.helsley@gmail.com>
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    
    (cherry-picked from commit d3fd42d8644310abcae23bbf534f8c445296bcb7)
    Not really required, but it makes cherry-picking
    4dfd86b2201b2b19761a1abb3c580cecf0060224 easier.

diff --git a/src/evdev.c b/src/evdev.c
index 2c73c67..e48edd9 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1202,11 +1202,11 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
     int i;
 
     char name[1024]                  = {0};
-    long bitmask[NBITS(EV_MAX)]      = {0};
-    long key_bitmask[NBITS(KEY_MAX)] = {0};
-    long rel_bitmask[NBITS(REL_MAX)] = {0};
-    long abs_bitmask[NBITS(ABS_MAX)] = {0};
-    long led_bitmask[NBITS(LED_MAX)] = {0};
+    long bitmask[NLONGS(EV_MAX)]      = {0};
+    long key_bitmask[NLONGS(KEY_MAX)] = {0};
+    long rel_bitmask[NLONGS(REL_MAX)] = {0};
+    long abs_bitmask[NLONGS(ABS_MAX)] = {0};
+    long led_bitmask[NLONGS(LED_MAX)] = {0};
     struct input_absinfo absinfo[ABS_MAX];
 
     if (ioctl(pInfo->fd,
@@ -1302,9 +1302,9 @@ error:
 static int
 EvdevProbe(InputInfoPtr pInfo)
 {
-    long key_bitmask[NBITS(KEY_MAX)] = {0};
-    long rel_bitmask[NBITS(REL_MAX)] = {0};
-    long abs_bitmask[NBITS(ABS_MAX)] = {0};
+    long key_bitmask[NLONGS(KEY_MAX)] = {0};
+    long rel_bitmask[NLONGS(REL_MAX)] = {0};
+    long abs_bitmask[NLONGS(ABS_MAX)] = {0};
     int i, has_axes, has_keys, num_buttons;
     int kernel24 = 0;
     EvdevPtr pEvdev = pInfo->private;
diff --git a/src/evdev.h b/src/evdev.h
index af88741..107dc77 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -47,7 +47,9 @@
 #endif
 
 #define LONG_BITS (sizeof(long) * 8)
-#define NBITS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
+
+/* Number of longs needed to hold the given number of bits */
+#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
 
 /* axis specific data for wheel emulation */
 typedef struct {
@@ -120,11 +122,11 @@ typedef struct {
 
     /* Cached info from device. */
     char name[1024];
-    long bitmask[NBITS(EV_MAX)];
-    long key_bitmask[NBITS(KEY_MAX)];
-    long rel_bitmask[NBITS(REL_MAX)];
-    long abs_bitmask[NBITS(ABS_MAX)];
-    long led_bitmask[NBITS(LED_MAX)];
+    long bitmask[NLONGS(EV_MAX)];
+    long key_bitmask[NLONGS(KEY_MAX)];
+    long rel_bitmask[NLONGS(REL_MAX)];
+    long abs_bitmask[NLONGS(ABS_MAX)];
+    long led_bitmask[NLONGS(LED_MAX)];
     struct input_absinfo absinfo[ABS_MAX];
 
     /* minor/major number */

commit 2db04ba3c35e4976b34d92f8f7c6c2c9ec09f3ab
Author: Alan Coopersmith <alan.coopersmith@sun.com>
Date:   Fri Jan 9 16:13:09 2009 -0800

    Remove xorgconfig & xorgcfg from See Also list in man page
    (cherry picked from commit 0f0a149067abdd1ed89717de43febe89b2a3490b)

diff --git a/man/evdev.man b/man/evdev.man
index cf087e8..c38a2c2 100644
--- a/man/evdev.man
+++ b/man/evdev.man
@@ -201,5 +201,5 @@ server, such as touchscreens that require run-time calibration.
 .SH AUTHORS
 Kristian Høgsberg.
 .SH "SEE ALSO"
-__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__),
+__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__),
 README.mouse.

commit 363d0bdb9fcae7f57f53c50667429ac9b37d41cc
Author: Yan Li <yan.i.li@intel.com>
Date:   Mon Jan 5 16:35:09 2009 +0800

    Fix XkbModel parsing error
    
    Signed-off-by: Yan Li <yan.i.li@intel.com>
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    (cherry picked from commit d170cba0cdd8f7a2e500e094f5b21fc33aefb52a)

diff --git a/src/evdev.c b/src/evdev.c
index 921f9ff..2c73c67 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -854,7 +854,7 @@ EvdevAddKeyClass(DeviceIntPtr device)
         SetXkbOption(pInfo, "xkb_rules", &pEvdev->xkb_rules);
         SetXkbOption(pInfo, "xkb_model", &pEvdev->xkb_model);
 	if (!pEvdev->xkb_model)
-	    SetXkbOption(pInfo, "XkbModel", &pEvdev->xkb_rules);
+	    SetXkbOption(pInfo, "XkbModel", &pEvdev->xkb_model);
         SetXkbOption(pInfo, "xkb_layout", &pEvdev->xkb_layout);
 	if (!pEvdev->xkb_layout)
 	    SetXkbOption(pInfo, "XkbLayout", &pEvdev->xkb_layout);

commit 16a26a1eca6395284fcb8e62be7b2bc30becb0d3
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Wed Nov 26 15:01:57 2008 +1000

    Finalize MB emu (and wakeup handlers) before closing the fd.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
    (cherry picked from commit 2bf6e29b40f0da2bc417964fd2bd819306e5d3ed)

diff --git a/src/evdev.c b/src/evdev.c
index 25325a3..921f9ff 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1150,6 +1150,8 @@ EvdevProc(DeviceIntPtr device, int what)
         return EvdevOn(device);
 
     case DEVICE_OFF:
+        if (pEvdev->flags & EVDEV_INITIALIZED)
+            EvdevMBEmuFinalize(pInfo);
         if (pInfo->fd != -1)
         {
             if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))

commit b879ae73510ad733c266fba80e0ec4b0f903e71b
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Mon Nov 17 09:27:25 2008 +1000

    evdev 2.1

diff --git a/configure.ac b/configure.ac
index f1d06cd..f668d1e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-input-evdev],
-        2.0.99.3,
+        2.1.0,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-input-evdev)
 

commit 53566b7d4d7e641df4db5720ae9132eb4c812c84
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Mon Nov 17 10:03:11 2008 +1000

    Store device file's minor/major to avoid duplicate devices.
    
    Devices added that use the same min/maj as an already added device are ignored
    by the driver. This way users can have an xorg.conf entry on
    /dev/input/by-id/blahblah and not get the same device added by HAL.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
    (cherry picked from commit 63af314368cec47b6b8266db331f2c820e7a071f)

diff --git a/src/evdev.c b/src/evdev.c
index 3051531..25325a3 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -32,6 +32,7 @@
 
 #include <X11/keysym.h>
 
+#include <sys/stat.h>
 #include <unistd.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -51,6 +52,10 @@
 #include <evdev-properties.h>
 #endif
 
+#ifndef MAXDEVICES
+#include <inputstr.h> /* for MAX_DEVICES */
+#define MAXDEVICES MAX_DEVICES
+#endif
 
 /* 2.4 compatibility */
 #ifndef EVIOCGRAB
@@ -112,6 +117,88 @@ static Atom prop_calibration = 0;
 static Atom prop_swap = 0;
 #endif
 
+/* All devices the evdev driver has allocated and knows about.
+ * MAXDEVICES is safe as null-terminated array, as two devices (VCP and VCK)
+ * cannot be used by evdev, leaving us with a space of 2 at the end. */
+static EvdevPtr evdev_devices[MAXDEVICES] = {0};
+
+static int
+EvdevGetMajorMinor(InputInfoPtr pInfo)
+{
+    struct stat st;
+
+    if (fstat(pInfo->fd, &st) == -1)
+    {
+        xf86Msg(X_ERROR, "%s: stat failed (%s). cannot check for duplicates.\n",
+                pInfo->name, strerror(errno));
+        return 0;
+    }
+
+    return st.st_rdev;
+}
+
+/**
+ * Return TRUE if one of the devices we know about has the same min/maj
+ * number.
+ */
+static BOOL
+EvdevIsDuplicate(InputInfoPtr pInfo)
+{
+    EvdevPtr pEvdev = pInfo->private;
+    EvdevPtr* dev   = evdev_devices;
+
+    if (pEvdev->min_maj)
+    {
+        while(*dev)
+        {
+            if ((*dev) != pEvdev &&
+                (*dev)->min_maj &&
+                (*dev)->min_maj == pEvdev->min_maj)
+                return TRUE;
+            dev++;
+        }
+    }
+    return FALSE;
+}
+
+/**
+ * Add to internal device list.
+ */
+static void
+EvdevAddDevice(InputInfoPtr pInfo)
+{
+    EvdevPtr pEvdev = pInfo->private;
+    EvdevPtr* dev = evdev_devices;
+
+    while(*dev)
+        dev++;
+
+    *dev = pEvdev;
+}
+
+/**
+ * Remove from internal device list.
+ */
+static void
+EvdevRemoveDevice(InputInfoPtr pInfo)
+{
+    EvdevPtr pEvdev = pInfo->private;
+    EvdevPtr *dev   = evdev_devices;
+    int count       = 0;
+
+    while(*dev)
+    {
+        count++;
+        if (*dev == pEvdev)
+        {
+            memmove(dev, dev + 1,
+                    sizeof(evdev_devices) - (count * sizeof(EvdevPtr)));
+            break;
+        }
+        dev++;
+    }
+}
+
 
 static void
 SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
@@ -205,6 +292,7 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
             DisableDevice(pInfo->dev);
             close(pInfo->fd);
             pInfo->fd = -1;
+            pEvdev->min_maj = 0; /* don't hog the device */
         }
         pEvdev->reopen_left = 0;
         return 0;
@@ -217,6 +305,7 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
         xf86Msg(X_ERROR, "%s: Failed to reopen device after %d attempts.\n",
                 pInfo->name, pEvdev->reopen_attempts);
         DisableDevice(pInfo->dev);
+        pEvdev->min_maj = 0; /* don't hog the device */
         return 0;
     }
 
@@ -1024,6 +1113,14 @@ EvdevOn(DeviceIntPtr device)
         pEvdev->reopen_timer = TimerSet(NULL, 0, 100, EvdevReopenTimer, pInfo);
     } else
     {
+        pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
+        if (EvdevIsDuplicate(pInfo))
+        {
+            xf86Msg(X_WARNING, "%s: Refusing to enable duplicate device.\n",
+                    pInfo->name);
+            return !Success;
+        }
+
         xf86FlushInput(pInfo->fd);
         xf86AddEnabledDevice(pInfo);
         EvdevMBEmuOn(pInfo);
@@ -1062,6 +1159,7 @@ EvdevProc(DeviceIntPtr device, int what)
             close(pInfo->fd);
             pInfo->fd = -1;
         }
+        pEvdev->min_maj = 0;
         if (pEvdev->flags & EVDEV_INITIALIZED)
             EvdevMBEmuFinalize(pInfo);
         pEvdev->flags &= ~EVDEV_INITIALIZED;
@@ -1079,6 +1177,8 @@ EvdevProc(DeviceIntPtr device, int what)
             close(pInfo->fd);
             pInfo->fd = -1;
         }
+        EvdevRemoveDevice(pInfo);
+        pEvdev->min_maj = 0;
 	break;
     }
 
@@ -1386,6 +1486,17 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
         return NULL;
     }
 
+    /* Check major/minor of device node to avoid adding duplicate devices. */
+    pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
+    if (EvdevIsDuplicate(pInfo))
+    {
+        xf86Msg(X_WARNING, "%s: device file already in use. Ignoring.\n",
+                pInfo->name);
+        close(pInfo->fd);
+        xf86DeleteInput(pInfo, 0);
+        return NULL;
+    }
+
     pEvdev->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10);
     pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE);
     pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
@@ -1407,6 +1518,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
     }
 
     EvdevCacheCompare(pInfo, FALSE); /* cache device data */
+    EvdevAddDevice(pInfo);
 
     if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
     {
diff --git a/src/evdev.h b/src/evdev.h
index 32da81c..af88741 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -31,6 +31,7 @@
 #define EVDEV_H
 
 #include <linux/input.h>
+#include <linux/types.h>
 
 #include <xf86Xinput.h>
 #include <xf86_OSproc.h>
@@ -125,6 +126,9 @@ typedef struct {
     long abs_bitmask[NBITS(ABS_MAX)];
     long led_bitmask[NBITS(LED_MAX)];
     struct input_absinfo absinfo[ABS_MAX];
+
+    /* minor/major number */
+    dev_t min_maj;
 } EvdevRec, *EvdevPtr;
 
 unsigned int EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code);

commit 29c2765fc30c74171e51ba694ea4810916803c31
Author: Fernando Carrijo <fcarrijo@yahoo.com.br>
Date:   Thu Nov 6 13:20:16 2008 -0500

    Fix error message
    (cherry picked from commit 4c5c9c111d406e5590429377262b86e91868ef76)

diff --git a/src/evdev.c b/src/evdev.c
index 638831d..3051531 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1118,7 +1118,7 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
 
     if (ioctl(pInfo->fd,
               EVIOCGBIT(0, sizeof(bitmask)), bitmask) < 0) {
-        xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
+        xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
         goto error;
     }
 

commit 7ef4e2c5e14e558f41fb7f411e2976f517b6b526
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Mon Nov 3 13:47:15 2008 +1030

    evdev 2.1 RC 3
    
    That's it, no more new features. Now it's down to bugfixing only.

diff --git a/configure.ac b/configure.ac
index 144964c..f1d06cd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-input-evdev],
-        2.0.99.2,
+        2.0.99.3,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-input-evdev)
 

commit dd0eeacc24a80893209f24d9ad028a6bc7e3a390
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Mon Nov 3 13:25:06 2008 +1030

    Add support for axes swapping.
    
    New option: SwapAxes (boolean)
    New property: EVDEV_PROP_SWAP_AXES.
    
    Actual swapping code written by Donnie Berkholz.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
    (cherry picked from commit 4826969f23a0b298da2750c2e23a92b9d91819dd)

diff --git a/include/evdev-properties.h b/include/evdev-properties.h
index be4307b..31f6c66 100644
--- a/include/evdev-properties.h
+++ b/include/evdev-properties.h
@@ -62,4 +62,8 @@
 /* CARD32, 4 values [minx, maxx, miny, maxy], or no values for unset */
 #define EVDEV_PROP_CALIBRATION "Evdev Axis Calibration"
 
+/* Swap x and y axis. */
+/* BOOL */
+#define EVDEV_PROP_SWAP_AXES "Evdev Axes Swap"
+
 #endif
diff --git a/man/evdev.man b/man/evdev.man
index fc8a96a..cf087e8 100644
--- a/man/evdev.man
+++ b/man/evdev.man
@@ -147,6 +147,9 @@ waking up from suspend). In between each attempt is a 100ms wait. Default: 10.
 .BI "Option \*qInvertY\*q \*q" Bool \*q
 Invert the given axis. Default: off. Property: "Evdev Axis Inversion".
 .TP 7
+.BI "Option \*qSwapAxes\*q \*q" Bool \*q
+Swap x/y axes. Default: off. Property: "Evdev Axes Swap".
+.TP 7
 .BI "Option \*qGrabDevice\*q \*q" boolean \*q
 Force a grab on the event device. Doing so will ensure that no other driver
 can initialise the same device and it will also stop the device from sending
@@ -191,6 +194,9 @@ value.
 run-time axis calibration. This feature is required for devices that need to
 scale to a different coordinate system than originally reported to the X
 server, such as touchscreens that require run-time calibration.
+.TP 7
+.BI "Evdev Axis Swap"
+1 boolean values (8 bit, 0 or 1). 1 swaps x/y axes.
 
 .SH AUTHORS
 Kristian Høgsberg.
diff --git a/src/evdev.c b/src/evdev.c
index aa8a10d..638831d 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -109,6 +109,7 @@ static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
 static Atom prop_invert = 0;
 static Atom prop_reopen = 0;
 static Atom prop_calibration = 0;
+static Atom prop_swap = 0;
 #endif
 
 
@@ -227,13 +228,14 @@ EvdevReadInput(InputInfoPtr pInfo)
 {
     struct input_event ev;
     int len, value;
-    int dx, dy;
+    int dx, dy, tmp;
     unsigned int abs;
     unsigned int button;
     EvdevPtr pEvdev = pInfo->private;
 
     dx = 0;
     dy = 0;
+    tmp = 0;
     abs = 0;
 
     while (xf86WaitForInput (pInfo->fd, 0) > 0) {
@@ -369,6 +371,11 @@ EvdevReadInput(InputInfoPtr pInfo)
     }
 
     if (dx != 0 || dy != 0) {
+        if (pEvdev->swap_axes) {
+            tmp = dx;
+            dx = dy;
+            dy = tmp;
+        }
         if (pEvdev->invert_x)
             dx *= -1;
         if (pEvdev->invert_y)
@@ -387,8 +394,8 @@ EvdevReadInput(InputInfoPtr pInfo)
      */
     if (abs && pEvdev->tool) {
         int abs_x, abs_y;
-        abs_x = pEvdev->abs_x;
-        abs_y = pEvdev->abs_y;
+        abs_x = (pEvdev->swap_axes) ? pEvdev->abs_y : pEvdev->abs_x;
+        abs_y = (pEvdev->swap_axes) ? pEvdev->abs_x : pEvdev->abs_y;
 
         if (pEvdev->flags & EVDEV_CALIBRATED)
         {
@@ -1382,6 +1389,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
     pEvdev->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10);
     pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE);
     pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
+    pEvdev->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE);
 
     /* Grabbing the event device stops in-kernel event forwarding. In other
        words, it disables rfkill and the "Macintosh mouse button emulation".
@@ -1565,6 +1573,16 @@ EvdevInitProperty(DeviceIntPtr dev)
         return;
 
     XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
+
+    prop_swap = MakeAtom(EVDEV_PROP_SWAP_AXES,
+                         strlen(EVDEV_PROP_SWAP_AXES), TRUE);
+
+    rc = XIChangeDeviceProperty(dev, prop_swap, XA_INTEGER, 8,
+                                PropModeReplace, 1, &pEvdev->swap_axes, FALSE);
+    if (rc != Success)
+        return;
+
+    XISetDevicePropertyDeletable(dev, prop_swap, FALSE);
 }
 
 static int
@@ -1620,6 +1638,13 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
                 pEvdev->calibration.max_y = vals[3];
             }
         }
+    } else if (atom == prop_swap)
+    {
+        if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
+            return BadMatch;
+
+        if (!checkonly)
+            pEvdev->swap_axes = *((BOOL*)val->data);
     }
 
     return Success;
diff --git a/src/evdev.h b/src/evdev.h
index 5696978..32da81c 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -64,6 +64,7 @@ typedef struct {
     int flags;
     int tool;
     int buttons;            /* number of buttons */
+    BOOL swap_axes;
     BOOL invert_x;
     BOOL invert_y;
 

commit 67c0ea6c9421a5226c1b8bc3a198b1cb01f6b355
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Thu Oct 30 16:55:29 2008 +1030

    Add support for run-time calibration.
    
    Some devices require run-time axis calibration. We can't change the min/max
    ranges once we've initialised the valuator structs though, so in-driver
    run-time calibration is required.
    
    If the property is set, the driver scales from the calibrated range to the
    values reported to the X server (which then may scale to screen coordinates).
    If the property is not set (i.e. zero items) no scaling is performed.
    (cherry picked from commit 33eb36f26663c09c873acede1b35e91ef4c64479)

diff --git a/include/evdev-properties.h b/include/evdev-properties.h
index 89f25f1..be4307b 100644
--- a/include/evdev-properties.h
+++ b/include/evdev-properties.h
@@ -58,4 +58,8 @@
 /* CARD8 */
 #define EVDEV_PROP_REOPEN "Evdev Reopen Attempts"
 
+/* Run-time calibration */
+/* CARD32, 4 values [minx, maxx, miny, maxy], or no values for unset */
+#define EVDEV_PROP_CALIBRATION "Evdev Axis Calibration"
+
 #endif
diff --git a/man/evdev.man b/man/evdev.man
index 9d336fc..fc8a96a 100644
--- a/man/evdev.man
+++ b/man/evdev.man
@@ -186,6 +186,11 @@ value.
 .TP 7
 .BI "Evdev Axis Inversion"
 2 boolean values (8 bit, 0 or 1), order X, Y. 1 inverts the axis.
+.BI "Evdev Axis Calibration"
+4 32-bit values, order min-x, max-x, min-y, max-y or 0 values to disable
+run-time axis calibration. This feature is required for devices that need to
+scale to a different coordinate system than originally reported to the X
+server, such as touchscreens that require run-time calibration.
 
 .SH AUTHORS
 Kristian Høgsberg.
diff --git a/src/evdev.c b/src/evdev.c
index 9ef2829..aa8a10d 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -76,6 +76,7 @@
 #define EVDEV_TOUCHPAD		(1 << 4)
 #define EVDEV_INITIALIZED	(1 << 5) /* WheelInit etc. called already? */
 #define EVDEV_TOUCHSCREEN	(1 << 6)
+#define EVDEV_CALIBRATED	(1 << 7) /* run-time calibrated? */
 
 #define MIN_KEYCODE 8
 #define GLYPHS_PER_KEY 2
@@ -107,6 +108,7 @@ static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
                             XIPropertyValuePtr val, BOOL checkonly);
 static Atom prop_invert = 0;
 static Atom prop_reopen = 0;
+static Atom prop_calibration = 0;
 #endif
 
 
@@ -387,6 +389,17 @@ EvdevReadInput(InputInfoPtr pInfo)
         int abs_x, abs_y;
         abs_x = pEvdev->abs_x;
         abs_y = pEvdev->abs_y;
+
+        if (pEvdev->flags & EVDEV_CALIBRATED)
+        {
+            abs_x = xf86ScaleAxis(abs_x,
+                    pEvdev->max_x, pEvdev->min_x,
+                    pEvdev->calibration.max_x, pEvdev->calibration.min_x);
+            abs_y = xf86ScaleAxis(abs_y,
+                    pEvdev->max_y, pEvdev->min_y,
+                    pEvdev->calibration.max_y, pEvdev->calibration.min_y);
+        }
+
         if (pEvdev->invert_x)
             abs_x = pEvdev->max_x - (abs_x - pEvdev->min_x);
         if (pEvdev->invert_y)
@@ -1542,6 +1555,16 @@ EvdevInitProperty(DeviceIntPtr dev)
         return;
 
     XISetDevicePropertyDeletable(dev, prop_reopen, FALSE);
+
+
+    prop_calibration = MakeAtom(EVDEV_PROP_CALIBRATION,
+                                strlen(EVDEV_PROP_CALIBRATION), TRUE);
+    rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER, 32,
+                                PropModeReplace, 0, NULL, FALSE);
+    if (rc != Success)
+        return;
+
+    XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
 }
 
 static int
@@ -1570,6 +1593,33 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
 
         if (!checkonly)
             pEvdev->reopen_attempts = *((CARD8*)val->data);
+    } else if (atom == prop_calibration)
+    {
+        if (val->format != 32 || val->type != XA_INTEGER)
+            return BadMatch;
+        if (val->size != 4 && val->size != 0)
+            return BadMatch;
+
+        if (!checkonly)
+        {
+            if (val->size == 0)
+            {
+                pEvdev->flags &= ~EVDEV_CALIBRATED;
+                pEvdev->calibration.min_x = 0;
+                pEvdev->calibration.max_x = 0;
+                pEvdev->calibration.min_y = 0;
+                pEvdev->calibration.max_y = 0;
+            } else if (val->size == 4)
+            {
+                CARD32 *vals = (CARD32*)val->data;
+
+                pEvdev->flags |= EVDEV_CALIBRATED;
+                pEvdev->calibration.min_x = vals[0];
+                pEvdev->calibration.max_x = vals[1];
+                pEvdev->calibration.min_y = vals[2];
+                pEvdev->calibration.max_y = vals[3];
+            }
+        }
     }
 
     return Success;
diff --git a/src/evdev.h b/src/evdev.h
index 5a97185..5696978 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -102,6 +102,13 @@ typedef struct {
         Time                expires;     /* time of expiry */
         Time                timeout;
     } emulateWheel;
+    /* run-time calibration */
+    struct {
+        int                 min_x;
+        int                 max_x;
+        int                 min_y;
+        int                 max_y;
+    } calibration;
 
     unsigned char btnmap[32];           /* config-file specified button mapping */
 

commit 6bcbbc0411cf3466edeb1fcbb393290cadfd3082
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Wed Oct 29 13:50:07 2008 +1030

    Treat BTN_[0-2] as LMR buttons if necessary.
    
    Treat BTN_[0-2] as LMR buttons on devices that do not advertise BTN_LEFT,
    BTN_MIDDLE, BTN_RIGHT (e.g. 3Dconnexion SpaceNavigator).
    
    Otherwise, treat BTN_[0+n] as button 5+n. Note: This causes duplicate
    mappings for BTN_0 + n and  BTN_SIDE + n.
    
    This also fixes a bug where we could end up with negative button numbers after
    trying to map BTN_0.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
    (cherry picked from commit 64554e4799a697d37dfd8be480f8eee636b9bea1)

diff --git a/src/evdev.c b/src/evdev.c
index cc072d8..9ef2829 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -326,7 +326,7 @@ EvdevReadInput(InputInfoPtr pInfo)
                 /* Intentional fallthrough! */
 
             default:
-		button = EvdevUtilButtonEventToButtonNumber(ev.code);
+		button = EvdevUtilButtonEventToButtonNumber(pEvdev, ev.code);
 
 		/* Handle drag lock */
 		if (EvdevDragLockFilterEvent(pInfo, button, value))
@@ -1448,7 +1448,7 @@ _X_EXPORT XF86ModuleData evdevModuleData =
  * returns 0 on non-button event.
  */
 unsigned int
-EvdevUtilButtonEventToButtonNumber(int code)
+EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code)
 {
     unsigned int button = 0;
 
@@ -1465,6 +1465,21 @@ EvdevUtilButtonEventToButtonNumber(int code)
 	button = 2;
 	break;
 
+        /* Treat BTN_[0-2] as LMR buttons on devices that do not advertise
+           BTN_LEFT, BTN_MIDDLE, BTN_RIGHT.
+           Otherwise, treat BTN_[0+n] as button 5+n.
+           XXX: This causes duplicate mappings for BTN_0 + n and BTN_SIDE + n
+         */
+    case BTN_0:
+        button = (TestBit(BTN_LEFT, pEvdev->key_bitmask)) ?  8 : 1;
+        break;
+    case BTN_1:
+        button = (TestBit(BTN_MIDDLE, pEvdev->key_bitmask)) ?  9 : 2;
+        break;
+    case BTN_2:
+        button = (TestBit(BTN_RIGHT, pEvdev->key_bitmask)) ?  10 : 3;
+        break;
+
     case BTN_SIDE:
     case BTN_EXTRA:
     case BTN_FORWARD:
@@ -1475,8 +1490,12 @@ EvdevUtilButtonEventToButtonNumber(int code)
 
     default:
 	if ((code > BTN_TASK) && (code < KEY_OK)) {
-	    if (code < BTN_JOYSTICK)
-		button = (code - BTN_LEFT + 5);
+	    if (code < BTN_JOYSTICK) {
+                if (code < BTN_MOUSE)
+                    button = (code - BTN_0 + 5);
+                else
+                    button = (code - BTN_LEFT + 5);
+            }
 	}
     }


Reply to: