diff options
| author | Olivier Fourdan <fourdan@xfce.org> | 2015-02-04 15:14:31 +0100 |
|---|---|---|
| committer | Olivier Fourdan <ofourdan@redhat.com> | 2015-02-04 22:56:00 +0100 |
| commit | 49be65f8355aa54e28ac97fa569fc2b436d8b4b9 (patch) | |
| tree | 6f800355ad205100d64f81574b4e154652fed798 | |
| parent | 5a7f55a049147320adb8e2dc8495d6f868c4d6ac (diff) | |
| download | xfce4-settings-49be65f8355aa54e28ac97fa569fc2b436d8b4b9.tar.gz | |
Add support for libinput Xorg driver
Bug #11469
Signed-off-by: Olivier Fourdan <fourdan@xfce.org>
| -rw-r--r-- | configure.ac.in | 11 | ||||
| -rw-r--r-- | dialogs/mouse-settings/Makefile.am | 2 | ||||
| -rw-r--r-- | dialogs/mouse-settings/main.c | 254 | ||||
| -rw-r--r-- | dialogs/mouse-settings/mouse-dialog.glade | 8 | ||||
| -rw-r--r-- | xfsettingsd/Makefile.am | 2 | ||||
| -rw-r--r-- | 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, |