[Xfce4-commits] [xfce/xfce4-settings] 01/01: Add support for libinput Xorg driver

noreply at xfce.org noreply at xfce.org
Wed Feb 4 22:56:05 CET 2015


This is an automated email from the git hooks/post-receive script.

olivier pushed a commit to branch master
in repository xfce/xfce4-settings.

commit 49be65f8355aa54e28ac97fa569fc2b436d8b4b9
Author: Olivier Fourdan <fourdan at xfce.org>
Date:   Wed Feb 4 15:14:31 2015 +0100

    Add support for libinput Xorg driver
    
    Bug: 11469
    
    Signed-off-by: Olivier Fourdan <fourdan at xfce.org>
---
 configure.ac.in                           |   11 ++
 dialogs/mouse-settings/Makefile.am        |    2 +
 dialogs/mouse-settings/main.c             |  254 +++++++++++++++++++++++------
 dialogs/mouse-settings/mouse-dialog.glade |    8 +-
 xfsettingsd/Makefile.am                   |    2 +
 xfsettingsd/pointers.c                    |  110 ++++++++++++-
 6 files changed, 330 insertions(+), 57 deletions(-)

diff --git a/configure.ac.in b/configure.ac.in
index 0469194..9bdb4cd 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -158,6 +158,12 @@ dnl ************************************
 XDT_CHECK_OPTIONAL_PACKAGE([XCURSOR], [xcursor], [1.1.0],
                            [xcursor], [Cursor themes support])
 
+dnl *************************************************
+dnl *** Optional support for libinput Xorg driver ***
+dnl *************************************************
+XDT_CHECK_OPTIONAL_PACKAGE([LIBINPUT], [xorg-libinput], [0.6.0],
+                           [xorg-libinput], [libinput Xorg driver support])
+
 dnl ****************************************
 dnl *** Optional support for Libxklavier ***
 dnl ****************************************
@@ -272,6 +278,11 @@ echo "* Xcursor support:           yes"
 else
 echo "* Xcursor support:           no"
 fi
+if test x"$LIBINPUT_FOUND" = x"yes"; then
+echo "* Xorg libinput support:     yes"
+else
+echo "* Xorg libinput support:     no"
+fi
 if test x"$ENABLE_PLUGGABLE_DIALOGS" = x"1"; then
 echo "* Embedded settings dialogs  yes"
 else
diff --git a/dialogs/mouse-settings/Makefile.am b/dialogs/mouse-settings/Makefile.am
index 53de6ab..171a605 100644
--- a/dialogs/mouse-settings/Makefile.am
+++ b/dialogs/mouse-settings/Makefile.am
@@ -23,6 +23,7 @@ xfce4_mouse_settings_CFLAGS = \
 	$(XI_CFLAGS) \
 	$(XFCONF_CFLAGS) \
 	$(LIBX11_CFLAGS) \
+	$(LIBINPUT_CFLAGS) \
 	$(PLATFORM_CFLAGS)
 
 xfce4_mouse_settings_LDFLAGS = \
@@ -36,6 +37,7 @@ xfce4_mouse_settings_LDADD = \
 	$(XFCONF_LIBS) \
 	$(XI_LIBS) \
 	$(LIBX11_LIBS) \
+	$(LIBINPUT_LIBS) \
 	-lm
 
 if HAVE_XCURSOR
diff --git a/dialogs/mouse-settings/main.c b/dialogs/mouse-settings/main.c
index 46168e7..85f5cf3 100644
--- a/dialogs/mouse-settings/main.c
+++ b/dialogs/mouse-settings/main.c
@@ -36,6 +36,10 @@
 #include <X11/Xcursor/Xcursor.h>
 #endif /* !HAVE_XCURSOR */
 
+#ifdef HAVE_LIBINPUT
+#include "libinput-properties.h"
+#endif /* HAVE_LIBINPUT */
+
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
 
@@ -114,7 +118,17 @@ enum
     N_DEVICE_COLUMNS
 };
 
-
+typedef union
+{
+    gchar   c;
+    guchar  uc;
+    gint16  i16;
+    guint16 u16;
+    gint32  i32;
+    guint32 u32;
+    float   f;
+    Atom    a;
+} propdata_t;
 
 static gchar *
 mouse_settings_format_value_px (GtkScale *scale,
@@ -576,6 +590,128 @@ mouse_settings_themes_populate_store (GtkBuilder *builder)
 
 
 
+#ifdef HAVE_LIBINPUT
+/* FIXME: Completely overkill here and better suited in some common file */
+static gboolean
+mouse_settings_get_device_prop (Display     *xdisplay,
+                                XDevice     *device,
+                                const gchar *prop_name,
+                                Atom         type,
+                                propdata_t  *retval)
+{
+    Atom     prop, float_type, type_ret;
+    gulong   n_items, bytes_after;
+    gint     rc, format;
+    guchar  *data;
+    gboolean success;
+
+    prop = XInternAtom (xdisplay, prop_name, False);
+    float_type = XInternAtom (xdisplay, "FLOAT", False);
+
+    gdk_error_trap_push ();
+    rc = XGetDeviceProperty (xdisplay, device, prop, 0, 1, False,
+                             type, &type_ret, &format, &n_items,
+                             &bytes_after, &data);
+    gdk_error_trap_pop ();
+    if (rc == Success && type_ret == type && n_items > 0)
+    {
+        success = TRUE;
+        switch (type_ret)
+        {
+            case XA_INTEGER:
+                switch (format)
+                {
+                    case 8:
+                        retval->c = *((gchar*) data);
+                        break;
+                    case 16:
+                        retval->i16 = *((gint16 *) data);
+                        break;
+                    case 32:
+                        retval->i32 = *((gint32 *) data);
+                        break;
+                }
+                break;
+            case XA_CARDINAL:
+                switch (format)
+                {
+                    case 8:
+                        retval->uc = *((guchar*) data);
+                        break;
+                    case 16:
+                        retval->u16 = *((guint16 *) data);
+                        break;
+                    case 32:
+                        retval->u32 = *((guint32 *) data);
+                        break;
+                }
+                break;
+            case XA_ATOM:
+                retval->a = *((Atom *) data);
+                break;
+            default:
+                if (type_ret == float_type)
+                {
+                    retval->f = *((float*) data);
+                }
+                else
+                {
+                    success = FALSE;
+                    g_warning ("Unhandled type, please implement it");
+                }
+                break;
+        }
+        XFree (data);
+
+        return success;
+    }
+
+    return FALSE;
+}
+
+static gboolean
+mouse_settings_get_libinput_accel (Display *xdisplay,
+                                   XDevice *device,
+                                   gdouble *val)
+{
+    propdata_t pdata;
+    Atom float_type;
+
+    float_type = XInternAtom (xdisplay, "FLOAT", False);
+    if (mouse_settings_get_device_prop (xdisplay, device, LIBINPUT_PROP_ACCEL, float_type, &pdata))
+    {
+        /* We use double internally, for whatever reason */
+        *val = (gdouble) (pdata.f + 1.0) * 5.0;
+
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+
+
+static gboolean
+mouse_settings_get_libinput_boolean (Display     *xdisplay,
+                                     XDevice     *device,
+                                     const gchar *prop_name,
+                                     gboolean    *val)
+{
+    propdata_t pdata;
+
+    if (mouse_settings_get_device_prop (xdisplay, device, prop_name, XA_INTEGER, &pdata))
+    {
+        *val = (gboolean) (pdata.c);
+
+        return TRUE;
+    }
+
+    return FALSE;
+}
+#endif /* HAVE_LIBINPUT */
+
+
+
 #ifdef DEVICE_PROPERTIES
 static gint
 mouse_settings_device_get_int_property (XDevice *device,
@@ -989,6 +1125,9 @@ mouse_settings_device_selection_changed (GtkBuilder *builder)
     gint               ndevices;
     gboolean           is_synaptics = FALSE;
     gboolean           is_wacom = FALSE;
+    gboolean           is_libinput = FALSE;
+    gboolean           left_handed = FALSE;
+    gboolean           reverse_scrolling = FALSE;
 #ifdef DEVICE_PROPERTIES
     Atom               synaptics_prop;
     Atom               wacom_prop;
@@ -1047,63 +1186,73 @@ mouse_settings_device_selection_changed (GtkBuilder *builder)
 
             XFreeDeviceList (device_info);
         }
-
-        /* get the button mapping */
-        if (nbuttons > 0)
+#ifdef HAVE_LIBINPUT
+        is_libinput = mouse_settings_get_libinput_boolean (xdisplay, device, LIBINPUT_PROP_LEFT_HANDED, &left_handed);
+        mouse_settings_get_libinput_boolean (xdisplay, device, LIBINPUT_PROP_NATURAL_SCROLL, &reverse_scrolling);
+        if (!is_libinput)
+#endif /* HAVE_LIBINPUT */
         {
-            buttonmap = g_new0 (guchar, nbuttons);
-            gdk_error_trap_push ();
-            XGetDeviceButtonMapping (xdisplay, device, buttonmap, nbuttons);
-            if (gdk_error_trap_pop () != 0)
-                g_critical ("Failed to get button map");
-
-            /* figure out the position of the first and second/third button in the map */
-            for (i = 0; i < nbuttons; i++)
+            /* get the button mapping */
+            if (nbuttons > 0)
+            {
+                buttonmap = g_new0 (guchar, nbuttons);
+                gdk_error_trap_push ();
+                XGetDeviceButtonMapping (xdisplay, device, buttonmap, nbuttons);
+                if (gdk_error_trap_pop () != 0)
+                    g_critical ("Failed to get button map");
+
+                /* figure out the position of the first and second/third button in the map */
+                for (i = 0; i < nbuttons; i++)
+                {
+                    if (buttonmap[i] == 1)
+                        id_1 = i;
+                    else if (buttonmap[i] == (nbuttons < 3 ? 2 : 3))
+                        id_3 = i;
+                    else if (buttonmap[i] == 4)
+                        id_4 = i;
+                    else if (buttonmap[i] == 5)
+                        id_5 = i;
+                }
+                g_free (buttonmap);
+                left_handed = (id_1 > id_3);
+                reverse_scrolling = !!(id_5 < id_4);
+            }
+            else
             {
-                if (buttonmap[i] == 1)
-                    id_1 = i;
-                else if (buttonmap[i] == (nbuttons < 3 ? 2 : 3))
-                    id_3 = i;
-                else if (buttonmap[i] == 4)
-                    id_4 = i;
-                else if (buttonmap[i] == 5)
-                    id_5 = i;
+                g_critical ("Device has no buttons");
             }
-
-            g_free (buttonmap);
-        }
-        else
-        {
-            g_critical ("Device has no buttons");
-        }
-
-        /* get the feedback states for this device */
-        gdk_error_trap_push ();
-        states = XGetFeedbackControl (xdisplay, device, &nstates);
-        if (gdk_error_trap_pop () != 0 || states == NULL)
-        {
-             g_critical ("Failed to get feedback states");
         }
-        else
+#ifdef HAVE_LIBINPUT
+        if (!mouse_settings_get_libinput_accel (xdisplay, device, &acceleration))
+#endif /* HAVE_LIBINPUT */
         {
-            /* get the pointer feedback class */
-            for (pt = states, i = 0; i < nstates; i++)
+            /* get the feedback states for this device */
+            gdk_error_trap_push ();
+            states = XGetFeedbackControl (xdisplay, device, &nstates);
+            if (gdk_error_trap_pop () != 0 || states == NULL)
+            {
+                 g_critical ("Failed to get feedback states");
+            }
+            else
             {
-                if (pt->class == PtrFeedbackClass)
+                /* get the pointer feedback class */
+                for (pt = states, i = 0; i < nstates; i++)
                 {
-                    /* get the state */
-                    state = (XPtrFeedbackState *) pt;
-                    acceleration = (gdouble) state->accelNum / (gdouble) state->accelDenom;
-                    threshold = state->threshold;
+                    if (pt->class == PtrFeedbackClass)
+                    {
+                        /* get the state */
+                        state = (XPtrFeedbackState *) pt;
+                        acceleration = (gdouble) state->accelNum / (gdouble) state->accelDenom;
+                        threshold = state->threshold;
+                    }
+
+                    /* advance the offset */
+                    pt = (XFeedbackState *) ((gchar *) pt + pt->length);
                 }
 
-                /* advance the offset */
-                pt = (XFeedbackState *) ((gchar *) pt + pt->length);
+                XFreeFeedbackList (states);
             }
-
-            XFreeFeedbackList (states);
         }
-
 #ifdef DEVICE_PROPERTIES
         /* wacom and synaptics specific properties */
         device_enabled_prop = XInternAtom (xdisplay, "Device Enabled", True);
@@ -1149,7 +1298,7 @@ mouse_settings_device_selection_changed (GtkBuilder *builder)
     }
 
     /* update button order */
-    object = gtk_builder_get_object (builder, id_1 > id_3 ? "device-left-handed" : "device-right-handed");
+    object = gtk_builder_get_object (builder, left_handed ? "device-left-handed" : "device-right-handed");
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), TRUE);
 
     object = gtk_builder_get_object (builder, "device-reverse-scrolling");
@@ -1164,7 +1313,9 @@ mouse_settings_device_selection_changed (GtkBuilder *builder)
     /* update threshold scale */
     object = gtk_builder_get_object (builder, "device-threshold-scale");
     gtk_range_set_value (GTK_RANGE (object), threshold);
-    gtk_widget_set_sensitive (GTK_WIDGET (object), threshold != -1);
+    gtk_widget_set_visible (GTK_WIDGET (object), threshold != -1);
+    object = gtk_builder_get_object (builder, "device-threshold-label");
+    gtk_widget_set_visible (GTK_WIDGET (object), threshold != -1);
 
     object = gtk_builder_get_object (builder, "device-enabled");
 #ifdef DEVICE_PROPERTIES
@@ -1177,6 +1328,11 @@ mouse_settings_device_selection_changed (GtkBuilder *builder)
     gtk_widget_set_visible (GTK_WIDGET (object), FALSE);
 #endif
 
+#ifdef HAVE_LIBINPUT
+    object = gtk_builder_get_object (builder, "device-reset-feedback");
+    gtk_widget_set_visible (GTK_WIDGET (object), !is_libinput);
+#endif /* HAVE_LIBINPUT */
+
     /* synaptics options */
     object = gtk_builder_get_object (builder, "synaptics-tab");
     gtk_widget_set_visible (GTK_WIDGET (object), is_synaptics);
diff --git a/dialogs/mouse-settings/mouse-dialog.glade b/dialogs/mouse-settings/mouse-dialog.glade
index dc1f208..1783d42 100644
--- a/dialogs/mouse-settings/mouse-dialog.glade
+++ b/dialogs/mouse-settings/mouse-dialog.glade
@@ -17,10 +17,10 @@
     <property name="page_increment">100</property>
   </object>
   <object class="GtkAdjustment" id="device-acceleration">
-    <property name="lower">0.10000000000000001</property>
+    <property name="lower">0</property>
     <property name="upper">10</property>
     <property name="value">2</property>
-    <property name="step_increment">0.10000000000000001</property>
+    <property name="step_increment">0.1</property>
     <property name="page_increment">1</property>
   </object>
   <object class="GtkAdjustment" id="device-threshold">
@@ -43,10 +43,10 @@
     <property name="stock">gtk-revert-to-saved</property>
   </object>
   <object class="GtkAdjustment" id="synaptics-disable-duration">
-    <property name="lower">0.10000000000000001</property>
+    <property name="lower">0.1</property>
     <property name="upper">4</property>
     <property name="value">2</property>
-    <property name="step_increment">0.10000000000000001</property>
+    <property name="step_increment">0.1</property>
     <property name="page_increment">1</property>
   </object>
   <object class="GtkListStore" id="synaptics-scroll-store">
diff --git a/xfsettingsd/Makefile.am b/xfsettingsd/Makefile.am
index a04fbd2..7815b12 100644
--- a/xfsettingsd/Makefile.am
+++ b/xfsettingsd/Makefile.am
@@ -54,6 +54,7 @@ xfsettingsd_CFLAGS = \
 	$(LIBX11_CFLAGS) \
 	$(LIBNOTIFY_CFLAGS) \
 	$(FONTCONFIG_CFLAGS) \
+	$(LIBINPUT_CFLAGS) \
 	$(PLATFORM_CFLAGS)
 
 xfsettingsd_LDFLAGS = \
@@ -75,6 +76,7 @@ xfsettingsd_LDADD = \
 	$(LIBX11_LIBS) \
 	$(LIBNOTIFY_LIBS) \
 	$(FONTCONFIG_LIBS) \
+	$(LIBINPUT_LIBS) \
 	-lm
 
 #
diff --git a/xfsettingsd/pointers.c b/xfsettingsd/pointers.c
index d081c0d..a871c2b 100644
--- a/xfsettingsd/pointers.c
+++ b/xfsettingsd/pointers.c
@@ -30,6 +30,10 @@
 #include <string.h>
 #endif
 
+#ifdef HAVE_LIBINPUT
+#include "libinput-properties.h"
+#endif /* HAVE_LIBINPUT */
+
 #include <glib.h>
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
@@ -42,7 +46,6 @@
 #include "pointers.h"
 #include "pointers-defines.h"
 
-
 #define MAX_DENOMINATOR (100.00)
 
 #define XFCONF_TYPE_G_VALUE_ARRAY (dbus_g_type_get_collection ("GPtrArray", G_TYPE_VALUE))
@@ -190,6 +193,65 @@ xfce_pointers_helper_finalize (GObject *object)
 
 
 
+#ifdef HAVE_LIBINPUT
+static gboolean
+xfce_pointers_is_libinput (Display *xdisplay,
+                           XDevice *device)
+{
+    Atom     prop, type;
+    gulong   n_items, bytes_after;
+    gint     rc, format;
+    guchar  *data;
+
+    prop = XInternAtom (xdisplay, LIBINPUT_PROP_LEFT_HANDED, False);
+    gdk_error_trap_push ();
+    rc = XGetDeviceProperty (xdisplay, device, prop, 0, 1, False,
+                             XA_INTEGER, &type, &format, &n_items,
+                             &bytes_after, &data);
+    gdk_error_trap_pop ();
+    if (rc == Success)
+    {
+        XFree (data);
+        return (n_items > 0);
+    }
+
+    return FALSE;
+}
+
+static void
+xfce_pointers_change_property (XDeviceInfo  *device_info,
+                               XDevice      *device,
+                               Display      *xdisplay,
+                               const gchar  *prop_name,
+                               Atom          type,
+                               int           format,
+                               void         *data,
+                               gulong        nitems)
+{
+    gulong nitems_ret, bytes_after_ret;
+    gint rc, format_ret;
+    Atom prop, type_ret;
+    guchar *data_ret;
+
+    prop = XInternAtom (xdisplay, prop_name, False);
+    rc = XGetDeviceProperty (xdisplay, device, prop, 0, 0, False,
+                             type, &type_ret, &format_ret,
+                             &nitems_ret, &bytes_after_ret, &data_ret);
+    if (rc == Success)
+    {
+        XFree (data_ret);
+
+        if (type_ret == type && format_ret == format)
+        {
+            XChangeDeviceProperty (xdisplay, device, prop, type,
+                                   format, PropModeReplace, data, nitems);
+        }
+    }
+}
+#endif /* HAVE_LIBINPUT */
+
+
+
 static void
 xfce_pointers_helper_syndaemon_stop (XfcePointersHelper *helper)
 {
@@ -355,6 +417,29 @@ xfce_pointers_helper_change_button_mapping (XDeviceInfo *device_info,
     gint          right_button;
     GString      *readable_map;
 
+#ifdef HAVE_LIBINPUT
+    if (xfce_pointers_is_libinput (xdisplay, device))
+    {
+        if (right_handed != -1)
+        {
+            gboolean left_handed = !right_handed;
+
+            xfce_pointers_change_property (device_info, device, xdisplay,
+                                           LIBINPUT_PROP_LEFT_HANDED,
+                                           XA_INTEGER, 8, &left_handed, 1);
+        }
+
+        if (reverse_scrolling != -1)
+        {
+            xfce_pointers_change_property (device_info, device, xdisplay,
+                                           LIBINPUT_PROP_NATURAL_SCROLL,
+                                           XA_INTEGER, 8, &reverse_scrolling, 1);
+        }
+
+        return;
+    }
+#endif /* HAVE_LIBINPUT */
+
     /* search the number of buttons */
     for (n = 0, ptr = device_info->inputclassinfo; n < device_info->num_classes; n++)
     {
@@ -464,6 +549,20 @@ xfce_pointers_helper_change_feedback (XDeviceInfo *device_info,
     gint                 num, denom, gcd;
     gboolean             found = FALSE;
 
+#ifdef HAVE_LIBINPUT
+    if (xfce_pointers_is_libinput (xdisplay, device))
+    {
+        gfloat libinput_accel;
+
+        libinput_accel = (acceleration / 5) - 1.0;
+        xfce_pointers_change_property (device_info, device, xdisplay,
+                                       LIBINPUT_PROP_ACCEL,
+                                       XInternAtom (xdisplay, "FLOAT", False),
+                                       32, &libinput_accel, 1);
+
+        return;
+    }
+#endif /* HAVE_LIBINPUT */
     /* get the feedback states for this device */
     gdk_error_trap_push ();
     states = XGetFeedbackControl (xdisplay, device, &num_feedbacks);
@@ -497,9 +596,9 @@ xfce_pointers_helper_change_feedback (XDeviceInfo *device_info,
 
         /* above 0 is a valid value, -1 is reset, -2.00
          * is passed if no change is required */
-        if (acceleration > 0 || acceleration == -1)
+        if (acceleration >= 0 || acceleration == -1)
         {
-            if (acceleration > 0)
+            if (acceleration >= 0)
             {
                 /* calculate the faction of the acceleration */
                 num = acceleration * MAX_DENOMINATOR;
@@ -642,6 +741,7 @@ xfce_pointers_helper_change_property (XDeviceInfo  *device_info,
         guchar *c;
         gshort *s;
         glong  *l;
+        float  *f;
         Atom   *a;
     } data;
 
@@ -734,7 +834,7 @@ xfce_pointers_helper_change_property (XDeviceInfo  *device_info,
                          && type == float_atom
                          && format == 32)
                 {
-                    data.l[i] = g_value_get_double (val);
+                    data.f[i] = (float) g_value_get_double (val);
                 }
                 else
                 {
@@ -771,9 +871,11 @@ xfce_pointers_helper_change_property (XDeviceInfo  *device_info,
 
     XFree (props);
 }
+#endif
 
 
 
+#ifdef DEVICE_PROPERTIES
 static void
 xfce_pointers_helper_change_properties (gpointer key,
                                         gpointer value,

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list