[gpointing-device-settings] Watch DevicePresenceNotify event.
- From: Hiroyuki Ikezoe <hiikezoe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gpointing-device-settings] Watch DevicePresenceNotify event.
- Date: Sat, 26 Jun 2010 11:00:49 +0000 (UTC)
commit ff25a24d387887bc3bbacfb5bcaf2756695df096
Author: Hiroyuki Ikezoe <hiikezoe gnome org>
Date: Sat Jun 26 19:55:40 2010 +0900
Watch DevicePresenceNotify event.
Some devices are not reported by xserver at the time of startiung up
of gnome-settings-daemon, so we need to watch DevicePresenceNotify
event at that time.
Fix for bug #609050.
.../gsd-pointing-device-plugin.c | 120 ++++++++++++++------
src/gpds-xinput-utils.c | 27 +++++
src/gpds-xinput-utils.h | 2 +
test/test-xinput-utils.c | 16 +++-
4 files changed, 131 insertions(+), 34 deletions(-)
---
diff --git a/modules/gnome-settings-daemon-plugins/gsd-pointing-device-plugin.c b/modules/gnome-settings-daemon-plugins/gsd-pointing-device-plugin.c
index 31dd336..8a2d98f 100644
--- a/modules/gnome-settings-daemon-plugins/gsd-pointing-device-plugin.c
+++ b/modules/gnome-settings-daemon-plugins/gsd-pointing-device-plugin.c
@@ -24,10 +24,13 @@
#include <gnome-settings-daemon/gnome-settings-plugin.h>
#include <glib/gi18n.h>
#include <gconf/gconf-client.h>
+#include <gdk/gdkx.h>
+#include <X11/extensions/XInput.h>
#include "gsd-pointing-device-manager.h"
#include "gpds-gconf.h"
#include "gpds-xinput-pointer-info.h"
+#include "gpds-xinput-utils.h"
#define GSD_TYPE_POINTING_DEVICE_PLUGIN (gsd_pointing_device_plugin_get_type ())
#define GSD_POINTING_DEVICE_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_POINTING_DEVICE_PLUGIN, GsdPointingDevicePlugin))
@@ -61,44 +64,90 @@ gsd_pointing_device_plugin_init (GsdPointingDevicePlugin *plugin)
plugin->managers = NULL;
}
-static GList *
-collect_pointer_device_infos_from_gconf (void)
+static gboolean
+has_manager (GsdPointingDevicePlugin *plugin, const gchar *device_name)
{
- GConfClient *gconf;
- GSList *dirs, *node;
- GList *infos = NULL;
-
- gconf = gconf_client_get_default();
- dirs = gconf_client_all_dirs(gconf, GPDS_GCONF_DIR, NULL);
-
- for (node = dirs; node; node = g_slist_next(node)) {
- const gchar *dir = node->data;
- gchar *device_type;
- gchar *device_type_key;
-
- device_type_key = gconf_concat_dir_and_key(dir, GPDS_GCONF_DEVICE_TYPE_KEY);
- device_type = gconf_client_get_string(gconf, device_type_key, NULL);
- if (device_type) {
- GpdsXInputPointerInfo *info;
- gchar *device_name, *unescaped_device_name;
-
- device_name = g_path_get_basename(dir);
- unescaped_device_name = gconf_unescape_key(device_name, -1);
- info = gpds_xinput_pointer_info_new(unescaped_device_name, device_type);
- infos = g_list_prepend(infos, info);
- g_free(unescaped_device_name);
- g_free(device_name);
+ GList *node;
+
+ for (node = plugin->managers; node; node = g_list_next(node)) {
+ GsdPointingDeviceManager *manager = node->data;
+
+ if (g_str_equal(gsd_pointing_device_manager_get_device_name(manager), device_name))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static GdkFilterReturn
+device_presence_filter (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer data)
+{
+ XEvent *xev = (XEvent *)xevent;
+ XEventClass class_presence;
+ int xi_presence;
+ GsdPointingDevicePlugin *plugin = GSD_POINTING_DEVICE_PLUGIN(data);
+
+ DevicePresence(gdk_x11_get_default_xdisplay(), xi_presence, class_presence);
+
+ if (xev->type == xi_presence) {
+ XDeviceInfo *device_info = NULL;
+ XDevicePresenceNotifyEvent *notify_event = (XDevicePresenceNotifyEvent *)xev;
+
+ device_info = gpds_xinput_utils_get_device_info_from_id(notify_event->deviceid, NULL);
+ if (notify_event->devchange == DeviceEnabled) {
+ GsdPointingDeviceManager *manager;
+
+ if (has_manager(plugin, device_info->name))
+ return GDK_FILTER_CONTINUE;
+
+ manager = gsd_pointing_device_manager_new(gdk_x11_get_xatom_name(device_info->type),
+ device_info->name);
+ if (manager) {
+ gsd_pointing_device_manager_start(manager, NULL);
+ plugin->managers = g_list_prepend(plugin->managers, manager);
+ }
+ } else if (notify_event->devchange == DeviceRemoved) {
}
+ }
- g_free(device_type_key);
- g_free(device_type);
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
+add_device_presence_filter (GsdPointingDevicePlugin *plugin)
+{
+ Display *display;
+ XEventClass class_presence;
+ gint xi_presence;
+
+ gint op_code, event, error;
+
+ if (!XQueryExtension(GDK_DISPLAY(),
+ "XInputExtension",
+ &op_code,
+ &event,
+ &error)) {
+ return;
}
- g_slist_foreach(dirs, (GFunc)g_free, NULL);
- g_slist_free(dirs);
- g_object_unref(gconf);
+ display = gdk_x11_get_default_xdisplay();
- return infos;
+ gdk_error_trap_push();
+ DevicePresence(display, xi_presence, class_presence);
+ XSelectExtensionEvent(display,
+ RootWindow(display, DefaultScreen(display)),
+ &class_presence, 1);
+ gdk_flush();
+ if (!gdk_error_trap_pop())
+ gdk_window_add_filter(NULL, device_presence_filter, plugin);
+}
+
+static void
+remove_device_presence_filter (GsdPointingDevicePlugin *plugin)
+{
+ gdk_window_remove_filter(NULL, device_presence_filter, plugin);
}
static void
@@ -109,7 +158,10 @@ activate (GnomeSettingsPlugin *plugin)
pointing_device_plugin = GSD_POINTING_DEVICE_PLUGIN(plugin);
- pointer_device_infos = collect_pointer_device_infos_from_gconf();
+ add_device_presence_filter(pointing_device_plugin);
+
+ pointer_device_infos = gpds_xinput_utils_collect_pointer_infos();
+
for (node = pointer_device_infos; node; node = g_list_next(node)) {
GsdPointingDeviceManager *manager;
GpdsXInputPointerInfo *info = node->data;
@@ -133,6 +185,8 @@ stop_all_managers (GsdPointingDevicePlugin *plugin)
{
GList *node;
+ remove_device_presence_filter(plugin);
+
for (node = plugin->managers; node; node = g_list_next(node)) {
GsdPointingDeviceManager *manager = node->data;
diff --git a/src/gpds-xinput-utils.c b/src/gpds-xinput-utils.c
index 48dc2a5..0f7ceea 100644
--- a/src/gpds-xinput-utils.c
+++ b/src/gpds-xinput-utils.c
@@ -62,6 +62,33 @@ gpds_xinput_utils_get_device_info (const gchar *device_name, GError **error)
return NULL;
}
+XDeviceInfo *
+gpds_xinput_utils_get_device_info_from_id (XID id, GError **error)
+{
+ XDeviceInfo *device_infos;
+ gint i, n_device_infos;
+
+ device_infos = XListInputDevices(GDK_DISPLAY(), &n_device_infos);
+
+ for (i = 0; i < n_device_infos; i++) {
+ if (device_infos[i].use != IsXExtensionPointer)
+ continue;
+ if (device_infos[i].id == id) {
+ XFreeDeviceList(device_infos);
+ return &device_infos[i];
+ }
+ }
+
+ XFreeDeviceList(device_infos);
+
+ g_set_error(error,
+ GPDS_XINPUT_UTILS_ERROR,
+ GPDS_XINPUT_UTILS_ERROR_NO_DEVICE,
+ _("No device found for %d."), (int)id);
+
+ return NULL;
+}
+
gshort
gpds_xinput_utils_get_device_num_buttons (const gchar *device_name, GError **error)
{
diff --git a/src/gpds-xinput-utils.h b/src/gpds-xinput-utils.h
index 9cc4564..74e491a 100644
--- a/src/gpds-xinput-utils.h
+++ b/src/gpds-xinput-utils.h
@@ -38,6 +38,8 @@ typedef enum
GQuark gpds_xinput_utils_error_quark (void);
XDeviceInfo *gpds_xinput_utils_get_device_info (const gchar *device_name,
GError **error);
+XDeviceInfo *gpds_xinput_utils_get_device_info_from_id (XID id,
+ GError **error);
XDevice *gpds_xinput_utils_open_device (const gchar *device_name, GError **error);
Atom gpds_xinput_utils_get_float_atom (GError **error);
gshort gpds_xinput_utils_get_device_num_buttons (const gchar *device_name, GError **error);
diff --git a/test/test-xinput-utils.c b/test/test-xinput-utils.c
index 29b3f4e..a06dcbc 100644
--- a/test/test-xinput-utils.c
+++ b/test/test-xinput-utils.c
@@ -6,6 +6,7 @@
void test_exist_device (void);
void test_get_float_atom (void);
void test_get_device_info (void);
+void test_get_device_info_from_id (void);
void test_open_device (void);
void test_open_no_device (void);
void test_get_device_num_buttons (void);
@@ -49,7 +50,7 @@ test_get_float_atom (void)
void
test_get_device_info (void)
{
- XDeviceInfo *device_info = NULL;
+ XDeviceInfo *device_info = NULL;
device_info = gpds_xinput_utils_get_device_info(DEVICE_NAME, &error);
cut_assert(device_info);
@@ -57,6 +58,19 @@ test_get_device_info (void)
}
void
+test_get_device_info_from_id (void)
+{
+ XDeviceInfo *device_info = NULL;
+ device_info = gpds_xinput_utils_get_device_info(DEVICE_NAME, &error);
+ cut_assert(device_info);
+
+ gcut_assert_error(error);
+
+ device_info = gpds_xinput_utils_get_device_info_from_id(device_info->id, &error);
+ cut_assert_equal_string(DEVICE_NAME, device_info->name);
+}
+
+void
test_open_device (void)
{
device = gpds_xinput_utils_open_device(DEVICE_NAME, &error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]