xserver: Branch 'master' - 2 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Dec 30 16:59:47 PST 2009


 config/Makefile.am              |   20 ++-
 config/config-backends.h        |   21 ++-
 config/config.c                 |   77 +++++++++++
 config/hal.c                    |   63 ---------
 config/udev.c                   |  260 ++++++++++++++++++++++++++++++++++++++++
 configure.ac                    |   23 +++
 hw/kdrive/src/kinput.c          |    8 +
 hw/xfree86/common/xf86Config.c  |   15 +-
 hw/xfree86/common/xf86Globals.c |    2 
 hw/xfree86/common/xf86Xinput.c  |   25 ++-
 include/dix-config.h.in         |    3 
 11 files changed, 426 insertions(+), 91 deletions(-)

New commits:
commit 435f27667f84269768efecde34de4af2b2d43376
Author: Julien Cristau <jcristau at debian.org>
Date:   Sun Sep 27 14:45:47 2009 +0200

    config: add libudev input-hotplug backend
    
    Add a backend using libudev for input hotplug, and disable the hal and
    dbus backends if this one is enabled.
    
    XKB configuration happens using xkb{rules,model,layout,variant,options}
    properties (case-insensitive) on the device.  We fill in InputAttributes
    to allow configuration through InputClass in Xorg.
    
    Requires udev 148 for the input_id helper and ID_INPUT* properties.
    
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    Acked-by: Dan Nicholson <dbn.lists at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/config/Makefile.am b/config/Makefile.am
index 7fa2df8..27f251b 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -1,12 +1,20 @@
-AM_CFLAGS = @DIX_CFLAGS@
+AM_CFLAGS = $(DIX_CFLAGS)
 
 noinst_LTLIBRARIES = libconfig.la
 libconfig_la_SOURCES = config.c config-backends.h
 
+if CONFIG_UDEV
+
+AM_CFLAGS += $(UDEV_CFLAGS)
+libconfig_la_SOURCES += udev.c
+libconfig_la_LIBADD = $(UDEV_LIBS)
+
+else
+
 if CONFIG_NEED_DBUS
-AM_CFLAGS += @DBUS_CFLAGS@
+AM_CFLAGS += $(DBUS_CFLAGS)
 libconfig_la_SOURCES += dbus-core.c
-endif
+libconfig_la_LIBADD = $(DBUS_LIBS)
 
 if CONFIG_DBUS_API
 dbusconfigdir = $(sysconfdir)/dbus-1/system.d
@@ -16,7 +24,13 @@ libconfig_la_SOURCES += dbus.c
 endif
 
 if CONFIG_HAL
+AM_CFLAGS += $(HAL_CFLAGS)
 libconfig_la_SOURCES += hal.c
+libconfig_la_LIBADD += $(HAL_LIBS)
 endif
 
+endif # CONFIG_NEED_DBUS
+
+endif # !CONFIG_UDEV
+
 EXTRA_DIST = xorg-server.conf x11-input.fdi
diff --git a/config/config-backends.h b/config/config-backends.h
index 907e86b..0a2a22a 100644
--- a/config/config-backends.h
+++ b/config/config-backends.h
@@ -26,8 +26,18 @@
 #ifdef HAVE_DIX_CONFIG_H
 #include <dix-config.h>
 #endif
+#include "input.h"
 
-#ifdef CONFIG_NEED_DBUS
+void remove_devices(const char *backend, const char *config_info);
+BOOL device_is_duplicate(const char *config_info);
+void add_option(InputOption **options, const char *key, const char *value);
+
+#ifdef CONFIG_UDEV
+int config_udev_init(void);
+void config_udev_fini(void);
+#else
+
+# ifdef CONFIG_NEED_DBUS
 #include <dbus/dbus.h>
 
 typedef void (*config_dbus_core_connect_hook)(DBusConnection *connection,
@@ -46,14 +56,15 @@ int config_dbus_core_init(void);
 void config_dbus_core_fini(void);
 int config_dbus_core_add_hook(struct config_dbus_core_hook *hook);
 void config_dbus_core_remove_hook(struct config_dbus_core_hook *hook);
-#endif
+# endif
 
-#ifdef CONFIG_DBUS_API
+# ifdef CONFIG_DBUS_API
 int config_dbus_init(void);
 void config_dbus_fini(void);
-#endif
+# endif
 
-#ifdef CONFIG_HAL
+# ifdef CONFIG_HAL
 int config_hal_init(void);
 void config_hal_fini(void);
+# endif
 #endif
diff --git a/config/config.c b/config/config.c
index b013293..7bf5e41 100644
--- a/config/config.c
+++ b/config/config.c
@@ -28,13 +28,17 @@
 #endif
 
 #include "os.h"
+#include "inputstr.h"
 #include "hotplug.h"
 #include "config-backends.h"
 
 void
 config_init(void)
 {
-#if defined(CONFIG_DBUS_API) || defined(CONFIG_HAL)
+#ifdef CONFIG_UDEV
+    if (!config_udev_init())
+        ErrorF("[config] failed to initialise udev\n");
+#elif defined(CONFIG_NEED_DBUS)
     if (config_dbus_core_init()) {
 # ifdef CONFIG_DBUS_API
        if (!config_dbus_init())
@@ -54,7 +58,9 @@ config_init(void)
 void
 config_fini(void)
 {
-#if defined(CONFIG_DBUS_API) || defined(CONFIG_HAL)
+#if defined(CONFIG_UDEV)
+    config_udev_fini();
+#elif defined(CONFIG_NEED_DBUS)
 # ifdef CONFIG_HAL
     config_hal_fini();
 # endif
@@ -64,3 +70,70 @@ config_fini(void)
     config_dbus_core_fini();
 #endif
 }
+
+static void
+remove_device(const char *backend, DeviceIntPtr dev)
+{
+    /* this only gets called for devices that have already been added */
+    LogMessage(X_INFO, "config/%s: removing device %s\n", backend, dev->name);
+
+    /* Call PIE here so we don't try to dereference a device that's
+     * already been removed. */
+    OsBlockSignals();
+    ProcessInputEvents();
+    DeleteInputDeviceRequest(dev);
+    OsReleaseSignals();
+}
+
+void
+remove_devices(const char *backend, const char *config_info)
+{
+    DeviceIntPtr dev, next;
+
+    for (dev = inputInfo.devices; dev; dev = next) {
+        next = dev->next;
+        if (dev->config_info && strcmp(dev->config_info, config_info) == 0)
+            remove_device(backend, dev);
+    }
+    for (dev = inputInfo.off_devices; dev; dev = next) {
+        next = dev->next;
+        if (dev->config_info && strcmp(dev->config_info, config_info) == 0)
+            remove_device(backend, dev);
+    }
+}
+
+BOOL
+device_is_duplicate(const char *config_info)
+{
+    DeviceIntPtr dev;
+
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+        if (dev->config_info && (strcmp(dev->config_info, config_info) == 0))
+            return TRUE;
+    }
+
+    for (dev = inputInfo.off_devices; dev; dev = dev->next)
+    {
+        if (dev->config_info && (strcmp(dev->config_info, config_info) == 0))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+void
+add_option(InputOption **options, const char *key, const char *value)
+{
+    if (!value || *value == '\0')
+        return;
+
+    for (; *options; options = &(*options)->next)
+        ;
+    *options = xcalloc(sizeof(**options), 1);
+    if (!*options) /* Yeesh. */
+        return;
+    (*options)->key = xstrdup(key);
+    (*options)->value = xstrdup(value);
+    (*options)->next = NULL;
+}
diff --git a/config/hal.c b/config/hal.c
index 6bebbdf..1b01ecc 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -58,25 +58,9 @@ struct xkb_options {
     char* options;
 };
 
-
-static void
-remove_device(DeviceIntPtr dev)
-{
-    /* this only gets called for devices that have already been added */
-    LogMessage(X_INFO, "config/hal: removing device %s\n", dev->name);
-
-    /* Call PIE here so we don't try to dereference a device that's
-     * already been removed. */
-    OsBlockSignals();
-    ProcessInputEvents();
-    DeleteInputDeviceRequest(dev);
-    OsReleaseSignals();
-}
-
 static void
 device_removed(LibHalContext *ctx, const char *udi)
 {
-    DeviceIntPtr dev, next;
     char *value;
 
     value = xalloc(strlen(udi) + 5); /* "hal:" + NULL */
@@ -84,36 +68,11 @@ device_removed(LibHalContext *ctx, const char *udi)
         return;
     sprintf(value, "hal:%s", udi);
 
-    for (dev = inputInfo.devices; dev; dev = next) {
-	next = dev->next;
-        if (dev->config_info && strcmp(dev->config_info, value) == 0)
-            remove_device(dev);
-    }
-    for (dev = inputInfo.off_devices; dev; dev = next) {
-	next = dev->next;
-        if (dev->config_info && strcmp(dev->config_info, value) == 0)
-            remove_device(dev);
-    }
+    remove_devices("hal", value);
 
     xfree(value);
 }
 
-static void
-add_option(InputOption **options, const char *key, const char *value)
-{
-    if (!value || *value == '\0')
-        return;
-
-    for (; *options; options = &(*options)->next)
-        ;
-    *options = xcalloc(sizeof(**options), 1);
-    if (!*options) /* Yeesh. */
-        return;
-    (*options)->key = xstrdup(key);
-    (*options)->value = xstrdup(value);
-    (*options)->next = NULL;
-}
-
 static char *
 get_prop_string(LibHalContext *hal_ctx, const char *udi, const char *name)
 {
@@ -166,26 +125,6 @@ get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop)
     return ret;
 }
 
-static BOOL
-device_is_duplicate(char *config_info)
-{
-    DeviceIntPtr dev;
-
-    for (dev = inputInfo.devices; dev; dev = dev->next)
-    {
-        if (dev->config_info && (strcmp(dev->config_info, config_info) == 0))
-            return TRUE;
-    }
-
-    for (dev = inputInfo.off_devices; dev; dev = dev->next)
-    {
-        if (dev->config_info && (strcmp(dev->config_info, config_info) == 0))
-            return TRUE;
-    }
-
-    return FALSE;
-}
-
 static void
 device_added(LibHalContext *hal_ctx, const char *udi)
 {
diff --git a/config/udev.c b/config/udev.c
new file mode 100644
index 0000000..3ef0d7f
--- /dev/null
+++ b/config/udev.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright © 2009 Julien Cristau
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Julien Cristau <jcristau at debian.org>
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <libudev.h>
+
+#include "input.h"
+#include "inputstr.h"
+#include "hotplug.h"
+#include "config-backends.h"
+#include "os.h"
+
+#define UDEV_XKB_PROP_KEY "xkb"
+
+static struct udev_monitor *udev_monitor;
+
+static void
+device_added(struct udev_device *udev_device)
+{
+    const char *path, *name = NULL;
+    char *config_info = NULL;
+    const char *syspath;
+    const char *key, *value, *tmp;
+    InputOption *options = NULL, *tmpo;
+    InputAttributes attrs = {};
+    DeviceIntPtr dev = NULL;
+    struct udev_list_entry *set, *entry;
+    struct udev_device *parent;
+    int rc;
+
+    path = udev_device_get_devnode(udev_device);
+
+    syspath = udev_device_get_syspath(udev_device);
+
+    if (!path || !syspath)
+        return;
+
+    if (!udev_device_get_property_value(udev_device, "ID_INPUT"))
+        return;
+
+    options = xcalloc(sizeof(*options), 1);
+    if (!options)
+        return;
+
+    options->key = xstrdup("_source");
+    options->value = xstrdup("server/udev");
+    if (!options->key || !options->value)
+        goto unwind;
+
+    parent = udev_device_get_parent(udev_device);
+    if (parent)
+        name = udev_device_get_property_value(parent, "NAME");
+    if (!name)
+        name = "(unnamed)";
+    else
+        attrs.product = name;
+    add_option(&options, "name", name);
+
+    add_option(&options, "path", path);
+    add_option(&options, "device", path);
+    attrs.device = path;
+
+    config_info = Xprintf("udev:%s", syspath);
+    if (!config_info)
+        goto unwind;
+
+    if (device_is_duplicate(config_info)) {
+        LogMessage(X_WARNING, "config/udev: device %s already added. "
+                              "Ignoring.\n", name);
+        goto unwind;
+    }
+
+    set = udev_device_get_properties_list_entry(udev_device);
+    udev_list_entry_foreach(entry, set) {
+        key = udev_list_entry_get_name(entry);
+        if (!key)
+            continue;
+        value = udev_list_entry_get_value(entry);
+        if (!strncasecmp(key, UDEV_XKB_PROP_KEY,
+                                sizeof(UDEV_XKB_PROP_KEY) - 1)) {
+            tmp = key + sizeof(UDEV_XKB_PROP_KEY) - 1;
+            if (!strcasecmp(tmp, "rules"))
+                add_option(&options, "xkb_rules", value);
+            else if (!strcasecmp(tmp, "layout"))
+                add_option(&options, "xkb_layout", value);
+            else if (!strcasecmp(tmp, "variant"))
+                add_option(&options, "xkb_variant", value);
+            else if (!strcasecmp(tmp, "model"))
+                add_option(&options, "xkb_model", value);
+            else if (!strcasecmp(tmp, "options"))
+                add_option(&options, "xkb_options", value);
+        } else if (!strcmp(key, "ID_VENDOR")) {
+            attrs.vendor = value;
+        } else if (!strcmp(key, "ID_INPUT_KEY")) {
+            attrs.flags |= ATTR_KEYBOARD;
+        } else if (!strcmp(key, "ID_INPUT_MOUSE")) {
+            attrs.flags |= ATTR_POINTER;
+        } else if (!strcmp(key, "ID_INPUT_JOYSTICK")) {
+            attrs.flags |= ATTR_JOYSTICK;
+        } else if (!strcmp(key, "ID_INPUT_TABLET")) {
+            attrs.flags |= ATTR_TABLET;
+        } else if (!strcmp(key, "ID_INPUT_TOUCHPAD")) {
+            attrs.flags |= ATTR_TOUCHPAD;
+        } else if (!strcmp(key, "ID_INPUT_TOUCHSCREEN")) {
+            attrs.flags |= ATTR_TOUCHSCREEN;
+        }
+    }
+    LogMessage(X_INFO, "config/udev: Adding input device %s (%s)\n",
+               name, path);
+    rc = NewInputDeviceRequest(options, &attrs, &dev);
+    if (rc != Success)
+        goto unwind;
+
+    for (; dev; dev = dev->next) {
+        xfree(dev->config_info);
+        dev->config_info = xstrdup(config_info);
+    }
+
+ unwind:
+    xfree(config_info);
+    while (!dev && (tmpo = options)) {
+        options = tmpo->next;
+        xfree(tmpo->key);
+        xfree(tmpo->value);
+        xfree(tmpo);
+    }
+
+    return;
+}
+
+static void
+device_removed(struct udev_device *device)
+{
+    char *value;
+    const char *syspath = udev_device_get_syspath(device);
+
+    value = Xprintf("udev:%s", syspath);
+    if (!value)
+        return;
+
+    remove_devices("udev", value);
+
+    xfree(value);
+}
+
+static void
+wakeup_handler(pointer data, int err, pointer read_mask)
+{
+    int udev_fd = udev_monitor_get_fd(udev_monitor);
+    struct udev_device *udev_device;
+    const char *action;
+
+    if (err < 0)
+        return;
+
+    if (FD_ISSET(udev_fd, (fd_set *)read_mask)) {
+        udev_device = udev_monitor_receive_device(udev_monitor);
+        if (!udev_device)
+            return;
+        action = udev_device_get_action(udev_device);
+        if (action) {
+            if (!strcmp(action, "add"))
+                device_added(udev_device);
+            else if (!strcmp(action, "remove"))
+                device_removed(udev_device);
+        }
+        udev_device_unref(udev_device);
+    }
+}
+
+static void
+block_handler(pointer data, struct timeval **tv, pointer read_mask)
+{
+}
+
+int
+config_udev_init(void)
+{
+    struct udev *udev;
+    struct udev_enumerate *enumerate;
+    struct udev_list_entry *devices, *device;
+    int rc;
+
+    udev = udev_new();
+    if (!udev)
+        return 0;
+    udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
+    if (!udev_monitor)
+        return 0;
+    rc = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor,
+                                                         "input", NULL);
+    if (rc < 0)
+        return 0;
+
+    if (udev_monitor_enable_receiving(udev_monitor)) {
+        ErrorF("config/udev: failed to bind the udev monitor\n");
+        return 0;
+    }
+
+    enumerate = udev_enumerate_new(udev);
+    if (!enumerate)
+        return 0;
+    udev_enumerate_add_match_subsystem(enumerate, "input");
+    udev_enumerate_scan_devices(enumerate);
+    devices = udev_enumerate_get_list_entry(enumerate);
+    udev_list_entry_foreach(device, devices) {
+        const char *syspath = udev_list_entry_get_name(device);
+        struct udev_device *udev_device = udev_device_new_from_syspath(udev, syspath);
+        device_added(udev_device);
+        udev_device_unref(udev_device);
+    }
+    udev_enumerate_unref(enumerate);
+
+    RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
+    AddGeneralSocket(udev_monitor_get_fd(udev_monitor));
+
+    return 1;
+}
+
+void
+config_udev_fini(void)
+{
+    struct udev *udev;
+
+    if (!udev_monitor)
+        return;
+
+    udev = udev_monitor_get_udev(udev_monitor);
+
+    RemoveGeneralSocket(udev_monitor_get_fd(udev_monitor));
+    RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, udev_monitor);
+    udev_monitor_unref(udev_monitor);
+    udev_monitor = NULL;
+    udev_unref(udev);
+}
diff --git a/configure.ac b/configure.ac
index e5eb380..7e2c6a5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -618,6 +618,7 @@ AC_ARG_ENABLE(multibuffer,    AS_HELP_STRING([--enable-multibuffer], [Build Mult
 AC_ARG_ENABLE(dbe,            AS_HELP_STRING([--disable-dbe], [Build DBE extension (default: enabled)]), [DBE=$enableval], [DBE=yes])
 AC_ARG_ENABLE(xf86bigfont,    AS_HELP_STRING([--disable-xf86bigfont], [Build XF86 Big Font extension (default: disabled)]), [XF86BIGFONT=$enableval], [XF86BIGFONT=no])
 AC_ARG_ENABLE(dpms,           AS_HELP_STRING([--disable-dpms], [Build DPMS extension (default: enabled)]), [DPMSExtension=$enableval], [DPMSExtension=yes])
+AC_ARG_ENABLE(config-udev,    AS_HELP_STRING([--enable-config-udev], [Build udev support (default: no)]), [CONFIG_UDEV=$enableval], [CONFIG_UDEV=no])
 AC_ARG_ENABLE(config-dbus,    AS_HELP_STRING([--enable-config-dbus], [Build D-BUS API support (default: no)]), [CONFIG_DBUS_API=$enableval], [CONFIG_DBUS_API=no])
 AC_ARG_ENABLE(config-hal,     AS_HELP_STRING([--disable-config-hal], [Build HAL support (default: auto)]), [CONFIG_HAL=$enableval], [CONFIG_HAL=auto])
 AC_ARG_ENABLE(xfree86-utils,     AS_HELP_STRING([--enable-xfree86-utils], [Build xfree86 DDX utilities (default: enabled)]), [XF86UTILS=$enableval], [XF86UTILS=yes])
@@ -775,6 +776,26 @@ LIBXI="xi >= 1.2.99.1"
 LIBXTST="xtst >= 1.0.99.2"
 LIBPCIACCESS="pciaccess >= 0.8.0"
 LIBGLIB="glib-2.0 >= 2.16"
+LIBUDEV="libudev >= 143"
+
+if test "x$CONFIG_UDEV" = xyes &&
+ { test "x$CONFIG_DBUS_API" = xyes || test "x$CONFIG_HAL" = xyes; }; then
+	AC_MSG_ERROR([Hotplugging through both libudev and dbus/hal not allowed])
+fi
+
+PKG_CHECK_MODULES(UDEV, $LIBUDEV, [HAVE_LIBUDEV=yes], [HAVE_LIBUDEV=no])
+if test "x$CONFIG_UDEV" = xauto; then
+	CONFIG_UDEV="$HAVE_LIBUDEV"
+fi
+AM_CONDITIONAL(CONFIG_UDEV, [test "x$CONFIG_UDEV" = xyes])
+if test "x$CONFIG_UDEV" = xyes; then
+	CONFIG_DBUS_API=no
+	CONFIG_HAL=no
+	if ! test "x$HAVE_LIBUDEV" = xyes; then
+		AC_MSG_ERROR([udev configuration API requested, but libudev is not installed])
+	fi
+	AC_DEFINE(CONFIG_UDEV, 1, [Use libudev for input hotplug])
+fi
 
 dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
 dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config
@@ -808,13 +829,11 @@ if test "x$CONFIG_HAL" = xyes; then
 	fi
 
 	AC_DEFINE(CONFIG_HAL, 1, [Use the HAL hotplug API])
-        REQUIRED_LIBS="$REQUIRED_LIBS hal"
 	CONFIG_NEED_DBUS="yes"
 fi
 AM_CONDITIONAL(CONFIG_HAL, [test "x$CONFIG_HAL" = xyes])
 
 if test "x$CONFIG_NEED_DBUS" = xyes; then
-	REQUIRED_LIBS="$REQUIRED_LIBS dbus-1"
         AC_DEFINE(CONFIG_NEED_DBUS, 1, [Use D-Bus for input hotplug])
 fi
 AM_CONDITIONAL(CONFIG_NEED_DBUS, [test "x$CONFIG_NEED_DBUS" = xyes])
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index c084591..09b5d3b 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -2281,6 +2281,14 @@ NewInputDeviceRequest(InputOption *options, InputAttributes *attrs,
             return BadValue;
         }
 #endif
+#ifdef CONFIG_UDEV
+        else if (strcmp(option->key, "_source") == 0 &&
+                 strcmp(option->value, "server/udev") == 0)
+        {
+            ErrorF("Ignoring device from udev.\n");
+            return BadValue;
+        }
+#endif
     }
 
     if (!ki && !pi) {
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 56ab2ee..1abc182 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1461,12 +1461,19 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
     }
 
     if (xf86Info.allowEmptyInput && !(foundPointer && foundKeyboard)) {
-#ifdef CONFIG_HAL
-	xf86Msg(X_INFO, "The server relies on HAL to provide the list of "
+#if defined(CONFIG_HAL) || defined(CONFIG_UDEV)
+	const char *config_backend;
+#if defined(CONFIG_HAL)
+	config_backend = "HAL";
+#else
+	config_backend = "udev";
+#endif
+	xf86Msg(X_INFO, "The server relies on %s to provide the list of "
 	                "input devices.\n\tIf no devices become available, "
-	                "reconfigure HAL or disable AutoAddDevices.\n");
+	                "reconfigure %s or disable AutoAddDevices.\n",
+			config_backend, config_backend);
 #else
-	xf86Msg(X_INFO, "HAL is disabled and no input devices were configured.\n"
+	xf86Msg(X_INFO, "Hotplugging is disabled and no input devices were configured.\n"
 			"\tTry disabling AllowEmptyInput.\n");
 #endif
     }
diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
index 317b78a..8b483f3 100644
--- a/hw/xfree86/common/xf86Globals.c
+++ b/hw/xfree86/common/xf86Globals.c
@@ -132,7 +132,7 @@ xf86InfoRec xf86Info = {
     .kbdCustomKeycodes          = FALSE,
     .disableRandR               = FALSE,
     .randRFrom                  = X_DEFAULT,
-#ifdef CONFIG_HAL
+#if defined(CONFIG_HAL) || defined(CONFIG_UDEV)
     .allowEmptyInput            = TRUE,
     .autoAddDevices             = TRUE,
     .autoEnableDevices          = TRUE
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 87b5100..57db056 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -692,9 +692,9 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
             }
         }
 
-        /* Right now, the only automatic config we know of is HAL. */
         if (strcmp(option->key, "_source") == 0 &&
-            strcmp(option->value, "server/hal") == 0) {
+            (strcmp(option->value, "server/hal") == 0 ||
+             strcmp(option->value, "server/udev") == 0)) {
             is_auto = 1;
             if (!xf86Info.autoAddDevices) {
                 rval = BadMatch;
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index ab04414..84c78db 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -399,6 +399,9 @@
 /* Support D-Bus */
 #undef HAVE_DBUS
 
+/* Use libudev for input hotplug */
+#undef CONFIG_UDEV
+
 /* Use D-Bus for input hotplug */
 #undef CONFIG_NEED_DBUS
 
commit b8b12e41c453c3bf94b11e7a18934d3b6e1869bf
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Dec 23 16:05:16 2009 +1000

    xfree86: move sanity checks below option and input classes merges.
    
    While the identifier is likely set before the input classes are merged, the
    driver may not be. Hence don't check for a driver before we've completed
    configuration for this device.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dan Nicholson <dbn.lists at gmail.com>
    Signed-off-by: Julien Cristau <jcristau at debian.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index e0c7830..87b5100 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -702,16 +702,6 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
             }
         }
     }
-    if (!idev->driver || !idev->identifier) {
-        xf86Msg(X_ERROR, "No input driver/identifier specified (ignoring)\n");
-        rval = BadRequest;
-        goto unwind;
-    }
-
-    if (!idev->identifier) {
-        xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n");
-        return BadMatch;
-    }
 
     for (option = options; option; option = option->next) {
         /* Steal option key/value strings from the provided list.
@@ -729,6 +719,17 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
             goto unwind;
     }
 
+    if (!idev->driver || !idev->identifier) {
+        xf86Msg(X_ERROR, "No input driver/identifier specified (ignoring)\n");
+        rval = BadRequest;
+        goto unwind;
+    }
+
+    if (!idev->identifier) {
+        xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n");
+        return BadMatch;
+    }
+
     rval = xf86NewInputDevice(idev, pdev,
                 (!is_auto || (is_auto && xf86Info.autoEnableDevices)));
     if (rval == Success)


More information about the xorg-commit mailing list