aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/config/hal.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2009-07-25 19:39:46 +0000
committermarha <marha@users.sourceforge.net>2009-07-25 19:39:46 +0000
commit4a3dbb926ae3f5410198d7cc4f4ebe4f62eebf05 (patch)
treec1e02b9d3509aa97703aa4b540d4cd22ec4600ed /xorg-server/config/hal.c
parentdc3c299dd0995549e2a6973ca0f25b254afd38a5 (diff)
downloadvcxsrv-4a3dbb926ae3f5410198d7cc4f4ebe4f62eebf05.tar.gz
vcxsrv-4a3dbb926ae3f5410198d7cc4f4ebe4f62eebf05.tar.bz2
vcxsrv-4a3dbb926ae3f5410198d7cc4f4ebe4f62eebf05.zip
Added xorg-server-1.6.2.tar.gz
Diffstat (limited to 'xorg-server/config/hal.c')
-rw-r--r--xorg-server/config/hal.c120
1 files changed, 110 insertions, 10 deletions
diff --git a/xorg-server/config/hal.c b/xorg-server/config/hal.c
index 639e0ec2b..36fa839fb 100644
--- a/xorg-server/config/hal.c
+++ b/xorg-server/config/hal.c
@@ -120,7 +120,7 @@ get_prop_string(LibHalContext *hal_ctx, const char *udi, const char *name)
char *prop, *ret;
prop = libhal_device_get_property_string(hal_ctx, udi, name, NULL);
- LogMessageVerb(X_INFO, 10, "config/hal: getting %s on %s returned %s\n", name, udi, prop);
+ LogMessageVerb(X_INFO, 10, "config/hal: getting %s on %s returned %s\n", name, udi, prop ? prop : "(null)");
if (prop) {
ret = xstrdup(prop);
libhal_free_string(prop);
@@ -191,9 +191,10 @@ device_added(LibHalContext *hal_ctx, const char *udi)
{
char *path = NULL, *driver = NULL, *name = NULL, *config_info = NULL;
InputOption *options = NULL, *tmpo = NULL;
- DeviceIntPtr dev;
+ DeviceIntPtr dev = NULL;
DBusError error;
struct xkb_options xkb_opts = {0};
+ int rc;
LibHalPropertySet *set = NULL;
LibHalPropertySetIterator set_iter;
@@ -399,8 +400,8 @@ device_added(LibHalContext *hal_ctx, const char *udi)
/* this isn't an error, but how else do you output something that the user can see? */
LogMessage(X_INFO, "config/hal: Adding input device %s\n", name);
- if (NewInputDeviceRequest(options, &dev) != Success) {
- LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed\n");
+ if ((rc = NewInputDeviceRequest(options, &dev)) != Success) {
+ LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed (%d)\n", rc);
dev = NULL;
goto unwind;
}
@@ -466,11 +467,10 @@ disconnect_hook(void *data)
info->system_bus = NULL;
}
-static void
-connect_hook(DBusConnection *connection, void *data)
+static BOOL
+connect_and_register(DBusConnection *connection, struct config_hal_info *info)
{
DBusError error;
- struct config_hal_info *info = data;
char **devices;
int num_devices, i;
@@ -478,8 +478,10 @@ connect_hook(DBusConnection *connection, void *data)
dbus_error_init(&error);
- if (!info->hal_ctx)
- info->hal_ctx = libhal_ctx_new();
+ if (info->hal_ctx)
+ return TRUE; /* already registered, pretend we did something */
+
+ info->hal_ctx = libhal_ctx_new();
if (!info->hal_ctx) {
LogMessage(X_ERROR, "config/hal: couldn't create HAL context\n");
goto out_err;
@@ -511,7 +513,7 @@ connect_hook(DBusConnection *connection, void *data)
dbus_error_free(&error);
- return;
+ return TRUE;
out_ctx2:
if (!libhal_ctx_shutdown(info->hal_ctx, &error))
@@ -525,6 +527,104 @@ out_err:
info->hal_ctx = NULL;
info->system_bus = NULL;
+ return FALSE;
+}
+
+
+/**
+ * Handle NewOwnerChanged signals to deal with HAL startup at X server runtime.
+ *
+ * NewOwnerChanged is send once when HAL shuts down, and once again when it
+ * comes back up. Message has three arguments, first is the name
+ * (org.freedesktop.Hal), the second one is the old owner, third one is new
+ * owner.
+ */
+static DBusHandlerResult
+ownerchanged_handler(DBusConnection *connection, DBusMessage *message, void *data)
+{
+ int ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ if (dbus_message_is_signal(message,
+ "org.freedesktop.DBus",
+ "NameOwnerChanged")) {
+ DBusError error;
+ char *name, *old_owner, *new_owner;
+
+ dbus_error_init(&error);
+ dbus_message_get_args(message, &error,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &old_owner,
+ DBUS_TYPE_STRING, &new_owner,
+ DBUS_TYPE_INVALID);
+
+ if (dbus_error_is_set(&error)) {
+ ErrorF("[config/hal] failed to get NameOwnerChanged args: %s (%s)\n",
+ error.name, error.message);
+ } else if (name && strcmp(name, "org.freedesktop.Hal") == 0) {
+
+ if (!old_owner || !strlen(old_owner)) {
+ DebugF("[config/hal] HAL startup detected.\n");
+ if (connect_and_register(connection, (struct config_hal_info*)data))
+ dbus_connection_unregister_object_path(connection,
+ "/org/freedesktop/DBus");
+ else
+ ErrorF("[config/hal] Failed to connect to HAL bus.\n");
+ }
+
+ ret = DBUS_HANDLER_RESULT_HANDLED;
+ }
+ dbus_error_free(&error);
+ }
+
+ return ret;
+}
+
+/**
+ * Register a handler for the NameOwnerChanged signal.
+ */
+static BOOL
+listen_for_startup(DBusConnection *connection, void *data)
+{
+ DBusObjectPathVTable vtable = { .message_function = ownerchanged_handler, };
+ DBusError error;
+ const char MATCH_RULE[] = "sender='org.freedesktop.DBus',"
+ "interface='org.freedesktop.DBus',"
+ "type='signal',"
+ "path='/org/freedesktop/DBus',"
+ "member='NameOwnerChanged'";
+ int rc = FALSE;
+
+ dbus_error_init(&error);
+ dbus_bus_add_match(connection, MATCH_RULE, &error);
+ if (!dbus_error_is_set(&error)) {
+ if (dbus_connection_register_object_path(connection,
+ "/org/freedesktop/DBus",
+ &vtable,
+ data))
+ rc = TRUE;
+ else
+ ErrorF("[config/hal] cannot register object path.\n");
+ } else {
+ ErrorF("[config/hal] couldn't add match rule: %s (%s)\n", error.name,
+ error.message);
+ ErrorF("[config/hal] cannot detect a HAL startup.\n");
+ }
+
+ dbus_error_free(&error);
+
+ return rc;
+}
+
+static void
+connect_hook(DBusConnection *connection, void *data)
+{
+ struct config_hal_info *info = data;
+
+ if (listen_for_startup(connection, data) &&
+ connect_and_register(connection, info))
+ dbus_connection_unregister_object_path(connection,
+ "/org/freedesktop/DBus");
+
return;
}