This patch introduces a command-line option -input-hotplug for kdrive-based applications, which can be used to enable input hotplugging support, instead of passing explicit -keybd and/or -mouse options.
It also includes udev backend implementation for input hotplugging support. Another patches are required for hal or wscons backends. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=33140 Signed-off-by: Laércio de Sousa <[email protected]> --- hw/kdrive/src/Makefile.am | 2 ++ hw/kdrive/src/kdrive.c | 41 ++++++++++++++++++++++++++ hw/kdrive/src/kinput.c | 75 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 112 insertions(+), 6 deletions(-) diff --git a/hw/kdrive/src/Makefile.am b/hw/kdrive/src/Makefile.am index d69f0dd..f446f1a 100644 --- a/hw/kdrive/src/Makefile.am +++ b/hw/kdrive/src/Makefile.am @@ -23,3 +23,5 @@ libkdrive_la_SOURCES = \ kshadow.c \ $(KDRIVE_XV_SOURCES) \ $(top_srcdir)/mi/miinitext.c + +libkdrive_la_LIBADD = $(top_builddir)/config/libconfig.la diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c index dddbe6e..1ed5a46 100644 --- a/hw/kdrive/src/kdrive.c +++ b/hw/kdrive/src/kdrive.c @@ -44,6 +44,7 @@ #endif #include <signal.h> +#include <hotplug.h> typedef struct _kdDepths { CARD8 depth; @@ -81,6 +82,7 @@ char *kdSwitchCmd; DDXPointRec kdOrigin; Bool kdHasPointer = FALSE; Bool kdHasKbd = FALSE; +Bool kdEnableInputHotplugging = FALSE; static Bool kdCaughtSignal = FALSE; @@ -444,6 +446,8 @@ KdUseMsg(void) ErrorF ("-rgba rgb/bgr/vrgb/vbgr/none Specify subpixel ordering for LCD panels\n"); ErrorF + ("-input-hotplug Enable input device hotplugging support\n"); + ErrorF ("-mouse driver [,n,,options] Specify the pointer driver and its options (n is the number of buttons)\n"); ErrorF ("-keybd driver [,,options] Specify the keyboard driver and its options\n"); @@ -555,6 +559,10 @@ KdProcessArgument(int argc, char **argv, int i) sscanf(argv[i], "vt%2d", &kdVirtualTerminal) == 1) { return 1; } + if (!strcmp(argv[i], "-input-hotplug")) { + kdEnableInputHotplugging = TRUE; + return 1; + } if (!strcmp(argv[i], "-mouse") || !strcmp(argv[i], "-pointer")) { if (i + 1 >= argc) UseMsg(); @@ -1125,6 +1133,9 @@ KdInitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) KdAddScreen(pScreenInfo, screen, argc, argv); OsRegisterSigWrapper(KdSignalWrapper); + + if (kdEnableInputHotplugging) + config_pre_init(); } void @@ -1143,3 +1154,33 @@ DPMSSupported(void) { return FALSE; } + +/* These stubs can be safely removed once we can + * split input and GPU parts in hotplug.h et al. */ +#ifdef CONFIG_UDEV +void +NewGPUDeviceRequest(struct OdevAttributes *attribs) +{ +} + +void +DeleteGPUDeviceRequest(struct OdevAttributes *attribs) +{ +} +#endif + +struct xf86_platform_device * +xf86_find_platform_device_by_devnum(int major, int minor) +{ + return NULL; +} + +void +systemd_logind_release_fd(int _major, int _minor, int fd) +{ +} + +void +systemd_logind_vtenter(void) +{ +} diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index 057f53b..e2b65df 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -50,6 +50,11 @@ #include "xserver-properties.h" #include "inpututils.h" #include "optionstr.h" +#include <hotplug.h> + +#ifdef KDRIVE_EVDEV +#define DEV_INPUT_EVENT_PREFIX "/dev/input/event" +#endif #define AtomFromName(x) MakeAtom(x, strlen(x), 1) @@ -92,6 +97,7 @@ static KdInputFd kdInputFds[KD_MAX_INPUT_FDS]; static int kdNumInputFds; extern Bool kdRawPointerCoordinates; +extern Bool kdEnableInputHotplugging; static void KdSigio(int sig) @@ -391,7 +397,8 @@ KdPointerProc(DeviceIntPtr pDevice, int onoff) #endif if (!pi->driver) { if (!pi->driverPrivate) { - ErrorF("no driver specified for %s\n", pi->name); + ErrorF("no driver specified for pointer device \"%s\" (%s)\n", + pi->name ? pi->name : "(unnamed)", pi->path); return BadImplementation; } @@ -711,7 +718,8 @@ KdKeyboardProc(DeviceIntPtr pDevice, int onoff) #endif if (!ki->driver) { if (!ki->driverPrivate) { - ErrorF("no driver specified!\n"); + ErrorF("no driver specified for keyboard device \"%s\" (%s)\n", + ki->name ? ki->name : "(unnamed)", ki->path); return BadImplementation; } @@ -1280,11 +1288,17 @@ KdInitInput(void) } mieqInit(); + + if (kdEnableInputHotplugging) + config_init(); } void KdCloseInput(void) { + if (kdEnableInputHotplugging) + config_fini(); + mieqFini(); } @@ -2181,9 +2195,33 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs, #ifdef CONFIG_UDEV else if (strcmp(key, "_source") == 0 && strcmp(value, "server/udev") == 0) { - ErrorF("Ignoring device from udev.\n"); - return BadValue; + if (kdEnableInputHotplugging) { + if (attrs->flags & ATTR_POINTER) { + pi = KdNewPointer(); + if (!pi) + return BadAlloc; + } + else if (attrs->flags & ATTR_KEYBOARD) { + ki = KdNewKeyboard(); + if (!ki) + return BadAlloc; + } + } + else { + ErrorF("Ignoring device from udev.\n"); + return BadValue; + } } +#ifdef KDRIVE_EVDEV + else if (strcmp(key, "device") == 0) { + if (kdEnableInputHotplugging && value && + strncmp(value, + DEV_INPUT_EVENT_PREFIX, + sizeof(DEV_INPUT_EVENT_PREFIX) - 1) == 0) { + options = input_option_new(options, "driver", "evdev"); + } + } +#endif #endif } @@ -2224,13 +2262,35 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs, ki->options = options; } } +#ifdef CONFIG_UDEV + else if (strcmp(key, "xkb_rules") == 0) { + if (ki && value) + ki->xkbRules = strdup(value); + } + else if (strcmp(key, "xkb_model") == 0) { + if (ki && value) + ki->xkbModel = strdup(value); + } + else if (strcmp(key, "xkb_layout") == 0) { + if (ki && value) + ki->xkbLayout = strdup(value); + } + else if (strcmp(key, "xkb_variant") == 0) { + if (ki && value) + ki->xkbVariant = strdup(value); + } + else if (strcmp(key, "xkb_options") == 0) { + if (ki && value) + ki->xkbOptions = strdup(value); + } +#endif } if (pi) { if (KdAddPointer(pi) != Success || ActivateDevice(pi->dixdev, TRUE) != Success || EnableDevice(pi->dixdev, TRUE) != TRUE) { - ErrorF("couldn't add or enable pointer\n"); + ErrorF("couldn't add or enable pointer %s\n", pi->path); return BadImplementation; } } @@ -2238,7 +2298,7 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs, if (KdAddKeyboard(ki) != Success || ActivateDevice(ki->dixdev, TRUE) != Success || EnableDevice(ki->dixdev, TRUE) != TRUE) { - ErrorF("couldn't add or enable keyboard\n"); + ErrorF("couldn't add or enable keyboard %s\n", ki->path); return BadImplementation; } } @@ -2256,5 +2316,8 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs, void DeleteInputDeviceRequest(DeviceIntPtr pDev) { + /* XXX: fix potential memory leaks when unplugging pointer devices */ + OsBlockSignals(); RemoveDevice(pDev, TRUE); + OsReleaseSignals(); } -- 2.2.0 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
