mirror of
https://github.com/X11Libre/xf86-input-joystick.git
synced 2026-03-24 01:34:06 +00:00
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:
@@ -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])
|
||||
|
||||
131
src/jstk.c
131
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
138
src/jstk_key.c
138
src/jstk_key.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user