X.Org Bug 89332 <http://bugs.freedesktop.org/show_bug.cgi?id=89332>

Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
---
 include/libinput-properties.h |   8 +++
 man/libinput.man              |   8 +++
 src/libinput.c                | 160 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 176 insertions(+)

diff --git a/include/libinput-properties.h b/include/libinput-properties.h
index bbc85d0..1d7b416 100644
--- a/include/libinput-properties.h
+++ b/include/libinput-properties.h
@@ -58,4 +58,12 @@
 /* Scroll button for button scrolling: 32-bit int, 1 value */
 #define LIBINPUT_PROP_SCROLL_BUTTON "libinput Button Scrolling Button"
 
+/* Click method: BOOL read-only, 2 values in order buttonareas, clickfinger
+   shows available click methods */
+#define LIBINPUT_PROP_CLICK_METHODS_AVAILABLE "libinput Click Methods 
Available"
+
+/* Click method: BOOL, 2 values in order buttonareas, clickfinger
+   only one enabled at a time at max */
+#define LIBINPUT_PROP_CLICK_METHOD_ENABLED "libinput Click Method Enabled"
+
 #endif /* _LIBINPUT_PROPERTIES_H_ */
diff --git a/man/libinput.man b/man/libinput.man
index 692d56a..f4e9bed 100644
--- a/man/libinput.man
+++ b/man/libinput.man
@@ -53,6 +53,14 @@ A string of 9 space-separated floating point numbers.
 Sets the calibration matrix to the 3x3 matrix where the first row is (abc),
 the second row is (def) and the third row is (ghi).
 .TP 7
+.BI "Option \*qClickMethod\*q \*q" string \*q
+Enables a click method. Permitted values are
+.BI none,
+.BI buttonareas,
+.BI clickfinger.
+Not all devices support all methods, if an option is unsupported, the
+default click method for this device is used.
+.TP 7
 .BI "Option \*qLeftHanded\*q \*q" bool \*q
 Enables left-handed button orientation, i.e. swapping left and right buttons.
 .TP 7
diff --git a/src/libinput.c b/src/libinput.c
index 9be17b4..5bcb995 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -94,6 +94,7 @@ struct xf86libinput {
                float speed;
                float matrix[9];
                enum libinput_config_scroll_method scroll_method;
+               enum libinput_config_click_method click_method;
        } options;
 };
 
@@ -291,6 +292,23 @@ LibinputApplyConfig(DeviceIntPtr dev)
                                    "Failed to set ScrollButton to %d\n",
                                    driver_data->options.scroll_button);
        }
+
+       if (libinput_device_config_click_set_method(device,
+                                                   
driver_data->options.click_method) != LIBINPUT_CONFIG_STATUS_SUCCESS) {
+               const char *method;
+
+               switch (driver_data->options.click_method) {
+               case LIBINPUT_CONFIG_CLICK_METHOD_NONE: method = "none"; break;
+               case LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS: method = 
"buttonareas"; break;
+               case LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER: method = 
"clickfinger"; break;
+               default:
+                       method = "unknown"; break;
+               }
+
+               xf86IDrvMsg(pInfo, X_ERROR,
+                           "Failed to set click method to %s\n",
+                           method);
+       }
 }
 
 static int
@@ -948,6 +966,7 @@ xf86libinput_parse_options(InputInfoPtr pInfo,
                           struct libinput_device *device)
 {
        uint32_t scroll_methods;
+       uint32_t click_methods;
 
        if (libinput_device_config_tap_get_finger_count(device) > 0) {
                BOOL tap = xf86SetBoolOption(pInfo->options,
@@ -1118,6 +1137,31 @@ xf86libinput_parse_options(InputInfoPtr pInfo,
                driver_data->options.scroll_button = scroll_button;
        }
 
+       click_methods = libinput_device_config_click_get_methods(device);
+       if (click_methods != LIBINPUT_CONFIG_CLICK_METHOD_NONE) {
+               enum libinput_config_click_method m;
+               char *method = xf86SetStrOption(pInfo->options,
+                                               "ClickMethod",
+                                               NULL);
+
+               if (!method)
+                       m = libinput_device_config_click_get_method(device);
+               else if (strncasecmp(method, "buttonareas", 11) == 0)
+                       m = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
+               else if (strncasecmp(method, "clickfinger", 11) == 0)
+                       m = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
+               else if (strncasecmp(method, "none", 4) == 0)
+                       m = LIBINPUT_CONFIG_CLICK_METHOD_NONE;
+               else {
+                       xf86IDrvMsg(pInfo, X_ERROR,
+                                   "Unknown click method '%s'. Using 
default.\n",
+                                   method);
+                       m = libinput_device_config_click_get_method(device);
+               }
+
+               driver_data->options.click_method = m;
+               free(method);
+       }
 }
 
 static int
@@ -1287,6 +1331,8 @@ static Atom prop_left_handed;
 static Atom prop_scroll_methods_available;
 static Atom prop_scroll_method_enabled;
 static Atom prop_scroll_button;
+static Atom prop_click_methods_available;
+static Atom prop_click_method_enabled;
 
 /* general properties */
 static Atom prop_float;
@@ -1593,6 +1639,48 @@ LibinputSetPropertyScrollButton(DeviceIntPtr dev,
        return Success;
 }
 
+static inline int
+LibinputSetPropertyClickMethod(DeviceIntPtr dev,
+                              Atom atom,
+                              XIPropertyValuePtr val,
+                              BOOL checkonly)
+{
+       InputInfoPtr pInfo = dev->public.devicePrivate;
+       struct xf86libinput *driver_data = pInfo->private;
+       struct libinput_device *device = driver_data->device;
+       BOOL* data;
+       uint32_t modes = 0;
+
+       if (val->format != 8 || val->size != 2 || val->type != XA_INTEGER)
+               return BadMatch;
+
+       data = (BOOL*)val->data;
+
+       if (data[0])
+               modes |= LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
+       if (data[1])
+               modes |= LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
+
+       if (checkonly) {
+               uint32_t supported;
+
+               if (__builtin_popcount(modes) > 1)
+                       return BadValue;
+
+               if (!xf86libinput_check_device(dev, atom))
+                       return BadMatch;
+
+               supported = libinput_device_config_click_get_methods(device);
+               if (modes && (modes & supported) == 0)
+                       return BadValue;
+       } else {
+               driver_data->options.click_method = modes;
+       }
+
+       return Success;
+}
+
+
 static int
 LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
                  BOOL checkonly)
@@ -1620,6 +1708,10 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, 
XIPropertyValuePtr val,
                rc = LibinputSetPropertyScrollMethods(dev, atom, val, 
checkonly);
        else if (atom == prop_scroll_button)
                rc = LibinputSetPropertyScrollButton(dev, atom, val, checkonly);
+       else if (atom == prop_click_methods_available)
+               return BadAccess; /* read-only */
+       else if (atom == prop_click_method_enabled)
+               rc = LibinputSetPropertyClickMethod(dev, atom, val, checkonly);
        else if (atom == prop_device || atom == prop_product_id)
                return BadAccess; /* read-only */
        else
@@ -1884,6 +1976,73 @@ LibinputInitScrollMethodsProperty(DeviceIntPtr dev,
 }
 
 static void
+LibinputInitClickMethodsProperty(DeviceIntPtr dev,
+                                struct xf86libinput *driver_data,
+                                struct libinput_device *device)
+{
+       uint32_t click_methods;
+       enum libinput_config_click_method method;
+       BOOL methods[2] = {FALSE};
+       int rc;
+
+       click_methods = libinput_device_config_click_get_methods(device);
+       if (click_methods == LIBINPUT_CONFIG_CLICK_METHOD_NONE)
+               return;
+
+       if (click_methods & LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS)
+               methods[0] = TRUE;
+       if (click_methods & LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER)
+               methods[1] = TRUE;
+
+       prop_click_methods_available =
+               MakeAtom(LIBINPUT_PROP_CLICK_METHODS_AVAILABLE,
+                        strlen(LIBINPUT_PROP_CLICK_METHODS_AVAILABLE),
+                        TRUE);
+       rc = XIChangeDeviceProperty(dev,
+                                   prop_click_methods_available,
+                                   XA_INTEGER, 8,
+                                   PropModeReplace,
+                                   ARRAY_SIZE(methods),
+                                   &methods, FALSE);
+       if (rc != Success)
+               return;
+       XISetDevicePropertyDeletable(dev,
+                                    prop_click_methods_available,
+                                    FALSE);
+
+       memset(methods, 0, sizeof(methods));
+
+       method = libinput_device_config_click_get_method(device);
+       switch(method) {
+       case LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS:
+               methods[0] = TRUE;
+               break;
+       case LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER:
+               methods[1] = TRUE;
+               break;
+       default:
+               break;
+       }
+
+       prop_click_method_enabled =
+               MakeAtom(LIBINPUT_PROP_CLICK_METHOD_ENABLED,
+                        strlen(LIBINPUT_PROP_CLICK_METHOD_ENABLED),
+                        TRUE);
+       rc = XIChangeDeviceProperty(dev,
+                                   prop_click_method_enabled,
+                                   XA_INTEGER, 8,
+                                   PropModeReplace,
+                                   ARRAY_SIZE(methods),
+                                   &methods, FALSE);
+       if (rc != Success)
+               return;
+
+       XISetDevicePropertyDeletable(dev,
+                                    prop_click_method_enabled,
+                                    FALSE);
+}
+
+static void
 LibinputInitProperty(DeviceIntPtr dev)
 {
        InputInfoPtr pInfo  = dev->public.devicePrivate;
@@ -1902,6 +2061,7 @@ LibinputInitProperty(DeviceIntPtr dev)
        LibinputInitSendEventsProperty(dev, driver_data, device);
        LibinputInitLeftHandedProperty(dev, driver_data, device);
        LibinputInitScrollMethodsProperty(dev, driver_data, device);
+       LibinputInitClickMethodsProperty(dev, driver_data, device);
 
        /* Device node property, read-only  */
        device_node = driver_data->path;
-- 
2.1.0

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to