Blame SOURCES/legacy-x11-input-configuration.patch

1a7f9f
From 705818340dec181335b48ab73d6411e639daaeae Mon Sep 17 00:00:00 2001
1a7f9f
From: Carlos Garnacho <carlosg@gnome.org>
1a7f9f
Date: Tue, 1 Jun 2021 11:44:20 +0200
1a7f9f
Subject: [PATCH 1/6] backends/x11: Support synaptics configuration
1a7f9f
1a7f9f
The code is taken mostly as-is from g-s-d, so we can drag the
1a7f9f
dead horse a bit longer.
1a7f9f
---
1a7f9f
 src/backends/x11/meta-input-settings-x11.c | 275 +++++++++++++++++++++
1a7f9f
 1 file changed, 275 insertions(+)
1a7f9f
1a7f9f
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
1a7f9f
index 96390285a6..0631fd2fee 100644
1a7f9f
--- a/src/backends/x11/meta-input-settings-x11.c
1a7f9f
+++ b/src/backends/x11/meta-input-settings-x11.c
1a7f9f
@@ -26,6 +26,7 @@
1a7f9f
 #include "backends/x11/meta-input-settings-x11.h"
1a7f9f
 
1a7f9f
 #include <gdk/gdkx.h>
1a7f9f
+#include <stdlib.h>
1a7f9f
 #include <string.h>
1a7f9f
 #include <X11/Xatom.h>
1a7f9f
 #include <X11/extensions/XInput2.h>
1a7f9f
@@ -165,6 +166,184 @@ change_property (ClutterInputDevice *device,
1a7f9f
   meta_XFree (data_ret);
1a7f9f
 }
1a7f9f
 
1a7f9f
+static gboolean
1a7f9f
+is_device_synaptics (ClutterInputDevice *device)
1a7f9f
+{
1a7f9f
+  guchar *has_setting;
1a7f9f
+
1a7f9f
+  /* We just need looking for a synaptics-specific property */
1a7f9f
+  has_setting = get_property (device, "Synaptics Off", XA_INTEGER, 8, 1);
1a7f9f
+  if (!has_setting)
1a7f9f
+    return FALSE;
1a7f9f
+
1a7f9f
+  meta_XFree (has_setting);
1a7f9f
+  return TRUE;
1a7f9f
+}
1a7f9f
+
1a7f9f
+static void
1a7f9f
+change_synaptics_tap_left_handed (ClutterInputDevice *device,
1a7f9f
+                                  gboolean            tap_enabled,
1a7f9f
+                                  gboolean            left_handed)
1a7f9f
+{
1a7f9f
+  MetaDisplay *display = meta_get_display ();
1a7f9f
+  MetaX11Display *x11_display = display ? display->x11_display : NULL;
1a7f9f
+  MetaBackend *backend = meta_get_backend ();
1a7f9f
+  Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
1a7f9f
+  int device_id;
1a7f9f
+  XDevice *xdevice;
1a7f9f
+  guchar *tap_action, *buttons;
1a7f9f
+  guint buttons_capacity = 16, n_buttons;
1a7f9f
+
1a7f9f
+  device_id = meta_input_device_x11_get_device_id (device);
1a7f9f
+  xdevice = XOpenDevice (xdisplay, device_id);
1a7f9f
+  if (!xdevice)
1a7f9f
+    return;
1a7f9f
+
1a7f9f
+  tap_action = get_property (device, "Synaptics Tap Action",
1a7f9f
+                             XA_INTEGER, 8, 7);
1a7f9f
+  if (!tap_action)
1a7f9f
+    goto out;
1a7f9f
+
1a7f9f
+  tap_action[4] = tap_enabled ? (left_handed ? 3 : 1) : 0;
1a7f9f
+  tap_action[5] = tap_enabled ? (left_handed ? 1 : 3) : 0;
1a7f9f
+  tap_action[6] = tap_enabled ? 2 : 0;
1a7f9f
+
1a7f9f
+  change_property (device, "Synaptics Tap Action",
1a7f9f
+                   XA_INTEGER, 8, tap_action, 7);
1a7f9f
+  meta_XFree (tap_action);
1a7f9f
+
1a7f9f
+  if (x11_display)
1a7f9f
+    meta_x11_error_trap_push (x11_display);
1a7f9f
+  buttons = g_new (guchar, buttons_capacity);
1a7f9f
+  n_buttons = XGetDeviceButtonMapping (xdisplay, xdevice,
1a7f9f
+                                       buttons, buttons_capacity);
1a7f9f
+
1a7f9f
+  while (n_buttons > buttons_capacity)
1a7f9f
+    {
1a7f9f
+      buttons_capacity = n_buttons;
1a7f9f
+      buttons = (guchar *) g_realloc (buttons,
1a7f9f
+                                      buttons_capacity * sizeof (guchar));
1a7f9f
+
1a7f9f
+      n_buttons = XGetDeviceButtonMapping (xdisplay, xdevice,
1a7f9f
+                                           buttons, buttons_capacity);
1a7f9f
+    }
1a7f9f
+
1a7f9f
+  buttons[0] = left_handed ? 3 : 1;
1a7f9f
+  buttons[2] = left_handed ? 1 : 3;
1a7f9f
+  XSetDeviceButtonMapping (xdisplay, xdevice, buttons, n_buttons);
1a7f9f
+  g_free (buttons);
1a7f9f
+
1a7f9f
+  if (x11_display && meta_x11_error_trap_pop_with_return (x11_display))
1a7f9f
+    {
1a7f9f
+      g_warning ("Could not set synaptics touchpad left-handed for %s",
1a7f9f
+                 clutter_input_device_get_device_name (device));
1a7f9f
+    }
1a7f9f
+
1a7f9f
+ out:
1a7f9f
+  XCloseDevice (xdisplay, xdevice);
1a7f9f
+}
1a7f9f
+
1a7f9f
+static void
1a7f9f
+change_synaptics_speed (ClutterInputDevice *device,
1a7f9f
+                        gdouble             speed)
1a7f9f
+{
1a7f9f
+  MetaDisplay *display = meta_get_display ();
1a7f9f
+  MetaX11Display *x11_display = display ? display->x11_display : NULL;
1a7f9f
+  MetaBackend *backend = meta_get_backend ();
1a7f9f
+  Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
1a7f9f
+  int device_id;
1a7f9f
+  XDevice *xdevice;
1a7f9f
+  XPtrFeedbackControl feedback;
1a7f9f
+  XFeedbackState *states, *state;
1a7f9f
+  int i, num_feedbacks, motion_threshold, numerator, denominator;
1a7f9f
+  gfloat motion_acceleration;
1a7f9f
+
1a7f9f
+  device_id = meta_input_device_x11_get_device_id (device);
1a7f9f
+  xdevice = XOpenDevice (xdisplay, device_id);
1a7f9f
+  if (!xdevice)
1a7f9f
+    return;
1a7f9f
+  /* Get the list of feedbacks for the device */
1a7f9f
+  states = XGetFeedbackControl (xdisplay, xdevice, &num_feedbacks);
1a7f9f
+  if (!states)
1a7f9f
+    return;
1a7f9f
+
1a7f9f
+  /* Calculate acceleration and threshold */
1a7f9f
+  motion_acceleration = (speed + 1) * 5; /* speed is [-1..1], map to [0..10] */
1a7f9f
+  motion_threshold = CLAMP (10 - floor (motion_acceleration), 1, 10);
1a7f9f
+
1a7f9f
+  if (motion_acceleration >= 1.0)
1a7f9f
+    {
1a7f9f
+      /* we want to get the acceleration, with a resolution of 0.5
1a7f9f
+       */
1a7f9f
+      if ((motion_acceleration - floor (motion_acceleration)) < 0.25)
1a7f9f
+        {
1a7f9f
+          numerator = floor (motion_acceleration);
1a7f9f
+          denominator = 1;
1a7f9f
+        }
1a7f9f
+      else if ((motion_acceleration - floor (motion_acceleration)) < 0.5)
1a7f9f
+        {
1a7f9f
+          numerator = ceil (2.0 * motion_acceleration);
1a7f9f
+          denominator = 2;
1a7f9f
+        }
1a7f9f
+      else if ((motion_acceleration - floor (motion_acceleration)) < 0.75)
1a7f9f
+        {
1a7f9f
+          numerator = floor (2.0 *motion_acceleration);
1a7f9f
+          denominator = 2;
1a7f9f
+        }
1a7f9f
+      else
1a7f9f
+        {
1a7f9f
+          numerator = ceil (motion_acceleration);
1a7f9f
+          denominator = 1;
1a7f9f
+        }
1a7f9f
+    }
1a7f9f
+  else if (motion_acceleration < 1.0 && motion_acceleration > 0)
1a7f9f
+    {
1a7f9f
+      /* This we do to 1/10ths */
1a7f9f
+      numerator = floor (motion_acceleration * 10) + 1;
1a7f9f
+      denominator= 10;
1a7f9f
+    }
1a7f9f
+  else
1a7f9f
+    {
1a7f9f
+      numerator = -1;
1a7f9f
+      denominator = -1;
1a7f9f
+    }
1a7f9f
+
1a7f9f
+  if (x11_display)
1a7f9f
+    meta_x11_error_trap_push (x11_display);
1a7f9f
+
1a7f9f
+  state = (XFeedbackState *) states;
1a7f9f
+
1a7f9f
+  for (i = 0; i < num_feedbacks; i++)
1a7f9f
+    {
1a7f9f
+      if (state->class == PtrFeedbackClass)
1a7f9f
+        {
1a7f9f
+          /* And tell the device */
1a7f9f
+          feedback.class      = PtrFeedbackClass;
1a7f9f
+          feedback.length     = sizeof (XPtrFeedbackControl);
1a7f9f
+          feedback.id         = state->id;
1a7f9f
+          feedback.threshold  = motion_threshold;
1a7f9f
+          feedback.accelNum   = numerator;
1a7f9f
+          feedback.accelDenom = denominator;
1a7f9f
+
1a7f9f
+          XChangeFeedbackControl (xdisplay, xdevice,
1a7f9f
+                                  DvAccelNum | DvAccelDenom | DvThreshold,
1a7f9f
+                                  (XFeedbackControl *) &feedback);
1a7f9f
+          break;
1a7f9f
+        }
1a7f9f
+
1a7f9f
+      state = (XFeedbackState *) ((char *) state + state->length);
1a7f9f
+    }
1a7f9f
+
1a7f9f
+  if (x11_display && meta_x11_error_trap_pop_with_return (x11_display))
1a7f9f
+    {
1a7f9f
+      g_warning ("Could not set synaptics touchpad acceleration for %s",
1a7f9f
+                 clutter_input_device_get_device_name (device));
1a7f9f
+    }
1a7f9f
+
1a7f9f
+  XFreeFeedbackList (states);
1a7f9f
+  XCloseDevice (xdisplay, xdevice);
1a7f9f
+}
1a7f9f
+
1a7f9f
 static void
1a7f9f
 meta_input_settings_x11_set_send_events (MetaInputSettings        *settings,
1a7f9f
                                          ClutterInputDevice       *device,
1a7f9f
@@ -173,6 +352,13 @@ meta_input_settings_x11_set_send_events (MetaInputSettings        *settings,
1a7f9f
   guchar values[2] = { 0 }; /* disabled, disabled-on-external-mouse */
1a7f9f
   guchar *available;
1a7f9f
 
1a7f9f
+  if (is_device_synaptics (device))
1a7f9f
+    {
1a7f9f
+      values[0] = mode != G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED;
1a7f9f
+      change_property (device, "Synaptics Off", XA_INTEGER, 8, &values, 1);
1a7f9f
+      return;
1a7f9f
+    }
1a7f9f
+
1a7f9f
   available = get_property (device, "libinput Send Events Modes Available",
1a7f9f
                             XA_INTEGER, 8, 2);
1a7f9f
   if (!available)
1a7f9f
@@ -225,6 +411,12 @@ meta_input_settings_x11_set_speed (MetaInputSettings  *settings,
1a7f9f
   Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
1a7f9f
   gfloat value = speed;
1a7f9f
 
1a7f9f
+  if (is_device_synaptics (device))
1a7f9f
+    {
1a7f9f
+      change_synaptics_speed (device, speed);
1a7f9f
+      return;
1a7f9f
+    }
1a7f9f
+
1a7f9f
   change_property (device, "libinput Accel Speed",
1a7f9f
                    XInternAtom (xdisplay, "FLOAT", False),
1a7f9f
                    32, &value, 1);
1a7f9f
@@ -251,6 +443,19 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings  *settings,
1a7f9f
   else
1a7f9f
     {
1a7f9f
       value = enabled ? 1 : 0;
1a7f9f
+
1a7f9f
+      if (is_device_synaptics (device))
1a7f9f
+        {
1a7f9f
+          GSettings *settings;
1a7f9f
+
1a7f9f
+          settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
1a7f9f
+          change_synaptics_tap_left_handed (device,
1a7f9f
+                                            g_settings_get_boolean (settings, "tap-to-click"),
1a7f9f
+                                            enabled);
1a7f9f
+          g_object_unref (settings);
1a7f9f
+          return;
1a7f9f
+        }
1a7f9f
+
1a7f9f
       change_property (device, "libinput Left Handed Enabled",
1a7f9f
                        XA_INTEGER, 8, &value, 1);
1a7f9f
     }
1a7f9f
@@ -274,6 +479,20 @@ meta_input_settings_x11_set_tap_enabled (MetaInputSettings  *settings,
1a7f9f
 {
1a7f9f
   guchar value = (enabled) ? 1 : 0;
1a7f9f
 
1a7f9f
+  if (is_device_synaptics (device))
1a7f9f
+    {
1a7f9f
+      GDesktopTouchpadHandedness handedness;
1a7f9f
+      GSettings *settings;
1a7f9f
+
1a7f9f
+      settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
1a7f9f
+      handedness = g_settings_get_enum (settings, "left-handed");
1a7f9f
+      g_object_unref (settings);
1a7f9f
+
1a7f9f
+      change_synaptics_tap_left_handed (device, enabled,
1a7f9f
+                                        handedness == G_DESKTOP_TOUCHPAD_HANDEDNESS_LEFT);
1a7f9f
+      return;
1a7f9f
+    }
1a7f9f
+
1a7f9f
   change_property (device, "libinput Tapping Enabled",
1a7f9f
                    XA_INTEGER, 8, &value, 1);
1a7f9f
 }
1a7f9f
@@ -307,6 +526,27 @@ meta_input_settings_x11_set_invert_scroll (MetaInputSettings  *settings,
1a7f9f
 {
1a7f9f
   guchar value = (inverted) ? 1 : 0;
1a7f9f
 
1a7f9f
+  if (is_device_synaptics (device))
1a7f9f
+    {
1a7f9f
+      gint32 *scrolling_distance;
1a7f9f
+
1a7f9f
+      scrolling_distance = get_property (device, "Synaptics Scrolling Distance",
1a7f9f
+                                         XA_INTEGER, 32, 2);
1a7f9f
+      if (scrolling_distance)
1a7f9f
+        {
1a7f9f
+          scrolling_distance[0] = inverted ?
1a7f9f
+            -abs (scrolling_distance[0]) : abs (scrolling_distance[0]);
1a7f9f
+          scrolling_distance[1] = inverted ?
1a7f9f
+            -abs (scrolling_distance[1]) : abs (scrolling_distance[1]);
1a7f9f
+
1a7f9f
+          change_property (device, "Synaptics Scrolling Distance",
1a7f9f
+                           XA_INTEGER, 32, scrolling_distance, 2);
1a7f9f
+          meta_XFree (scrolling_distance);
1a7f9f
+        }
1a7f9f
+
1a7f9f
+      return;
1a7f9f
+    }
1a7f9f
+
1a7f9f
   change_property (device, "libinput Natural Scrolling Enabled",
1a7f9f
                    XA_INTEGER, 8, &value, 1);
1a7f9f
 }
1a7f9f
@@ -320,6 +560,41 @@ change_scroll_method (ClutterInputDevice           *device,
1a7f9f
   guchar *current = NULL;
1a7f9f
   guchar *available = NULL;
1a7f9f
 
1a7f9f
+  if (is_device_synaptics (device))
1a7f9f
+    {
1a7f9f
+      switch (method)
1a7f9f
+        {
1a7f9f
+        case SCROLL_METHOD_FIELD_EDGE:
1a7f9f
+          current = get_property (device, "Synaptics Edge Scrolling",
1a7f9f
+                                  XA_INTEGER, 8, 3);
1a7f9f
+          if (current)
1a7f9f
+            {
1a7f9f
+              current[0] = enabled;
1a7f9f
+              current[1] = enabled;
1a7f9f
+              change_property (device, "Synaptics Edge Scrolling",
1a7f9f
+                               XA_INTEGER, 8, current, 3);
1a7f9f
+              meta_XFree (current);
1a7f9f
+            }
1a7f9f
+          break;
1a7f9f
+        case SCROLL_METHOD_FIELD_2FG:
1a7f9f
+          current = get_property (device, "Synaptics Two-Finger Scrolling",
1a7f9f
+                                  XA_INTEGER, 8, 2);
1a7f9f
+          if (current)
1a7f9f
+            {
1a7f9f
+              current[0] = enabled;
1a7f9f
+              current[1] = enabled;
1a7f9f
+              change_property (device, "Synaptics Two-Finger Scrolling",
1a7f9f
+                               XA_INTEGER, 8, current, 2);
1a7f9f
+              meta_XFree (current);
1a7f9f
+            }
1a7f9f
+          break;
1a7f9f
+        default:
1a7f9f
+          break;
1a7f9f
+        }
1a7f9f
+
1a7f9f
+      return;
1a7f9f
+    }
1a7f9f
+
1a7f9f
   available = get_property (device, "libinput Scroll Methods Available",
1a7f9f
                             XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS);
1a7f9f
   if (!available || !available[method])
1a7f9f
-- 
1a7f9f
2.31.1
1a7f9f
1a7f9f
1a7f9f
From 50c4733acf56b3b67a2706d32f5c455cb51f9458 Mon Sep 17 00:00:00 2001
1a7f9f
From: Carlos Garnacho <carlosg@gnome.org>
1a7f9f
Date: Tue, 13 Feb 2018 11:44:40 +0100
1a7f9f
Subject: [PATCH 2/6] clutter: Extend touchpad device property check for
1a7f9f
 Synaptics
1a7f9f
1a7f9f
So we reliably get CLUTTER_TOUCHPAD_DEVICE for those. The other heuristics
1a7f9f
to get the device type may fall short.
1a7f9f
---
1a7f9f
 src/backends/x11/meta-seat-x11.c | 17 +++++++++++++++--
1a7f9f
 1 file changed, 15 insertions(+), 2 deletions(-)
1a7f9f
1a7f9f
diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c
1a7f9f
index d43834bd7b..73938e22e0 100644
1a7f9f
--- a/src/backends/x11/meta-seat-x11.c
1a7f9f
+++ b/src/backends/x11/meta-seat-x11.c
1a7f9f
@@ -246,7 +246,8 @@ is_touch_device (XIAnyClassInfo         **classes,
1a7f9f
 }
1a7f9f
 
1a7f9f
 static gboolean
1a7f9f
-is_touchpad_device (XIDeviceInfo *info)
1a7f9f
+query_exists_device_property (XIDeviceInfo *info,
1a7f9f
+                              const char   *property)
1a7f9f
 {
1a7f9f
   gulong nitems, bytes_after;
1a7f9f
   uint32_t *data = NULL;
1a7f9f
@@ -254,7 +255,7 @@ is_touchpad_device (XIDeviceInfo *info)
1a7f9f
   Atom type;
1a7f9f
   Atom prop;
1a7f9f
 
1a7f9f
-  prop = XInternAtom (clutter_x11_get_default_display (), "libinput Tapping Enabled", True);
1a7f9f
+  prop = XInternAtom (clutter_x11_get_default_display (), property, True);
1a7f9f
   if (prop == None)
1a7f9f
     return FALSE;
1a7f9f
 
1a7f9f
@@ -275,6 +276,18 @@ is_touchpad_device (XIDeviceInfo *info)
1a7f9f
   return TRUE;
1a7f9f
 }
1a7f9f
 
1a7f9f
+static gboolean
1a7f9f
+is_touchpad_device (XIDeviceInfo *info)
1a7f9f
+{
1a7f9f
+  if (query_exists_device_property (info, "libinput Tapping Enabled"))
1a7f9f
+    return TRUE;
1a7f9f
+
1a7f9f
+  if (query_exists_device_property (info, "Synaptics Off"))
1a7f9f
+    return TRUE;
1a7f9f
+
1a7f9f
+  return FALSE;
1a7f9f
+}
1a7f9f
+
1a7f9f
 static gboolean
1a7f9f
 get_device_ids (XIDeviceInfo  *info,
1a7f9f
                 char         **vendor_id,
1a7f9f
-- 
1a7f9f
2.31.1
1a7f9f
1a7f9f
1a7f9f
From 307970305d11cdca1b97c53c85bda8b809ff4f0f Mon Sep 17 00:00:00 2001
1a7f9f
From: Rui Matos <tiagomatos@gmail.com>
1a7f9f
Date: Mon, 9 Oct 2017 18:39:52 +0200
1a7f9f
Subject: [PATCH 3/6] backends/x11: Add a synaptics check for two finger scroll
1a7f9f
 availability
1a7f9f
1a7f9f
Commit "backends/x11: Support synaptics configuration" added support
1a7f9f
for synaptics two finger scrolling but didn't add the code to check
1a7f9f
that it is available resulting in the upper layer always assuming it
1a7f9f
isn't.
1a7f9f
---
1a7f9f
 src/backends/x11/meta-input-settings-x11.c | 11 +++++++++++
1a7f9f
 1 file changed, 11 insertions(+)
1a7f9f
1a7f9f
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
1a7f9f
index 0631fd2fee..2ac080127c 100644
1a7f9f
--- a/src/backends/x11/meta-input-settings-x11.c
1a7f9f
+++ b/src/backends/x11/meta-input-settings-x11.c
1a7f9f
@@ -638,6 +638,17 @@ meta_input_settings_x11_has_two_finger_scroll (MetaInputSettings  *settings,
1a7f9f
   guchar *available = NULL;
1a7f9f
   gboolean has_two_finger = TRUE;
1a7f9f
 
1a7f9f
+  if (is_device_synaptics (device))
1a7f9f
+    {
1a7f9f
+      available = get_property (device, "Synaptics Capabilities",
1a7f9f
+                                XA_INTEGER, 8, 4);
1a7f9f
+      if (!available || !available[3])
1a7f9f
+          has_two_finger = FALSE;
1a7f9f
+
1a7f9f
+      meta_XFree (available);
1a7f9f
+      return has_two_finger;
1a7f9f
+    }
1a7f9f
+
1a7f9f
   available = get_property (device, "libinput Scroll Methods Available",
1a7f9f
                             XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS);
1a7f9f
   if (!available || !available[SCROLL_METHOD_FIELD_2FG])
1a7f9f
-- 
1a7f9f
2.31.1
1a7f9f
1a7f9f
1a7f9f
From cba31f88ddbfb7355de1daa34397aba8e8607765 Mon Sep 17 00:00:00 2001
1a7f9f
From: Rui Matos <tiagomatos@gmail.com>
1a7f9f
Date: Mon, 9 Oct 2017 18:55:56 +0200
1a7f9f
Subject: [PATCH 4/6] backends/x11: Add disable while typing support for
1a7f9f
 synaptics
1a7f9f
1a7f9f
This is basically a copy of the old g-s-d mouse plugin code to manage
1a7f9f
syndaemon when the synaptics driver is being used.
1a7f9f
---
1a7f9f
 src/backends/x11/meta-input-settings-x11.c | 112 +++++++++++++++++++++
1a7f9f
 1 file changed, 112 insertions(+)
1a7f9f
1a7f9f
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
1a7f9f
index 2ac080127c..2658b82172 100644
1a7f9f
--- a/src/backends/x11/meta-input-settings-x11.c
1a7f9f
+++ b/src/backends/x11/meta-input-settings-x11.c
1a7f9f
@@ -35,6 +35,9 @@
1a7f9f
 #ifdef HAVE_LIBGUDEV
1a7f9f
 #include <gudev/gudev.h>
1a7f9f
 #endif
1a7f9f
+#ifdef __linux
1a7f9f
+#include <sys/prctl.h>
1a7f9f
+#endif
1a7f9f
 
1a7f9f
 #include "backends/x11/meta-backend-x11.h"
1a7f9f
 #include "backends/x11/meta-input-device-x11.h"
1a7f9f
@@ -46,6 +49,8 @@ typedef struct _MetaInputSettingsX11Private
1a7f9f
 #ifdef HAVE_LIBGUDEV
1a7f9f
   GUdevClient *udev_client;
1a7f9f
 #endif
1a7f9f
+  gboolean syndaemon_spawned;
1a7f9f
+  GPid syndaemon_pid;
1a7f9f
 } MetaInputSettingsX11Private;
1a7f9f
 
1a7f9f
 G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettingsX11, meta_input_settings_x11,
1a7f9f
@@ -344,6 +349,107 @@ change_synaptics_speed (ClutterInputDevice *device,
1a7f9f
   XCloseDevice (xdisplay, xdevice);
1a7f9f
 }
1a7f9f
 
1a7f9f
+/* Ensure that syndaemon dies together with us, to avoid running several of
1a7f9f
+ * them */
1a7f9f
+static void
1a7f9f
+setup_syndaemon (gpointer user_data)
1a7f9f
+{
1a7f9f
+#ifdef __linux
1a7f9f
+  prctl (PR_SET_PDEATHSIG, SIGHUP);
1a7f9f
+#endif
1a7f9f
+}
1a7f9f
+
1a7f9f
+static gboolean
1a7f9f
+have_program_in_path (const char *name)
1a7f9f
+{
1a7f9f
+  gchar *path;
1a7f9f
+  gboolean result;
1a7f9f
+
1a7f9f
+  path = g_find_program_in_path (name);
1a7f9f
+  result = (path != NULL);
1a7f9f
+  g_free (path);
1a7f9f
+  return result;
1a7f9f
+}
1a7f9f
+
1a7f9f
+static void
1a7f9f
+syndaemon_died (GPid     pid,
1a7f9f
+                gint     status,
1a7f9f
+                gpointer user_data)
1a7f9f
+{
1a7f9f
+  MetaInputSettingsX11 *settings_x11 = META_INPUT_SETTINGS_X11 (user_data);
1a7f9f
+  MetaInputSettingsX11Private *priv =
1a7f9f
+    meta_input_settings_x11_get_instance_private (settings_x11);
1a7f9f
+  GError *error = NULL;
1a7f9f
+
1a7f9f
+  if (!g_spawn_check_exit_status (status, &error))
1a7f9f
+    {
1a7f9f
+      if ((WIFSIGNALED (status) && WTERMSIG (status) != SIGHUP) ||
1a7f9f
+          error->domain == G_SPAWN_EXIT_ERROR)
1a7f9f
+        g_warning ("Syndaemon exited unexpectedly: %s", error->message);
1a7f9f
+      g_error_free (error);
1a7f9f
+    }
1a7f9f
+
1a7f9f
+  g_spawn_close_pid (pid);
1a7f9f
+  priv->syndaemon_spawned = FALSE;
1a7f9f
+}
1a7f9f
+
1a7f9f
+static void
1a7f9f
+set_synaptics_disable_w_typing (MetaInputSettings *settings,
1a7f9f
+                                gboolean           state)
1a7f9f
+{
1a7f9f
+  MetaInputSettingsX11 *settings_x11 = META_INPUT_SETTINGS_X11 (settings);
1a7f9f
+  MetaInputSettingsX11Private *priv =
1a7f9f
+    meta_input_settings_x11_get_instance_private (settings_x11);
1a7f9f
+
1a7f9f
+  if (state)
1a7f9f
+    {
1a7f9f
+      GError *error = NULL;
1a7f9f
+      GPtrArray *args;
1a7f9f
+
1a7f9f
+      if (priv->syndaemon_spawned)
1a7f9f
+        return;
1a7f9f
+
1a7f9f
+      if (!have_program_in_path ("syndaemon"))
1a7f9f
+        return;
1a7f9f
+
1a7f9f
+      args = g_ptr_array_new ();
1a7f9f
+
1a7f9f
+      g_ptr_array_add (args, (gpointer)"syndaemon");
1a7f9f
+      g_ptr_array_add (args, (gpointer)"-i");
1a7f9f
+      g_ptr_array_add (args, (gpointer)"1.0");
1a7f9f
+      g_ptr_array_add (args, (gpointer)"-t");
1a7f9f
+      g_ptr_array_add (args, (gpointer)"-K");
1a7f9f
+      g_ptr_array_add (args, (gpointer)"-R");
1a7f9f
+      g_ptr_array_add (args, NULL);
1a7f9f
+
1a7f9f
+      /* we must use G_SPAWN_DO_NOT_REAP_CHILD to avoid
1a7f9f
+       * double-forking, otherwise syndaemon will immediately get
1a7f9f
+       * killed again through (PR_SET_PDEATHSIG when the intermediate
1a7f9f
+       * process dies */
1a7f9f
+      g_spawn_async (g_get_home_dir (), (char **) args->pdata, NULL,
1a7f9f
+                     G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD, setup_syndaemon, NULL,
1a7f9f
+                     &priv->syndaemon_pid, &error);
1a7f9f
+
1a7f9f
+      priv->syndaemon_spawned = (error == NULL);
1a7f9f
+      g_ptr_array_free (args, TRUE);
1a7f9f
+
1a7f9f
+      if (error)
1a7f9f
+        {
1a7f9f
+          g_warning ("Failed to launch syndaemon: %s", error->message);
1a7f9f
+          g_error_free (error);
1a7f9f
+        }
1a7f9f
+      else
1a7f9f
+        {
1a7f9f
+          g_child_watch_add (priv->syndaemon_pid, syndaemon_died, settings);
1a7f9f
+        }
1a7f9f
+    }
1a7f9f
+  else if (priv->syndaemon_spawned)
1a7f9f
+    {
1a7f9f
+      kill (priv->syndaemon_pid, SIGHUP);
1a7f9f
+      priv->syndaemon_spawned = FALSE;
1a7f9f
+    }
1a7f9f
+}
1a7f9f
+
1a7f9f
 static void
1a7f9f
 meta_input_settings_x11_set_send_events (MetaInputSettings        *settings,
1a7f9f
                                          ClutterInputDevice       *device,
1a7f9f
@@ -468,6 +574,12 @@ meta_input_settings_x11_set_disable_while_typing (MetaInputSettings  *settings,
1a7f9f
 {
1a7f9f
   guchar value = (enabled) ? 1 : 0;
1a7f9f
 
1a7f9f
+  if (is_device_synaptics (device))
1a7f9f
+    {
1a7f9f
+      set_synaptics_disable_w_typing (settings, enabled);
1a7f9f
+      return;
1a7f9f
+    }
1a7f9f
+
1a7f9f
   change_property (device, "libinput Disable While Typing Enabled",
1a7f9f
                    XA_INTEGER, 8, &value, 1);
1a7f9f
 }
1a7f9f
-- 
1a7f9f
2.31.1
1a7f9f
1a7f9f
1a7f9f
From 354d34263534d0c7a5c7f7169d8b4a3dba79491c Mon Sep 17 00:00:00 2001
1a7f9f
From: Carlos Garnacho <carlosg@gnome.org>
1a7f9f
Date: Wed, 13 Jun 2018 13:48:24 +0200
1a7f9f
Subject: [PATCH 5/6] clutter: Only reset scroll axes on slave devices
1a7f9f
1a7f9f
As a plus, unknown source device IDs will just warn instead of crash.
1a7f9f
---
1a7f9f
 src/backends/x11/meta-seat-x11.c | 4 +++-
1a7f9f
 1 file changed, 3 insertions(+), 1 deletion(-)
1a7f9f
1a7f9f
diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c
1a7f9f
index 73938e22e0..6d2c7d3740 100644
1a7f9f
--- a/src/backends/x11/meta-seat-x11.c
1a7f9f
+++ b/src/backends/x11/meta-seat-x11.c
1a7f9f
@@ -2362,7 +2362,9 @@ meta_seat_x11_translate_event (MetaSeatX11  *seat,
1a7f9f
               seat->has_pointer_focus = FALSE;
1a7f9f
           }
1a7f9f
 
1a7f9f
-        meta_input_device_x11_reset_scroll_info (source_device);
1a7f9f
+        if (clutter_input_device_get_device_mode (source_device) ==
1a7f9f
+            CLUTTER_INPUT_MODE_PHYSICAL)
1a7f9f
+          meta_input_device_x11_reset_scroll_info (source_device);
1a7f9f
 
1a7f9f
         clutter_event_set_device (event, device);
1a7f9f
         clutter_event_set_source_device (event, source_device);
1a7f9f
-- 
1a7f9f
2.31.1
1a7f9f
1a7f9f
1a7f9f
From b7f94b5dd09953d5a4c8aee1b79491d71f8c1e0e Mon Sep 17 00:00:00 2001
1a7f9f
From: Rui Matos <tiagomatos@gmail.com>
1a7f9f
Date: Tue, 10 Oct 2017 19:07:27 +0200
1a7f9f
Subject: [PATCH 6/6] backends/x11: Support plain old X device configuration
1a7f9f
1a7f9f
We re-use part of the code added to support synaptics and add a few
1a7f9f
bits specific for xorg-x11-drv-evdev devices.
1a7f9f
---
1a7f9f
 src/backends/x11/meta-input-settings-x11.c | 98 +++++++++++++++++-----
1a7f9f
 1 file changed, 75 insertions(+), 23 deletions(-)
1a7f9f
1a7f9f
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
1a7f9f
index 2658b82172..80bc33c6b5 100644
1a7f9f
--- a/src/backends/x11/meta-input-settings-x11.c
1a7f9f
+++ b/src/backends/x11/meta-input-settings-x11.c
1a7f9f
@@ -185,10 +185,23 @@ is_device_synaptics (ClutterInputDevice *device)
1a7f9f
   return TRUE;
1a7f9f
 }
1a7f9f
 
1a7f9f
+static gboolean
1a7f9f
+is_device_libinput (ClutterInputDevice *device)
1a7f9f
+{
1a7f9f
+  guchar *has_setting;
1a7f9f
+
1a7f9f
+  /* We just need looking for a synaptics-specific property */
1a7f9f
+  has_setting = get_property (device, "libinput Send Events Modes Available", XA_INTEGER, 8, 2);
1a7f9f
+  if (!has_setting)
1a7f9f
+    return FALSE;
1a7f9f
+
1a7f9f
+  meta_XFree (has_setting);
1a7f9f
+  return TRUE;
1a7f9f
+}
1a7f9f
+
1a7f9f
 static void
1a7f9f
-change_synaptics_tap_left_handed (ClutterInputDevice *device,
1a7f9f
-                                  gboolean            tap_enabled,
1a7f9f
-                                  gboolean            left_handed)
1a7f9f
+change_x_device_left_handed (ClutterInputDevice *device,
1a7f9f
+                             gboolean            left_handed)
1a7f9f
 {
1a7f9f
   MetaDisplay *display = meta_get_display ();
1a7f9f
   MetaX11Display *x11_display = display ? display->x11_display : NULL;
1a7f9f
@@ -196,7 +209,7 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device,
1a7f9f
   Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
1a7f9f
   int device_id;
1a7f9f
   XDevice *xdevice;
1a7f9f
-  guchar *tap_action, *buttons;
1a7f9f
+  guchar *buttons;
1a7f9f
   guint buttons_capacity = 16, n_buttons;
1a7f9f
 
1a7f9f
   device_id = meta_input_device_x11_get_device_id (device);
1a7f9f
@@ -204,19 +217,6 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device,
1a7f9f
   if (!xdevice)
1a7f9f
     return;
1a7f9f
 
1a7f9f
-  tap_action = get_property (device, "Synaptics Tap Action",
1a7f9f
-                             XA_INTEGER, 8, 7);
1a7f9f
-  if (!tap_action)
1a7f9f
-    goto out;
1a7f9f
-
1a7f9f
-  tap_action[4] = tap_enabled ? (left_handed ? 3 : 1) : 0;
1a7f9f
-  tap_action[5] = tap_enabled ? (left_handed ? 1 : 3) : 0;
1a7f9f
-  tap_action[6] = tap_enabled ? 2 : 0;
1a7f9f
-
1a7f9f
-  change_property (device, "Synaptics Tap Action",
1a7f9f
-                   XA_INTEGER, 8, tap_action, 7);
1a7f9f
-  meta_XFree (tap_action);
1a7f9f
-
1a7f9f
   if (x11_display)
1a7f9f
     meta_x11_error_trap_push (x11_display);
1a7f9f
   buttons = g_new (guchar, buttons_capacity);
1a7f9f
@@ -240,17 +240,39 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device,
1a7f9f
 
1a7f9f
   if (x11_display && meta_x11_error_trap_pop_with_return (x11_display))
1a7f9f
     {
1a7f9f
-      g_warning ("Could not set synaptics touchpad left-handed for %s",
1a7f9f
+      g_warning ("Could not set left-handed for %s",
1a7f9f
                  clutter_input_device_get_device_name (device));
1a7f9f
     }
1a7f9f
 
1a7f9f
- out:
1a7f9f
   XCloseDevice (xdisplay, xdevice);
1a7f9f
 }
1a7f9f
 
1a7f9f
 static void
1a7f9f
-change_synaptics_speed (ClutterInputDevice *device,
1a7f9f
-                        gdouble             speed)
1a7f9f
+change_synaptics_tap_left_handed (ClutterInputDevice *device,
1a7f9f
+                                  gboolean            tap_enabled,
1a7f9f
+                                  gboolean            left_handed)
1a7f9f
+{
1a7f9f
+  guchar *tap_action;
1a7f9f
+
1a7f9f
+  tap_action = get_property (device, "Synaptics Tap Action",
1a7f9f
+                             XA_INTEGER, 8, 7);
1a7f9f
+  if (!tap_action)
1a7f9f
+    return;
1a7f9f
+
1a7f9f
+  tap_action[4] = tap_enabled ? (left_handed ? 3 : 1) : 0;
1a7f9f
+  tap_action[5] = tap_enabled ? (left_handed ? 1 : 3) : 0;
1a7f9f
+  tap_action[6] = tap_enabled ? 2 : 0;
1a7f9f
+
1a7f9f
+  change_property (device, "Synaptics Tap Action",
1a7f9f
+                   XA_INTEGER, 8, tap_action, 7);
1a7f9f
+  meta_XFree (tap_action);
1a7f9f
+
1a7f9f
+  change_x_device_left_handed (device, left_handed);
1a7f9f
+}
1a7f9f
+
1a7f9f
+static void
1a7f9f
+change_x_device_speed (ClutterInputDevice *device,
1a7f9f
+                       gdouble             speed)
1a7f9f
 {
1a7f9f
   MetaDisplay *display = meta_get_display ();
1a7f9f
   MetaX11Display *x11_display = display ? display->x11_display : NULL;
1a7f9f
@@ -349,6 +371,23 @@ change_synaptics_speed (ClutterInputDevice *device,
1a7f9f
   XCloseDevice (xdisplay, xdevice);
1a7f9f
 }
1a7f9f
 
1a7f9f
+static void
1a7f9f
+change_x_device_scroll_button (ClutterInputDevice *device,
1a7f9f
+                               guint               button)
1a7f9f
+{
1a7f9f
+  guchar value;
1a7f9f
+
1a7f9f
+  value = button > 0 ? 1 : 0;
1a7f9f
+  change_property (device, "Evdev Wheel Emulation",
1a7f9f
+                   XA_INTEGER, 8, &value, 1);
1a7f9f
+  if (button > 0)
1a7f9f
+    {
1a7f9f
+      value = button;
1a7f9f
+      change_property (device, "Evdev Wheel Emulation Button",
1a7f9f
+                       XA_INTEGER, 8, &value, 1);
1a7f9f
+    }
1a7f9f
+}
1a7f9f
+
1a7f9f
 /* Ensure that syndaemon dies together with us, to avoid running several of
1a7f9f
  * them */
1a7f9f
 static void
1a7f9f
@@ -517,9 +556,10 @@ meta_input_settings_x11_set_speed (MetaInputSettings  *settings,
1a7f9f
   Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
1a7f9f
   gfloat value = speed;
1a7f9f
 
1a7f9f
-  if (is_device_synaptics (device))
1a7f9f
+  if (is_device_synaptics (device) ||
1a7f9f
+      !is_device_libinput (device))
1a7f9f
     {
1a7f9f
-      change_synaptics_speed (device, speed);
1a7f9f
+      change_x_device_speed (device, speed);
1a7f9f
       return;
1a7f9f
     }
1a7f9f
 
1a7f9f
@@ -561,6 +601,11 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings  *settings,
1a7f9f
           g_object_unref (settings);
1a7f9f
           return;
1a7f9f
         }
1a7f9f
+      else if (!is_device_libinput (device) && device_type != CLUTTER_PAD_DEVICE)
1a7f9f
+        {
1a7f9f
+          change_x_device_left_handed (device, enabled);
1a7f9f
+          return;
1a7f9f
+        }
1a7f9f
 
1a7f9f
       change_property (device, "libinput Left Handed Enabled",
1a7f9f
                        XA_INTEGER, 8, &value, 1);
1a7f9f
@@ -778,7 +823,14 @@ meta_input_settings_x11_set_scroll_button (MetaInputSettings  *settings,
1a7f9f
 {
1a7f9f
   gchar lock = button_lock;
1a7f9f
 
1a7f9f
+  if (!is_device_libinput (device))
1a7f9f
+    {
1a7f9f
+      change_x_device_scroll_button (device, button);
1a7f9f
+      return;
1a7f9f
+    }
1a7f9f
+
1a7f9f
   change_scroll_method (device, SCROLL_METHOD_FIELD_BUTTON, button != 0);
1a7f9f
+
1a7f9f
   change_property (device, "libinput Button Scrolling Button",
1a7f9f
                    XA_CARDINAL, 32, &button, 1);
1a7f9f
   change_property (device, "libinput Button Scrolling Button Lock Enabled",
1a7f9f
-- 
1a7f9f
2.31.1
1a7f9f