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

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



 Makefile.am                      |    2 
 config/50-x11-input-joystick.fdi |   16 ++
 config/Makefile.am               |    1 
 configure.ac                     |   60 ++++---
 man/joystick.man                 |   25 ++-
 src/Makefile.am                  |   15 +
 src/backend_bsd.c                |  309 +++++++++++++++++++++++++++++++++++++++
 src/backend_bsd.h                |   35 ++++
 src/backend_evdev.c              |  294 +++++++++++++++++++++++++++++++++++++
 src/backend_evdev.h              |   35 ++++
 src/backend_joystick.c           |  197 ++++++++++++++++++++++++
 src/backend_joystick.h           |   35 ++++
 src/bsd_jstk.c                   |  308 --------------------------------------
 src/jstk.c                       |   66 +++++++-
 src/jstk.h                       |   16 +-
 src/jstk_hw.h                    |   38 ----
 src/jstk_key.c                   |    1 
 src/jstk_options.c               |    1 
 src/linux_jstk.c                 |  195 ------------------------
 19 files changed, 1066 insertions(+), 583 deletions(-)

New commits:
commit 01637abd2b059923f5c41ab80c80ab93579cbe9b
Author: Sascha Hlusiak <saschahlusiak@arcor.de>
Date:   Fri Dec 7 00:17:56 2007 +0100

    Mentioned hotplugging and hal policy in man page

diff --git a/man/joystick.man b/man/joystick.man
index 786228b..8e48883 100644
--- a/man/joystick.man
+++ b/man/joystick.man
@@ -42,12 +42,14 @@ The following Driver
 are supported:
 .TP 7
 .BI "Option \*qDevice\*q \*q" string \*q
+.TP 7
+.BI "Option \*qPath\*q \*q" string \*q
 Specifies the device through which the joystick can be accessed. This option is mandatory and there is no default setting.
 
 For Linux, joysticks are mostly accessible as
 .IR /dev/input/jsX " or " /dev/input/eventX .
 
-For *BSD, joysticks are recognized as 
+In *BSD, joysticks are usually recognized as 
 .IR /dev/uhidX .
 .TP 7
 .BI "Option \*qDebugLevel\*q \*q" integer \*q
@@ -292,9 +294,15 @@ Axes in the mode
 will be ignored. The mode has no effect on the reported value. The axis does not need to be assigned to a direction.
 
 .SH "NOTES"
-The driver does not do hotplugging. The joystick needs to be plugged in when the driver is loaded.
+The driver does not do hotplugging on it's own. The joystick needs to be plugged in when the driver is loaded.
 If the joystick is unplugged, the device will be deactivated.
 .P
+There is an example hal policy in
+.I ${sourcecode}/config/50-x11-input-joystick.fdi
+which will take care of hotplugging. Place it in
+.I /etc/hal/fdi/policy 
+and customize it to your needs. This is highly experimental and for now you can't pass options to the driver.
+.P
 Make sure you add the 
 .I \*qSendCoreEvents\*q
 keyword to the device entry of your

commit 47cd8141f9bf3e69d5418f3b5f448366f500cf0d
Author: Sascha Hlusiak <saschahlusiak@arcor.de>
Date:   Thu Dec 6 23:55:20 2007 +0100

    Bumped to version 1.3.1

diff --git a/configure.ac b/configure.ac
index a511b83..a4b9e4a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-input-joystick],
-        1.3.0,
+        1.3.1,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-input-joystick)
 

commit c463776b8b35e6e721128a7348e088d306c4ee02
Author: Sascha Hlusiak <saschahlusiak@arcor.de>
Date:   Thu Dec 6 23:48:49 2007 +0100

    Added example hal policy file for input hotplugging of joysticks
    
    Hal policy config/50-x11-input-joystick.fdi is not installed by default and you probably
    don't want to.

diff --git a/Makefile.am b/Makefile.am
index af2effb..6bef39a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,7 +19,7 @@
 #  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 AUTOMAKE_OPTIONS = foreign
-SUBDIRS = src man
+SUBDIRS = src man config
 
 EXTRA_DIST = autogen.sh ChangeLog
 
diff --git a/config/50-x11-input-joystick.fdi b/config/50-x11-input-joystick.fdi
new file mode 100644
index 0000000..f32a36a
--- /dev/null
+++ b/config/50-x11-input-joystick.fdi
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<deviceinfo version="0.2">
+  <device>
+    <match key="info.capabilities" contains="input">
+      <!-- Match on anything you like from lshal -->
+      <match key="input.product" string="Logitech Logitech Dual Action">
+        <!-- Currently Xorg looks for these two capabilities, so
+             we need to add them. This might confuse other hal clients. -->
+        <append key="info.capabilities" type="strlist">input.keys</append> 
+        <append key="info.capabilities" type="strlist">input.mouse</append>
+        <merge key="input.x11_driver" type="string">joystick</merge>
+        <!-- How to add custom parameters to configure the device? -->
+      </match>
+    </match>
+  </device>
+</deviceinfo>
diff --git a/config/Makefile.am b/config/Makefile.am
new file mode 100644
index 0000000..c96ffeb
--- /dev/null
+++ b/config/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = 50-x11-input-joystick.fdi
diff --git a/configure.ac b/configure.ac
index 4660213..a511b83 100644
--- a/configure.ac
+++ b/configure.ac
@@ -108,7 +108,7 @@ AC_HEADER_STDC
 XORG_MANPAGE_SECTIONS
 XORG_RELEASE_VERSION
 
-AC_OUTPUT([Makefile src/Makefile man/Makefile])
+AC_OUTPUT([Makefile src/Makefile man/Makefile config/Makefile])
 
 echo 
 echo Building Linux joystick backend: $linux_backend

commit 833454bd7bea04924b85105bf38ed57dd2b5e5c2
Author: Sascha Hlusiak <saschahlusiak@arcor.de>
Date:   Thu Dec 6 23:22:43 2007 +0100

    Looking for Path parameter besides Device (used by HAL+input hotplug)

diff --git a/src/jstk.c b/src/jstk.c
index ee3d602..f55405b 100644
--- a/src/jstk.c
+++ b/src/jstk.c
@@ -548,6 +548,8 @@ jstkCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
 
     /* Joystick device is mandatory */
     priv->device = xf86SetStrOption(dev->commonOptions, "Device", NULL);
+    if (!priv->device)
+        priv->device = xf86SetStrOption(dev->commonOptions, "Path", NULL);
 
     if (!priv->device) {
         xf86Msg (X_ERROR, "%s: No Device specified.\n", local->name);

commit dca42ff25dde490073a798dc873b048c4bfeb0f4
Author: Sascha Hlusiak <saschahlusiak@arcor.de>
Date:   Thu Dec 6 23:22:06 2007 +0100

    Fixed default button mappings
    
    Default button mappings were set to buttons 4, 5 and 6 instead of 1, 2 and 3.

diff --git a/src/jstk.c b/src/jstk.c
index c98c521..ee3d602 100644
--- a/src/jstk.c
+++ b/src/jstk.c
@@ -509,13 +509,15 @@ jstkCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
             priv->button[i].keys[j] = 0;
     }
 
+    priv->buttonmap.map[0] = 0;
+
     /* First three joystick buttons generate mouse clicks */
     priv->button[0].mapping      = MAPPING_BUTTON;
-    priv->button[0].buttonnumber = 1;
+    priv->button[0].buttonnumber = jstkGetButtonNumberInMap(priv, 1);
     priv->button[1].mapping      = MAPPING_BUTTON;
-    priv->button[1].buttonnumber = 2;
+    priv->button[1].buttonnumber = jstkGetButtonNumberInMap(priv, 2);
     priv->button[2].mapping      = MAPPING_BUTTON;
-    priv->button[2].buttonnumber = 3;
+    priv->button[2].buttonnumber = jstkGetButtonNumberInMap(priv, 3);
 
     /* First two axes are a stick for moving */
     priv->axis[0].type      = TYPE_BYVALUE;
@@ -539,7 +541,6 @@ jstkCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
     priv->buttonmap.scrollbutton[1] = jstkGetButtonNumberInMap(priv, 5);
     priv->buttonmap.scrollbutton[2] = jstkGetButtonNumberInMap(priv, 6);
     priv->buttonmap.scrollbutton[3] = jstkGetButtonNumberInMap(priv, 7);
-    priv->buttonmap.map[0] = 0;
 
 
     xf86CollectInputOptions(local, NULL, NULL);

commit fba24465bc4867568cbefc3d554bae756abc1204
Author: Sascha Hlusiak <saschahlusiak@arcor.de>
Date:   Thu Dec 6 22:56:26 2007 +0100

    Return NULL on device configure fail instead of unconfigured device, which made X segfault.

diff --git a/src/jstk.c b/src/jstk.c
index 9f9c455..c98c521 100644
--- a/src/jstk.c
+++ b/src/jstk.c
@@ -622,7 +622,8 @@ SetupProc_fail:
         xfree(priv);
     if (local)
         local->private = NULL;
-    return (local);
+    return NULL;
+/*    return (local); */ /* Makes X segfault on error */
 }
 
 

commit 2fba11efcafdbc2002bc7083a2b74cb7d908b3a9
Author: Sascha Hlusiak <saschahlusiak@arcor.de>
Date:   Thu Dec 6 22:28:12 2007 +0100

    New: evdev backend

diff --git a/src/backend_evdev.c b/src/backend_evdev.c
index 6eeab08..aaad342 100644
--- a/src/backend_evdev.c
+++ b/src/backend_evdev.c
@@ -36,7 +36,7 @@
 #include <errno.h>
 #include <string.h>
 #include <stdlib.h>
-#include <linux/joystick.h>
+#include <linux/input.h>
 
 #include <xf86.h>
 #include <xf86_OSproc.h>
@@ -45,6 +45,22 @@
 #include "backend_evdev.h"
 
 
+#define BITS_PER_LONG (sizeof(long) * 8)
+#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
+#define OFF(x)  ((x)%BITS_PER_LONG)
+#define LONG(x) ((x)/BITS_PER_LONG)
+#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
+
+
+struct jstk_evdev_data {
+    struct jstk_evdev_axis_data {
+        int number;
+        int min, max;
+    } axis[ABS_MAX];
+    int key[KEY_MAX];
+};
+
+
 /***********************************************************************
  *
  * jstkOpenDevice --
@@ -59,17 +75,114 @@
 int
 jstkOpenDevice_evdev(JoystickDevPtr joystick)
 {
-    if (1) {
-        xf86Msg(X_ERROR, "Joystick: '%s': evdev failed: IMPLEMENTATION MISSING\n", 
-                  joystick->device);
+    int driver_version;
+    char name[256];
+    char uniq[256];
+    struct input_id id;
+    struct jstk_evdev_data *evdevdata;
+    unsigned long button_bits[NBITS(ABS_MAX)];
+    unsigned long key_bits[NBITS(KEY_MAX)];
+    int axes, buttons, j;
+
+    if ((joystick->fd = open(joystick->device, O_RDONLY | O_NDELAY, 0)) < 0) {
+        xf86Msg(X_ERROR, "Cannot open joystick '%s' (%s)\n", 
+                joystick->device, strerror(errno));
+        return -1;
+    }
+
+    if (ioctl(joystick->fd, EVIOCGVERSION, &driver_version) == -1) {
+        xf86Msg(X_ERROR, "Joystick: ioctl EVIOCGVERSION on '%s' failed: %s\n", 
+                joystick->device, strerror(errno));
+        close(joystick->fd);
+        joystick->fd = -1;
+        return -1;
+    }
+
+    if (ioctl(joystick->fd, EVIOCGID, &id) == -1) {
+        xf86Msg(X_ERROR, "Joystick: ioctl EVIOCGID on '%s' failed: %s\n",
+                joystick->device, strerror(errno));
+        close(joystick->fd);
+        joystick->fd = -1;
+        return -1;
+    }
+
+
+    memset(button_bits, 0, sizeof(button_bits));
+    if (ioctl(joystick->fd, EVIOCGBIT(EV_ABS, ABS_MAX), button_bits) == -1)
+    {
+        xf86Msg(X_ERROR, "Joystick: ioctl EVIOCGBIT on '%s' failed: %s\n",
+                joystick->device, strerror(errno));
+        close(joystick->fd);
+        joystick->fd = -1;
+        return -1;
+    }
+
+    evdevdata = (struct jstk_evdev_data*)
+                malloc(sizeof(struct jstk_evdev_data));
+    for (axes=0; axes<ABS_MAX; axes++)
+    {
+        evdevdata->axis[axes].number = -1;
+        evdevdata->axis[axes].min = 0;
+        evdevdata->axis[axes].max = 1;
+    }
+    for (buttons=0; buttons<KEY_MAX; buttons++)
+    {
+        evdevdata->key[buttons] = -1;
+    }
+
+    axes = 0; /* Our logical index */
+    for (j = 0; j < ABS_MAX; j++)
+        if (test_bit(j, button_bits))
+        {
+            struct input_absinfo abs;
+            if (ioctl(joystick->fd, EVIOCGABS(j), &abs) == -1) {
+                xf86Msg(X_ERROR, "Joystick: ioctl EVIOCGABS on '%s' failed: %s\n",
+                        joystick->device, strerror(errno));
+                close(joystick->fd);
+                joystick->fd = -1;
+                free(evdevdata);
+                return -1;
+            }
+            evdevdata->axis[j].number = axes; /* physical -> logical mapping */
+            evdevdata->axis[j].min = abs.minimum;
+            evdevdata->axis[j].max = abs.maximum;
+            DBG(3, ErrorF("Axis %d: phys %d min %d max %d\n",
+               axes, j, abs.minimum, abs.maximum));
+
+            axes++;
+        }
+
+    memset(key_bits, 0, sizeof(key_bits));
+    if (ioctl(joystick->fd, EVIOCGBIT(EV_KEY, KEY_MAX), key_bits) == -1)
+    {
+        xf86Msg(X_ERROR, "Joystick: ioctl EVIOCGBIT on '%s' failed: %s\n",
+                joystick->device, strerror(errno));
+        close(joystick->fd);
+        joystick->fd = -1;
         return -1;
     }
+    buttons = 0; /* Our logical index */
+    for (j = 0; j < KEY_MAX; j++)
+        if (test_bit(j, key_bits))
+        {
+            evdevdata->key[j] = buttons;
+            DBG(3, ErrorF("Button %d: phys %d\n", buttons, j));
+            buttons++;
+        }
+
+    if (ioctl(joystick->fd, EVIOCGNAME(sizeof(name)), name) == -1)
+        strcpy(name, "No name");
 
-/*    xf86Msg(X_INFO, "Joystick: %s. %d axes, %d buttons\n", 
-            joy_name, axes, buttons); */
+    if (ioctl(joystick->fd, EVIOCGUNIQ(sizeof(uniq)), uniq) == -1)
+        strcpy(uniq, "No name");
+
+    xf86Msg(X_INFO, "Joystick: %s. %d axes, %d buttons.\n", name, axes, buttons);
+    xf86Msg(X_INFO, "Joystick: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n",
+            id.bustype, id.vendor, id.product, id.version);
 
     joystick->read_proc = jstkReadData_evdev;
     joystick->close_proc = jstkCloseDevice_evdev;
+    joystick->devicedata = (void*) evdevdata;
     return joystick->fd;
 }
 
@@ -86,10 +199,14 @@ jstkOpenDevice_evdev(JoystickDevPtr joystick)
 void
 jstkCloseDevice_evdev(JoystickDevPtr joystick)
 {
-/*    if ((joystick->fd >= 0)) {
+    if ((joystick->fd >= 0)) {
         xf86CloseSerial(joystick->fd);
+        if (joystick->devicedata) {
+            free(joystick->devicedata);
+            joystick->devicedata = NULL;
+        }
         joystick->fd = -1;
-    }*/
+    }
 }
 
 
@@ -110,8 +227,68 @@ jstkReadData_evdev(JoystickDevPtr joystick,
                    JOYSTICKEVENT *event,
                    int *number)
 {
+    struct input_event iev;
+    signed int value;
+    struct jstk_evdev_data *data;
     if (event != NULL) *event = EVENT_NONE;
-    return 0;
+    if (xf86ReadSerial(joystick->fd, &iev, sizeof(struct input_event)) !=
+        sizeof(struct input_event))
+        return 0;
+    if (!joystick->devicedata) return 0; /* we are supposed to have devicedata */
+    data = (struct jstk_evdev_data*)joystick->devicedata;
 
+    DBG(10, if (iev.type)
+        ErrorF("Event (evdev): type: 0x%04X, code: 0x%04X, value: 0x%04X\n", 
+               (unsigned int)iev.type,
+               (unsigned int)iev.code,
+               (int)iev.value));
+
+    switch(iev.type) {
+    case EV_KEY:
+        if ((data->key[iev.code] >= 0) &&
+            (data->key[iev.code] < MAXBUTTONS))
+        {
+            if (joystick->button[data->key[iev.code]].pressed != iev.value)
+            {
+                joystick->button[data->key[iev.code]].pressed = iev.value;
+                if (event != NULL) *event = EVENT_BUTTON;
+                if (number != NULL) *number = data->key[iev.code];
+            }
+        }
+        break;
+    case EV_ABS:
+        if (iev.code < ABS_MAX) {
+            struct jstk_evdev_axis_data *axis;
+            axis = &data->axis[iev.code];
+            if ((axis->number >= 0) && (axis->number < MAXAXES)) {
+                value = (iev.value - axis->min) * 65535
+                        / (axis->max - axis->min) - 32768;
+                if (abs(value) < joystick->axis[axis->number].deadzone) {
+                    /* We only want one event when in deadzone */
+                    if (joystick->axis[axis->number].value != 0) {
+                        joystick->axis[axis->number].oldvalue = 
+                            joystick->axis[axis->number].value;
+                        joystick->axis[axis->number].value = 0;
+                        if (event != NULL) *event = EVENT_AXIS;
+                        if (number != NULL) *number = axis->number;
+                    }
+                }else{
+                    joystick->axis[axis->number].oldvalue = 
+                        joystick->axis[axis->number].value;
+                    joystick->axis[axis->number].value = value;
+                    if (event != NULL) *event = EVENT_AXIS;
+                    if (number != NULL) *number = axis->number;
+                }
+            }
+        }
+        break;
+    default:
+        DBG(3, if (iev.type)
+                   ErrorF("Unhandled evdev event: type: 0x%04X, code: 0x%04X, "
+                          "value: 0x%04X\n", 
+                  (unsigned int)iev.type, 
+                  (unsigned int)iev.code,
+                  (int)iev.value));
+    }
     return 1;
 }

commit 78616fb8174e93a2c3c523bd425acc33a4b8773c
Author: Sascha Hlusiak <saschahlusiak@arcor.de>
Date:   Wed Dec 5 22:17:36 2007 +0100

    Mentioned multiple backends in man page

diff --git a/man/joystick.man b/man/joystick.man
index cd08098..786228b 100644
--- a/man/joystick.man
+++ b/man/joystick.man
@@ -13,8 +13,15 @@ joystick \- Joystick input driver
 .fi
 .SH DESCRIPTION
 .B joystick
-is an __xservername__ input driver for Joysticks, using either Linux's
-joystick devices or *BSD's uhid devices. The driver reports cursor movement
+is an __xservername__ input driver for Joysticks. There are 3 backends available that are used in the following order, if support was found:
+
+.nf
+.B - Linux's evdev interface
+.B - Linux's joystick interface
+.B - BSD's usbhid interface
+.fi
+
+The driver reports cursor movement
 as well as raw axis values through valuators. 
 
 .SH SUPPORTED HARDWARE
@@ -38,7 +45,7 @@ are supported:
 Specifies the device through which the joystick can be accessed. This option is mandatory and there is no default setting.
 
 For Linux, joysticks are mostly accessible as
-.IR /dev/input/jsX .
+.IR /dev/input/jsX " or " /dev/input/eventX .
 
 For *BSD, joysticks are recognized as 
 .IR /dev/uhidX .

commit 9e5f4e6fccb8c9e1b6c4dfccb39f1f0c89f79b60
Author: Sascha Hlusiak <saschahlusiak@arcor.de>
Date:   Wed Dec 5 21:33:27 2007 +0100

    Fixed implicit declaration warnings because of missed header files

diff --git a/src/jstk_key.c b/src/jstk_key.c
index 5cddf25..a5c5106 100644
--- a/src/jstk_key.c
+++ b/src/jstk_key.c
@@ -29,6 +29,7 @@
 
 
 #include <xf86.h>
+#include <xf86Xinput.h>
 #include <X11/extensions/XKB.h>
 #include <X11/extensions/XKBstr.h>
 #include <X11/extensions/XKBsrv.h>
diff --git a/src/jstk_options.c b/src/jstk_options.c
index 66b8f37..f1dfcc8 100644
--- a/src/jstk_options.c
+++ b/src/jstk_options.c
@@ -142,7 +142,6 @@ jstkParseButtonOption(const char* org,
                       const char* name)
 {
     char *param;
-    char *tmp;
     int value;
     float fvalue;
     char p[64];

commit 43790502b5d1077fc74e81b7eedd9c880673463c
Author: Sascha Hlusiak <saschahlusiak@arcor.de>
Date:   Wed Dec 5 21:30:12 2007 +0100

    Renamed backend files from *_jstk.{c,h} to backend_*.{c,h}

diff --git a/src/Makefile.am b/src/Makefile.am
index d65c859..cdb96b6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,9 +34,9 @@
 				jstk_options.c jstk_options.h \
 				StrKeysym.c StrKeysym.h ks_tables.h
 
-BSD_SRCS   = bsd_jstk.c bsd_jstk.h
-LINUX_SRCS = linux_jstk.c linux_jstk.h
-EVDEV_SRCS = evdev_jstk.c evdev_jstk.h
+BSD_SRCS   = backend_bsd.c backend_bsd.h
+LINUX_SRCS = backend_joystick.c backend_joystick.h
+EVDEV_SRCS = backend_evdev.c backend_evdev.h
 
 if BSD_BACKEND
 @DRIVER_NAME@_drv_la_SOURCES += $(BSD_SRCS)
diff --git a/src/backend_bsd.c b/src/backend_bsd.c
new file mode 100644
index 0000000..4628c0d
--- /dev/null
+++ b/src/backend_bsd.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2007      by Sascha Hlusiak. <saschahlusiak@freedesktop.org>     
+ *                                                                            
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is  hereby granted without fee, provided that
+ * the  above copyright   notice appear  in   all  copies and  that both  that
+ * copyright  notice   and   this  permission   notice  appear  in  supporting
+ * documentation, and that   the  name of  Sascha   Hlusiak  not  be  used  in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific,  written      prior  permission.     Sascha   Hlusiak   makes  no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.                   
+ *                                                                            
+ * SASCHA  HLUSIAK  DISCLAIMS ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
+ * EVENT  SHALL SASCHA  HLUSIAK  BE   LIABLE   FOR ANY  SPECIAL, INDIRECT   OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA  OR PROFITS, WHETHER  IN  AN ACTION OF  CONTRACT,  NEGLIGENCE OR OTHER
+ * TORTIOUS  ACTION, ARISING    OUT OF OR   IN  CONNECTION  WITH THE USE    OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/**
+ * This provides the backend for USB-HIDs for NetBSD, OpenBSD and FreeBSD
+ * Needs the uhid module loaded. Device names are /dev/uhid?
+ **/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <xf86.h>
+#include <xf86_OSproc.h>
+
+#include <usbhid.h>
+#include <dev/usb/usb.h>
+#include <dev/usb/usbhid.h>
+
+#include "jstk.h"
+#include "backend_bsd.h"
+
+
+struct jstk_bsd_hid_data {
+    int dlen;                                /* Length of one data chunk */
+    char *data_buf;                          /* Data buffer with right size */
+    struct hid_item axis_item[MAXAXES];      /* Axis HID items */
+    struct hid_item button_item[MAXBUTTONS]; /* Button HID items */
+    struct hid_item hat_item[MAXAXES];       /* HID items for hats */
+    int hats;                                /* Number of hats */
+    int axes;                                /* Number of found axes */
+    int buttons;                             /* Number of found buttons */
+    int hotdata;                             /* Is unprocessed data available
+                                                in data_buf? */
+};
+
+
+
+/***********************************************************************
+ *
+ * jstkOpenDevice --
+ *
+ * Open and initialize a joystick device
+ * Returns the filedescriptor, or -1 in case of error
+ *
+ ***********************************************************************
+ */
+
+int
+jstkOpenDevice_bsd(JoystickDevPtr joystick)
+{
+    int cur_axis;
+    int is_joystick, report_id = 0;
+    int got_something;
+    struct hid_data *d;
+    struct hid_item h;
+    report_desc_t rd;
+    struct jstk_bsd_hid_data *bsddata;
+
+    if ((joystick->fd = open(joystick->device, O_RDWR | O_NDELAY, 0)) < 0) {
+        xf86Msg(X_ERROR, "Cannot open joystick '%s' (%s)\n", joystick->device,
+                strerror(errno));
+        return -1;
+    }
+
+    if ((rd = hid_get_report_desc(joystick->fd)) == 0) {
+        xf86Msg(X_ERROR, "Joystick: hid_get_report_desc failed: %s\n",
+                strerror(errno));
+        close(joystick->fd);
+        joystick->fd = -1;
+        return -1;
+    }
+
+    if (ioctl(joystick->fd, USB_GET_REPORT_ID, &report_id) < 0) {
+        xf86Msg(X_ERROR, "Joystick: ioctl USB_GET_REPORT_ID failed: %s\n",
+                strerror(errno));
+        close(joystick->fd);
+        joystick->fd = -1;
+        return -1;
+    }
+
+    bsddata = (struct jstk_bsd_hid_data*)
+              malloc(sizeof(struct jstk_bsd_hid_data));
+    bsddata->dlen = hid_report_size(rd, hid_input, report_id);
+
+    if ((bsddata->data_buf = malloc(bsddata->dlen)) == NULL) {
+        fprintf(stderr, "error: couldn't malloc %d bytes\n", bsddata->dlen);
+        hid_dispose_report_desc(rd);
+        free(bsddata);
+        close(joystick->fd);
+        joystick->fd = -1;
+        return -1;
+    }
+
+    is_joystick = 0;
+    got_something = 0;
+    cur_axis = 0;
+    bsddata->hats = 0;
+    bsddata->axes = 0;
+    bsddata->buttons = 0;
+
+    for (d = hid_start_parse(rd, 1 << hid_input, report_id);
+         hid_get_item(d, &h); )
+    {
+        int usage, page;
+
+        page = HID_PAGE(h.usage);
+        usage = HID_USAGE(h.usage);
+
+        is_joystick = is_joystick ||
+                      (h.kind == hid_collection &&
+                       page == HUP_GENERIC_DESKTOP &&
+                       (usage == HUG_JOYSTICK || usage == HUG_GAME_PAD));
+
+        if (h.kind != hid_input)
+            continue;
+
+        if (!is_joystick)
+            continue;
+
+        if (page == HUP_GENERIC_DESKTOP) {
+            if (usage == HUG_HAT_SWITCH) {
+                if ((bsddata->hats < MAXAXES) && (bsddata->axes <= MAXAXES-2)) {
+                    got_something = 1;
+                    memcpy(&bsddata->hat_item[bsddata->hats], &h, sizeof(h));
+                    bsddata->hats++;
+                    bsddata->axes += 2;
+                }
+            } else {
+                if (bsddata->axes < MAXAXES) {
+                    got_something = 1;
+                    memcpy(&bsddata->axis_item[cur_axis], &h, sizeof(h));
+                    cur_axis++;
+                    bsddata->axes++;
+                }
+            }
+        } else if (page == HUP_BUTTON) {
+            if (bsddata->buttons < MAXBUTTONS) {
+                got_something = 1;
+                memcpy(&bsddata->button_item[bsddata->buttons], &h, sizeof(h));
+                bsddata->buttons++;
+            }
+	}
+    }
+    hid_end_parse(d);
+
+    if (!got_something) {
+        free(bsddata->data_buf);
+        xf86Msg(X_ERROR, "Joystick: Didn't find any usable axes.\n");
+        free(bsddata);
+        close(joystick->fd);
+        joystick->fd = -1;
+        return -1;
+    }
+
+    bsddata->hotdata = 0;
+    joystick->devicedata = (void*) bsddata;
+    xf86Msg(X_INFO, "Joystick: %d buttons, %d axes\n", 
+            bsddata->buttons, bsddata->axes);
+
+    joystick->read_proc = jstkReadData_bsd;
+    joystick->close_proc = jstkCloseDevice_bsd;
+
+    return joystick->fd;
+}
+
+
+/***********************************************************************
+ *
+ * jstkCloseDevice --
+ *
+ * close the handle.
+ *
+ ***********************************************************************
+ */
+
+void
+jstkCloseDevice_bsd(JoystickDevPtr joystick)
+{
+    if ((joystick->fd >= 0)) {
+      xf86CloseSerial(joystick->fd);
+      joystick->fd = -1;
+    }
+    if (joystick->devicedata != NULL) {
+        if (((struct jstk_bsd_hid_data*)joystick->devicedata)->data_buf)
+            free(((struct jstk_bsd_hid_data*)joystick->devicedata)->data_buf);
+        free(joystick->devicedata);
+    }
+}
+
+
+/***********************************************************************
+ *
+ * jstkReadData --
+ *
+ * Reads data from fd and stores it in the JoystickDevRec struct
+ * fills in the type of event and the number of the button/axis
+ * return 1 if success, 0 otherwise. Success does not neccessarily
+ * mean that there is a new event waiting.
+ *
+ ***********************************************************************
+ */
+
+int
+jstkReadData_bsd(JoystickDevPtr joystick,
+             JOYSTICKEVENT *event,
+             int *number)
+{
+    int j,d;
+    struct jstk_bsd_hid_data *bsddata = 
+        (struct jstk_bsd_hid_data*)(joystick->devicedata);
+
+    if (event != NULL) *event = EVENT_NONE;
+    if (bsddata->hotdata == 0) {
+        j= xf86ReadSerial(joystick->fd,
+                          bsddata->data_buf,
+                          bsddata->dlen);
+        if (j != bsddata->dlen) {
+            ErrorF("Read: %d byte! Should be %d\n",j,bsddata->dlen);
+            return 0;
+        }
+        bsddata->hotdata = 1;
+    }
+
+    for (j=0; j<bsddata->axes - (bsddata->hats * 2); j++) {
+        d = hid_get_data(bsddata->data_buf, &bsddata->axis_item[j]);
+        /* Scale the range to our expected range of -32768 to 32767 */
+        d = d - (bsddata->axis_item[j].logical_maximum 
+                 - bsddata->axis_item[j].logical_minimum) / 2;
+        d = d * 65536 / (bsddata->axis_item[j].logical_maximum 
+                         - bsddata->axis_item[j].logical_minimum);
+        if (abs(d) < joystick->axis[j].deadzone) d = 0;
+        if (d != joystick->axis[j].value) {
+            joystick->axis[j].oldvalue = joystick->axis[j].value;
+            joystick->axis[j].value = d;
+            if (event != NULL) *event = EVENT_AXIS;
+            if (number != NULL) *number = j;
+            return 2;
+        }
+    }
+
+    for (j=0; j<bsddata->hats; j++) {
+        int a;
+        int v1_data[9] = 
+            { 0, 32767, 32767, 32767, 0, -32768, -32768, -32768, 0 };
+        int v2_data[9] =
+            { -32768, -32768, 0, 32767, 32767, 32767, 0, -32767, 0 };
+
+        a = j*2 + bsddata->axes - bsddata->hats *2;
+        d = hid_get_data(bsddata->data_buf, &bsddata->hat_item[j]) 
+            - bsddata->hat_item[j].logical_minimum;
+        if (joystick->axis[a].value != v1_data[d]) {
+            joystick->axis[a].oldvalue = joystick->axis[a].value;
+            joystick->axis[a].value = v1_data[d];
+            if (event != NULL) *event = EVENT_AXIS;
+            if (number != NULL) *number = a;
+            return 2;
+        }
+        if (joystick->axis[a+1].value != v2_data[d]) {
+            joystick->axis[a+1].oldvalue = joystick->axis[a+1].value;
+            joystick->axis[a+1].value = v2_data[d];
+            if (event != NULL) *event = EVENT_AXIS;
+            if (number != NULL) *number = a+1;
+            return 2;
+        }
+    }
+
+    for (j=0; j<bsddata->buttons; j++) {
+        int pressed;
+        d = hid_get_data(bsddata->data_buf, &bsddata->button_item[j]);
+        pressed = (d == bsddata->button_item[j].logical_minimum) ? 0 : 1;
+        if (pressed != joystick->button[j].pressed) {
+            joystick->button[j].pressed = pressed;
+            if (event != NULL) *event = EVENT_BUTTON;
+            if (number != NULL) *number = j;
+            return 2;
+        }
+    }
+
+    bsddata->hotdata = 0;
+    return 1;
+}
diff --git a/src/backend_bsd.h b/src/backend_bsd.h
new file mode 100644
index 0000000..452b206
--- /dev/null
+++ b/src/backend_bsd.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2007      by Sascha Hlusiak. <saschahlusiak@freedesktop.org>     
+ *                                                                            
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is  hereby granted without fee, provided that
+ * the  above copyright   notice appear  in   all  copies and  that both  that
+ * copyright  notice   and   this  permission   notice  appear  in  supporting
+ * documentation, and that   the  name of  Sascha   Hlusiak  not  be  used  in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific,  written      prior  permission.     Sascha   Hlusiak   makes  no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.                   
+ *                                                                            
+ * SASCHA  HLUSIAK  DISCLAIMS ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
+ * EVENT  SHALL SASCHA  HLUSIAK  BE   LIABLE   FOR ANY  SPECIAL, INDIRECT   OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA  OR PROFITS, WHETHER  IN  AN ACTION OF  CONTRACT,  NEGLIGENCE OR OTHER
+ * TORTIOUS  ACTION, ARISING    OUT OF OR   IN  CONNECTION  WITH THE USE    OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef _BACKEND_BSD_H_INCLUDED_
+#define _BACKEND_BSD_H_INCLUDED_
+
+#include "jstk.h"
+
+int jstkOpenDevice_bsd(JoystickDevPtr joystick);
+void jstkCloseDevice_bsd(JoystickDevPtr joystick);
+int jstkReadData_bsd(JoystickDevPtr joystick,
+                          JOYSTICKEVENT *event,
+                          int *number);
+
+#endif
diff --git a/src/backend_evdev.c b/src/backend_evdev.c
new file mode 100644
index 0000000..6eeab08
--- /dev/null
+++ b/src/backend_evdev.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007      by Sascha Hlusiak. <saschahlusiak@freedesktop.org>     
+ *                                                                            
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is  hereby granted without fee, provided that
+ * the  above copyright   notice appear  in   all  copies and  that both  that
+ * copyright  notice   and   this  permission   notice  appear  in  supporting
+ * documentation, and that   the  name of  Sascha   Hlusiak  not  be  used  in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific,  written      prior  permission.     Sascha   Hlusiak   makes  no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.                   
+ *                                                                            
+ * SASCHA  HLUSIAK  DISCLAIMS ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
+ * EVENT  SHALL SASCHA  HLUSIAK  BE   LIABLE   FOR ANY  SPECIAL, INDIRECT   OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA  OR PROFITS, WHETHER  IN  AN ACTION OF  CONTRACT,  NEGLIGENCE OR OTHER
+ * TORTIOUS  ACTION, ARISING    OUT OF OR   IN  CONNECTION  WITH THE USE    OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/**
+ * This provides the backend for Linux evdev devices.
+ * Devices are usually /dev/input/event?
+ **/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <linux/joystick.h>
+
+#include <xf86.h>
+#include <xf86_OSproc.h>
+
+#include "jstk.h"
+#include "backend_evdev.h"
+
+
+/***********************************************************************
+ *
+ * jstkOpenDevice --
+ *
+ * Open and initialize a joystick device. The device name is
+ * taken from JoystickDevPtr 
+ * Returns the filedescriptor, or -1 in case of error
+ *
+ ***********************************************************************
+ */
+
+int
+jstkOpenDevice_evdev(JoystickDevPtr joystick)
+{
+    if (1) {
+        xf86Msg(X_ERROR, "Joystick: '%s': evdev failed: IMPLEMENTATION MISSING\n", 
+                  joystick->device);



Reply to: