Blob Blame History Raw
From e71872002edec18a28ff4f2d7e197cf2d2533eeb Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Tue, 10 Oct 2017 07:57:29 -0700
Subject: [PATCH 1/4] wacom: Set combo-topbutton to current value for styli
 with > 2 buttons

Although the Wacom panel doesn't have explicit support for styli with more
than two buttons, it tries to at least allow configuration of the upper and
lower buttons. This commit fixes an incorrect conditional which prevents
the panel from setting the combo box for the upper switch to the current
setting.

https://bugzilla.gnome.org/show_bug.cgi?id=790028
---
 panels/wacom/cc-wacom-stylus-page.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/panels/wacom/cc-wacom-stylus-page.c b/panels/wacom/cc-wacom-stylus-page.c
index c3829454e..ff1ea5d13 100644
--- a/panels/wacom/cc-wacom-stylus-page.c
+++ b/panels/wacom/cc-wacom-stylus-page.c
@@ -450,7 +450,7 @@ cc_wacom_stylus_page_new (CcWacomTool *stylus)
 
 	update_stylus_ui (page, layout);
 
-	if (num_buttons == 2)
+	if (num_buttons >= 2)
 		set_button_mapping_from_gsettings (GTK_COMBO_BOX (WID ("combo-topbutton")),
 						   priv->stylus_settings, "secondary-button-action");
 	if (num_buttons >= 1)
-- 
2.17.0


From 60202dcbc4feae2543e0970f53b5cd4936abf140 Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Tue, 10 Oct 2017 07:44:02 -0700
Subject: [PATCH 2/4] wacom: Make remove_buttons dynamic

Both 'remove_buttons' and 'remove_button' perform the same general task and
can be unified into a single function. This makes supporting an arbitrary
number of stylus buttons more straightforward.

https://bugzilla.gnome.org/show_bug.cgi?id=790028
---
 panels/wacom/cc-wacom-stylus-page.c | 35 +++++++++++++----------------
 1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/panels/wacom/cc-wacom-stylus-page.c b/panels/wacom/cc-wacom-stylus-page.c
index ff1ea5d13..644d5b22a 100644
--- a/panels/wacom/cc-wacom-stylus-page.c
+++ b/panels/wacom/cc-wacom-stylus-page.c
@@ -331,20 +331,17 @@ enum {
 };
 
 static void
-remove_buttons (CcWacomStylusPagePrivate *priv)
+remove_buttons (CcWacomStylusPagePrivate *priv, int n)
 {
-	gtk_widget_destroy (WID ("combo-topbutton"));
-	gtk_widget_destroy (WID ("combo-bottombutton"));
-	gtk_widget_destroy (WID ("label-top-button"));
-	gtk_widget_destroy (WID ("label-lower-button"));
-}
-
-static void
-remove_button (CcWacomStylusPagePrivate *priv)
-{
-	gtk_widget_destroy (WID ("combo-topbutton"));
-	gtk_widget_destroy (WID ("label-top-button"));
-	gtk_label_set_text (GTK_LABEL (WID ("label-lower-button")), _("Button"));
+	if (n < 2) {
+		gtk_widget_destroy (WID ("combo-topbutton"));
+		gtk_widget_destroy (WID ("label-top-button"));
+		gtk_label_set_text (GTK_LABEL (WID ("label-lower-button")), _("Button"));
+	}
+	if (n < 1) {
+		gtk_widget_destroy (WID ("combo-bottombutton"));
+		gtk_widget_destroy (WID ("label-lower-button"));
+	}
 }
 
 static void
@@ -362,10 +359,10 @@ update_stylus_ui (CcWacomStylusPage *page,
 
 	switch (layout) {
 	case LAYOUT_NORMAL:
-		/* easy! */
+		remove_buttons (page->priv, 2);
 		break;
 	case LAYOUT_INKING:
-		remove_buttons (page->priv);
+		remove_buttons (page->priv, 0);
 		remove_eraser (page->priv);
 		gtk_container_child_set (CWID ("stylus-controls-grid"),
 					 WID ("label-tip-feel"),
@@ -375,7 +372,7 @@ update_stylus_ui (CcWacomStylusPage *page,
 					 "top_attach", 0, NULL);
 		break;
 	case LAYOUT_AIRBRUSH:
-		remove_button (page->priv);
+		remove_buttons (page->priv, 1);
 		gtk_container_child_set (CWID ("stylus-controls-grid"),
 					 WID ("label-lower-button"),
 					 "top_attach", 1, NULL);
@@ -390,6 +387,7 @@ update_stylus_ui (CcWacomStylusPage *page,
 					 "top_attach", 2, NULL);
 		break;
 	case LAYOUT_GENERIC_2_BUTTONS_NO_ERASER:
+		remove_buttons (page->priv, 2);
 		remove_eraser (page->priv);
 		break;
 	case LAYOUT_OTHER:
@@ -435,10 +433,7 @@ cc_wacom_stylus_page_new (CcWacomTool *stylus)
 		layout = LAYOUT_GENERIC_2_BUTTONS_NO_ERASER;
 	else {
 		layout = LAYOUT_OTHER;
-		if (num_buttons == 0)
-			remove_buttons (priv);
-		else if (num_buttons == 1)
-			remove_button (priv);
+		remove_buttons (priv, num_buttons);
 
 		/* Gray out eraser if not available */
 		gtk_widget_set_sensitive (WID ("eraser-box"), has_eraser);
-- 
2.17.0


From 6a39001ebcc36fd91d2afc345fa9f6f3b5a7d25b Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Tue, 10 Oct 2017 07:57:49 -0700
Subject: [PATCH 3/4] wacom: Add support for three-button styli

Wacom has introduced its new "Pro Pen 3D" stylus which includes a third
button. This commit adds support for arbitrary three-button styli.

https://bugzilla.gnome.org/show_bug.cgi?id=790028
---
 panels/wacom/cc-wacom-stylus-page.c          |  27 +++-
 panels/wacom/cc-wacom-tool.c                 |  15 +-
 panels/wacom/wacom-stylus-3btn-no-eraser.svg | 132 ++++++++++++++++++
 panels/wacom/wacom-stylus-3btn.svg           | 138 +++++++++++++++++++
 panels/wacom/wacom-stylus-page.ui            |  33 ++++-
 panels/wacom/wacom.gresource.xml             |   2 +
 6 files changed, 341 insertions(+), 6 deletions(-)
 create mode 100644 panels/wacom/wacom-stylus-3btn-no-eraser.svg
 create mode 100644 panels/wacom/wacom-stylus-3btn.svg

diff --git a/panels/wacom/cc-wacom-stylus-page.c b/panels/wacom/cc-wacom-stylus-page.c
index 644d5b22a..8adc7bca7 100644
--- a/panels/wacom/cc-wacom-stylus-page.c
+++ b/panels/wacom/cc-wacom-stylus-page.c
@@ -160,7 +160,8 @@ button_changed_cb (GtkComboBox *combo, gpointer user_data)
 	GtkTreeIter		iter;
 	GtkListStore		*liststore;
 	gint			mapping_b2,
-				mapping_b3;
+				mapping_b3,
+				mapping_b4;
 
 	if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (WID ("combo-bottombutton")), &iter))
 		return;
@@ -181,8 +182,20 @@ button_changed_cb (GtkComboBox *combo, gpointer user_data)
 		mapping_b3 = 0;
 	}
 
+	if (cc_wacom_tool_get_num_buttons (priv->stylus) > 2) {
+		if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (WID ("combo-thirdbutton")), &iter))
+			return;
+
+		gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter,
+				    BUTTONNUMBER_COLUMN, &mapping_b4,
+				    -1);
+	} else {
+		mapping_b4 = 0;
+	}
+
 	g_settings_set_enum (priv->stylus_settings, "button-action", mapping_b2);
 	g_settings_set_enum (priv->stylus_settings, "secondary-button-action", mapping_b3);
+	g_settings_set_enum (priv->stylus_settings, "tertiary-button-action", mapping_b4);
 }
 
 static void
@@ -299,6 +312,11 @@ cc_wacom_stylus_page_init (CcWacomStylusPage *self)
 	g_signal_connect (G_OBJECT (combo), "changed",
 			  G_CALLBACK (button_changed_cb), self);
 
+	combo = GTK_COMBO_BOX (WID ("combo-thirdbutton"));
+	combobox_text_cellrenderer (combo, BUTTONNAME_COLUMN);
+	g_signal_connect (G_OBJECT (combo), "changed",
+			  G_CALLBACK (button_changed_cb), self);
+
 	priv->nav = cc_wacom_nav_button_new ();
         gtk_widget_set_halign (priv->nav, GTK_ALIGN_END);
         gtk_widget_set_margin_start (priv->nav, 10);
@@ -333,6 +351,10 @@ enum {
 static void
 remove_buttons (CcWacomStylusPagePrivate *priv, int n)
 {
+	if (n < 3) {
+		gtk_widget_destroy (WID ("combo-thirdbutton"));
+		gtk_widget_destroy (WID ("label-third-button"));
+	}
 	if (n < 2) {
 		gtk_widget_destroy (WID ("combo-topbutton"));
 		gtk_widget_destroy (WID ("label-top-button"));
@@ -445,6 +467,9 @@ cc_wacom_stylus_page_new (CcWacomTool *stylus)
 
 	update_stylus_ui (page, layout);
 
+	if (num_buttons >= 3)
+		set_button_mapping_from_gsettings (GTK_COMBO_BOX (WID ("combo-thirdbutton")),
+						   priv->stylus_settings, "tertiary-button-action");
 	if (num_buttons >= 2)
 		set_button_mapping_from_gsettings (GTK_COMBO_BOX (WID ("combo-topbutton")),
 						   priv->stylus_settings, "secondary-button-action");
diff --git a/panels/wacom/cc-wacom-tool.c b/panels/wacom/cc-wacom-tool.c
index 21050875d..7c74e93e5 100644
--- a/panels/wacom/cc-wacom-tool.c
+++ b/panels/wacom/cc-wacom-tool.c
@@ -253,9 +253,18 @@ get_icon_name_from_type (const WacomStylus *wstylus)
 	case WSTYLUS_CLASSIC:
 		return "wacom-stylus-classic";
 	default:
-		if (!libwacom_stylus_has_eraser (wstylus))
-			return "wacom-stylus-no-eraser";
-		return "wacom-stylus";
+		if (!libwacom_stylus_has_eraser (wstylus)) {
+			if (libwacom_stylus_get_num_buttons (wstylus) >= 3)
+				return "wacom-stylus-3btn-no-eraser";
+			else
+				return "wacom-stylus-no-eraser";
+		}
+		else {
+			if (libwacom_stylus_get_num_buttons (wstylus) >= 3)
+				return "wacom-stylus-3btn";
+			else
+				return "wacom-stylus";
+		}
 	}
 }
 
diff --git a/panels/wacom/wacom-stylus-3btn-no-eraser.svg b/panels/wacom/wacom-stylus-3btn-no-eraser.svg
new file mode 100644
index 000000000..60642d7bb
--- /dev/null
+++ b/panels/wacom/wacom-stylus-3btn-no-eraser.svg
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg86343"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   width="148"
+   height="192"
+   sodipodi:docname="wacom-stylus-3btn-no-eraser.svg">
+  <metadata
+     id="metadata86349">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs86347" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="960"
+     inkscape:window-height="1014"
+     id="namedview86345"
+     showgrid="false"
+     inkscape:snap-nodes="false"
+     inkscape:snap-bbox="true"
+     inkscape:zoom="2.4748737"
+     inkscape:cx="176.8759"
+     inkscape:cy="81.687362"
+     inkscape:window-x="1920"
+     inkscape:window-y="27"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="g10631"
+     borderlayer="true"
+     inkscape:showpageshadow="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid86802"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true" />
+  </sodipodi:namedview>
+  <g
+     style="display:inline"
+     transform="translate(592.43375,-287.62088)"
+     id="g10545">
+    <path
+       sodipodi:nodetypes="cscscccccccccccccscscc"
+       inkscape:connector-curvature="0"
+       id="rect10526"
+       transform="translate(-928.4063,-95.84375)"
+       d="m 344.125,384.88832 c -1.9944,0 -3.59375,1.59935 -3.59375,3.59375 L 340.53125,516 338,545.125 c -0.1873,2.15512 1.62589,3.92035 3.75,4.125 l 4.625,10.90625 1.53125,0 0,2.15625 3.61536,8.57242 1.18546,0.0214 0.44918,3.78119 0.33938,-3.7414 1.14797,-0.0687 3.76265,-8.53366 0,-2.1875 1.53125,0 4.65625,-10.96875 c 1.96694,-0.35188 3.54637,-2.02216 3.40625,-4.0625 L 365.53125,516 l 0,-127.51793 c 0,-1.9944 -1.59935,-3.59375 -3.59375,-3.59375 z"
+       style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
+    <rect
+       style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="rect10541"
+       width="8.75"
+       height="22"
+       x="-579.65631"
+       y="385.90625"
+       rx="3.25"
+       ry="3.25" />
+    <rect
+       style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="rect10543"
+       width="8.75"
+       height="12.25"
+       x="-579.65631"
+       y="410.90625"
+       rx="3.25"
+       ry="3.2500002" />
+    <rect
+       style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="rect10544"
+       width="8.75"
+       height="8.75"
+       x="-579.65631"
+       y="429.15625"
+       rx="3.25"
+       ry="3.2500002" />
+  </g>
+  <g
+     style="opacity:0.2;display:inline"
+     id="g10631"
+     transform="translate(592.43375,-302.48416)">
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m -571.1563,413.06786 35.28033,0 0,-89.17947 82.46967,0"
+       id="path3342"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m -571.1563,430.06786 48.28033,0 0,-64.17947 69.46967,0"
+       id="path3344"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m -571.1563,448.31786 61.28033,0 0,-40.43396 56.46967,0"
+       id="path3344"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m -575.4063,492.06786 78.53033,0 0,-43.17947 43.46967,0"
+       id="path10629"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+  </g>
+</svg>
diff --git a/panels/wacom/wacom-stylus-3btn.svg b/panels/wacom/wacom-stylus-3btn.svg
new file mode 100644
index 000000000..2f3db9aa4
--- /dev/null
+++ b/panels/wacom/wacom-stylus-3btn.svg
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg86343"
+   version="1.1"
+   inkscape:version="0.48.2 r9819"
+   width="148"
+   height="192"
+   sodipodi:docname="wacom-stylus-3btn.svg">
+  <metadata
+     id="metadata86349">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs86347" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1280"
+     inkscape:window-height="742"
+     id="namedview86345"
+     showgrid="false"
+     inkscape:snap-nodes="false"
+     inkscape:snap-bbox="true"
+     inkscape:zoom="7"
+     inkscape:cx="93.888956"
+     inkscape:cy="186.10424"
+     inkscape:window-x="0"
+     inkscape:window-y="26"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg86343"
+     borderlayer="true"
+     inkscape:showpageshadow="false">
+    <inkscape:grid
+       type="xygrid"
+       id="grid86802"
+       empspacing="5"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true" />
+  </sodipodi:namedview>
+  <g
+     style="display:inline"
+     transform="translate(592.43375,-287.62088)"
+     id="g10545">
+    <path
+       sodipodi:nodetypes="sscsscscccccccccccccscsscsss"
+       inkscape:connector-curvature="0"
+       id="rect10526"
+       transform="translate(-928.4063,-95.84375)"
+       d="m 349.69531,384.96463 c -2.3083,0 -3.2326,1.49535 -3.69531,4.51323 L 345.53125,396 344.125,396 c -1.9944,0 -3.59375,1.59935 -3.59375,3.59375 L 340.53125,516 338,545.125 c -0.1873,2.15512 1.62589,3.92035 3.75,4.125 l 4.625,10.90625 1.53125,0 0,2.15625 3.61536,8.57242 1.18546,0.0214 0.44918,3.78119 0.33938,-3.7414 1.14797,-0.0687 3.76265,-8.53366 0,-2.1875 1.53125,0 4.65625,-10.96875 c 1.96694,-0.35188 3.54637,-2.02216 3.40625,-4.0625 L 365.53125,516 l 0,-116.40625 c 0,-1.9944 -1.59935,-3.59375 -3.59375,-3.59375 l -1.40625,0 L 360,389.47786 c -0.23272,-2.85711 -1.26201,-4.51323 -3.69531,-4.51323 z"
+       style="color:#000000;fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+    <rect
+       style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="rect10541"
+       width="8.75"
+       height="22"
+       x="-579.65631"
+       y="385.90625"
+       rx="3.25"
+       ry="3.25" />
+    <rect
+       style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="rect10543"
+       width="8.75"
+       height="12.25"
+       x="-579.65631"
+       y="410.90625"
+       rx="3.25"
+       ry="3.2500002" />
+    <rect
+       style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="rect10544"
+       width="8.75"
+       height="8.75"
+       x="-579.65631"
+       y="429.15625"
+       rx="3.25"
+       ry="3.2500002" />
+  </g>
+  <g
+     style="opacity:0.2;display:inline"
+     id="g10631"
+     transform="translate(592.43375,-302.48416)">
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m -568.1563,309.03125 32.25,0 0,14.85714 82.5,0"
+       id="path10556"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m -571.1563,413.06786 35.28033,0 0,-52.14286 82.46967,0"
+       id="path10552"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m -571.1563,430.06786 48.28033,0 0,-27.14286 69.46967,0"
+       id="path86913"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m -571.1563,448.31786 61.28033,0 0,-3.39286 56.46967,0"
+       id="path3344"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       d="m -575.4063,492.06786 78.53033,0 0,-5.14286 43.46967,0"
+       id="path10629"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+  </g>
+</svg>
diff --git a/panels/wacom/wacom-stylus-page.ui b/panels/wacom/wacom-stylus-page.ui
index 6e3cbfb02..b6f152d7f 100644
--- a/panels/wacom/wacom-stylus-page.ui
+++ b/panels/wacom/wacom-stylus-page.ui
@@ -290,6 +290,35 @@
                 <property name="top_attach">2</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkLabel" id="label-third-button">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="valign">center</property>
+                <property name="label" translatable="yes">Lowest Button</property>
+                <property name="justify">right</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">3</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkComboBox" id="combo-thirdbutton">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="valign">center</property>
+                <property name="model">liststore-buttons</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">3</property>
+              </packing>
+            </child>
             <child>
               <object class="GtkLabel" id="label-tip-feel">
                 <property name="visible">True</property>
@@ -304,7 +333,7 @@
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">3</property>
+                <property name="top_attach">4</property>
               </packing>
             </child>
             <child>
@@ -360,7 +389,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">3</property>
+                <property name="top_attach">4</property>
               </packing>
             </child>
           </object>
diff --git a/panels/wacom/wacom.gresource.xml b/panels/wacom/wacom.gresource.xml
index 7683b4d38..a18ffb1ed 100644
--- a/panels/wacom/wacom.gresource.xml
+++ b/panels/wacom/wacom.gresource.xml
@@ -6,6 +6,8 @@
     <file preprocess="xml-stripblanks">button-mapping.ui</file>
     <file>wacom-tablet.svg</file>
     <file>wacom-stylus.svg</file>
+    <file>wacom-stylus-3btn-no-eraser.svg</file>
+    <file>wacom-stylus-3btn.svg</file>
     <file>wacom-stylus-no-eraser.svg</file>
     <file>wacom-stylus-airbrush.svg</file>
     <file>wacom-stylus-inking.svg</file>
-- 
2.17.0


From c65f5feb695e7c6737aa60c6e96086e58aa43244 Mon Sep 17 00:00:00 2001
From: Jason Gerecke <killertofu@gmail.com>
Date: Tue, 10 Oct 2017 07:56:17 -0700
Subject: [PATCH 4/4] wacom: Support the WSTYLUS_3D stylus type

Wacom's new "Pro Pen 3D" stylus is declared as a new stylus type within
libwacom: WSTYLUS_3D. Now that the Wacom panel supports arbitrary three-
button styli, we can add specific support for this new stylus type to
suppress the warning message that is generated.

https://bugzilla.gnome.org/show_bug.cgi?id=790028
---
 panels/wacom/cc-wacom-stylus-page.c | 7 +++++++
 panels/wacom/cc-wacom-tool.c        | 6 ++++++
 2 files changed, 13 insertions(+)

diff --git a/panels/wacom/cc-wacom-stylus-page.c b/panels/wacom/cc-wacom-stylus-page.c
index 8adc7bca7..56aeeef3a 100644
--- a/panels/wacom/cc-wacom-stylus-page.c
+++ b/panels/wacom/cc-wacom-stylus-page.c
@@ -345,6 +345,7 @@ enum {
 	LAYOUT_INKING,                      /* tip */
 	LAYOUT_AIRBRUSH,                    /* eraser, 1 button, tip */
 	LAYOUT_GENERIC_2_BUTTONS_NO_ERASER, /* 2 buttons, tip, no eraser */
+	LAYOUT_3DPEN,                       /* 3 buttons, tip, no eraser */
 	LAYOUT_OTHER
 };
 
@@ -412,6 +413,10 @@ update_stylus_ui (CcWacomStylusPage *page,
 		remove_buttons (page->priv, 2);
 		remove_eraser (page->priv);
 		break;
+	case LAYOUT_3DPEN:
+		remove_buttons (page->priv, 3);
+		remove_eraser (page->priv);
+		break;
 	case LAYOUT_OTHER:
 		/* We already warn about it in cc_wacom_stylus_page_new () */
 		break;
@@ -453,6 +458,8 @@ cc_wacom_stylus_page_new (CcWacomTool *stylus)
 		layout = LAYOUT_AIRBRUSH;
 	else if (num_buttons == 2 && !has_eraser)
 		layout = LAYOUT_GENERIC_2_BUTTONS_NO_ERASER;
+	else if (num_buttons == 3 && !has_eraser)
+		layout = LAYOUT_3DPEN;
 	else {
 		layout = LAYOUT_OTHER;
 		remove_buttons (priv, num_buttons);
diff --git a/panels/wacom/cc-wacom-tool.c b/panels/wacom/cc-wacom-tool.c
index 7c74e93e5..1330c8dc8 100644
--- a/panels/wacom/cc-wacom-tool.c
+++ b/panels/wacom/cc-wacom-tool.c
@@ -18,8 +18,12 @@
  *
  */
 
+#include "config.h"
+
 #include "cc-wacom-tool.h"
 
+#define WSTYLUS_3D 8
+
 enum {
 	PROP_0,
 	PROP_SERIAL,
@@ -252,6 +256,8 @@ get_icon_name_from_type (const WacomStylus *wstylus)
 		return "wacom-stylus-art-pen";
 	case WSTYLUS_CLASSIC:
 		return "wacom-stylus-classic";
+	case WSTYLUS_3D:
+		return "wacom-stylus-3btn-no-eraser";
 	default:
 		if (!libwacom_stylus_has_eraser (wstylus)) {
 			if (libwacom_stylus_get_num_buttons (wstylus) >= 3)
-- 
2.17.0