[gnome-control-center] wacom: Update from gnome-settings-daemon
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] wacom: Update from gnome-settings-daemon
- Date: Wed, 14 Dec 2011 18:56:04 +0000 (UTC)
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]