forked from pool/xorg-x11-server
Egbert Eich
7aff496244
- Backport upstream patches for Xephyr input hot-plugging / single-GPU multi-seat support: * U_kdrive-fix-up-NewInputDeviceRequest-implementation.patch * U_kdrive-set-evdev-driver-for-input-devices-automatica.patch * U_ephyr-don-t-load-ephyr-input-driver-if-seat-option-i.patch * U_kdrive-don-t-let-evdev-driver-overwrite-existing-dev.patch * U_ephyr-ignore-Xorg-multiseat-command-line-options.patch * U_ephyr-enable-option-sw-cursor-by-default-in-multi-se.patch * U_kdrive-introduce-input-hot-plugging-support-for-udev.patch * U_kdrive-add-options-to-set-default-XKB-properties.patch * U_kdrive-evdev-update-keyboard-LEDs-22302.patch * U_config-udev-distinguish-between-real-keyboards-and-o.patch OBS-URL: https://build.opensuse.org/request/show/367497 OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xorg-x11-server?expand=0&rev=616
438 lines
14 KiB
Diff
438 lines
14 KiB
Diff
From 0cf3d72be6bd99cd2c66b7885339322c7e5bf73d Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?La=C3=A9rcio=20de=20Sousa?=
|
|
<laerciosousa@sme-mogidascruzes.sp.gov.br>
|
|
Date: Fri, 12 Feb 2016 14:17:59 -0200
|
|
Subject: [PATCH 53/56] kdrive: introduce input hot-plugging support for udev
|
|
and hal backends (#33140)
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
This patch introduces input hot-plugging support for kdrive-based
|
|
applications in multi-seat context. This feature is enabled by passing
|
|
-seat option with desired seat name. All keyboard/mouse devices assigned
|
|
to that seat will be automatically grabbed by kdrive.
|
|
|
|
It supports udev and hal backends for input hot-plugging support.
|
|
Another patches may be required for wscons backend.
|
|
|
|
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=33140
|
|
|
|
Reviewed-by: Adam Jackson <ajax@redhat.com>
|
|
Signed-off-by: Laércio de Sousa <laerciosousa@sme-mogidascruzes.sp.gov.br>
|
|
---
|
|
hw/kdrive/src/Makefile.am | 8 +++
|
|
hw/kdrive/src/kdrive.c | 46 +++++++++++++
|
|
hw/kdrive/src/kinfo.c | 4 ++
|
|
hw/kdrive/src/kinput.c | 162 +++++++++++++++++++++++++++++++++++++++-------
|
|
4 files changed, 198 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/hw/kdrive/src/Makefile.am b/hw/kdrive/src/Makefile.am
|
|
index d69f0dd..b7f94b0 100644
|
|
--- a/hw/kdrive/src/Makefile.am
|
|
+++ b/hw/kdrive/src/Makefile.am
|
|
@@ -23,3 +23,11 @@ libkdrive_la_SOURCES = \
|
|
kshadow.c \
|
|
$(KDRIVE_XV_SOURCES) \
|
|
$(top_srcdir)/mi/miinitext.c
|
|
+
|
|
+if CONFIG_UDEV
|
|
+libkdrive_la_LIBADD = $(top_builddir)/config/libconfig.la
|
|
+else
|
|
+if CONFIG_HAL
|
|
+libkdrive_la_LIBADD = $(top_builddir)/config/libconfig.la
|
|
+endif
|
|
+endif
|
|
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
|
|
index 582ff66..269b609 100644
|
|
--- a/hw/kdrive/src/kdrive.c
|
|
+++ b/hw/kdrive/src/kdrive.c
|
|
@@ -45,6 +45,14 @@
|
|
|
|
#include <signal.h>
|
|
|
|
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
|
|
+#include <hotplug.h>
|
|
+#endif
|
|
+
|
|
+/* This stub can be safely removed once we can
|
|
+ * split input and GPU parts in hotplug.h et al. */
|
|
+#include <systemd-logind.h>
|
|
+
|
|
typedef struct _kdDepths {
|
|
CARD8 depth;
|
|
CARD8 bpp;
|
|
@@ -1125,6 +1133,11 @@ KdInitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
|
|
KdAddScreen(pScreenInfo, screen, argc, argv);
|
|
|
|
OsRegisterSigWrapper(KdSignalWrapper);
|
|
+
|
|
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
|
|
+ if (SeatId) /* Enable input hot-plugging */
|
|
+ config_pre_init();
|
|
+#endif
|
|
}
|
|
|
|
void
|
|
@@ -1143,3 +1156,36 @@ 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_KMS
|
|
+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;
|
|
+}
|
|
+
|
|
+#ifdef SYSTEMD_LOGIND
|
|
+void
|
|
+systemd_logind_vtenter(void)
|
|
+{
|
|
+}
|
|
+
|
|
+void
|
|
+systemd_logind_release_fd(int major, int minor, int fd)
|
|
+{
|
|
+ close(fd);
|
|
+}
|
|
+#endif
|
|
diff --git a/hw/kdrive/src/kinfo.c b/hw/kdrive/src/kinfo.c
|
|
index 01ae1e4..f91d575 100644
|
|
--- a/hw/kdrive/src/kinfo.c
|
|
+++ b/hw/kdrive/src/kinfo.c
|
|
@@ -134,6 +134,7 @@ KdFreePointer(KdPointerInfo * pi)
|
|
free(pi->name);
|
|
free(pi->path);
|
|
input_option_free_list(&pi->options);
|
|
+ pi->next = NULL;
|
|
free(pi);
|
|
}
|
|
|
|
@@ -145,6 +146,9 @@ KdFreeKeyboard(KdKeyboardInfo * ki)
|
|
free(ki->xkbRules);
|
|
free(ki->xkbModel);
|
|
free(ki->xkbLayout);
|
|
+ free(ki->xkbVariant);
|
|
+ free(ki->xkbOptions);
|
|
+ input_option_free_list(&ki->options);
|
|
ki->next = NULL;
|
|
free(ki);
|
|
}
|
|
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
|
|
index 3a1c6a0..fd6a952 100644
|
|
--- a/hw/kdrive/src/kinput.c
|
|
+++ b/hw/kdrive/src/kinput.c
|
|
@@ -51,6 +51,10 @@
|
|
#include "inpututils.h"
|
|
#include "optionstr.h"
|
|
|
|
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
|
|
+#include <hotplug.h>
|
|
+#endif
|
|
+
|
|
#ifdef KDRIVE_EVDEV
|
|
#define DEV_INPUT_EVENT_PREFIX "/dev/input/event"
|
|
#define DEV_INPUT_EVENT_PREFIX_LEN (sizeof(DEV_INPUT_EVENT_PREFIX) - 1)
|
|
@@ -407,7 +411,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;
|
|
}
|
|
|
|
@@ -727,7 +732,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;
|
|
}
|
|
|
|
@@ -901,6 +907,8 @@ KdNewKeyboard(void)
|
|
ki->bellDuration = 200;
|
|
ki->next = NULL;
|
|
ki->options = NULL;
|
|
+ ki->name = strdup("Generic Keyboard");
|
|
+ ki->path = NULL;
|
|
ki->xkbRules = strdup(XKB_DFLT_RULES);
|
|
ki->xkbModel = strdup(XKB_DFLT_MODEL);
|
|
ki->xkbLayout = strdup(XKB_DFLT_LAYOUT);
|
|
@@ -1084,18 +1092,52 @@ KdParseKbdOptions(KdKeyboardInfo * ki)
|
|
const char *key = input_option_get_key(option);
|
|
const char *value = input_option_get_value(option);
|
|
|
|
- if (strcasecmp(key, "XkbRules") == 0)
|
|
+ if (
|
|
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
|
|
+ strcasecmp(key, "xkb_rules") == 0 ||
|
|
+#endif
|
|
+ strcasecmp(key, "XkbRules") == 0)
|
|
ki->xkbRules = strdup(value);
|
|
- else if (strcasecmp(key, "XkbModel") == 0)
|
|
+ else if (
|
|
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
|
|
+ strcasecmp(key, "xkb_model") == 0 ||
|
|
+#endif
|
|
+ strcasecmp(key, "XkbModel") == 0)
|
|
ki->xkbModel = strdup(value);
|
|
- else if (strcasecmp(key, "XkbLayout") == 0)
|
|
+ else if (
|
|
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
|
|
+ strcasecmp(key, "xkb_layout") == 0 ||
|
|
+#endif
|
|
+ strcasecmp(key, "XkbLayout") == 0)
|
|
ki->xkbLayout = strdup(value);
|
|
- else if (strcasecmp(key, "XkbVariant") == 0)
|
|
+ else if (
|
|
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
|
|
+ strcasecmp(key, "xkb_variant") == 0 ||
|
|
+#endif
|
|
+ strcasecmp(key, "XkbVariant") == 0)
|
|
ki->xkbVariant = strdup(value);
|
|
- else if (strcasecmp(key, "XkbOptions") == 0)
|
|
+ else if (
|
|
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
|
|
+ strcasecmp(key, "xkb_options") == 0 ||
|
|
+#endif
|
|
+ strcasecmp(key, "XkbOptions") == 0)
|
|
ki->xkbOptions = strdup(value);
|
|
- else if (!strcasecmp(key, "device"))
|
|
+ else if (!strcasecmp(key, "device")) {
|
|
+ if (ki->path != NULL)
|
|
+ free(ki->path);
|
|
ki->path = strdup(value);
|
|
+ }
|
|
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
|
|
+ else if (!strcasecmp(key, "path")) {
|
|
+ if (ki->path != NULL)
|
|
+ free(ki->path);
|
|
+ ki->path = strdup(value);
|
|
+ }
|
|
+ else if (!strcasecmp(key, "name")) {
|
|
+ free(ki->name);
|
|
+ ki->name = strdup(value);
|
|
+ }
|
|
+#endif
|
|
else if (!strcasecmp(key, "driver"))
|
|
ki->driver = KdFindKeyboardDriver(value);
|
|
else
|
|
@@ -1196,8 +1238,22 @@ KdParsePointerOptions(KdPointerInfo * pi)
|
|
pi->transformCoordinates = TRUE;
|
|
else if (!strcasecmp(key, "rawcoord"))
|
|
pi->transformCoordinates = FALSE;
|
|
- else if (!strcasecmp(key, "device"))
|
|
+ else if (!strcasecmp(key, "device")) {
|
|
+ if (pi->path != NULL)
|
|
+ free(pi->path);
|
|
+ pi->path = strdup(value);
|
|
+ }
|
|
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
|
|
+ else if (!strcasecmp(key, "path")) {
|
|
+ if (pi->path != NULL)
|
|
+ free(pi->path);
|
|
pi->path = strdup(value);
|
|
+ }
|
|
+ else if (!strcasecmp(key, "name")) {
|
|
+ free(pi->name);
|
|
+ pi->name = strdup(value);
|
|
+ }
|
|
+#endif
|
|
else if (!strcasecmp(key, "protocol"))
|
|
pi->protocol = strdup(value);
|
|
else if (!strcasecmp(key, "driver"))
|
|
@@ -1320,11 +1376,21 @@ KdInitInput(void)
|
|
}
|
|
|
|
mieqInit();
|
|
+
|
|
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
|
|
+ if (SeatId) /* Enable input hot-plugging */
|
|
+ config_init();
|
|
+#endif
|
|
}
|
|
|
|
void
|
|
KdCloseInput(void)
|
|
{
|
|
+#if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
|
|
+ if (SeatId) /* Input hot-plugging is enabled */
|
|
+ config_fini();
|
|
+#endif
|
|
+
|
|
mieqFini();
|
|
}
|
|
|
|
@@ -2141,24 +2207,29 @@ int
|
|
NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
|
|
DeviceIntPtr *pdev)
|
|
{
|
|
- InputOption *option = NULL;
|
|
+ InputOption *option = NULL, *optionsdup = NULL;
|
|
KdPointerInfo *pi = NULL;
|
|
KdKeyboardInfo *ki = NULL;
|
|
|
|
nt_list_for_each_entry(option, options, list.next) {
|
|
const char *key = input_option_get_key(option);
|
|
const char *value = input_option_get_value(option);
|
|
+ optionsdup = input_option_new(optionsdup, key, value);
|
|
|
|
if (strcmp(key, "type") == 0) {
|
|
if (strcmp(value, "pointer") == 0) {
|
|
pi = KdNewPointer();
|
|
- if (!pi)
|
|
+ if (!pi) {
|
|
+ input_option_free_list(&optionsdup);
|
|
return BadAlloc;
|
|
+ }
|
|
}
|
|
else if (strcmp(value, "keyboard") == 0) {
|
|
ki = KdNewKeyboard();
|
|
- if (!ki)
|
|
+ if (!ki) {
|
|
+ input_option_free_list(&optionsdup);
|
|
return BadAlloc;
|
|
+ }
|
|
}
|
|
else {
|
|
ErrorF("unrecognised device type!\n");
|
|
@@ -2168,25 +2239,66 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
|
|
#ifdef CONFIG_HAL
|
|
else if (strcmp(key, "_source") == 0 &&
|
|
strcmp(value, "server/hal") == 0) {
|
|
- ErrorF("Ignoring device from HAL.\n");
|
|
- return BadValue;
|
|
+ if (SeatId) {
|
|
+ /* Input hot-plugging is enabled */
|
|
+ if (attrs->flags & ATTR_POINTER) {
|
|
+ pi = KdNewPointer();
|
|
+ if (!pi) {
|
|
+ input_option_free_list(&optionsdup);
|
|
+ return BadAlloc;
|
|
+ }
|
|
+ }
|
|
+ else if (attrs->flags & ATTR_KEYBOARD) {
|
|
+ ki = KdNewKeyboard();
|
|
+ if (!ki) {
|
|
+ input_option_free_list(&optionsdup);
|
|
+ return BadAlloc;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ ErrorF("Ignoring device from HAL.\n");
|
|
+ input_option_free_list(&optionsdup);
|
|
+ return BadValue;
|
|
+ }
|
|
}
|
|
#endif
|
|
#ifdef CONFIG_UDEV
|
|
else if (strcmp(key, "_source") == 0 &&
|
|
strcmp(value, "server/udev") == 0) {
|
|
- ErrorF("Ignoring device from udev.\n");
|
|
- return BadValue;
|
|
+ if (SeatId) {
|
|
+ /* Input hot-plugging is enabled */
|
|
+ if (attrs->flags & ATTR_POINTER) {
|
|
+ pi = KdNewPointer();
|
|
+ if (!pi) {
|
|
+ input_option_free_list(&optionsdup);
|
|
+ return BadAlloc;
|
|
+ }
|
|
+ }
|
|
+ else if (attrs->flags & ATTR_KEYBOARD) {
|
|
+ ki = KdNewKeyboard();
|
|
+ if (!ki) {
|
|
+ input_option_free_list(&optionsdup);
|
|
+ return BadAlloc;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ ErrorF("Ignoring device from udev.\n");
|
|
+ input_option_free_list(&optionsdup);
|
|
+ return BadValue;
|
|
+ }
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if (pi) {
|
|
- pi->options = options;
|
|
+ pi->options = optionsdup;
|
|
KdParsePointerOptions(pi);
|
|
|
|
if (!pi->driver) {
|
|
- ErrorF("couldn't find driver!\n");
|
|
+ ErrorF("couldn't find driver for pointer device \"%s\" (%s)\n",
|
|
+ pi->name ? pi->name : "(unnamed)", pi->path);
|
|
KdFreePointer(pi);
|
|
return BadValue;
|
|
}
|
|
@@ -2194,18 +2306,21 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
|
|
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\" (%s)\n",
|
|
+ pi->name ? pi->name : "(unnamed)", pi->path);
|
|
+ KdFreePointer(pi);
|
|
return BadImplementation;
|
|
}
|
|
|
|
*pdev = pi->dixdev;
|
|
}
|
|
else if (ki) {
|
|
- ki->options = options;
|
|
+ ki->options = optionsdup;
|
|
KdParseKbdOptions(ki);
|
|
|
|
if (!ki->driver) {
|
|
- ErrorF("couldn't find driver!\n");
|
|
+ ErrorF("couldn't find driver for keyboard device \"%s\" (%s)\n",
|
|
+ ki->name ? ki->name : "(unnamed)", ki->path);
|
|
KdFreeKeyboard(ki);
|
|
return BadValue;
|
|
}
|
|
@@ -2213,7 +2328,9 @@ 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\" (%s)\n",
|
|
+ ki->name ? ki->name : "(unnamed)", ki->path);
|
|
+ KdFreeKeyboard(ki);
|
|
return BadImplementation;
|
|
}
|
|
|
|
@@ -2221,6 +2338,7 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
|
|
}
|
|
else {
|
|
ErrorF("unrecognised device identifier!\n");
|
|
+ input_option_free_list(&optionsdup);
|
|
return BadValue;
|
|
}
|
|
|
|
--
|
|
2.6.2
|
|
|