[PATCH joystick 9/9] Support input ABI 12

Peter Hutterer peter.hutterer at who-t.net
Tue Dec 14 18:58:14 PST 2010


This commit adds support for input ABI 12, consisting of a number of
changes:
- requires an X server with an ABI of 12
- valuators have a per-mode setting
- new PreInit prototype.

Because of the new PreInit prototype, the hotplug system has been switched
around too (should have probably been done in a separate commit before,
but...).

The old hotplug mechanism added a separate ModuleInfoRec for the keyboard
part of the driver. This isn't feasable for InputClass configurations, the
driver part may get overwritten.

On entering the driver, after checking a few default values, hotplug the
keyboard device (wacom-style) and let it initialize. Because NIDR calls
DEVICE_INIT and DEVICE_ON the keyboard must initialise the private pointer
and pass it back to the original device.

Call order is:
NewInputDeviceRequest
 - jstkCorePreInit
   - jstkKeyboardHotplug
     - NewInputDeviceRequest
       - jstkCorePreInit
         immediately return jstkKeyboardPreInit()
       - keyboard DEVICE_INIT
       - keyboard DEVICE_ON
     return keyboard device
   - copy keyboard->priv to joystick->priv
   - finish jstkCorePreInit as normal
   - joystick DEVICE_INIT
   - joystick DEVICE_ON

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 configure.ac   |    2 +-
 src/jstk.c     |  131 +++++++++++++----------------------------------------
 src/jstk_key.c |  137 +++++++++++++++++++++++++++++++++++++++-----------------
 src/jstk_key.h |    5 +-
 4 files changed, 131 insertions(+), 144 deletions(-)

diff --git a/configure.ac b/configure.ac
index 6da920b..04b2f44 100644
--- a/configure.ac
+++ b/configure.ac
@@ -49,7 +49,7 @@ XORG_DRIVER_CHECK_EXT(XINPUT, inputproto)
 XORG_DRIVER_CHECK_EXT(XKB, kbproto)
 
 # Checks for pkg-config packages
-PKG_CHECK_MODULES(XORG, [xorg-server >= 1.9.0] xproto $REQUIRED_MODULES)
+PKG_CHECK_MODULES(XORG, [xorg-server >= 1.9.99.2] xproto $REQUIRED_MODULES)
 
 DRIVER_NAME=joystick
 AC_SUBST([DRIVER_NAME])
diff --git a/src/jstk.c b/src/jstk.c
index 03d8b87..9796a46 100644
--- a/src/jstk.c
+++ b/src/jstk.c
@@ -347,7 +347,8 @@ jstkDeviceControlProc(DeviceIntPtr       pJstk,
                                    screenInfo.screens[0]->width, /* max val */
                                    1, /* resolution */
                                    0, /* min_res */
-                                   1); /* max_res */
+                                   1, /* max_res */
+                                   Absolute);
             InitValuatorAxisStruct(pJstk,
                                    1, /* valuator num */
                                    XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y),
@@ -355,7 +356,8 @@ jstkDeviceControlProc(DeviceIntPtr       pJstk,
                                    screenInfo.screens[0]->height, /* max val */
                                    1, /* resolution */
                                    0, /* min_res */
-                                   1); /* max_res */
+                                   1, /* max_res */
+                                   Absolute);
             for (i=0; i<MAXAXES; i++) 
                 if (priv->axis[i].valuator != -1)
             {
@@ -366,23 +368,13 @@ jstkDeviceControlProc(DeviceIntPtr       pJstk,
                                        32767,  /* max val */
                                        1, /* resolution */
                                        0, /* min_res */
-                                       1); /* max_res */
+                                       1, /* max_res */
+                                       Absolute);
             }
             /* allocate the motion history buffer if needed */
             xf86MotionHistoryAllocate(pInfo);
         }
 
-
-        if (priv->keyboard_device != NULL)
-        {
-            DBG(2, ErrorF("Activating keyboard device\n"));
-            xf86ActivateDevice(priv->keyboard_device);
-            priv->keyboard_device->dev->inited = 
-                (priv->keyboard_device->device_control(priv->keyboard_device->dev, DEVICE_INIT) == Success);
-            xf86EnableDevice(priv->keyboard_device->dev);
-            DBG(2, ErrorF("Keyboard device activated\n"));
-        }
-
 	jstkInitProperties(pJstk, priv);
 
         break;
@@ -433,18 +425,6 @@ jstkDeviceControlProc(DeviceIntPtr       pJstk,
     return Success;
 }
 
-
-
-
-_X_EXPORT InputDriverRec JSTK_KEYBOARD = {
-    1,
-    "joystick_keyboard",
-    NULL,
-    jstkKeyboardPreInit,
-    jstkKeyboardUnInit,
-    NULL
-};
-
 /*
  ***************************************************************************
  *
@@ -452,37 +432,41 @@ _X_EXPORT InputDriverRec JSTK_KEYBOARD = {
  *
  * Called when a device will be instantiated
  *
+ * This is a tad complicated. NewInputDeviceRequest(), which we use to
+ * hotplug a keyboard device,. enables the device, so we need to make sure
+ * that all options for the dependent device are set correctly.
+ *
+ * This means that we parse the keyboard-specific options into the
+ * keyboard device's PreInit, and re-use the keyboard's priv field.
+ *
  ***************************************************************************
  */
 
-static InputInfoPtr
-jstkCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
+static int
+jstkCorePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
 {
-    InputInfoPtr      pInfo = NULL;
+    InputInfoPtr        keyboard_device;
     JoystickDevPtr      priv = NULL;
     char                *s;
     int                 i, j;
 
-    pInfo = xf86AllocateInput(drv, 0);
-    if (!pInfo) {
-        goto SetupProc_fail;
-    }
-
-    pInfo->private = (JoystickDevPtr)malloc(sizeof(JoystickDevRec));
-    priv = (JoystickDevPtr)pInfo->private;
+    s = xf86CheckStrOption(pInfo->options, "_source", "");
+    if (strcmp(s, "_driver/joystick") == 0)
+        return jstkKeyboardPreInit(drv, pInfo, flags);
 
-    pInfo->name   = dev->identifier;
-    pInfo->flags  = XI86_SEND_DRAG_EVENTS;
     pInfo->device_control = jstkDeviceControlProc;
     pInfo->read_input = jstkReadProc;
     pInfo->control_proc = NULL;
     pInfo->switch_mode = NULL;
     pInfo->fd = -1;
     pInfo->dev = NULL;
-    pInfo->private = priv;
     pInfo->type_name = XI_JOYSTICK;
-    pInfo->always_core_feedback = NULL;
-    pInfo->conf_idev = dev;
+
+    keyboard_device = jstkKeyboardHotplug(pInfo, flags);
+    if (!keyboard_device)
+        return BadAlloc;
+
+    pInfo->private = priv = keyboard_device->private;
 
     priv->fd = -1;
     priv->open_proc = NULL;
@@ -495,9 +479,7 @@ jstkCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
     priv->mouse_enabled = TRUE;
     priv->keys_enabled = TRUE;
     priv->amplify = 1.0f;
-    priv->keyboard_device = NULL;
-    priv->repeat_delay = 0;
-    priv->repeat_interval = 0;
+    priv->keyboard_device = keyboard_device;
     priv->num_axes    = MAXAXES;
     priv->num_buttons = MAXBUTTONS;
 
@@ -555,8 +537,6 @@ jstkCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
     priv->axis[5].type      = JSTK_TYPE_ACCELERATED;
     priv->axis[5].mapping   = JSTK_MAPPING_Y;
 
-    xf86CollectInputOptions(pInfo, NULL, NULL);
-
     /* Joystick device is mandatory */
     priv->device = xf86SetStrOption(pInfo->options, "Device", NULL);
     if (!priv->device)
@@ -567,8 +547,6 @@ jstkCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
         goto SetupProc_fail;
     }
 
-    xf86ProcessCommonOptions(pInfo, pInfo->options);
-
 #if DEBUG
     debug_level = xf86SetIntOption(pInfo->options, "DebugLevel", 0);
     if (debug_level > 0) {
@@ -582,43 +560,6 @@ jstkCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
     }
 #endif
 
-    /* Parse option for autorepeat */
-    if ((s = xf86SetStrOption(pInfo->options, "AutoRepeat", NULL))) {
-        int delay, rate;
-        if (sscanf(s, "%d %d", &delay, &rate) != 2) {
-            xf86Msg(X_ERROR, "%s: \"%s\" is not a valid AutoRepeat value", 
-                    pInfo->name, s);
-        } else {
-            priv->repeat_delay = delay;
-            if (rate != 0)
-                priv->repeat_interval = 1000/rate;
-            else priv->repeat_interval = 0;
-            DBG(1, xf86Msg(X_CONFIG, "Autorepeat set to delay=%d, interval=%d\n",
-                           priv->repeat_delay,priv->repeat_interval));
-        }
-        free(s);
-    }
-    
-    priv->rmlvo.rules = xf86SetStrOption(pInfo->options, "xkb_rules", NULL);
-    if (!priv->rmlvo.rules)
-	priv->rmlvo.rules = xf86SetStrOption(pInfo->options, "XkbRules", "evdev");
-
-    priv->rmlvo.model = xf86SetStrOption(pInfo->options, "xkb_model", NULL);
-    if (!priv->rmlvo.model)
-	priv->rmlvo.model = xf86SetStrOption(pInfo->options, "XkbModel", "evdev");
-
-    priv->rmlvo.layout = xf86SetStrOption(pInfo->options, "xkb_layout", NULL);
-    if (!priv->rmlvo.layout)
-	priv->rmlvo.layout = xf86SetStrOption(pInfo->options, "XkbLayout", "us");
-
-    priv->rmlvo.variant = xf86SetStrOption(pInfo->options, "xkb_variant", NULL);
-    if (!priv->rmlvo.variant)
-	priv->rmlvo.variant = xf86SetStrOption(pInfo->options, "XkbVariant", "");
-
-    priv->rmlvo.options = xf86SetStrOption(pInfo->options, "xkb_options", NULL);
-    if (!priv->rmlvo.options)
-	priv->rmlvo.options = xf86SetStrOption(pInfo->options, "XkbOptions", "");
-
     priv->mouse_enabled = xf86SetBoolOption(pInfo->options, "StartMouseEnabled", TRUE);
     priv->keys_enabled = xf86SetBoolOption(pInfo->options, "StartKeysEnabled", TRUE);
 
@@ -649,23 +590,17 @@ jstkCorePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
                        priv->axis[i].amplify));
     }
 
-    /* return the LocalDevice */
-    pInfo->flags |= XI86_CONFIGURED;
-
-    priv->keyboard_device = jstkKeyboardPreInit(&JSTK_KEYBOARD, dev, flags);
-    if (priv->keyboard_device) {
-        priv->keyboard_device->private = priv;
-    }
-
-    return (pInfo);
+    return Success;
 
 SetupProc_fail:
-    if (priv)
+    if (priv) {
         free(priv);
+        if (keyboard_device)
+            keyboard_device->private = NULL;
+    }
     if (pInfo)
         pInfo->private = NULL;
-    return NULL;
-/*    return (pInfo); */ /* Makes X segfault on error */
+    return BadValue;
 }
 
 
@@ -710,7 +645,6 @@ _X_EXPORT InputDriverRec JOYSTICK = {
     NULL
 };
 
-
 /*
  ***************************************************************************
  *
@@ -728,7 +662,6 @@ jstkDriverPlug(pointer  module,
                int      *errmin)
 {
     xf86AddInputDriver(&JOYSTICK, module, 0);
-    xf86AddInputDriver(&JSTK_KEYBOARD, module, 0);
     return module;
 }
 
diff --git a/src/jstk_key.c b/src/jstk_key.c
index bfca3a5..70eda72 100644
--- a/src/jstk_key.c
+++ b/src/jstk_key.c
@@ -137,7 +137,7 @@ jstkGenerateKeys(InputInfoPtr device, KEYSCANCODES keys, char pressed)
  *
  ***************************************************************************
  */
-static Bool
+Bool
 jstkKeyboardDeviceControlProc(DeviceIntPtr       dev,
                               int                what)
 {
@@ -180,65 +180,118 @@ jstkKeyboardDeviceControlProc(DeviceIntPtr       dev,
  *
  * jstkKeyboardPreInit --
  *
- * Called manually to create a keyboard device for the joystick
+ * See comment in jstkCorePreInit() for details.
  *
  ***************************************************************************
  */
-InputInfoPtr
-jstkKeyboardPreInit(InputDriverPtr drv, IDevPtr _dev, int flags)
-{
-    InputInfoPtr pInfo = NULL;
-    IDevPtr dev = NULL;
-    char name[512] = {0};
 
-    pInfo = xf86AllocateInput(drv, 0);
-    if (!pInfo) {
-        goto SetupProc_fail;
-    }
+int jstkKeyboardPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+    JoystickDevPtr priv = NULL;
+    char *s;
 
-    dev = calloc(sizeof(IDevRec), 1);
-    strcpy(name, _dev->identifier);
-    strcat(name, " (keys)");
-    dev->identifier = xstrdup(name);
-    dev->driver = xstrdup(_dev->driver);
-    dev->commonOptions = (pointer)xf86optionListDup(_dev->commonOptions);
-    dev->extraOptions = (pointer)xf86optionListDup(_dev->extraOptions);
+    pInfo->private = priv = calloc(1, sizeof(JoystickDevRec));
+    if (!priv)
+        return BadAlloc;
 
-    pInfo->name   = dev->identifier;
-    pInfo->flags  = XI86_KEYBOARD_CAPABLE;
     pInfo->device_control = jstkKeyboardDeviceControlProc;
     pInfo->read_input = NULL;
-    pInfo->close_proc = NULL;
     pInfo->control_proc = NULL;
     pInfo->switch_mode = NULL;
-    pInfo->conversion_proc = NULL;
     pInfo->fd = -1;
-    pInfo->dev = NULL;
-    pInfo->private = NULL;
     pInfo->type_name = XI_JOYSTICK;
-    pInfo->history_size = 0;
-    pInfo->always_core_feedback = 0;
-    pInfo->conf_idev = dev;
 
-    xf86CollectInputOptions(pInfo, NULL, NULL);
-    xf86OptionListReport(pInfo->options);
-    xf86ProcessCommonOptions(pInfo, pInfo->options);
+    /* parse keyboard-related options */
+    priv->repeat_delay = 0;
+    priv->repeat_interval = 0;
+
+    /* Parse option for autorepeat */
+    if ((s = xf86SetStrOption(pInfo->options, "AutoRepeat", NULL))) {
+        int delay, rate;
+        if (sscanf(s, "%d %d", &delay, &rate) != 2) {
+            xf86Msg(X_ERROR, "%s: \"%s\" is not a valid AutoRepeat value",
+                    pInfo->name, s);
+        } else {
+            priv->repeat_delay = delay;
+            if (rate != 0)
+                priv->repeat_interval = 1000/rate;
+            else priv->repeat_interval = 0;
+            DBG(1, xf86Msg(X_CONFIG, "Autorepeat set to delay=%d, interval=%d\n",
+                           priv->repeat_delay,priv->repeat_interval));
+        }
+        free(s);
+    }
+
+    priv->rmlvo.rules = xf86SetStrOption(pInfo->options, "xkb_rules", NULL);
+    if (!priv->rmlvo.rules)
+	priv->rmlvo.rules = xf86SetStrOption(pInfo->options, "XkbRules", "evdev");
+
+    priv->rmlvo.model = xf86SetStrOption(pInfo->options, "xkb_model", NULL);
+    if (!priv->rmlvo.model)
+	priv->rmlvo.model = xf86SetStrOption(pInfo->options, "XkbModel", "evdev");
+
+    priv->rmlvo.layout = xf86SetStrOption(pInfo->options, "xkb_layout", NULL);
+    if (!priv->rmlvo.layout)
+	priv->rmlvo.layout = xf86SetStrOption(pInfo->options, "XkbLayout", "us");
+
+    priv->rmlvo.variant = xf86SetStrOption(pInfo->options, "xkb_variant", NULL);
+    if (!priv->rmlvo.variant)
+	priv->rmlvo.variant = xf86SetStrOption(pInfo->options, "XkbVariant", "");
+
+    priv->rmlvo.options = xf86SetStrOption(pInfo->options, "xkb_options", NULL);
+    if (!priv->rmlvo.options)
+	priv->rmlvo.options = xf86SetStrOption(pInfo->options, "XkbOptions", "");
+
+    return Success;
+}
 
 
-    /* return the LocalDevice */
-    pInfo->flags |= XI86_CONFIGURED;
 
-    return (pInfo);
+InputInfoPtr
+jstkKeyboardHotplug(InputInfoPtr pInfo, int flags)
+{
+    int rc;
+    char name[512] = {0};
+    InputAttributes *attrs = NULL;
+    InputOption *options;
+    InputOption *iopts = NULL, *tmp;
+    DeviceIntPtr dev;
+
+    /* duplicate option list, append to name */
+    options = xf86OptionListDuplicate(pInfo->options);
+    strcpy(name, pInfo->name);
+    strcat(name, " (keys)");
+    options = xf86ReplaceStrOption(options, "Name", name);
+    options = xf86ReplaceStrOption(options, "_source", "_driver/joystick");
+
+    while(options)
+    {
+        tmp = calloc(1, sizeof(InputOption));
 
-SetupProc_fail:
-    if (pInfo)
-        pInfo->private = NULL;
-    if (dev) {
-        if (dev->identifier) free(dev->identifier);
-        if (dev->driver) free(dev->driver);
-        free(dev);
+        tmp->key = xf86OptionName(options);
+        tmp->value = xf86OptionValue(options);
+        tmp->next = iopts;
+        iopts = tmp;
+        options = xf86NextOption(options);
     }
-    return NULL;
+
+    /* duplicate attribute list */
+    attrs = DuplicateInputAttributes(pInfo->attrs);
+
+    rc = NewInputDeviceRequest(iopts, attrs, &dev);
+
+    while(iopts)
+    {
+        tmp = iopts->next;
+        free(iopts->key);
+        free(iopts->value);
+        free(iopts);
+        iopts = tmp;
+    }
+
+    FreeInputAttributes(attrs);
+
+    return (rc == Success) ? dev->public.devicePrivate : NULL;
 }
 
 
diff --git a/src/jstk_key.h b/src/jstk_key.h
index 01327f6..fc0c782 100644
--- a/src/jstk_key.h
+++ b/src/jstk_key.h
@@ -27,7 +27,8 @@
 
 void jstkGenerateKeys(InputInfoPtr device, KEYSCANCODES keys, char pressed);
 
-InputInfoPtr jstkKeyboardPreInit(InputDriverPtr drv, IDevPtr dev, int flags);
+int jstkKeyboardPreInit(InputDriverPtr pInfo, InputInfoPtr dev, int flags);
 void jstkKeyboardUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
-
+Bool jstkKeyboardDeviceControlProc(DeviceIntPtr dev, int what);
+InputInfoPtr jstkKeyboardHotplug(InputInfoPtr dev, int flags);
 #endif
-- 
1.7.3.3



More information about the xorg-devel mailing list