From a8f12e7afdb35ebda581cee6a32b295cb6e643ec Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 13 Dec 2019 14:22:12 +0100 Subject: [PATCH] backends/x11: Observe multiple pad mode switch buttons in a group Some tablets like the Cintiq 24HDT have several mode switch buttons per group. Those are meant to jump straight to a given mode, however we just handle cycling across modes (as most other tablets have a single mode switch button per group). So spice up the mode switch handling so we handle multiple mode switch buttons, assigning each of them a mode. If the device only has one mode switch button, we do the old-fashioned cycling. https://gitlab.gnome.org/GNOME/mutter/merge_requests/970 --- .../clutter/x11/clutter-input-device-xi2.c | 71 ++++++++++++++++--- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c index 1254aca3a..c33adffc2 100644 --- a/clutter/clutter/x11/clutter-input-device-xi2.c +++ b/clutter/clutter/x11/clutter-input-device-xi2.c @@ -318,6 +318,57 @@ clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device, return g_array_index (device_xi2->group_modes, guint, group); } +static gboolean +pad_switch_mode (ClutterInputDevice *device, + uint32_t button, + uint32_t group, + uint32_t *mode) +{ + ClutterInputDeviceXI2 *device_x11 = CLUTTER_INPUT_DEVICE_XI2 (device); + uint32_t n_buttons, n_modes, button_group, next_mode, i; + GList *switch_buttons = NULL; + + n_buttons = libwacom_get_num_buttons (device_x11->wacom_device); + + for (i = 0; i < n_buttons; i++) + { + button_group = clutter_input_device_xi2_get_button_group (device, i); + if (button_group == group) + switch_buttons = g_list_prepend (switch_buttons, GINT_TO_POINTER (button)); + } + + switch_buttons = g_list_reverse (switch_buttons); + n_modes = clutter_input_device_get_group_n_modes (device, group); + + if (g_list_length (switch_buttons) > 1) + { + /* If there's multiple switch buttons, we don't toggle but assign a mode + * to each of those buttons. + */ + next_mode = g_list_position (switch_buttons, GINT_TO_POINTER (button)); + } + else if (switch_buttons) + { + uint32_t cur_mode; + + /* If there is a single button, have it toggle across modes */ + cur_mode = g_array_index (device_x11->group_modes, uint32_t, group); + next_mode = (cur_mode + 1) % n_modes; + } + else + { + return FALSE; + } + + g_list_free (switch_buttons); + + if (next_mode < 0 || next_mode > n_modes) + return FALSE; + + *mode = next_mode; + return TRUE; +} + void clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device, guint button, @@ -330,23 +381,21 @@ clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device, gboolean is_mode_switch = FALSE; button_group = clutter_input_device_xi2_get_button_group (device, button); - is_mode_switch = button_group >= 0; - /* Assign all non-mode-switch buttons to group 0 so far */ - button_group = MAX (0, button_group); - - if (button_group >= device_xi2->group_modes->len) - return; + if (button_group < 0 || button_group >= device_xi2->group_modes->len) + { + *group = *mode = 0; + return; + } group_mode = &g_array_index (device_xi2->group_modes, guint, button_group); - if (is_mode_switch && state) + if (state) { - guint next, n_modes; + uint32_t next_mode; - n_modes = clutter_input_device_get_group_n_modes (device, button_group); - next = (*group_mode + 1) % n_modes; - *group_mode = next; + if (pad_switch_mode (device, button, button_group, &next_mode)) + *group_mode = next_mode; } if (group) -- 2.23.0