From c131a9b7fa79e53b5ed008d0fe53cf2062d3663d Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 13 Dec 2019 14:22:12 +0100 Subject: [PATCH 38/48] 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 --- src/backends/x11/meta-input-device-x11.c | 75 ++++++++++++++++++++---- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/src/backends/x11/meta-input-device-x11.c b/src/backends/x11/meta-input-device-x11.c index 26a40620f..af07c34f6 100644 --- a/src/backends/x11/meta-input-device-x11.c +++ b/src/backends/x11/meta-input-device-x11.c @@ -393,6 +393,57 @@ meta_input_device_x11_get_pad_group_mode (ClutterInputDevice *device, return g_array_index (device_xi2->group_modes, uint32_t, group); } +static gboolean +pad_switch_mode (ClutterInputDevice *device, + uint32_t button, + uint32_t group, + uint32_t *mode) +{ + MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (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 = meta_input_device_x11_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_index (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 meta_input_device_x11_update_pad_state (ClutterInputDevice *device, uint32_t button, @@ -402,26 +453,26 @@ meta_input_device_x11_update_pad_state (ClutterInputDevice *device, { MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device); uint32_t button_group, *group_mode; - gboolean is_mode_switch = FALSE; button_group = meta_input_device_x11_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) + { + if (group) + *group = 0; + if (mode) + *mode = 0; + return; + } group_mode = &g_array_index (device_xi2->group_modes, uint32_t, button_group); - if (is_mode_switch && state) + if (state) { - uint32_t 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.26.0.rc2