xserver: Branch 'master' - 4 commits

Adam Jackson ajax at kemper.freedesktop.org
Tue Mar 1 15:56:41 UTC 2016


 config/hal.c                   |    2 
 config/udev.c                  |    4 
 config/wscons.c                |    2 
 hw/kdrive/ephyr/ephyrinit.c    |    3 
 hw/kdrive/src/Makefile.am      |    8 +
 hw/kdrive/src/kdrive.c         |   96 +++++++++++++++++++++
 hw/kdrive/src/kinfo.c          |    4 
 hw/kdrive/src/kinput.c         |  182 ++++++++++++++++++++++++++++++++++-------
 hw/xfree86/common/xf86Xinput.c |    2 
 include/input.h                |    1 
 10 files changed, 273 insertions(+), 31 deletions(-)

New commits:
commit daa6d2d58f65b9301b1b1f3c6df07719ecb5c03d
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Feb 12 14:18:02 2016 -0200

    config/udev: distinguish between real keyboards and other key devices
    
    This patch introduces a new flag ATTR_KEY for hotplugged input devices,
    so we can better distinguish between real keyboards (i.e. devices with
    udev property ID_INPUT_KEYBOARD="1") and other key input devices like
    lid switches, power buttons, etc.
    
    All supported hotplug backends (udev, hal, and wscons) will set both
    flags ATTR_KEY and ATTR_KEYBOARD for real keyboards, but udev backend
    will set ATTR_KEY, but not ATTR_KEYBOARD, for non-keyboard key input
    devices (hal and wscons will set both flags in any case). With this
    distinction, kdrive input hotplugging mechanism will be allowed to only
    grab real keyboards, as other key input devices are currently not
    supported.
    
    In order to don't break current behaviour, this patch will replace all
    ATTR_KEYBOARD occurrences with ATTR_KEY in hw/xfree86/common/xf86Xinput.c.
    
    [ajax: Just add ATTR_KEY, don't re-number the other attributes]
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/config/hal.c b/config/hal.c
index ea574ca..c76eced 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -170,7 +170,7 @@ device_added(LibHalContext * hal_ctx, const char *udi)
     free(hal_tags);
 
     if (libhal_device_query_capability(hal_ctx, udi, "input.keys", NULL))
-        attrs.flags |= ATTR_KEYBOARD;
+        attrs.flags |= ATTR_KEY | ATTR_KEYBOARD;
     if (libhal_device_query_capability(hal_ctx, udi, "input.mouse", NULL))
         attrs.flags |= ATTR_POINTER;
     if (libhal_device_query_capability(hal_ctx, udi, "input.joystick", NULL))
diff --git a/config/udev.c b/config/udev.c
index 08a954b..1a6e82a 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -240,6 +240,10 @@ device_added(struct udev_device *udev_device)
         }
         else if (!strcmp(key, "ID_INPUT_KEY")) {
             LOG_PROPERTY(path, key, value);
+            attrs.flags |= ATTR_KEY;
+        }
+        else if (!strcmp(key, "ID_INPUT_KEYBOARD")) {
+            LOG_PROPERTY(path, key, value);
             attrs.flags |= ATTR_KEYBOARD;
         }
         else if (!strcmp(key, "ID_INPUT_MOUSE")) {
diff --git a/config/wscons.c b/config/wscons.c
index fb114bd..ee45675 100644
--- a/config/wscons.c
+++ b/config/wscons.c
@@ -163,7 +163,7 @@ wscons_add_keyboard(void)
         }
 
  kbd_config_done:
-    attrs.flags |= ATTR_KEYBOARD;
+    attrs.flags |= ATTR_KEY | ATTR_KEYBOARD;
     rc = NewInputDeviceRequest(input_options, &attrs, &dev);
     if (rc != Success)
         goto unwind;
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 836db79..ae19a9d 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -2343,7 +2343,9 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
         *pdev = ki->dixdev;
     }
     else {
-        ErrorF("unrecognised device identifier!\n");
+        ErrorF("unrecognised device identifier: %s\n",
+               input_option_get_value(input_option_find(optionsdup,
+                                                        "device")));
         input_option_free_list(&optionsdup);
         return BadValue;
     }
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index a9ce62a..4f2e6c8 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -635,7 +635,7 @@ InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
 
     /* MatchIs* booleans */
     if (iclass->is_keyboard.set &&
-        iclass->is_keyboard.val != ! !(attrs->flags & ATTR_KEYBOARD))
+        iclass->is_keyboard.val != ! !(attrs->flags & ATTR_KEY))
         return FALSE;
     if (iclass->is_pointer.set &&
         iclass->is_pointer.val != ! !(attrs->flags & ATTR_POINTER))
diff --git a/include/input.h b/include/input.h
index d8bd9c6..9662123 100644
--- a/include/input.h
+++ b/include/input.h
@@ -236,6 +236,7 @@ typedef struct _InputAttributes {
 #define ATTR_TABLET (1<<3)
 #define ATTR_TOUCHPAD (1<<4)
 #define ATTR_TOUCHSCREEN (1<<5)
+#define ATTR_KEY (1<<6)
 
 /* Key/Button has been run through all input processing and events sent to clients. */
 #define KEY_PROCESSED 1
commit 851ff9ec04b73412c7dbad7b4911a1feac21f354
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Feb 12 14:18:01 2016 -0200

    ephyr: enable option -sw-cursor by default in multi-seat mode
    
    Option -seat passed to Xephyr requires -sw-cursor to be passed as well,
    otherwise the mouse cursor will remain invisible for the given seat.
    This patch takes care of enabling -sw-cursor if -seat is passed.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 849a4e1..149ea98 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -373,6 +373,9 @@ OsVendorInit(void)
 {
     EPHYR_DBG("mark");
 
+    if (SeatId)
+        hostx_use_sw_cursor();
+
     if (hostx_want_host_cursor())
         ephyrFuncs.initCursor = &ephyrCursorInit;
 
commit 40e32e9fc9f3a1bd8287ee03dd399d8161cb98dd
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Feb 12 14:18:00 2016 -0200

    kdrive: add options to set default XKB properties
    
    This patch introduces convenient command-line options -xkb-rules,
    -xkb-model, -xkb-layout, -xkb-variant, and -xkb-options, to set default
    values for these properties.
    
    These options can be handful for cases in which compile-time default
    values don't match user locale, since kdrive doesn't support InputClass
    matching rules yet and not all Linux distros provide default rules to
    store these values in udev properties (which by the way is a discouraged
    practice).
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index 269b609..52bea5a 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -89,6 +89,11 @@ char *kdSwitchCmd;
 DDXPointRec kdOrigin;
 Bool kdHasPointer = FALSE;
 Bool kdHasKbd = FALSE;
+const char *kdGlobalXkbRules = NULL;
+const char *kdGlobalXkbModel = NULL;
+const char *kdGlobalXkbLayout = NULL;
+const char *kdGlobalXkbVariant = NULL;
+const char *kdGlobalXkbOptions = NULL;
 
 static Bool kdCaughtSignal = FALSE;
 
@@ -455,6 +460,11 @@ KdUseMsg(void)
         ("-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");
+    ErrorF("-xkb-rules       Set default XkbRules value (can be overriden by -keybd options)\n");
+    ErrorF("-xkb-model       Set default XkbModel value (can be overriden by -keybd options)\n");
+    ErrorF("-xkb-layout      Set default XkbLayout value (can be overriden by -keybd options)\n");
+    ErrorF("-xkb-variant     Set default XkbVariant value (can be overriden by -keybd options)\n");
+    ErrorF("-xkb-options     Set default XkbOptions value (can be overriden by -keybd options)\n");
     ErrorF("-zaphod          Disable cursor screen switching\n");
     ErrorF("-2button         Emulate 3 button mouse\n");
     ErrorF("-3button         Disable 3 button mouse emulation\n");
@@ -563,6 +573,46 @@ KdProcessArgument(int argc, char **argv, int i)
         sscanf(argv[i], "vt%2d", &kdVirtualTerminal) == 1) {
         return 1;
     }
+    if (!strcmp(argv[i], "-xkb-rules")) {
+        if (i + 1 >= argc) {
+            UseMsg();
+            FatalError("Missing argument for option -xkb-rules.\n");
+        }
+        kdGlobalXkbRules = argv[i + 1];
+        return 2;
+    }
+    if (!strcmp(argv[i], "-xkb-model")) {
+        if (i + 1 >= argc) {
+            UseMsg();
+            FatalError("Missing argument for option -xkb-model.\n");
+        }
+        kdGlobalXkbModel = argv[i + 1];
+        return 2;
+    }
+    if (!strcmp(argv[i], "-xkb-layout")) {
+        if (i + 1 >= argc) {
+            UseMsg();
+            FatalError("Missing argument for option -xkb-layout.\n");
+        }
+        kdGlobalXkbLayout = argv[i + 1];
+        return 2;
+    }
+    if (!strcmp(argv[i], "-xkb-variant")) {
+        if (i + 1 >= argc) {
+            UseMsg();
+            FatalError("Missing argument for option -xkb-variant.\n");
+        }
+        kdGlobalXkbVariant = argv[i + 1];
+        return 2;
+    }
+    if (!strcmp(argv[i], "-xkb-options")) {
+        if (i + 1 >= argc) {
+            UseMsg();
+            FatalError("Missing argument for option -xkb-options.\n");
+        }
+        kdGlobalXkbOptions = argv[i + 1];
+        return 2;
+    }
     if (!strcmp(argv[i], "-mouse") || !strcmp(argv[i], "-pointer")) {
         if (i + 1 >= argc)
             UseMsg();
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index fd6a952..836db79 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -102,6 +102,12 @@ static int kdNumInputFds;
 
 extern Bool kdRawPointerCoordinates;
 
+extern const char *kdGlobalXkbRules;
+extern const char *kdGlobalXkbModel;
+extern const char *kdGlobalXkbLayout;
+extern const char *kdGlobalXkbVariant;
+extern const char *kdGlobalXkbOptions;
+
 static void
 KdSigio(int sig)
 {
@@ -909,11 +915,11 @@ KdNewKeyboard(void)
     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);
-    ki->xkbVariant = strdup(XKB_DFLT_VARIANT);
-    ki->xkbOptions = strdup(XKB_DFLT_OPTIONS);
+    ki->xkbRules = strdup(kdGlobalXkbRules ? kdGlobalXkbRules : XKB_DFLT_RULES);
+    ki->xkbModel = strdup(kdGlobalXkbModel ? kdGlobalXkbModel : XKB_DFLT_MODEL);
+    ki->xkbLayout = strdup(kdGlobalXkbLayout ? kdGlobalXkbLayout : XKB_DFLT_LAYOUT);
+    ki->xkbVariant = strdup(kdGlobalXkbVariant ? kdGlobalXkbVariant :XKB_DFLT_VARIANT);
+    ki->xkbOptions = strdup(kdGlobalXkbOptions ? kdGlobalXkbOptions : XKB_DFLT_OPTIONS);
 
     return ki;
 }
commit 0cf3d72be6bd99cd2c66b7885339322c7e5bf73d
Author: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
Date:   Fri Feb 12 14:17:59 2016 -0200

    kdrive: introduce input hot-plugging support for udev and hal backends (#33140)
    
    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 at redhat.com>
    Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>

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;
     }
 


More information about the xorg-commit mailing list