Support input ABI 12

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@who-t.net>
Reviewed-by: Trevor Woerner <twoerner@gmail.com>
This commit is contained in:
Peter Hutterer
2010-12-14 17:00:28 +10:00
parent f2050e6be5
commit 8c7ad54d6d
4 changed files with 132 additions and 144 deletions

View File

@@ -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])

View File

@@ -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;
}
s = xf86CheckStrOption(pInfo->options, "_source", "");
if (strcmp(s, "_driver/joystick") == 0)
return jstkKeyboardPreInit(drv, pInfo, flags);
pInfo->private = (JoystickDevPtr)malloc(sizeof(JoystickDevRec));
priv = (JoystickDevPtr)pInfo->private;
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;
}

View File

@@ -137,7 +137,7 @@ jstkGenerateKeys(InputInfoPtr device, KEYSCANCODES keys, char pressed)
*
***************************************************************************
*/
static Bool
Bool
jstkKeyboardDeviceControlProc(DeviceIntPtr dev,
int what)
{
@@ -180,62 +180,116 @@ 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)
int jstkKeyboardPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
{
InputInfoPtr pInfo = NULL;
IDevPtr dev = NULL;
char name[512] = {0};
JoystickDevPtr priv = NULL;
char *s;
pInfo = xf86AllocateInput(drv, 0);
if (!pInfo) {
goto SetupProc_fail;
}
pInfo->private = priv = calloc(1, sizeof(JoystickDevRec));
if (!priv)
return BadAlloc;
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->name = dev->identifier;
pInfo->flags = XI86_KEYBOARD_CAPABLE;
pInfo->device_control = jstkKeyboardDeviceControlProc;
pInfo->read_input = NULL;
pInfo->control_proc = NULL;
pInfo->switch_mode = 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);
xf86ProcessCommonOptions(pInfo, pInfo->options);
/* parse keyboard-related options */
priv->repeat_delay = 0;
priv->repeat_interval = 0;
/* return the LocalDevice */
pInfo->flags |= XI86_CONFIGURED;
return (pInfo);
SetupProc_fail:
if (pInfo)
pInfo->private = NULL;
if (dev) {
if (dev->identifier) free(dev->identifier);
if (dev->driver) free(dev->driver);
free(dev);
/* 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);
}
return NULL;
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;
}
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));
tmp->key = xf86OptionName(options);
tmp->value = xf86OptionValue(options);
tmp->next = iopts;
iopts = tmp;
options = xf86NextOption(options);
}
/* 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;
}

View File

@@ -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