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

1679d1
From 22fe64732e11199901d4a35f9d3c63d5d6deb3a3 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
---
1679d1
 src/backends/x11/meta-input-settings-x11.c | 274 +++++++++++++++++++++
1679d1
 1 file changed, 274 insertions(+)
1a7f9f
1a7f9f
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
1679d1
index 371e2f60e..426056390 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>
1679d1
@@ -165,6 +166,183 @@ 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
+  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
+
1679d1
+  clutter_x11_trap_x_errors();
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
+
1679d1
+  if (clutter_x11_untrap_x_errors())
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
+  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 */
1679d1
+  clutter_x11_trap_x_errors();
1a7f9f
+  states = XGetFeedbackControl (xdisplay, xdevice, &num_feedbacks);
1679d1
+  if (clutter_x11_untrap_x_errors())
1679d1
+    return;
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
+
1679d1
+  clutter_x11_trap_x_errors();
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
+
1679d1
+  if (clutter_x11_untrap_x_errors())
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,
1679d1
@@ -173,6 +351,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)
1679d1
@@ -225,6 +410,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);
1679d1
@@ -251,6 +442,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
     }
1679d1
@@ -274,6 +478,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
 }
1679d1
@@ -307,6 +525,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
 }
1679d1
@@ -320,6 +559,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
-- 
1679d1
2.36.1
1a7f9f
1a7f9f
1679d1
From 963ff120898e7e42d80d5761753e76adcf16c132 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
1679d1
index d43834bd7..73938e22e 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
-- 
1679d1
2.36.1
1a7f9f
1a7f9f
1679d1
From 86cc1b46dae01da619980af826eb9bf81cf31143 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
1679d1
index 426056390..db2b2a4fb 100644
1a7f9f
--- a/src/backends/x11/meta-input-settings-x11.c
1a7f9f
+++ b/src/backends/x11/meta-input-settings-x11.c
1679d1
@@ -637,6 +637,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
-- 
1679d1
2.36.1
1a7f9f
1a7f9f
1679d1
From 32e2da07eeb1f9edcf03751285a756ab1acca6a8 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
1679d1
index db2b2a4fb..bf9d769e9 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,
1679d1
@@ -343,6 +348,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,
1679d1
@@ -467,6 +573,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
-- 
1679d1
2.36.1
1a7f9f
1a7f9f
1679d1
From 6da0bfe86f416d3cfc5cc6993e8e2f6ca255e85a 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
1679d1
index 73938e22e..6d2c7d374 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
-- 
1679d1
2.36.1
1a7f9f
1a7f9f
1679d1
From da60cf38c7fcec68f8e79a8a3a174e551c07a64a 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
1679d1
index bf9d769e9..49dcb74f1 100644
1a7f9f
--- a/src/backends/x11/meta-input-settings-x11.c
1a7f9f
+++ b/src/backends/x11/meta-input-settings-x11.c
1679d1
@@ -185,17 +185,30 @@ 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 ();
1679d1
   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
+  guchar *buttons;
1a7f9f
   guint buttons_capacity = 16, n_buttons;
1a7f9f
 
1a7f9f
   device_id = meta_input_device_x11_get_device_id (device);
1679d1
@@ -203,19 +216,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
-
1679d1
   clutter_x11_trap_x_errors();
1a7f9f
   buttons = g_new (guchar, buttons_capacity);
1679d1
   n_buttons = XGetDeviceButtonMapping (xdisplay, xdevice,
1679d1
@@ -238,17 +238,39 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device,
1a7f9f
 
1679d1
   if (clutter_x11_untrap_x_errors())
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 ();
1679d1
   MetaBackend *backend = meta_get_backend ();
1679d1
@@ -348,6 +370,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
1679d1
@@ -516,9 +555,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
 
1679d1
@@ -560,6 +600,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);
1679d1
@@ -777,7 +822,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
-- 
1679d1
2.36.1
1a7f9f