i have succeeded in modifying xorg-server-1.7.6
to do away with hal and use udev.
i decide to do this until nvidia supports xorg-server-1.8
ebuild;
# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/x11-base/xorg-server/xorg-server-1.7.6.ebuild,v 1.1 2010/03/17 15:35:54 scarabeus Exp $
EAPI="2"
# Must be before x-modular eclass is inherited
SNAPSHOT="yes"
inherit x-modular multilib versionator
EGIT_REPO_URI="git://anongit.freedesktop.org/git/xorg/xserver"
OPENGL_DIR="xorg-x11"
DESCRIPTION="X.Org X servers"
KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~mips ~ppc ~ppc64 ~sh ~sparc ~x86 ~x86-fbsd"
IUSE_SERVERS="dmx kdrive xorg"
IUSE="${IUSE_SERVERS} tslib udev ipv6 minimal nptl sdl"
RDEPEND="udev? ( sys-fs/udev [extras])
tslib? ( >=x11-libs/tslib-1.0 x11-proto/xcalibrateproto )
dev-libs/openssl
>=x11-libs/libXfont-1.3.3
>=x11-libs/xtrans-1.2.2
>=x11-libs/libXau-1.0.4
>=x11-libs/libxkbfile-1.0.4
>=x11-libs/libXdmcp-1.0.2
>=x11-libs/libpciaccess-0.10.3
>=x11-libs/pixman-0.15.20
media-libs/freetype
>=x11-misc/xbitmaps-1.0.1
>=x11-misc/xkeyboard-config-1.4
x11-apps/xkbcomp
>=x11-apps/iceauth-1.0.2
>=x11-apps/rgb-1.0.3
>=x11-apps/xauth-1.0.3
>=x11-apps/xinit-1.0.8-r3
>=app-admin/eselect-opengl-1.0.8
dmx? (
x11-libs/libXt
>=x11-libs/libdmx-1.0.99.1
>=x11-libs/libX11-1.1.5
>=x11-libs/libXaw-1.0.4
>=x11-libs/libXext-1.0.5
>=x11-libs/libXfixes-4.0.3
>=x11-libs/libXi-1.2.99.1
>=x11-libs/libXmu-1.0.3
>=x11-libs/libXtst-1.0.3
)
!minimal? (
>=x11-libs/libX11-1.1.5
>=x11-libs/libXext-1.0.5
>=x11-libs/libXres-1.0.3
>=media-libs/mesa-7.4[nptl=]
)
>=x11-libs/libxkbui-1.0.2
kdrive? (
>=x11-libs/libXext-1.0.5
sdl? ( media-libs/libsdl ) )"
# Xres is dmx-dependent
# Xaw is dmx-dependent
# Xpm is dmx-dependent, pulls in Xt
# xkbcomp is launched at startup but not checked by ./configure
## Deps that don't have a version in configure.ac but do here:
# x11-proto/resourceproto
# x11-proto/fontsproto
# x11-libs/libXau
# x11-libs/libXfont
# x11-libs/libXdmcp
# x11-libs/libXext
# x11-libs/libX11
# x11-libs/libXrender
# x11-libs/libXmu
# x11-libs/libXfixes
# x11-libs/libXtst
# x11-proto/xineramaproto
# x11-proto/dmxproto
## Deps that are larger here than in configure.ac
# x11-libs/libpciaccess-0.8.0
#
DEPEND="${RDEPEND}
!!net-dialup/dtrace
sys-devel/flex
>=x11-proto/randrproto-1.2.99.3
>=x11-proto/renderproto-0.11
>=x11-proto/fixesproto-4.1
>=x11-proto/damageproto-1.1
>=x11-proto/xextproto-7.0.99.3
>=x11-proto/xproto-7.0.13
>=x11-proto/xf86dgaproto-2.0.99.1
>=x11-proto/xf86rushproto-1.1.2
>=x11-proto/xf86vidmodeproto-2.2.99.1
>=x11-proto/compositeproto-0.4
>=x11-proto/recordproto-1.13.99.1
>=x11-proto/resourceproto-1.0.2
>=x11-proto/videoproto-2.2.2
>=x11-proto/scrnsaverproto-1.1
>=x11-proto/trapproto-3.4.3
>=x11-proto/xineramaproto-1.1.3
>=x11-proto/fontsproto-2.0.2
>=x11-proto/kbproto-1.0.3
>=x11-proto/inputproto-1.9.99.902
>=x11-proto/bigreqsproto-1.1.0
>=x11-proto/xcmiscproto-1.2.0
>=x11-proto/glproto-1.4.9
dmx? ( >=x11-proto/dmxproto-2.2.99.1 )
!minimal? (
>=x11-proto/xf86driproto-2.1.0
>=x11-proto/dri2proto-2.1
>=x11-libs/libdrm-2.3.0
)"
PDEPEND="xorg? ( >=x11-base/xorg-drivers-$(get_version_component_range 1-2) )"
EPATCH_FORCE="yes"
EPATCH_SUFFIX="patch"
# These have been sent upstream
UPSTREAMED_PATCHES=(
#"${WORKDIR}/patches/"
# Fix from bug
http://bugs.freedesktop.org/show_bug.cgi?id=25400
"${FILESDIR}/1.7.3.901-0001-dix-if-owner-events-is-true-for-passive-grabs-add-th.patch"
# Fix for bug #304067
"${FILESDIR}/1.7.5.902-fix-tslib-1.0-check.patch"
"${FILESDIR}/add-libudev-input-hotplug-backend.patch"
)
PATCHES=(
"${UPSTREAMED_PATCHES[@]}"
)
pkg_setup() {
use minimal || ensure_a_server_is_building
# SDL only available in kdrive build
if use kdrive && use sdl; then
conf_opts="${conf_opts} --enable-xsdl"
else
conf_opts="${conf_opts} --disable-xsdl"
fi
# localstatedir is used for the log location; we need to override the default
# from ebuild.sh
# sysconfdir is used for the xorg.conf location; same applies
# --enable-install-setuid needed because sparcs default off
CONFIGURE_OPTIONS="
$(use_enable ipv6)
$(use_enable dmx)
$(use_enable kdrive)
$(use_enable tslib)
$(use_enable tslib xcalibrate)
$(use_enable !minimal xvfb)
$(use_enable !minimal xnest)
$(use_enable !minimal record)
$(use_enable !minimal xfree86-utils)
$(use_enable !minimal install-libxf86config)
$(use_enable !minimal dri)
$(use_enable !minimal dri2)
$(use_enable !minimal glx)
$(use_enable xorg)
$(use_enable nptl glx-tls)
$(use_enable udev config-udev)
--sysconfdir=/etc/X11
--localstatedir=/var
--enable-install-setuid
--with-fontdir=/usr/share/fonts
--with-xkb-output=/var/lib/xkb
--without-dtrace
${conf_opts}"
# (#121394) Causes window corruption
filter-flags -fweb
# Incompatible with GCC 3.x SSP on x86, bug #244352
if use x86 ; then
if [[ $(gcc-major-version) -lt 4 ]]; then
filter-flags -fstack-protector
fi
fi
OLD_IMPLEM="$(eselect opengl show)"
eselect opengl set ${OPENGL_DIR}
}
src_install() {
x-modular_src_install
dynamic_libgl_install
server_based_install
if ! use minimal && use xorg; then
# Install xorg.conf.example (see bugs #151421 and #151670)
insinto /etc/X11
doins hw/xfree86/xorg.conf.example \
|| die "couldn't install xorg.conf.example"
fi
}
pkg_postinst() {
switch_opengl_implem
echo
ewarn "You must rebuild all drivers if upgrading from xorg-server 1.6"
ewarn "or earlier, because the ABI changed. If you cannot start X because"
ewarn "of module version mismatch errors, this is your problem."
echo
ewarn "You can generate a list of all installed packages in the x11-drivers"
ewarn "category using this command:"
ewarn "emerge portage-utils; qlist -I -C x11-drivers/"
ebeep 5
epause 10
}
pkg_postrm() {
# Get rid of module dir to ensure opengl-update works properly
if ! has_version x11-base/xorg-server; then
if [[ -e ${ROOT}/usr/$(get_libdir)/xorg/modules ]]; then
rm -rf "${ROOT}"/usr/$(get_libdir)/xorg/modules
fi
fi
}
dynamic_libgl_install() {
# next section is to setup the dynamic libGL stuff
ebegin "Moving GL files for dynamic switching"
dodir /usr/$(get_libdir)/opengl/${OPENGL_DIR}/extensions
local x=""
for x in "${D}"/usr/$(get_libdir)/xorg/modules/extensions/lib{glx,dri,dri2}*; do
if [ -f ${x} -o -L ${x} ]; then
mv -f ${x} "${D}"/usr/$(get_libdir)/opengl/${OPENGL_DIR}/extensions
fi
done
eend 0
}
server_based_install() {
if ! use xorg; then
rm "${D}"/usr/share/man/man1/Xserver.1x \
"${D}"/usr/$(get_libdir)/xserver/SecurityPolicy \
"${D}"/usr/$(get_libdir)/pkgconfig/xorg-server.pc \
"${D}"/usr/share/man/man1/Xserver.1x
fi
}
switch_opengl_implem() {
# Switch to the xorg implementation.
# Use new opengl-update that will not reset user selected
# OpenGL interface ...
echo
eselect opengl set ${OLD_IMPLEM}
}
ensure_a_server_is_building() {
for server in ${IUSE_SERVERS}; do
use ${server} && return;
done
eerror "You need to specify at least one server to build."
eerror "Valid servers are: ${IUSE_SERVERS}."
die "No servers were specified to build."
}
patch from archlinux;
From 3cc8c2a137f931639a409769305c6d65068f25e2 Mon Sep 17 00:00:00 2001
From: Julien Cristau <
jcristau@debian.org>
Date: Sun, 27 Sep 2009 12:45:47 +0000
Subject: Add libudev input-hotplug backend v4
If libudev is found, we use that for hotplug and disable the hal and
dbus backends.
We look for event devices with an "x11_driver" property. XKB
configuration happens using xkb{rules,model,layout,variant,options}
properties. Arbitrary driver options can be set with a "x11_options."
prefix.
Signed-off-by: Julien Cristau <
jcristau@debian.org>
Tested-by: Peter Hutterer <
peter.hutterer@who-t.net>
Reviewed-by: Peter Hutterer <
peter.hutterer@who-t.net>
--
changes from v3:
- fixup for devices without "name" property
- squash patch to turn config/udev off by default
- change "action" handling as requested by Peter
---
diff --git a/config/Makefile.am b/config/Makefile.am
index 7fa2df8..8c57948 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -3,10 +3,18 @@ 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@
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 28f55a0..22af10f 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..90e8e0b
--- a/dev/null
+++ b/config/udev.c
@@ -0,0 +1,245 @@
+/*
+ * 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@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"
+#define UDEV_PROP_KEY "x11_options."
+
+static struct udev_monitor *udev_monitor;
+
+static void
+device_added(struct udev_device *udev_device)
+{
+ const char *path = NULL, *driver = NULL, *name = NULL;
+ char *config_info = NULL;
+ const char *syspath;
+ const char *key, *value, *tmp;
+ InputOption *options = NULL, *tmpo;
+ DeviceIntPtr dev = NULL;
+ struct udev_list_entry *set, *entry;
+ struct udev_device *parent;
+ int rc;
+
+ driver = udev_device_get_property_value(udev_device, "x11_driver");
+
+ path = udev_device_get_devnode(udev_device);
+
+ syspath = udev_device_get_syspath(udev_device);
+
+ parent = udev_device_get_parent(udev_device);
+ if (parent)
+ name = udev_device_get_property_value(parent, "NAME");
+ if (!name)
+ name = "(unnamed)";
+
+ if (!driver || !path || !syspath)
+ 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;
+
+ add_option(&options, "path", path);
+ add_option(&options, "device", path);
+ add_option(&options, "driver", driver);
+
+ 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;
+ if (!strncasecmp(key, UDEV_PROP_KEY, sizeof(UDEV_PROP_KEY) - 1)) {
+ value = udev_list_entry_get_value(entry);
+ add_option(&options, key + sizeof(UDEV_PROP_KEY) - 1, value);
+ } else if (!strncasecmp(key, UDEV_XKB_PROP_KEY,
+ sizeof(UDEV_XKB_PROP_KEY) - 1)) {
+ tmp = key + sizeof(UDEV_XKB_PROP_KEY) - 1;
+ value = udev_list_entry_get_value(entry);
+ 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);
+ }
+ }
+ add_option(&options, "name", name);
+ LogMessage(X_INFO, "config/udev: Adding input device %s (%s)\n",
+ name, path);
+ rc = NewInputDeviceRequest(options, &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/config/x11-input.rules b/config/x11-input.rules
new file mode 100644
index 0000000..a0b9e5e
--- a/dev/null
+++ b/config/x11-input.rules
@@ -0,0 +1,14 @@
+SUBSYSTEM!="input", GOTO="x11_input_end"
+ACTION!="change|add", GOTO="x11_input_end"
+KERNEL!="event*", GOTO="x11_input_end"
+
+# use the evdev driver by default
+ENV{x11_driver}="evdev"
+
+# set xkb layout if we have keys
+ENV{ID_INPUT_KEY}=="?*", ENV{xkblayout}="us"
+
+# use synaptics for touchpads
+ENV{ID_INPUT_TOUCHPAD}=="?*", ENV{x11_driver}="synaptics"
+
+LABEL="x11_input_end"
diff --git a/configure.ac b/configure.ac
index fe28a07..801acef 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 @@ LIBXTST="xtst >= 1.0.99.2"
LIBPCIACCESS="pciaccess >= 0.8.0"
LIBGLIB="glib-2.0 >= 2.16"
LIBSELINUX="libselinux >= 2.0.86"
+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 65fc75a..2d37a84 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -2280,6 +2280,14 @@ NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev)
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 6fbf613..d19c9a4 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1444,12 +1444,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 98f8284..bc59f3b 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 f637cfe..36c7552 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -605,9 +605,9 @@ NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev)
}
}
- /* 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 1096371..8da3a2c 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -396,6 +396,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
--
cgit v0.8.3-6-g21f6
From 3fad969a90ccab604359ec4de05e745bb4b909e1 Mon Sep 17 00:00:00 2001
From: Julien Cristau <
jcristau@debian.org>
Date: Sun, 06 Dec 2009 19:27:06 +0000
Subject: Move config_init() after CreateWellKnownSockets() and InitCoreDevices()
config_init() can now add devices directly instead of scheduling a
timer.
Signed-off-by: Julien Cristau <
jcristau@debian.org>
Reviewed-by: Peter Hutterer <
peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <
peter.hutterer@who-t.net>
---
diff --git a/dix/main.c b/dix/main.c
index f96245a..2117a1e 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -168,7 +168,6 @@ int main(int argc, char *argv[], char *envp[])
InitBlockAndWakeupHandlers();
/* Perform any operating system dependent initializations you'd like */
OsInit();
- config_init();
if(serverGeneration == 1)
{
CreateWellKnownSockets();
@@ -254,6 +253,7 @@ int main(int argc, char *argv[], char *envp[])
InitRootWindow(WindowTable
);
InitCoreDevices();
+ config_init();
InitInput(argc, argv);
InitAndStartDevices();
--
cgit v0.8.3-6-g21f6
i have this in /etc/udev.d/rules as 75-x11-input-rules;
SUBSYSTEM!="input", GOTO="x11_input_end"
ACTION!="change|add", GOTO="x11_input_end"
KERNEL!="event*", GOTO="x11_input_end"
# use the evdev driver by default
ENV{x11_driver}="evdev"
# set xkb layout if we have keys
ENV{ID_INPUT_KEY}=="?*", ENV{xkblayout}="it"
LABEL="x11_input_end"
this is a strange strange world.