clutter: Add vmethod to find out group for pad features

Do it so the wayland bits don't have to access native input devices
internals. The data is still readonly, idempotent, etc.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
This commit is contained in:
Carlos Garnacho 2020-11-19 18:51:58 +01:00 committed by Marge Bot
parent 18fdcfc95a
commit f117a157dc
7 changed files with 178 additions and 88 deletions

View File

@ -1611,6 +1611,13 @@ typedef enum
CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER, CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER,
} ClutterInputDevicePadSource; } ClutterInputDevicePadSource;
typedef enum
{
CLUTTER_PAD_FEATURE_BUTTON,
CLUTTER_PAD_FEATURE_RING,
CLUTTER_PAD_FEATURE_STRIP,
} ClutterInputDevicePadFeature;
typedef enum typedef enum
{ {
CLUTTER_INPUT_CONTENT_HINT_COMPLETION = 1 << 0, CLUTTER_INPUT_CONTENT_HINT_COMPLETION = 1 << 0,

View File

@ -67,6 +67,7 @@ enum
PROP_N_STRIPS, PROP_N_STRIPS,
PROP_N_RINGS, PROP_N_RINGS,
PROP_N_MODE_GROUPS, PROP_N_MODE_GROUPS,
PROP_N_BUTTONS,
PROP_DEVICE_NODE, PROP_DEVICE_NODE,
PROP_LAST PROP_LAST
@ -100,6 +101,7 @@ struct _ClutterInputDevicePrivate
int n_rings; int n_rings;
int n_strips; int n_strips;
int n_mode_groups; int n_mode_groups;
int n_buttons;
gboolean has_cursor; gboolean has_cursor;
}; };
@ -216,6 +218,10 @@ clutter_input_device_set_property (GObject *gobject,
priv->n_mode_groups = g_value_get_int (value); priv->n_mode_groups = g_value_get_int (value);
break; break;
case PROP_N_BUTTONS:
priv->n_buttons = g_value_get_int (value);
break;
case PROP_DEVICE_NODE: case PROP_DEVICE_NODE:
priv->node_path = g_value_dup_string (value); priv->node_path = g_value_dup_string (value);
break; break;
@ -282,6 +288,10 @@ clutter_input_device_get_property (GObject *gobject,
g_value_set_int (value, priv->n_mode_groups); g_value_set_int (value, priv->n_mode_groups);
break; break;
case PROP_N_BUTTONS:
g_value_set_int (value, priv->n_buttons);
break;
case PROP_DEVICE_NODE: case PROP_DEVICE_NODE:
g_value_set_string (value, priv->node_path); g_value_set_string (value, priv->node_path);
break; break;
@ -432,6 +442,13 @@ clutter_input_device_class_init (ClutterInputDeviceClass *klass)
0, G_MAXINT, 0, 0, G_MAXINT, 0,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
obj_props[PROP_N_BUTTONS] =
g_param_spec_int ("n-buttons",
P_("Number of buttons"),
P_("Number of buttons"),
0, G_MAXINT, 0,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
obj_props[PROP_DEVICE_NODE] = obj_props[PROP_DEVICE_NODE] =
g_param_spec_string ("device-node", g_param_spec_string ("device-node",
P_("Device node path"), P_("Device node path"),
@ -1236,6 +1253,19 @@ clutter_input_device_get_n_mode_groups (ClutterInputDevice *device)
return priv->n_mode_groups; return priv->n_mode_groups;
} }
gint
clutter_input_device_get_n_buttons (ClutterInputDevice *device)
{
ClutterInputDevicePrivate *priv =
clutter_input_device_get_instance_private (device);
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0);
g_return_val_if_fail (clutter_input_device_get_device_type (device) ==
CLUTTER_PAD_DEVICE, 0);
return priv->n_buttons;
}
gint gint
clutter_input_device_get_group_n_modes (ClutterInputDevice *device, clutter_input_device_get_group_n_modes (ClutterInputDevice *device,
gint group) gint group)
@ -1295,6 +1325,22 @@ clutter_input_device_get_mode_switch_button_group (ClutterInputDevice *device,
return -1; return -1;
} }
int
clutter_input_device_get_pad_feature_group (ClutterInputDevice *device,
ClutterInputDevicePadFeature feature,
int n_feature)
{
ClutterInputDeviceClass *device_class;
device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device);
if (!device_class->get_pad_feature_group)
return 0;
return CLUTTER_INPUT_DEVICE_GET_CLASS (device)->get_pad_feature_group (device,
feature,
n_feature);
}
const gchar * const gchar *
clutter_input_device_get_device_node (ClutterInputDevice *device) clutter_input_device_get_device_node (ClutterInputDevice *device)
{ {

View File

@ -50,6 +50,10 @@ struct _ClutterInputDeviceClass
gboolean (* is_grouped) (ClutterInputDevice *device, gboolean (* is_grouped) (ClutterInputDevice *device,
ClutterInputDevice *other_device); ClutterInputDevice *other_device);
int (* get_pad_feature_group) (ClutterInputDevice *device,
ClutterInputDevicePadFeature feature,
int n_feature);
/* Keyboard accessbility */ /* Keyboard accessbility */
void (* process_kbd_a11y_event) (ClutterEvent *event, void (* process_kbd_a11y_event) (ClutterEvent *event,
ClutterInputDevice *device, ClutterInputDevice *device,
@ -128,6 +132,9 @@ CLUTTER_EXPORT
gint clutter_input_device_get_n_strips (ClutterInputDevice *device); gint clutter_input_device_get_n_strips (ClutterInputDevice *device);
CLUTTER_EXPORT CLUTTER_EXPORT
gint clutter_input_device_get_n_mode_groups (ClutterInputDevice *device); gint clutter_input_device_get_n_mode_groups (ClutterInputDevice *device);
CLUTTER_EXPORT
int clutter_input_device_get_n_buttons (ClutterInputDevice *device);
CLUTTER_EXPORT CLUTTER_EXPORT
gint clutter_input_device_get_group_n_modes (ClutterInputDevice *device, gint clutter_input_device_get_group_n_modes (ClutterInputDevice *device,
@ -150,6 +157,11 @@ gboolean clutter_input_device_is_grouped (ClutterInputDev
CLUTTER_EXPORT CLUTTER_EXPORT
ClutterSeat * clutter_input_device_get_seat (ClutterInputDevice *device); ClutterSeat * clutter_input_device_get_seat (ClutterInputDevice *device);
CLUTTER_EXPORT
int clutter_input_device_get_pad_feature_group (ClutterInputDevice *device,
ClutterInputDevicePadFeature feature,
int n_feature);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_INPUT_DEVICE_H__ */ #endif /* __CLUTTER_INPUT_DEVICE_H__ */

View File

@ -52,6 +52,15 @@ typedef struct _SlowKeysEventPending
guint timer; guint timer;
} SlowKeysEventPending; } SlowKeysEventPending;
typedef struct _PadFeature PadFeature;
struct _PadFeature
{
ClutterInputDevicePadFeature feature;
int n_feature;
int group;
};
static void clear_slow_keys (MetaInputDeviceNative *device); static void clear_slow_keys (MetaInputDeviceNative *device);
static void stop_bounce_keys (MetaInputDeviceNative *device); static void stop_bounce_keys (MetaInputDeviceNative *device);
static void stop_toggle_slowkeys (MetaInputDeviceNative *device); static void stop_toggle_slowkeys (MetaInputDeviceNative *device);
@ -70,6 +79,8 @@ meta_input_device_native_finalize (GObject *object)
stop_toggle_slowkeys (device_evdev); stop_toggle_slowkeys (device_evdev);
stop_mousekeys_move (device_evdev); stop_mousekeys_move (device_evdev);
g_clear_pointer (&device_evdev->pad_features, g_array_unref);
G_OBJECT_CLASS (meta_input_device_native_parent_class)->finalize (object); G_OBJECT_CLASS (meta_input_device_native_parent_class)->finalize (object);
} }
@ -160,6 +171,31 @@ meta_input_device_native_is_grouped (ClutterInputDevice *device,
libinput_device_get_device_group (other_libinput_device); libinput_device_get_device_group (other_libinput_device);
} }
static int
meta_input_device_native_get_pad_feature_group (ClutterInputDevice *device,
ClutterInputDevicePadFeature feature,
int n_feature)
{
MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
int i;
if (!device_native->pad_features)
return -1;
for (i = 0; i < device_native->pad_features->len; i++)
{
PadFeature *pad_feature;
pad_feature = &g_array_index (device_native->pad_features, PadFeature, i);
if (pad_feature->feature == feature &&
pad_feature->n_feature == n_feature)
return pad_feature->group;
}
return -1;
}
static void static void
meta_input_device_native_bell_notify (MetaInputDeviceNative *device) meta_input_device_native_bell_notify (MetaInputDeviceNative *device)
{ {
@ -1183,17 +1219,18 @@ meta_input_device_native_a11y_maybe_notify_toggle_keys (MetaInputDeviceNative *d
static void static void
meta_input_device_native_class_init (MetaInputDeviceNativeClass *klass) meta_input_device_native_class_init (MetaInputDeviceNativeClass *klass)
{ {
ClutterInputDeviceClass *device_manager_class = CLUTTER_INPUT_DEVICE_CLASS (klass); ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_input_device_native_finalize; object_class->finalize = meta_input_device_native_finalize;
object_class->set_property = meta_input_device_native_set_property; object_class->set_property = meta_input_device_native_set_property;
object_class->get_property = meta_input_device_native_get_property; object_class->get_property = meta_input_device_native_get_property;
device_manager_class->is_mode_switch_button = meta_input_device_native_is_mode_switch_button; device_class->is_mode_switch_button = meta_input_device_native_is_mode_switch_button;
device_manager_class->get_group_n_modes = meta_input_device_native_get_group_n_modes; device_class->get_group_n_modes = meta_input_device_native_get_group_n_modes;
device_manager_class->is_grouped = meta_input_device_native_is_grouped; device_class->is_grouped = meta_input_device_native_is_grouped;
device_manager_class->process_kbd_a11y_event = meta_input_device_native_process_kbd_a11y_event; device_class->get_pad_feature_group = meta_input_device_native_get_pad_feature_group;
device_class->process_kbd_a11y_event = meta_input_device_native_process_kbd_a11y_event;
obj_props[PROP_DEVICE_MATRIX] = obj_props[PROP_DEVICE_MATRIX] =
g_param_spec_boxed ("device-matrix", g_param_spec_boxed ("device-matrix",
@ -1219,6 +1256,53 @@ meta_input_device_native_init (MetaInputDeviceNative *self)
self->output_ratio = 0; self->output_ratio = 0;
} }
static void
update_pad_features (MetaInputDeviceNative *device_native)
{
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_native);
struct libinput_device *libinput_device;
struct libinput_tablet_pad_mode_group *mode_group;
int n_groups, n_buttons, n_rings, n_strips, i, j;
libinput_device = meta_input_device_native_get_libinput_device (device);
n_rings = libinput_device_tablet_pad_get_num_rings (libinput_device);
n_strips = libinput_device_tablet_pad_get_num_strips (libinput_device);
n_groups = libinput_device_tablet_pad_get_num_mode_groups (libinput_device);
n_buttons = libinput_device_tablet_pad_get_num_buttons (libinput_device);
device_native->pad_features = g_array_new (FALSE, FALSE, sizeof (PadFeature));
for (i = 0; i < n_groups; i++)
{
mode_group =
libinput_device_tablet_pad_get_mode_group (libinput_device, i);
for (j = 0; j < n_buttons; j++)
{
PadFeature feature = { CLUTTER_PAD_FEATURE_BUTTON, j, i };
if (libinput_tablet_pad_mode_group_has_button (mode_group, j))
g_array_append_val (device_native->pad_features, feature);
}
for (j = 0; j < n_rings; j++)
{
PadFeature feature = { CLUTTER_PAD_FEATURE_RING, j, i };
if (libinput_tablet_pad_mode_group_has_ring (mode_group, j))
g_array_append_val (device_native->pad_features, feature);
}
for (j = 0; j < n_strips; j++)
{
PadFeature feature = { CLUTTER_PAD_FEATURE_STRIP, j, i };
if (libinput_tablet_pad_mode_group_has_strip (mode_group, j))
g_array_append_val (device_native->pad_features, feature);
}
}
}
/* /*
* meta_input_device_native_new: * meta_input_device_native_new:
* @manager: the device manager * @manager: the device manager
@ -1235,7 +1319,7 @@ meta_input_device_native_new (MetaSeatImpl *seat_impl,
MetaInputDeviceNative *device; MetaInputDeviceNative *device;
ClutterInputDeviceType type; ClutterInputDeviceType type;
char *vendor, *product; char *vendor, *product;
int n_rings = 0, n_strips = 0, n_groups = 1; int n_rings = 0, n_strips = 0, n_groups = 1, n_buttons = 0;
char *node_path; char *node_path;
double width, height; double width, height;
@ -1250,6 +1334,7 @@ meta_input_device_native_new (MetaSeatImpl *seat_impl,
n_rings = libinput_device_tablet_pad_get_num_rings (libinput_device); n_rings = libinput_device_tablet_pad_get_num_rings (libinput_device);
n_strips = libinput_device_tablet_pad_get_num_strips (libinput_device); n_strips = libinput_device_tablet_pad_get_num_strips (libinput_device);
n_groups = libinput_device_tablet_pad_get_num_mode_groups (libinput_device); n_groups = libinput_device_tablet_pad_get_num_mode_groups (libinput_device);
n_buttons = libinput_device_tablet_pad_get_num_buttons (libinput_device);
} }
device = g_object_new (META_TYPE_INPUT_DEVICE_NATIVE, device = g_object_new (META_TYPE_INPUT_DEVICE_NATIVE,
@ -1261,6 +1346,7 @@ meta_input_device_native_new (MetaSeatImpl *seat_impl,
"n-rings", n_rings, "n-rings", n_rings,
"n-strips", n_strips, "n-strips", n_strips,
"n-mode-groups", n_groups, "n-mode-groups", n_groups,
"n-buttons", n_buttons,
"device-node", node_path, "device-node", node_path,
"seat", seat_impl->seat_native, "seat", seat_impl->seat_native,
NULL); NULL);
@ -1274,6 +1360,10 @@ meta_input_device_native_new (MetaSeatImpl *seat_impl,
g_free (product); g_free (product);
g_free (node_path); g_free (node_path);
if (libinput_device_has_capability (libinput_device,
LIBINPUT_DEVICE_CAP_TABLET_PAD))
update_pad_features (device);
if (libinput_device_get_size (libinput_device, &width, &height) == 0) if (libinput_device_get_size (libinput_device, &width, &height) == 0)
device->device_aspect_ratio = width / height; device->device_aspect_ratio = width / height;

View File

@ -71,6 +71,7 @@ struct _MetaInputDeviceNative
struct libinput_device *libinput_device; struct libinput_device *libinput_device;
MetaSeatImpl *seat_impl; MetaSeatImpl *seat_impl;
ClutterInputDeviceTool *last_tool; ClutterInputDeviceTool *last_tool;
GArray *pad_features;
cairo_matrix_t device_matrix; cairo_matrix_t device_matrix;
double device_aspect_ratio; /* w:h */ double device_aspect_ratio; /* w:h */

View File

@ -32,12 +32,6 @@
#include "wayland/meta-wayland-tablet-pad.h" #include "wayland/meta-wayland-tablet-pad.h"
#include "wayland/meta-wayland-tablet-seat.h" #include "wayland/meta-wayland-tablet-seat.h"
#ifdef HAVE_NATIVE_BACKEND
#include "backends/native/meta-backend-native.h"
#include "backends/native/meta-event-native.h"
#include "backends/native/meta-input-device-native.h"
#endif
#include "tablet-unstable-v2-server-protocol.h" #include "tablet-unstable-v2-server-protocol.h"
static void static void
@ -123,26 +117,14 @@ gboolean
meta_wayland_tablet_pad_group_has_button (MetaWaylandTabletPadGroup *group, meta_wayland_tablet_pad_group_has_button (MetaWaylandTabletPadGroup *group,
guint button) guint button)
{ {
#ifdef HAVE_NATIVE_BACKEND int n_group = g_list_index (group->pad->groups, group);
MetaBackend *backend = meta_get_backend ();
if (META_IS_BACKEND_NATIVE (backend)) if (clutter_input_device_get_pad_feature_group (group->pad->device,
{ CLUTTER_PAD_FEATURE_BUTTON,
struct libinput_device *libinput_device; button) == n_group)
struct libinput_tablet_pad_mode_group *mode_group; return TRUE;
guint n_group;
libinput_device = meta_input_device_native_get_libinput_device (group->pad->device); return FALSE;
n_group = g_list_index (group->pad->groups, group);
mode_group = libinput_device_tablet_pad_get_mode_group (libinput_device, n_group);
return libinput_tablet_pad_mode_group_has_button (mode_group, button);
}
else
#endif
{
return g_list_length (group->pad->groups) == 1;
}
} }
static void static void

View File

@ -38,12 +38,6 @@
#include "wayland/meta-wayland-tablet-seat.h" #include "wayland/meta-wayland-tablet-seat.h"
#include "wayland/meta-wayland-tablet.h" #include "wayland/meta-wayland-tablet.h"
#ifdef HAVE_NATIVE_BACKEND
#include <libinput.h>
#include "backends/native/meta-backend-native.h"
#include "backends/native/meta-input-device-native.h"
#endif
#include "tablet-unstable-v2-server-protocol.h" #include "tablet-unstable-v2-server-protocol.h"
static void static void
@ -66,41 +60,20 @@ group_rings_strips (MetaWaylandTabletPad *pad)
{ {
gint n_group, n_elem; gint n_group, n_elem;
GList *g, *l; GList *g, *l;
#ifdef HAVE_NATIVE_BACKEND
MetaBackend *backend = meta_get_backend ();
struct libinput_device *libinput_device = NULL;
if (META_IS_BACKEND_NATIVE (backend))
libinput_device = meta_input_device_native_get_libinput_device (pad->device);
#endif
for (n_group = 0, g = pad->groups; g; g = g->next) for (n_group = 0, g = pad->groups; g; g = g->next)
{ {
MetaWaylandTabletPadGroup *group = g->data; MetaWaylandTabletPadGroup *group = g->data;
#ifdef HAVE_NATIVE_BACKEND
struct libinput_tablet_pad_mode_group *mode_group = NULL;
if (libinput_device)
mode_group = libinput_device_tablet_pad_get_mode_group (libinput_device, n_group);
#endif
for (n_elem = 0, l = pad->rings; l; l = l->next) for (n_elem = 0, l = pad->rings; l; l = l->next)
{ {
MetaWaylandTabletPadRing *ring = l->data; MetaWaylandTabletPadRing *ring = l->data;
#ifdef HAVE_NATIVE_BACKEND if (clutter_input_device_get_pad_feature_group (pad->device,
if (mode_group) CLUTTER_PAD_FEATURE_RING,
{ n_elem) == n_group)
if (libinput_tablet_pad_mode_group_has_ring (mode_group, n_elem)) meta_wayland_tablet_pad_ring_set_group (ring, group);
meta_wayland_tablet_pad_ring_set_group (ring, group);
}
else
#endif
{
/* Assign everything to the first group */
if (n_group == 0)
meta_wayland_tablet_pad_ring_set_group (ring, group);
}
n_elem++; n_elem++;
} }
@ -108,19 +81,10 @@ group_rings_strips (MetaWaylandTabletPad *pad)
{ {
MetaWaylandTabletPadStrip *strip = l->data; MetaWaylandTabletPadStrip *strip = l->data;
#ifdef HAVE_NATIVE_BACKEND if (clutter_input_device_get_pad_feature_group (pad->device,
if (mode_group) CLUTTER_PAD_FEATURE_STRIP,
{ n_elem) == n_group)
if (libinput_tablet_pad_mode_group_has_strip (mode_group, n_elem)) meta_wayland_tablet_pad_strip_set_group (strip, group);
meta_wayland_tablet_pad_strip_set_group (strip, group);
}
else
#endif
{
/* Assign everything to the first group */
if (n_group == 0)
meta_wayland_tablet_pad_strip_set_group (strip, group);
}
n_elem++; n_elem++;
} }
@ -133,9 +97,6 @@ MetaWaylandTabletPad *
meta_wayland_tablet_pad_new (ClutterInputDevice *device, meta_wayland_tablet_pad_new (ClutterInputDevice *device,
MetaWaylandTabletSeat *tablet_seat) MetaWaylandTabletSeat *tablet_seat)
{ {
#ifdef HAVE_NATIVE_BACKEND
MetaBackend *backend = meta_get_backend ();
#endif
MetaWaylandTabletPad *pad; MetaWaylandTabletPad *pad;
guint n_elems, i; guint n_elems, i;
@ -149,16 +110,7 @@ meta_wayland_tablet_pad_new (ClutterInputDevice *device,
pad->feedback = g_hash_table_new_full (NULL, NULL, NULL, pad->feedback = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) g_free); (GDestroyNotify) g_free);
#ifdef HAVE_NATIVE_BACKEND pad->n_buttons = clutter_input_device_get_n_buttons (device);
/* Buttons, only can be honored this with the native backend */
if (META_IS_BACKEND_NATIVE (backend))
{
struct libinput_device *libinput_device;
libinput_device = meta_input_device_native_get_libinput_device (device);
pad->n_buttons = libinput_device_tablet_pad_get_num_buttons (libinput_device);
}
#endif
n_elems = clutter_input_device_get_n_mode_groups (pad->device); n_elems = clutter_input_device_get_n_mode_groups (pad->device);