Blame SOURCES/smarter-pad-osd-layout.patch

dce4b5
From aee0f01c59f407b25475ab83814a8a186bed175e Mon Sep 17 00:00:00 2001
dce4b5
From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
dce4b5
Date: Thu, 7 Apr 2016 18:45:19 +0200
dce4b5
Subject: [PATCH] wacom: rely on the SVG to get the actual position of the
dce4b5
 text, not libwacom
dce4b5
dce4b5
The problem rises up with the Wacom ExpressKey Remote (EKR). This device
dce4b5
is a separate "pad" but the Left/Right buttons do not apply for it in the
dce4b5
way the OSD relies on it.
dce4b5
dce4b5
When a pad is set to be on the left side, we align the labels from the
dce4b5
start as we are drawing them on the right. However, in the EKR case,
dce4b5
the labels from the left are drawn on the left, not the right. We can
dce4b5
not realistically infer where the text should be put from the db only,
dce4b5
so retrieve the actual style from the SVG and use that as the hint for
dce4b5
the position.
dce4b5
dce4b5
https://bugzilla.gnome.org/show_bug.cgi?id=764743
dce4b5
---
dce4b5
 configure.ac                         |  6 +++
dce4b5
 plugins/wacom/Makefile.am            |  3 ++
dce4b5
 plugins/wacom/gsd-wacom-device.c     | 84 ++++++++++++++++++++++++++++++++++--
dce4b5
 plugins/wacom/gsd-wacom-device.h     |  1 +
dce4b5
 plugins/wacom/gsd-wacom-osd-window.c |  2 +-
dce4b5
 5 files changed, 91 insertions(+), 5 deletions(-)
dce4b5
dce4b5
diff --git a/configure.ac b/configure.ac
dce4b5
index 6d9408a..c86df22 100644
dce4b5
--- a/configure.ac
dce4b5
+++ b/configure.ac
dce4b5
@@ -229,6 +229,12 @@ dnl ---------------------------------------------------------------------------
dce4b5
 
dce4b5
 PKG_CHECK_MODULES(SOUND, [libpulse >= $PA_REQUIRED_VERSION $GUDEV_PKG libpulse-mainloop-glib >= $PA_REQUIRED_VERSION])
dce4b5
 
dce4b5
+dnl ---------------------------------------------------------------------------
dce4b5
+dnl - wacom plugin stuff
dce4b5
+dnl ---------------------------------------------------------------------------
dce4b5
+
dce4b5
+PKG_CHECK_MODULES(LIBXML2, [libxml-2.0])
dce4b5
+
dce4b5
 # ---------------------------------------------------------------------------
dce4b5
 # Power
dce4b5
 # ---------------------------------------------------------------------------
dce4b5
diff --git a/plugins/wacom/Makefile.am b/plugins/wacom/Makefile.am
dce4b5
index 6274e43..324ac3a 100644
dce4b5
--- a/plugins/wacom/Makefile.am
dce4b5
+++ b/plugins/wacom/Makefile.am
dce4b5
@@ -2,6 +2,9 @@ plugin_name = wacom
dce4b5
 
dce4b5
 plugin_LTLIBRARIES = libgsdwacom.la
dce4b5
 
dce4b5
+WACOM_CFLAGS += $(LIBXML2_CFLAGS)
dce4b5
+WACOM_LIBS += $(LIBXML2_LIBS)
dce4b5
+
dce4b5
 libgsdwacom_la_SOURCES =	\
dce4b5
 	gsd-wacom-plugin.c	\
dce4b5
 	gsd-wacom-manager.h	\
dce4b5
diff --git a/plugins/wacom/gsd-wacom-device.c b/plugins/wacom/gsd-wacom-device.c
dce4b5
index 33d9cc5..813be57 100644
dce4b5
--- a/plugins/wacom/gsd-wacom-device.c
dce4b5
+++ b/plugins/wacom/gsd-wacom-device.c
dce4b5
@@ -29,6 +29,9 @@
dce4b5
 #define GNOME_DESKTOP_USE_UNSTABLE_API
dce4b5
 #include <libgnome-desktop/gnome-rr.h>
dce4b5
 
dce4b5
+#include <libxml/parser.h>
dce4b5
+#include <libxml/xpath.h>
dce4b5
+
dce4b5
 #include <libwacom/libwacom.h>
dce4b5
 #include <X11/extensions/XInput.h>
dce4b5
 #include <X11/extensions/XInput2.h>
dce4b5
@@ -254,6 +257,64 @@ gsd_wacom_stylus_get_id (GsdWacomStylus *stylus)
dce4b5
 	return stylus->priv->id;
dce4b5
 }
dce4b5
 
dce4b5
+static gboolean
dce4b5
+gsd_wacom_xpath_has_style(const char         *id,
dce4b5
+			  xmlXPathContextPtr  xpath_context,
dce4b5
+			  const char         *style)
dce4b5
+{
dce4b5
+	xmlXPathObjectPtr xpath = NULL;
dce4b5
+	gboolean ret;
dce4b5
+	char *path;
dce4b5
+
dce4b5
+	path = g_strdup_printf ("//*[@id='%s'][contains(@style, '%s')]", id, style);
dce4b5
+	xpath = xmlXPathEvalExpression ((xmlChar *)path, xpath_context);
dce4b5
+	ret = xpath && xpath->nodesetval && xpath->nodesetval->nodeNr;
dce4b5
+
dce4b5
+	g_free (path);
dce4b5
+	xmlXPathFreeObject (xpath);
dce4b5
+
dce4b5
+	return ret;
dce4b5
+}
dce4b5
+
dce4b5
+static GsdWacomTabletButtonPos
dce4b5
+gsd_wacom_device_button_draw_pos (guint                    i,
dce4b5
+				  const char              *layout_file,
dce4b5
+				  GsdWacomTabletButtonPos  db_pos)
dce4b5
+{
dce4b5
+	GsdWacomTabletButtonPos ret = WACOM_TABLET_BUTTON_POS_UNDEF;
dce4b5
+	xmlXPathContextPtr xpath_context = NULL;
dce4b5
+	xmlDocPtr doc = NULL;
dce4b5
+	char *id;
dce4b5
+
dce4b5
+	id = g_strdup_printf ("Label%c", i);
dce4b5
+
dce4b5
+	doc = xmlParseFile (layout_file);
dce4b5
+	if (!doc)
dce4b5
+		g_error ("unable to parse '%s'", layout_file);
dce4b5
+
dce4b5
+	xpath_context = xmlXPathNewContext (doc);
dce4b5
+	if (!xpath_context)
dce4b5
+		g_error ("unable to create new XPath context");
dce4b5
+
dce4b5
+	if (gsd_wacom_xpath_has_style (id, xpath_context, "text-anchor:start"))
dce4b5
+		ret = WACOM_TABLET_BUTTON_POS_LEFT;
dce4b5
+	else if (gsd_wacom_xpath_has_style (id, xpath_context, "text-anchor:end"))
dce4b5
+		ret = WACOM_TABLET_BUTTON_POS_RIGHT;
dce4b5
+	else if (gsd_wacom_xpath_has_style (id, xpath_context, "text-anchor:middle"))
dce4b5
+		ret = db_pos == WACOM_TABLET_BUTTON_POS_BOTTOM ? \
dce4b5
+			WACOM_TABLET_BUTTON_POS_BOTTOM : \
dce4b5
+			WACOM_TABLET_BUTTON_POS_TOP;
dce4b5
+
dce4b5
+	if (ret == WACOM_TABLET_BUTTON_POS_UNDEF)
dce4b5
+		ret = db_pos;
dce4b5
+
dce4b5
+	g_free (id);
dce4b5
+	xmlXPathFreeContext (xpath_context);
dce4b5
+	xmlFreeDoc (doc);
dce4b5
+
dce4b5
+	return ret;
dce4b5
+}
dce4b5
+
dce4b5
 /* Tablet buttons */
dce4b5
 static GsdWacomTabletButton *
dce4b5
 gsd_wacom_tablet_button_new (const char               *name,
dce4b5
@@ -261,6 +322,7 @@ gsd_wacom_tablet_button_new (const char               *name,
dce4b5
 			     const char               *settings_path,
dce4b5
 			     GsdWacomTabletButtonType  type,
dce4b5
 			     GsdWacomTabletButtonPos   pos,
dce4b5
+			     GsdWacomTabletButtonPos   draw_pos,
dce4b5
 			     int                       group_id,
dce4b5
 			     int                       idx,
dce4b5
 			     int                       status_led,
dce4b5
@@ -282,6 +344,7 @@ gsd_wacom_tablet_button_new (const char               *name,
dce4b5
 	ret->idx = idx;
dce4b5
 	ret->type = type;
dce4b5
 	ret->pos = pos;
dce4b5
+	ret->draw_pos = draw_pos;
dce4b5
 	ret->status_led = status_led;
dce4b5
 	ret->has_oled = has_oled;
dce4b5
 
dce4b5
@@ -1033,6 +1096,7 @@ gsd_wacom_device_add_ring_modes (WacomDevice      *wacom_device,
dce4b5
 									   settings_path,
dce4b5
 									   WACOM_TABLET_BUTTON_TYPE_RING,
dce4b5
 									   WACOM_TABLET_BUTTON_POS_LEFT,
dce4b5
+									   WACOM_TABLET_BUTTON_POS_LEFT,
dce4b5
 									   group,
dce4b5
 									   0,
dce4b5
 									   GSD_WACOM_NO_LED,
dce4b5
@@ -1046,6 +1110,7 @@ gsd_wacom_device_add_ring_modes (WacomDevice      *wacom_device,
dce4b5
 				                                                   settings_path,
dce4b5
 				                                                   WACOM_TABLET_BUTTON_TYPE_RING,
dce4b5
 										   WACOM_TABLET_BUTTON_POS_LEFT,
dce4b5
+										   WACOM_TABLET_BUTTON_POS_LEFT,
dce4b5
 				                                                   group,
dce4b5
 				                                                   i - 1,
dce4b5
 										   GSD_WACOM_NO_LED,
dce4b5
@@ -1064,6 +1129,7 @@ gsd_wacom_device_add_ring_modes (WacomDevice      *wacom_device,
dce4b5
 									   settings_path,
dce4b5
 									   WACOM_TABLET_BUTTON_TYPE_RING,
dce4b5
 									   WACOM_TABLET_BUTTON_POS_RIGHT,
dce4b5
+									   WACOM_TABLET_BUTTON_POS_RIGHT,
dce4b5
 									   group,
dce4b5
 									   0,
dce4b5
 									   GSD_WACOM_NO_LED,
dce4b5
@@ -1077,6 +1143,7 @@ gsd_wacom_device_add_ring_modes (WacomDevice      *wacom_device,
dce4b5
 				                                                   settings_path,
dce4b5
 				                                                   WACOM_TABLET_BUTTON_TYPE_RING,
dce4b5
 										   WACOM_TABLET_BUTTON_POS_RIGHT,
dce4b5
+										   WACOM_TABLET_BUTTON_POS_RIGHT,
dce4b5
 				                                                   group,
dce4b5
 				                                                   i - 1,
dce4b5
 										   GSD_WACOM_NO_LED,
dce4b5
@@ -1117,6 +1184,7 @@ gsd_wacom_device_add_strip_modes (WacomDevice      *wacom_device,
dce4b5
 									   settings_path,
dce4b5
 									   WACOM_TABLET_BUTTON_TYPE_STRIP,
dce4b5
 									   WACOM_TABLET_BUTTON_POS_LEFT,
dce4b5
+									   WACOM_TABLET_BUTTON_POS_LEFT,
dce4b5
 									   group,
dce4b5
 									   0,
dce4b5
 									   GSD_WACOM_NO_LED,
dce4b5
@@ -1130,6 +1198,7 @@ gsd_wacom_device_add_strip_modes (WacomDevice      *wacom_device,
dce4b5
 				                                                   settings_path,
dce4b5
 				                                                   WACOM_TABLET_BUTTON_TYPE_STRIP,
dce4b5
 										   WACOM_TABLET_BUTTON_POS_LEFT,
dce4b5
+										   WACOM_TABLET_BUTTON_POS_LEFT,
dce4b5
 				                                                   group,
dce4b5
 				                                                   i - 1,
dce4b5
 										   GSD_WACOM_NO_LED,
dce4b5
@@ -1148,6 +1217,7 @@ gsd_wacom_device_add_strip_modes (WacomDevice      *wacom_device,
dce4b5
 									   settings_path,
dce4b5
 									   WACOM_TABLET_BUTTON_TYPE_STRIP,
dce4b5
 									   WACOM_TABLET_BUTTON_POS_RIGHT,
dce4b5
+									   WACOM_TABLET_BUTTON_POS_RIGHT,
dce4b5
 									   group,
dce4b5
 									   0,
dce4b5
 									   GSD_WACOM_NO_LED,
dce4b5
@@ -1161,6 +1231,7 @@ gsd_wacom_device_add_strip_modes (WacomDevice      *wacom_device,
dce4b5
 				                                                   settings_path,
dce4b5
 				                                                   WACOM_TABLET_BUTTON_TYPE_STRIP,
dce4b5
 										   WACOM_TABLET_BUTTON_POS_RIGHT,
dce4b5
+										   WACOM_TABLET_BUTTON_POS_RIGHT,
dce4b5
 				                                                   group,
dce4b5
 				                                                   i - 1,
dce4b5
 										   GSD_WACOM_NO_LED,
dce4b5
@@ -1215,6 +1286,7 @@ gsd_wacom_device_button_pos (WacomButtonFlags flags)
dce4b5
 static GList *
dce4b5
 gsd_wacom_device_add_buttons_dir (WacomDevice      *wacom_device,
dce4b5
 				  const char       *settings_path,
dce4b5
+				  const char       *layout_path,
dce4b5
 				  WacomButtonFlags  direction,
dce4b5
 				  const char       *button_str_id)
dce4b5
 {
dce4b5
@@ -1260,6 +1332,7 @@ gsd_wacom_device_add_buttons_dir (WacomDevice      *wacom_device,
dce4b5
 		                                                   settings_path,
dce4b5
 		                                                   WACOM_TABLET_BUTTON_TYPE_NORMAL,
dce4b5
 		                                                   gsd_wacom_device_button_pos (flags),
dce4b5
+		                                                   gsd_wacom_device_button_draw_pos (i, layout_path, gsd_wacom_device_button_pos (flags)),
dce4b5
 		                                                   flags_to_group (flags),
dce4b5
 		                                                   -1,
dce4b5
 								   GSD_WACOM_NO_LED,
dce4b5
@@ -1289,6 +1362,7 @@ gsd_wacom_device_add_buttons_dir (WacomDevice      *wacom_device,
dce4b5
 		                                                   settings_path,
dce4b5
 		                                                   WACOM_TABLET_BUTTON_TYPE_HARDCODED,
dce4b5
 		                                                   gsd_wacom_device_button_pos (flags),
dce4b5
+		                                                   gsd_wacom_device_button_draw_pos (i, layout_path, gsd_wacom_device_button_pos (flags)),
dce4b5
 		                                                   flags_to_group (flags),
dce4b5
 		                                                   -1,
dce4b5
 		                                                   status_led,
dce4b5
@@ -1311,20 +1385,22 @@ gsd_wacom_device_add_buttons (GsdWacomDevice *device,
dce4b5
 			      WacomDevice    *wacom_device,
dce4b5
 			      const char     *settings_path)
dce4b5
 {
dce4b5
+	const char *layout_path;
dce4b5
 	GList *l, *ret;
dce4b5
 
dce4b5
 	ret = NULL;
dce4b5
+	layout_path = gsd_wacom_device_get_layout_path (device);
dce4b5
 
dce4b5
-	l = gsd_wacom_device_add_buttons_dir (wacom_device, settings_path, WACOM_BUTTON_POSITION_LEFT, "button");
dce4b5
+	l = gsd_wacom_device_add_buttons_dir (wacom_device, settings_path, layout_path, WACOM_BUTTON_POSITION_LEFT, "button");
dce4b5
 	if (l)
dce4b5
 		ret = l;
dce4b5
-	l = gsd_wacom_device_add_buttons_dir (wacom_device, settings_path, WACOM_BUTTON_POSITION_RIGHT, "button");
dce4b5
+	l = gsd_wacom_device_add_buttons_dir (wacom_device, settings_path, layout_path, WACOM_BUTTON_POSITION_RIGHT, "button");
dce4b5
 	if (l)
dce4b5
 		ret = g_list_concat (ret, l);
dce4b5
-	l = gsd_wacom_device_add_buttons_dir (wacom_device, settings_path, WACOM_BUTTON_POSITION_TOP, "button");
dce4b5
+	l = gsd_wacom_device_add_buttons_dir (wacom_device, settings_path, layout_path, WACOM_BUTTON_POSITION_TOP, "button");
dce4b5
 	if (l)
dce4b5
 		ret = g_list_concat (ret, l);
dce4b5
-	l = gsd_wacom_device_add_buttons_dir (wacom_device, settings_path, WACOM_BUTTON_POSITION_BOTTOM, "button");
dce4b5
+	l = gsd_wacom_device_add_buttons_dir (wacom_device, settings_path, layout_path, WACOM_BUTTON_POSITION_BOTTOM, "button");
dce4b5
 	if (l)
dce4b5
 		ret = g_list_concat (ret, l);
dce4b5
 
dce4b5
diff --git a/plugins/wacom/gsd-wacom-device.h b/plugins/wacom/gsd-wacom-device.h
dce4b5
index 374eca9..ef3e0a0 100644
dce4b5
--- a/plugins/wacom/gsd-wacom-device.h
dce4b5
+++ b/plugins/wacom/gsd-wacom-device.h
dce4b5
@@ -118,6 +118,7 @@ typedef struct
dce4b5
 	GSettings                *settings;
dce4b5
 	GsdWacomTabletButtonType  type;
dce4b5
 	GsdWacomTabletButtonPos   pos;
dce4b5
+	GsdWacomTabletButtonPos   draw_pos;
dce4b5
 	int                       group_id, idx;
dce4b5
 	int                       status_led;
dce4b5
 	int                       has_oled;
dce4b5
diff --git a/plugins/wacom/gsd-wacom-osd-window.c b/plugins/wacom/gsd-wacom-osd-window.c
dce4b5
index d0814b0..42efb7a 100644
dce4b5
--- a/plugins/wacom/gsd-wacom-osd-window.c
dce4b5
+++ b/plugins/wacom/gsd-wacom-osd-window.c
dce4b5
@@ -1294,7 +1294,7 @@ gsd_wacom_osd_window_add_button_with_dir (GsdWacomOSDWindow    *osd_window,
dce4b5
 	g_free (str);
dce4b5
 
dce4b5
 	gsd_wacom_osd_button_set_button_type (osd_button, tablet_button->type);
dce4b5
-	gsd_wacom_osd_button_set_position (osd_button, tablet_button->pos);
dce4b5
+	gsd_wacom_osd_button_set_position (osd_button, tablet_button->draw_pos);
dce4b5
 	osd_window->priv->buttons = g_list_append (osd_window->priv->buttons, osd_button);
dce4b5
 
dce4b5
 	return osd_button;
dce4b5
-- 
dce4b5
2.9.3
dce4b5