[gnome-control-center] wacom: Update from gnome-settings-daemon



commit 1ffb3ffdc1d598d408eee68c252c3b5dc282212f
Author: Bastien Nocera <hadess hadess net>
Date:   Wed Dec 14 18:55:43 2011 +0000

    wacom: Update from gnome-settings-daemon

 panels/wacom/gsd-input-helper.c |   63 ++++++++++++++++++
 panels/wacom/gsd-input-helper.h |    7 ++-
 panels/wacom/gsd-wacom-device.c |  135 +++++++++++++++++++++++++++++++++++++--
 panels/wacom/gsd-wacom-device.h |    2 +
 4 files changed, 199 insertions(+), 8 deletions(-)
---
diff --git a/panels/wacom/gsd-input-helper.c b/panels/wacom/gsd-input-helper.c
index 47e9931..3653ef1 100644
--- a/panels/wacom/gsd-input-helper.c
+++ b/panels/wacom/gsd-input-helper.c
@@ -289,6 +289,69 @@ out:
         return NULL;
 }
 
+#define STYLUS_DEVICE_ID        0x02
+#define ERASER_DEVICE_ID        0x0A
+
+int
+xdevice_get_last_tool_id (int deviceid)
+{
+        Atom           prop;
+        Atom           act_type;
+        int            act_format;
+        unsigned long  nitems, bytes_after;
+        unsigned char *data, *ptr;
+        int            id;
+
+        id = 0x0;
+
+        gdk_display_sync (gdk_display_get_default ());
+
+        prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), WACOM_SERIAL_IDS_PROP, False);
+        if (!prop)
+                return id;
+
+        gdk_error_trap_push ();
+
+        if (!XIGetProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+                            deviceid, prop, 0, 1000, False,
+                            AnyPropertyType, &act_type, &act_format,
+                            &nitems, &bytes_after, &data) == Success) {
+                gdk_error_trap_pop_ignored ();
+                return 0x0;
+        }
+
+        if (gdk_error_trap_pop ())
+                goto out;
+
+	if (nitems != 4)
+		goto out;
+
+	if (act_type != XA_INTEGER)
+		goto out;
+
+	if (act_format != 32)
+		goto out;
+
+	/* item 0 = tablet ID
+	 * item 1 = old device serial number (== last tool in proximity)
+	 * item 2 = old hardware serial number (including tool ID)
+	 * item 3 = current serial number (0 if no tool in proximity) */
+	ptr = data;
+	ptr += act_format/8 * 2;
+
+	id = *((int32_t*)ptr);
+	id = id & 0xfffff;
+
+	/* That means that no tool was set down yet */
+	if (id == STYLUS_DEVICE_ID ||
+	    id == ERASER_DEVICE_ID)
+		return 0x0;
+
+out:
+        XFree (data);
+        return id;
+}
+
 gboolean
 set_device_enabled (int device_id,
                     gboolean enabled)
diff --git a/panels/wacom/gsd-input-helper.h b/panels/wacom/gsd-input-helper.h
index 0bc205b..3a774ea 100644
--- a/panels/wacom/gsd-input-helper.h
+++ b/panels/wacom/gsd-input-helper.h
@@ -27,6 +27,8 @@ G_BEGIN_DECLS
 #include <X11/extensions/XInput.h>
 #include <X11/extensions/XIproto.h>
 
+#define WACOM_SERIAL_IDS_PROP "Wacom Serial IDs"
+
 typedef enum {
         COMMAND_DEVICE_ADDED,
         COMMAND_DEVICE_REMOVED,
@@ -69,8 +71,9 @@ gboolean  device_set_property     (XDevice                *xdevice,
 gboolean  run_custom_command      (GdkDevice              *device,
                                    CustomCommand           command);
 
-GList *   get_disabled_devices    (GdkDeviceManager       *manager);
-char *    xdevice_get_device_node (int                     deviceid);
+GList *   get_disabled_devices     (GdkDeviceManager       *manager);
+char *    xdevice_get_device_node  (int                     deviceid);
+int       xdevice_get_last_tool_id (int                     deviceid);
 
 G_END_DECLS
 
diff --git a/panels/wacom/gsd-wacom-device.c b/panels/wacom/gsd-wacom-device.c
index c523a1f..bddc462 100644
--- a/panels/wacom/gsd-wacom-device.c
+++ b/panels/wacom/gsd-wacom-device.c
@@ -30,6 +30,7 @@
 
 #include <libwacom/libwacom.h>
 #include <X11/extensions/XInput.h>
+#include <X11/extensions/XInput2.h>
 
 #include "gsd-input-helper.h"
 
@@ -49,6 +50,7 @@ struct GsdWacomStylusPrivate
 {
 	GsdWacomDevice *device;
 	int id;
+	WacomStylusType type;
 	char *name;
 	const char *icon_name;
 	GSettings *settings;
@@ -131,7 +133,8 @@ gsd_wacom_stylus_new (GsdWacomDevice    *device,
 	stylus->priv->id = libwacom_stylus_get_id (wstylus);
 	stylus->priv->name = g_strdup (libwacom_stylus_get_name (wstylus));
 	stylus->priv->settings = settings;
-	stylus->priv->icon_name = get_icon_name_from_type (libwacom_stylus_get_type (wstylus));
+	stylus->priv->type = libwacom_stylus_get_type (wstylus);
+	stylus->priv->icon_name = get_icon_name_from_type (stylus->priv->type);
 
 	return stylus;
 }
@@ -181,6 +184,9 @@ gsd_wacom_stylus_get_device (GsdWacomStylus *stylus)
 struct GsdWacomDevicePrivate
 {
 	GdkDevice *gdk_device;
+	int device_id;
+	int opcode;
+
 	GsdWacomDeviceType type;
 	char *name;
 	char *icon_name;
@@ -204,6 +210,76 @@ static void     gsd_wacom_device_finalize    (GObject              *object);
 
 G_DEFINE_TYPE (GsdWacomDevice, gsd_wacom_device, G_TYPE_OBJECT)
 
+static GdkFilterReturn
+filter_events (XEvent         *xevent,
+               GdkEvent       *event,
+               GsdWacomDevice *device)
+{
+	XIEvent             *xiev;
+	XIPropertyEvent     *pev;
+	XGenericEventCookie *cookie;
+	char                *name;
+	int                  tool_id;
+
+        /* verify we have a property event */
+	if (xevent->type != GenericEvent)
+		return GDK_FILTER_CONTINUE;
+
+	cookie = &xevent->xcookie;
+	if (cookie->extension != device->priv->opcode)
+		return GDK_FILTER_CONTINUE;
+
+	xiev = (XIEvent *) xevent->xcookie.data;
+
+	if (xiev->evtype != XI_PropertyEvent)
+		return GDK_FILTER_CONTINUE;
+
+	pev = (XIPropertyEvent *) xiev;
+
+	/* Is the event for us? */
+	if (pev->deviceid != device->priv->device_id)
+		return GDK_FILTER_CONTINUE;
+
+	name = XGetAtomName (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), pev->property);
+	if (name == NULL ||
+	    g_strcmp0 (name, WACOM_SERIAL_IDS_PROP) != 0) {
+		return GDK_FILTER_CONTINUE;
+	}
+	XFree (name);
+
+	tool_id = xdevice_get_last_tool_id (device->priv->device_id);
+	gsd_wacom_device_set_current_stylus (device, tool_id);
+
+	return GDK_FILTER_CONTINUE;
+}
+
+static gboolean
+setup_property_notify (GsdWacomDevice *device)
+{
+	Display *dpy;
+	XIEventMask evmask;
+	unsigned char bitmask[2] = { 0 };
+	int tool_id;
+
+	XISetMask (bitmask, XI_PropertyEvent);
+
+	evmask.deviceid = device->priv->device_id;
+	evmask.mask_len = sizeof (bitmask);
+	evmask.mask = bitmask;
+
+	dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+	XISelectEvents (dpy, DefaultRootWindow(dpy), &evmask, 1);
+
+	gdk_window_add_filter (NULL,
+			       (GdkFilterFunc) filter_events,
+			       device);
+
+	tool_id = xdevice_get_last_tool_id (device->priv->device_id);
+	gsd_wacom_device_set_current_stylus (device, tool_id);
+
+	return TRUE;
+}
+
 static GsdWacomDeviceType
 get_device_type (XDeviceInfo *dev)
 {
@@ -360,9 +436,10 @@ gsd_wacom_device_constructor (GType                     type,
                               GObjectConstructParam     *construct_properties)
 {
         GsdWacomDevice *device;
+        GdkDeviceManager *device_manager;
         XDeviceInfo *device_info;
         WacomDevice *wacom_device;
-        int n_devices, id;
+        int n_devices;
         guint i;
         char *path;
 
@@ -373,7 +450,10 @@ gsd_wacom_device_constructor (GType                     type,
 	if (device->priv->gdk_device == NULL)
 		return G_OBJECT (device);
 
-        g_object_get (device->priv->gdk_device, "device-id", &id, NULL);
+	device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
+	g_object_get (device_manager, "opcode", &device->priv->opcode, NULL);
+
+        g_object_get (device->priv->gdk_device, "device-id", &device->priv->device_id, NULL);
 
         device_info = XListInputDevices (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &n_devices);
         if (device_info == NULL) {
@@ -382,7 +462,7 @@ gsd_wacom_device_constructor (GType                     type,
 	}
 
         for (i = 0; i < n_devices; i++) {
-		if (device_info[i].id == id) {
+		if (device_info[i].id == device->priv->device_id) {
 			device->priv->type = get_device_type (&device_info[i]);
 			device->priv->tool_name = g_strdup (device_info[i].name);
 			break;
@@ -394,9 +474,9 @@ gsd_wacom_device_constructor (GType                     type,
 	if (device->priv->type == WACOM_TYPE_INVALID)
 		goto end;
 
-	path = xdevice_get_device_node (id);
+	path = xdevice_get_device_node (device->priv->device_id);
 	if (path == NULL) {
-		g_warning ("Could not get the device node path for ID '%d'", id);
+		g_warning ("Could not get the device node path for ID '%d'", device->priv->device_id);
 		device->priv->type = WACOM_TYPE_INVALID;
 		goto end;
 	}
@@ -430,6 +510,11 @@ gsd_wacom_device_constructor (GType                     type,
 	libwacom_destroy (wacom_device);
 	g_free (path);
 
+	if (device->priv->type == WACOM_TYPE_STYLUS ||
+	    device->priv->type == WACOM_TYPE_ERASER) {
+		setup_property_notify (device);
+	}
+
 end:
         return G_OBJECT (device);
 }
@@ -536,6 +621,10 @@ gsd_wacom_device_finalize (GObject *object)
         g_free (p->icon_name);
         p->icon_name = NULL;
 
+	gdk_window_remove_filter (NULL,
+				  (GdkFilterFunc) filter_events,
+				  device);
+
         G_OBJECT_CLASS (gsd_wacom_device_parent_class)->finalize (object);
 }
 
@@ -603,6 +692,40 @@ gsd_wacom_device_get_settings (GsdWacomDevice *device)
 	return device->priv->wacom_settings;
 }
 
+void
+gsd_wacom_device_set_current_stylus (GsdWacomDevice *device,
+				     int             stylus_id)
+{
+	GList *l;
+
+	g_return_if_fail (GSD_IS_WACOM_DEVICE (device));
+
+	/* Don't change anything if the stylus is already set */
+	if (device->priv->last_stylus != NULL) {
+		GsdWacomStylus *stylus = device->priv->last_stylus;
+		if (stylus->priv->id == stylus_id)
+			return;
+	}
+
+	for (l = device->priv->styli; l; l = l->next) {
+		GsdWacomStylus *stylus = l->data;
+
+		/* Set a nice default if 0x0 */
+		if (stylus_id == 0x0 &&
+		    stylus->priv->type == WSTYLUS_GENERAL) {
+			g_object_set (device, "last-stylus", stylus, NULL);
+			return;
+		}
+
+		if (stylus->priv->id == stylus_id) {
+			g_object_set (device, "last-stylus", stylus, NULL);
+			return;
+		}
+	}
+
+	g_warning ("Could not find stylus ID 0x%x for tablet '%s'", stylus_id, device->priv->name);
+}
+
 GsdWacomDeviceType
 gsd_wacom_device_get_device_type (GsdWacomDevice *device)
 {
diff --git a/panels/wacom/gsd-wacom-device.h b/panels/wacom/gsd-wacom-device.h
index ecea0ae..235e75a 100644
--- a/panels/wacom/gsd-wacom-device.h
+++ b/panels/wacom/gsd-wacom-device.h
@@ -92,6 +92,8 @@ const char     * gsd_wacom_device_get_tool_name    (GsdWacomDevice *device);
 gboolean         gsd_wacom_device_reversible       (GsdWacomDevice *device);
 gboolean         gsd_wacom_device_is_screen_tablet (GsdWacomDevice *device);
 GSettings      * gsd_wacom_device_get_settings     (GsdWacomDevice *device);
+void             gsd_wacom_device_set_current_stylus (GsdWacomDevice *device,
+						      int             stylus_id);
 
 GsdWacomDeviceType gsd_wacom_device_get_device_type (GsdWacomDevice *device);
 const char     * gsd_wacom_device_type_to_string   (GsdWacomDeviceType type);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]