Add middle mouse button emulation config options
authorPeter Hutterer <peter.hutterer@who-t.net>
Tue, 14 Apr 2015 02:08:33 +0000 (12:08 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Fri, 17 Apr 2015 02:49:43 +0000 (12:49 +1000)
Adds the following quartett of functions to enable/disable middle mouse button
emulation on a device:
libinput_device_config_middle_emulation_is_available()
libinput_device_config_middle_emulation_set_enabled()
libinput_device_config_middle_emulation_get_enabled()
libinput_device_config_middle_emulation_get_default_enabled()

This patch only adds the config framework, it is not hooked up to anything
yet.

Note: like other features this is merely the config option, some devices will
provide middle button emulation without exposing it as configuration. i.e. the
return value of libinput_device_config_middle_emulation_is_available() only
tells you whether you can _configure_ middle button emulation.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
src/libinput-private.h
src/libinput.c
src/libinput.h
src/libinput.sym
tools/shared.c
tools/shared.h

index 36b3b40..cec529c 100644 (file)
@@ -178,6 +178,17 @@ struct libinput_device_config_click_method {
        enum libinput_config_click_method (*get_default_method)(struct libinput_device *device);
 };
 
+struct libinput_device_config_middle_emulation {
+       int (*available)(struct libinput_device *device);
+       enum libinput_config_status (*set)(
+                        struct libinput_device *device,
+                        enum libinput_config_middle_emulation_state);
+       enum libinput_config_middle_emulation_state (*get)(
+                        struct libinput_device *device);
+       enum libinput_config_middle_emulation_state (*get_default)(
+                        struct libinput_device *device);
+};
+
 struct libinput_device_config {
        struct libinput_device_config_tap *tap;
        struct libinput_device_config_calibration *calibration;
@@ -187,6 +198,7 @@ struct libinput_device_config {
        struct libinput_device_config_left_handed *left_handed;
        struct libinput_device_config_scroll_method *scroll_method;
        struct libinput_device_config_click_method *click_method;
+       struct libinput_device_config_middle_emulation *middle_emulation;
 };
 
 struct libinput_device_group {
index 980b44a..7dcf296 100644 (file)
@@ -1966,6 +1966,55 @@ libinput_device_config_click_get_default_method(struct libinput_device *device)
                return LIBINPUT_CONFIG_CLICK_METHOD_NONE;
 }
 
+LIBINPUT_EXPORT int
+libinput_device_config_middle_emulation_is_available(
+               struct libinput_device *device)
+{
+       if (device->config.middle_emulation)
+               return device->config.middle_emulation->available(device);
+       else
+               return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED;
+}
+
+LIBINPUT_EXPORT enum libinput_config_status
+libinput_device_config_middle_emulation_set_enabled(
+               struct libinput_device *device,
+               enum libinput_config_middle_emulation_state enable)
+{
+       switch (enable) {
+       case LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED:
+       case LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED:
+               break;
+       default:
+               return LIBINPUT_CONFIG_STATUS_INVALID;
+       }
+
+       if (!libinput_device_config_middle_emulation_is_available(device))
+               return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
+
+       return device->config.middle_emulation->set(device, enable);
+}
+
+LIBINPUT_EXPORT enum libinput_config_middle_emulation_state
+libinput_device_config_middle_emulation_get_enabled(
+               struct libinput_device *device)
+{
+       if (!libinput_device_config_middle_emulation_is_available(device))
+               return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED;
+
+       return device->config.middle_emulation->get(device);
+}
+
+LIBINPUT_EXPORT enum libinput_config_middle_emulation_state
+libinput_device_config_middle_emulation_get_default_enabled(
+               struct libinput_device *device)
+{
+       if (!libinput_device_config_middle_emulation_is_available(device))
+               return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED;
+
+       return device->config.middle_emulation->get_default(device);
+}
+
 LIBINPUT_EXPORT uint32_t
 libinput_device_config_scroll_get_methods(struct libinput_device *device)
 {
index 356c1bf..b4b373e 100644 (file)
@@ -2441,6 +2441,130 @@ libinput_device_config_click_get_default_method(struct libinput_device *device);
 
 /**
  * @ingroup config
+ */
+enum libinput_config_middle_emulation_state {
+       /**
+        * Middle mouse button emulation is to be disabled, or
+        * is currently disabled.
+        */
+       LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED,
+       /**
+        * Middle mouse button emulation is to be enabled, or
+        * is currently enabled.
+        */
+       LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED,
+};
+
+/**
+ * @ingroup config
+ *
+ * Check if middle mouse button emulation configuration is available on this
+ * device. See libinput_device_config_middle_emulation_set_enabled() for
+ * details.
+ *
+ * @note Some devices provide middle mouse button emulation but do not allow
+ * enabling/disabling that emulation. These devices return zero in
+ * libinput_device_config_middle_emulation_is_available().
+ *
+ * @param device The device to query
+ *
+ * @return Non-zero if middle mouse button emulation is available and can be
+ * configured, zero otherwise.
+ *
+ * @see libinput_device_config_middle_emulation_set_enabled
+ * @see libinput_device_config_middle_emulation_get_enabled
+ * @see libinput_device_config_middle_emulation_get_default_enabled
+ */
+int
+libinput_device_config_middle_emulation_is_available(
+               struct libinput_device *device);
+
+/**
+ * @ingroup config
+ *
+ * Enable or disable middle button emulation on this device. When enabled, a
+ * simultaneous press of the left and right button generates a middle mouse
+ * button event. Releasing the buttons generates a middle mouse button
+ * release, the left and right button events are discarded otherwise.
+ *
+ * The middle button release event may be generated when either button is
+ * released, or when both buttons have been released. The exact behavior is
+ * device-dependent.
+ *
+ * The middle button emulation behavior when combined with other device
+ * buttons, including a physical middle button is device-dependent.
+ *
+ * @note Some devices provide middle mouse button emulation but do not allow
+ * enabling/disabling that emulation.
+ *
+ * @param device The device to configure
+ * @param enable @ref LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED to
+ * disable, @ref LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED To enable
+ * middle button emulation.
+ *
+ * @return A config status code. Disabling middle button emulation on a
+ * device that does not support middle button emulation always succeeds.
+ *
+ * @see libinput_device_config_middle_emulation_is_available
+ * @see libinput_device_config_middle_emulation_get_enabled
+ * @see libinput_device_config_middle_emulation_get_default_enabled
+ */
+enum libinput_config_status
+libinput_device_config_middle_emulation_set_enabled(
+               struct libinput_device *device,
+               enum libinput_config_middle_emulation_state enable);
+
+/**
+ * @ingroup config
+ *
+ * Check if configurable middle button emulation is enabled on this device.
+ * If the device does not have configurable middle button emulation, this
+ * function returns @ref LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED.
+ *
+ * @note Some devices provide middle mouse button emulation but do not allow
+ * enabling/disabling that emulation. These devices always return @ref
+ * LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED.
+ *
+ * @param device The device to configure
+ * @return @ref LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED if disabled
+ * or not available/configurable, @ref
+ * LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED If enabled.
+ *
+ * @see libinput_device_config_middle_emulation_is_available
+ * @see libinput_device_config_middle_emulation_set_enabled
+ * @see libinput_device_config_middle_emulation_get_default_enabled
+ */
+enum libinput_config_middle_emulation_state
+libinput_device_config_middle_emulation_get_enabled(
+               struct libinput_device *device);
+
+/**
+ * @ingroup config
+ *
+ * Check if configurable middle button emulation is enabled by default on
+ * this device. If the device does not have configurable middle button
+ * emulation, this function returns @ref
+ * LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED.
+ *
+ * @note Some devices provide middle mouse button emulation but do not allow
+ * enabling/disabling that emulation. These devices always return @ref
+ * LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED.
+ *
+ * @param device The device to configure
+ * @return @ref LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED If disabled
+ * or not available, @ref LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED if
+ * enabled.
+ *
+ * @see libinput_device_config_middle_emulation_is_available
+ * @see libinput_device_config_middle_emulation_set_enabled
+ * @see libinput_device_config_middle_emulation_get_enabled
+ */
+enum libinput_config_middle_emulation_state
+libinput_device_config_middle_emulation_get_default_enabled(
+               struct libinput_device *device);
+
+/**
+ * @ingroup config
  *
  * The scroll method of a device selects when to generate scroll axis events
  * instead of pointer motion events.
index f9da905..3c47ee5 100644 (file)
@@ -127,3 +127,11 @@ global:
 local:
        *;
 };
+
+LIBINPUT_0.14.0 {
+global:
+       libinput_device_config_middle_emulation_is_available;
+       libinput_device_config_middle_emulation_set_enabled;
+       libinput_device_config_middle_emulation_get_enabled;
+       libinput_device_config_middle_emulation_get_default_enabled;
+} LIBINPUT_0.12.0;
index b169049..d8d23a7 100644 (file)
@@ -43,6 +43,8 @@ enum options {
        OPT_NATURAL_SCROLL_DISABLE,
        OPT_LEFT_HANDED_ENABLE,
        OPT_LEFT_HANDED_DISABLE,
+       OPT_MIDDLEBUTTON_ENABLE,
+       OPT_MIDDLEBUTTON_DISABLE,
        OPT_CLICK_METHOD,
        OPT_SPEED,
 };
@@ -71,6 +73,8 @@ tools_usage()
               "--disable-natural-scrolling.... enable/disable natural scrolling\n"
               "--enable-left-handed\n"
               "--disable-left-handed.... enable/disable left-handed button configuration\n"
+              "--enable-middlebutton\n"
+              "--disable-middlebutton.... enable/disable middle button emulation\n"
               "--set-click-method=[none|clickfinger|buttonareas] .... set the desired click method\n"
               "--set-speed=<value>.... set pointer acceleration speed\n"
               "\n"
@@ -90,6 +94,7 @@ tools_init_options(struct tools_options *options)
        options->tapping = -1;
        options->natural_scroll = -1;
        options->left_handed = -1;
+       options->middlebutton = -1;
        options->click_method = -1;
        options->backend = BACKEND_UDEV;
        options->seat = "seat0";
@@ -113,6 +118,8 @@ tools_parse_args(int argc, char **argv, struct tools_options *options)
                        { "disable-natural-scrolling", 0, 0, OPT_NATURAL_SCROLL_DISABLE },
                        { "enable-left-handed", 0, 0, OPT_LEFT_HANDED_ENABLE },
                        { "disable-left-handed", 0, 0, OPT_LEFT_HANDED_DISABLE },
+                       { "enable-middlebutton", 0, 0, OPT_MIDDLEBUTTON_ENABLE },
+                       { "disable-middlebutton", 0, 0, OPT_MIDDLEBUTTON_DISABLE },
                        { "set-click-method", 1, 0, OPT_CLICK_METHOD },
                        { "speed", 1, 0, OPT_SPEED },
                        { 0, 0, 0, 0}
@@ -161,6 +168,12 @@ tools_parse_args(int argc, char **argv, struct tools_options *options)
                        case OPT_LEFT_HANDED_DISABLE:
                                options->left_handed = 0;
                                break;
+                       case OPT_MIDDLEBUTTON_ENABLE:
+                               options->middlebutton = 1;
+                               break;
+                       case OPT_MIDDLEBUTTON_DISABLE:
+                               options->middlebutton = 0;
+                               break;
                        case OPT_CLICK_METHOD:
                                if (!optarg) {
                                        tools_usage();
@@ -297,6 +310,9 @@ tools_device_apply_config(struct libinput_device *device,
                                                                         options->natural_scroll);
        if (options->left_handed != -1)
                libinput_device_config_left_handed_set(device, options->left_handed);
+       if (options->middlebutton != -1)
+               libinput_device_config_middle_emulation_set_enabled(device,
+                                                                   options->middlebutton);
 
        if (options->click_method != -1)
                libinput_device_config_click_set_method(device, options->click_method);
index caf4855..01edffc 100644 (file)
@@ -39,6 +39,7 @@ struct tools_options {
        int tapping;
        int natural_scroll;
        int left_handed;
+       int middlebutton;
        enum libinput_config_click_method click_method;
        double speed;
 };