|
|
e47e58 |
From 647de5a802627809486fe760c657b05297470683 Mon Sep 17 00:00:00 2001
|
|
|
67f8b7 |
From: Carlos Garnacho <carlosg@gnome.org>
|
|
|
67f8b7 |
Date: Thu, 19 Jan 2017 15:03:41 +0100
|
|
|
67f8b7 |
Subject: [PATCH] backends/x11: Support synaptics configuration
|
|
|
67f8b7 |
|
|
|
67f8b7 |
The code is taken mostly as-is from g-s-d, so we can drag the
|
|
|
67f8b7 |
dead horse a bit longer.
|
|
|
67f8b7 |
---
|
|
|
e47e58 |
src/backends/x11/meta-input-settings-x11.c | 261 +++++++++++++++++++++++++++++
|
|
|
e47e58 |
1 file changed, 261 insertions(+)
|
|
|
67f8b7 |
|
|
|
67f8b7 |
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
|
|
|
e47e58 |
index 7a876ef..467a9b7 100644
|
|
|
67f8b7 |
--- a/src/backends/x11/meta-input-settings-x11.c
|
|
|
67f8b7 |
+++ b/src/backends/x11/meta-input-settings-x11.c
|
|
|
67f8b7 |
@@ -26,6 +26,7 @@
|
|
|
67f8b7 |
#include "meta-backend-x11.h"
|
|
|
67f8b7 |
#include "meta-input-settings-x11.h"
|
|
|
67f8b7 |
|
|
|
67f8b7 |
+#include <stdlib.h>
|
|
|
67f8b7 |
#include <string.h>
|
|
|
67f8b7 |
#include <gdk/gdkx.h>
|
|
|
67f8b7 |
#include <X11/Xatom.h>
|
|
|
e47e58 |
@@ -159,6 +160,173 @@ change_property (ClutterInputDevice *device,
|
|
|
67f8b7 |
meta_XFree (data_ret);
|
|
|
67f8b7 |
}
|
|
|
67f8b7 |
|
|
|
67f8b7 |
+static gboolean
|
|
|
67f8b7 |
+is_device_synaptics (ClutterInputDevice *device)
|
|
|
67f8b7 |
+{
|
|
|
67f8b7 |
+ guchar *has_setting;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ /* We just need looking for a synaptics-specific property */
|
|
|
67f8b7 |
+ has_setting = get_property (device, "Synaptics Off", XA_INTEGER, 8, 1);
|
|
|
67f8b7 |
+ if (!has_setting)
|
|
|
67f8b7 |
+ return FALSE;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ meta_XFree (has_setting);
|
|
|
67f8b7 |
+ return TRUE;
|
|
|
67f8b7 |
+}
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+static void
|
|
|
67f8b7 |
+change_synaptics_tap_left_handed (ClutterInputDevice *device,
|
|
|
67f8b7 |
+ gboolean tap_enabled,
|
|
|
67f8b7 |
+ gboolean left_handed)
|
|
|
67f8b7 |
+{
|
|
|
67f8b7 |
+ MetaDisplay *display = meta_get_display ();
|
|
|
67f8b7 |
+ MetaBackend *backend = meta_get_backend ();
|
|
|
67f8b7 |
+ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
|
|
67f8b7 |
+ XDevice *xdevice;
|
|
|
67f8b7 |
+ guchar *tap_action, *buttons;
|
|
|
67f8b7 |
+ guint buttons_capacity = 16, n_buttons;
|
|
|
67f8b7 |
+
|
|
|
e47e58 |
+ xdevice = device_ensure_xdevice (device);
|
|
|
67f8b7 |
+ if (!xdevice)
|
|
|
67f8b7 |
+ return;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ tap_action = get_property (device, "Synaptics Tap Action",
|
|
|
67f8b7 |
+ XA_INTEGER, 8, 7);
|
|
|
67f8b7 |
+ if (!tap_action)
|
|
|
e47e58 |
+ return;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ tap_action[4] = tap_enabled ? (left_handed ? 3 : 1) : 0;
|
|
|
67f8b7 |
+ tap_action[5] = tap_enabled ? (left_handed ? 1 : 3) : 0;
|
|
|
67f8b7 |
+ tap_action[6] = tap_enabled ? 2 : 0;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ change_property (device, "Synaptics Tap Action",
|
|
|
67f8b7 |
+ XA_INTEGER, 8, tap_action, 7);
|
|
|
67f8b7 |
+ meta_XFree (tap_action);
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ if (display)
|
|
|
67f8b7 |
+ meta_error_trap_push (display);
|
|
|
67f8b7 |
+ buttons = g_new (guchar, buttons_capacity);
|
|
|
67f8b7 |
+ n_buttons = XGetDeviceButtonMapping (xdisplay, xdevice,
|
|
|
67f8b7 |
+ buttons, buttons_capacity);
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ while (n_buttons > buttons_capacity)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ buttons_capacity = n_buttons;
|
|
|
67f8b7 |
+ buttons = (guchar *) g_realloc (buttons,
|
|
|
67f8b7 |
+ buttons_capacity * sizeof (guchar));
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ n_buttons = XGetDeviceButtonMapping (xdisplay, xdevice,
|
|
|
67f8b7 |
+ buttons, buttons_capacity);
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ buttons[0] = left_handed ? 3 : 1;
|
|
|
67f8b7 |
+ buttons[2] = left_handed ? 1 : 3;
|
|
|
67f8b7 |
+ XSetDeviceButtonMapping (xdisplay, xdevice, buttons, n_buttons);
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ if (display && meta_error_trap_pop_with_return (display))
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ g_warning ("Could not set synaptics touchpad left-handed for %s",
|
|
|
67f8b7 |
+ clutter_input_device_get_device_name (device));
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+}
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+static void
|
|
|
67f8b7 |
+change_synaptics_speed (ClutterInputDevice *device,
|
|
|
67f8b7 |
+ gdouble speed)
|
|
|
67f8b7 |
+{
|
|
|
67f8b7 |
+ MetaDisplay *display = meta_get_display ();
|
|
|
67f8b7 |
+ MetaBackend *backend = meta_get_backend ();
|
|
|
67f8b7 |
+ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
|
|
67f8b7 |
+ XDevice *xdevice;
|
|
|
67f8b7 |
+ XPtrFeedbackControl feedback;
|
|
|
67f8b7 |
+ XFeedbackState *states, *state;
|
|
|
67f8b7 |
+ int i, num_feedbacks, motion_threshold, numerator, denominator;
|
|
|
67f8b7 |
+ gfloat motion_acceleration;
|
|
|
67f8b7 |
+
|
|
|
e47e58 |
+ xdevice = device_ensure_xdevice (device);
|
|
|
67f8b7 |
+ if (!xdevice)
|
|
|
67f8b7 |
+ return;
|
|
|
67f8b7 |
+ /* Get the list of feedbacks for the device */
|
|
|
67f8b7 |
+ states = XGetFeedbackControl (xdisplay, xdevice, &num_feedbacks);
|
|
|
67f8b7 |
+ if (!states)
|
|
|
67f8b7 |
+ return;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ /* Calculate acceleration and threshold */
|
|
|
67f8b7 |
+ motion_acceleration = (speed + 1) * 5; /* speed is [-1..1], map to [0..10] */
|
|
|
67f8b7 |
+ motion_threshold = CLAMP (10 - floor (motion_acceleration), 1, 10);
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ if (motion_acceleration >= 1.0)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ /* we want to get the acceleration, with a resolution of 0.5
|
|
|
67f8b7 |
+ */
|
|
|
67f8b7 |
+ if ((motion_acceleration - floor (motion_acceleration)) < 0.25)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ numerator = floor (motion_acceleration);
|
|
|
67f8b7 |
+ denominator = 1;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+ else if ((motion_acceleration - floor (motion_acceleration)) < 0.5)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ numerator = ceil (2.0 * motion_acceleration);
|
|
|
67f8b7 |
+ denominator = 2;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+ else if ((motion_acceleration - floor (motion_acceleration)) < 0.75)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ numerator = floor (2.0 *motion_acceleration);
|
|
|
67f8b7 |
+ denominator = 2;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+ else
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ numerator = ceil (motion_acceleration);
|
|
|
67f8b7 |
+ denominator = 1;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+ else if (motion_acceleration < 1.0 && motion_acceleration > 0)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ /* This we do to 1/10ths */
|
|
|
67f8b7 |
+ numerator = floor (motion_acceleration * 10) + 1;
|
|
|
67f8b7 |
+ denominator= 10;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+ else
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ numerator = -1;
|
|
|
67f8b7 |
+ denominator = -1;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ if (display)
|
|
|
67f8b7 |
+ meta_error_trap_push (display);
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ state = (XFeedbackState *) states;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ for (i = 0; i < num_feedbacks; i++)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ if (state->class == PtrFeedbackClass)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ /* And tell the device */
|
|
|
67f8b7 |
+ feedback.class = PtrFeedbackClass;
|
|
|
67f8b7 |
+ feedback.length = sizeof (XPtrFeedbackControl);
|
|
|
67f8b7 |
+ feedback.id = state->id;
|
|
|
67f8b7 |
+ feedback.threshold = motion_threshold;
|
|
|
67f8b7 |
+ feedback.accelNum = numerator;
|
|
|
67f8b7 |
+ feedback.accelDenom = denominator;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ XChangeFeedbackControl (xdisplay, xdevice,
|
|
|
67f8b7 |
+ DvAccelNum | DvAccelDenom | DvThreshold,
|
|
|
67f8b7 |
+ (XFeedbackControl *) &feedback);
|
|
|
67f8b7 |
+ break;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ state = (XFeedbackState *) ((char *) state + state->length);
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ if (display && meta_error_trap_pop_with_return (display))
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ g_warning ("Could not set synaptics touchpad acceleration for %s",
|
|
|
67f8b7 |
+ clutter_input_device_get_device_name (device));
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ XFreeFeedbackList (states);
|
|
|
67f8b7 |
+}
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
static void
|
|
|
67f8b7 |
meta_input_settings_x11_set_send_events (MetaInputSettings *settings,
|
|
|
67f8b7 |
ClutterInputDevice *device,
|
|
|
e47e58 |
@@ -167,6 +335,13 @@ meta_input_settings_x11_set_send_events (MetaInputSettings *settings,
|
|
|
67f8b7 |
guchar values[2] = { 0 }; /* disabled, disabled-on-external-mouse */
|
|
|
67f8b7 |
guchar *available;
|
|
|
67f8b7 |
|
|
|
67f8b7 |
+ if (is_device_synaptics (device))
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ values[0] = mode != G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED;
|
|
|
67f8b7 |
+ change_property (device, "Synaptics Off", XA_INTEGER, 8, &values, 1);
|
|
|
67f8b7 |
+ return;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
available = get_property (device, "libinput Send Events Modes Available",
|
|
|
67f8b7 |
XA_INTEGER, 8, 2);
|
|
|
67f8b7 |
if (!available)
|
|
|
e47e58 |
@@ -219,6 +394,12 @@ meta_input_settings_x11_set_speed (MetaInputSettings *settings,
|
|
|
67f8b7 |
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
|
|
67f8b7 |
gfloat value = speed;
|
|
|
67f8b7 |
|
|
|
67f8b7 |
+ if (is_device_synaptics (device))
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ change_synaptics_speed (device, speed);
|
|
|
67f8b7 |
+ return;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
change_property (device, "libinput Accel Speed",
|
|
|
67f8b7 |
XInternAtom (xdisplay, "FLOAT", False),
|
|
|
67f8b7 |
32, &value, 1);
|
|
|
e47e58 |
@@ -245,6 +426,19 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings *settings,
|
|
|
e47e58 |
else
|
|
|
e47e58 |
{
|
|
|
e47e58 |
value = enabled ? 1 : 0;
|
|
|
67f8b7 |
+
|
|
|
e47e58 |
+ if (is_device_synaptics (device))
|
|
|
e47e58 |
+ {
|
|
|
e47e58 |
+ GSettings *settings;
|
|
|
e47e58 |
+
|
|
|
e47e58 |
+ settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
|
|
|
e47e58 |
+ change_synaptics_tap_left_handed (device,
|
|
|
e47e58 |
+ g_settings_get_boolean (settings, "tap-to-click"),
|
|
|
e47e58 |
+ enabled);
|
|
|
e47e58 |
+ g_object_unref (settings);
|
|
|
e47e58 |
+ return;
|
|
|
e47e58 |
+ }
|
|
|
67f8b7 |
+
|
|
|
e47e58 |
change_property (device, "libinput Left Handed Enabled",
|
|
|
e47e58 |
XA_INTEGER, 8, &value, 1);
|
|
|
e47e58 |
}
|
|
|
e47e58 |
@@ -268,6 +462,20 @@ meta_input_settings_x11_set_tap_enabled (MetaInputSettings *settings,
|
|
|
67f8b7 |
{
|
|
|
67f8b7 |
guchar value = (enabled) ? 1 : 0;
|
|
|
67f8b7 |
|
|
|
67f8b7 |
+ if (is_device_synaptics (device))
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ GDesktopTouchpadHandedness handedness;
|
|
|
67f8b7 |
+ GSettings *settings;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
|
|
|
67f8b7 |
+ handedness = g_settings_get_enum (settings, "left-handed");
|
|
|
67f8b7 |
+ g_object_unref (settings);
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ change_synaptics_tap_left_handed (device, enabled,
|
|
|
67f8b7 |
+ handedness == G_DESKTOP_TOUCHPAD_HANDEDNESS_LEFT);
|
|
|
67f8b7 |
+ return;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
change_property (device, "libinput Tapping Enabled",
|
|
|
67f8b7 |
XA_INTEGER, 8, &value, 1);
|
|
|
67f8b7 |
}
|
|
|
e47e58 |
@@ -290,6 +498,27 @@ meta_input_settings_x11_set_invert_scroll (MetaInputSettings *settings,
|
|
|
67f8b7 |
{
|
|
|
67f8b7 |
guchar value = (inverted) ? 1 : 0;
|
|
|
67f8b7 |
|
|
|
67f8b7 |
+ if (is_device_synaptics (device))
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ gint32 *scrolling_distance;
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ scrolling_distance = get_property (device, "Synaptics Scrolling Distance",
|
|
|
67f8b7 |
+ XA_INTEGER, 32, 2);
|
|
|
67f8b7 |
+ if (scrolling_distance)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ scrolling_distance[0] = inverted ?
|
|
|
67f8b7 |
+ -abs (scrolling_distance[0]) : abs (scrolling_distance[0]);
|
|
|
67f8b7 |
+ scrolling_distance[1] = inverted ?
|
|
|
67f8b7 |
+ -abs (scrolling_distance[1]) : abs (scrolling_distance[1]);
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ change_property (device, "Synaptics Scrolling Distance",
|
|
|
67f8b7 |
+ XA_INTEGER, 32, scrolling_distance, 2);
|
|
|
67f8b7 |
+ meta_XFree (scrolling_distance);
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ return;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
change_property (device, "libinput Natural Scrolling Enabled",
|
|
|
67f8b7 |
XA_INTEGER, 8, &value, 1);
|
|
|
67f8b7 |
}
|
|
|
e47e58 |
@@ -303,6 +532,22 @@ meta_input_settings_x11_set_edge_scroll (MetaInputSettings *settings,
|
|
|
67f8b7 |
guchar *current = NULL;
|
|
|
67f8b7 |
guchar *available = NULL;
|
|
|
67f8b7 |
|
|
|
67f8b7 |
+ if (is_device_synaptics (device))
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ current = get_property (device, "Synaptics Edge Scrolling",
|
|
|
67f8b7 |
+ XA_INTEGER, 8, 3);
|
|
|
67f8b7 |
+ if (current)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ current[0] = !!edge_scroll_enabled;
|
|
|
67f8b7 |
+ current[1] = !!edge_scroll_enabled;
|
|
|
67f8b7 |
+ change_property (device, "Synaptics Edge Scrolling",
|
|
|
67f8b7 |
+ XA_INTEGER, 8, current, 3);
|
|
|
67f8b7 |
+ meta_XFree (current);
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ return;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
available = get_property (device, "libinput Scroll Methods Available",
|
|
|
67f8b7 |
XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS);
|
|
|
67f8b7 |
if (!available || !available[SCROLL_METHOD_FIELD_EDGE])
|
|
|
e47e58 |
@@ -332,6 +577,22 @@ meta_input_settings_x11_set_two_finger_scroll (MetaInputSettings *set
|
|
|
67f8b7 |
guchar *current = NULL;
|
|
|
67f8b7 |
guchar *available = NULL;
|
|
|
67f8b7 |
|
|
|
67f8b7 |
+ if (is_device_synaptics (device))
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ current = get_property (device, "Synaptics Two-Finger Scrolling",
|
|
|
67f8b7 |
+ XA_INTEGER, 8, 2);
|
|
|
67f8b7 |
+ if (current)
|
|
|
67f8b7 |
+ {
|
|
|
67f8b7 |
+ current[0] = !!two_finger_scroll_enabled;
|
|
|
67f8b7 |
+ current[1] = !!two_finger_scroll_enabled;
|
|
|
67f8b7 |
+ change_property (device, "Synaptics Two-Finger Scrolling",
|
|
|
67f8b7 |
+ XA_INTEGER, 8, current, 2);
|
|
|
67f8b7 |
+ meta_XFree (current);
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
+ return;
|
|
|
67f8b7 |
+ }
|
|
|
67f8b7 |
+
|
|
|
67f8b7 |
available = get_property (device, "libinput Scroll Methods Available",
|
|
|
67f8b7 |
XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS);
|
|
|
67f8b7 |
if (!available || !available[SCROLL_METHOD_FIELD_2FG])
|
|
|
67f8b7 |
--
|
|
|
e47e58 |
1.8.3.1
|
|
|
67f8b7 |
|