From fba1122a3c292fd2a8f79df5ce07611d553811c6 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 5 Jun 2020 22:39:55 +0200 Subject: [PATCH 01/85] clutter: Add ClutterSeat::query_state() vmethod This will query a device state; position and modifiers. Note that ClutterSeat subclasses don't implement the vmethod yet, so calling clutter_seat_query_state() may crash ATM. Part-of: --- clutter/clutter/clutter-seat.c | 17 +++++++++++++++++ clutter/clutter/clutter-seat.h | 13 +++++++++++++ 2 files changed, 30 insertions(+) diff --git a/clutter/clutter/clutter-seat.c b/clutter/clutter/clutter-seat.c index 96bb0e9303e..77d8d523123 100644 --- a/clutter/clutter/clutter-seat.c +++ b/clutter/clutter/clutter-seat.c @@ -776,3 +776,20 @@ clutter_seat_has_touchscreen (ClutterSeat *seat) return has_touchscreen; } + +gboolean +clutter_seat_query_state (ClutterSeat *seat, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + graphene_point_t *coords, + ClutterModifierType *modifiers) +{ + g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); + + return CLUTTER_SEAT_GET_CLASS (seat)->query_state (seat, + device, + sequence, + coords, + modifiers); +} diff --git a/clutter/clutter/clutter-seat.h b/clutter/clutter/clutter-seat.h index 33497a43fc9..36bcd49cb30 100644 --- a/clutter/clutter/clutter-seat.h +++ b/clutter/clutter/clutter-seat.h @@ -113,6 +113,12 @@ struct _ClutterSeatClass int x, int y); + gboolean (* query_state) (ClutterSeat *seat, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + graphene_point_t *coords, + ClutterModifierType *modifiers); + /* Event platform data */ void (* copy_event_data) (ClutterSeat *seat, const ClutterEvent *src, @@ -197,4 +203,11 @@ gboolean clutter_seat_get_touch_mode (ClutterSeat *seat); CLUTTER_EXPORT gboolean clutter_seat_has_touchscreen (ClutterSeat *seat); +CLUTTER_EXPORT +gboolean clutter_seat_query_state (ClutterSeat *seat, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + graphene_point_t *coords, + ClutterModifierType *modifiers); + #endif /* CLUTTER_SEAT_H */ -- GitLab From 384b97792d7276ead3c6769806c78330f9d2c853 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 5 Jun 2020 22:40:32 +0200 Subject: [PATCH 02/85] backends/x11: Implement ClutterSeat::query_state() vmethod Part-of: --- src/backends/x11/meta-seat-x11.c | 164 +++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index 841eb9e27e4..f50c4fd8b39 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -19,7 +19,9 @@ #include "config.h" #include +#include +#include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-event-x11.h" #include "backends/x11/meta-input-device-tool-x11.h" #include "backends/x11/meta-input-device-x11.h" @@ -44,6 +46,15 @@ enum PROP_TOUCH_MODE, }; +typedef struct _MetaTouchInfo MetaTouchInfo; + +struct _MetaTouchInfo +{ + ClutterEventSequence *sequence; + double x; + double y; +}; + struct _MetaSeatX11 { ClutterSeat parent_instance; @@ -52,6 +63,7 @@ struct _MetaSeatX11 GList *devices; GHashTable *devices_by_id; GHashTable *tools_by_serial; + GHashTable *touch_coords; MetaKeymapX11 *keymap; int pointer_id; @@ -1500,6 +1512,7 @@ meta_seat_x11_finalize (GObject *object) g_hash_table_unref (seat_x11->devices_by_id); g_hash_table_unref (seat_x11->tools_by_serial); + g_hash_table_unref (seat_x11->touch_coords); g_list_free (seat_x11->devices); G_OBJECT_CLASS (meta_seat_x11_parent_class)->finalize (object); @@ -1598,6 +1611,140 @@ meta_seat_x11_warp_pointer (ClutterSeat *seat, x, y); } +static uint32_t +translate_state (XIButtonState *button_state, + XIModifierState *modifier_state, + XIGroupState *group_state) +{ + uint32_t state = 0; + int i; + + if (modifier_state) + state |= modifier_state->effective; + + if (button_state) + { + for (i = 1; i < XIMaskLen (button_state->mask_len); i++) + { + if (!XIMaskIsSet (button_state->mask, i)) + continue; + + switch (i) + { + case 1: + state |= CLUTTER_BUTTON1_MASK; + break; + case 2: + state |= CLUTTER_BUTTON2_MASK; + break; + case 3: + state |= CLUTTER_BUTTON3_MASK; + break; + case 8: + state |= CLUTTER_BUTTON4_MASK; + break; + case 9: + state |= CLUTTER_BUTTON5_MASK; + break; + default: + break; + } + } + } + + if (group_state) + state = XkbBuildCoreState (group_state->effective, state); + + return state; +} + +static gboolean +meta_seat_x11_query_state (ClutterSeat *seat, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + graphene_point_t *coords, + ClutterModifierType *modifiers) +{ + MetaBackendX11 *backend_x11 = META_BACKEND_X11 (meta_get_backend ()); + MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); + Window root_ret, child_ret; + double root_x, root_y, win_x, win_y; + XIButtonState button_state; + XIModifierState modifier_state; + XIGroupState group_state; + + clutter_x11_trap_x_errors (); + XIQueryPointer (clutter_x11_get_default_display (), + seat_x11->pointer_id, + meta_backend_x11_get_xwindow (backend_x11), + &root_ret, &child_ret, + &root_x, &root_y, &win_x, &win_y, + &button_state, &modifier_state, &group_state); + if (clutter_x11_untrap_x_errors ()) + return FALSE; + + if (sequence) + { + MetaTouchInfo *touch_info; + + touch_info = g_hash_table_lookup (seat_x11->touch_coords, sequence); + if (!touch_info) + return FALSE; + + if (coords) + { + coords->x = touch_info->x; + coords->y = touch_info->y; + } + } + else + { + if (coords) + { + coords->x = win_x; + coords->y = win_y; + } + } + + if (modifiers) + *modifiers = translate_state (&button_state, &modifier_state, &group_state); + + return TRUE; +} + +static void +meta_seat_x11_update_touchpoint (MetaSeatX11 *seat, + ClutterEventSequence *sequence, + double x, + double y) +{ + MetaTouchInfo *touch_info; + + touch_info = g_hash_table_lookup (seat->touch_coords, sequence); + if (!touch_info) + { + touch_info = g_new0 (MetaTouchInfo, 1); + touch_info->sequence = sequence; + g_hash_table_insert (seat->touch_coords, sequence, touch_info); + } + + touch_info->x = x; + touch_info->y = y; +} + +static void +meta_seat_x11_remove_touchpoint (MetaSeatX11 *seat, + ClutterEventSequence *sequence) +{ + g_hash_table_remove (seat->touch_coords, sequence); +} + +static void +meta_touch_info_free (MetaTouchInfo *touch_info) +{ + g_free (touch_info); +} + static void meta_seat_x11_class_init (MetaSeatX11Class *klass) { @@ -1621,6 +1768,7 @@ meta_seat_x11_class_init (MetaSeatX11Class *klass) seat_class->get_supported_virtual_device_types = meta_seat_x11_get_supported_virtual_device_types; seat_class->warp_pointer = meta_seat_x11_warp_pointer; seat_class->handle_device_event = meta_seat_x11_handle_device_event; + seat_class->query_state = meta_seat_x11_query_state; props[PROP_OPCODE] = g_param_spec_int ("opcode", @@ -1658,6 +1806,8 @@ meta_seat_x11_init (MetaSeatX11 *seat) (GDestroyNotify) g_object_unref); seat->tools_by_serial = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref); + seat->touch_coords = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) meta_touch_info_free); } MetaSeatX11 * @@ -2162,6 +2312,15 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, event->touch.modifier_state |= CLUTTER_BUTTON1_MASK; meta_stage_x11_set_user_time (stage_x11, event->touch.time); + meta_seat_x11_update_touchpoint (seat, + GUINT_TO_POINTER (xev->detail), + xev->root_x, + xev->root_y); + } + else if (xi_event->evtype == XI_TouchEnd) + { + meta_seat_x11_remove_touchpoint (seat, + GUINT_TO_POINTER (xev->detail)); } event->touch.sequence = GUINT_TO_POINTER (xev->detail); @@ -2216,6 +2375,11 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, if (xev->flags & XITouchEmulatingPointer) _clutter_event_set_pointer_emulated (event, TRUE); + meta_seat_x11_update_touchpoint (seat, + event->touch.sequence, + xev->root_x, + xev->root_y); + g_debug ("touch update: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f, axes:%s)", (unsigned int) stage_x11->xwin, meta_input_device_x11_get_device_id (event->touch.device), -- GitLab From 9d195b3fa42e5e2abc352256268f94838f131207 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 5 Jun 2020 22:41:03 +0200 Subject: [PATCH 03/85] backends/native: Implement ClutterSeat::query_state() vmethod Part-of: --- src/backends/native/meta-seat-native.c | 49 ++++++++++++++++++++++++++ src/backends/native/meta-xkb-utils.c | 12 +++++++ src/backends/native/meta-xkb-utils.h | 2 ++ 3 files changed, 63 insertions(+) diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index e2f62b09b32..1bfac5d8640 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -2833,6 +2833,54 @@ meta_seat_native_warp_pointer (ClutterSeat *seat, meta_cursor_tracker_update_position (cursor_tracker, x, y); } +static gboolean +meta_seat_native_query_state (ClutterSeat *seat, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + graphene_point_t *coords, + ClutterModifierType *modifiers) +{ + MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); + + if (sequence) + { + MetaTouchState *touch_state; + int slot; + + slot = meta_event_native_sequence_get_slot (sequence); + touch_state = meta_seat_native_lookup_touch_state (seat_native, slot); + if (!touch_state) + return FALSE; + + if (coords) + { + coords->x = touch_state->coords.x; + coords->y = touch_state->coords.y; + } + + if (modifiers) + *modifiers = meta_xkb_translate_modifiers (seat_native->xkb, 0); + + return TRUE; + } + else + { + if (coords) + { + coords->x = device->current_x; + coords->y = device->current_y; + } + + if (modifiers) + { + *modifiers = meta_xkb_translate_modifiers (seat_native->xkb, + seat_native->button_state); + } + + return TRUE; + } +} + static void meta_seat_native_class_init (MetaSeatNativeClass *klass) { @@ -2858,6 +2906,7 @@ meta_seat_native_class_init (MetaSeatNativeClass *klass) seat_class->compress_motion = meta_seat_native_compress_motion; seat_class->warp_pointer = meta_seat_native_warp_pointer; seat_class->handle_device_event = meta_seat_native_handle_device_event; + seat_class->query_state = meta_seat_native_query_state; props[PROP_SEAT_ID] = g_param_spec_string ("seat-id", diff --git a/src/backends/native/meta-xkb-utils.c b/src/backends/native/meta-xkb-utils.c index 6470e520e95..eb2a8320136 100644 --- a/src/backends/native/meta-xkb-utils.c +++ b/src/backends/native/meta-xkb-utils.c @@ -106,3 +106,15 @@ meta_xkb_translate_state (ClutterEvent *event, xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED), xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE) | button_state); } + +ClutterModifierType +meta_xkb_translate_modifiers (struct xkb_state *state, + ClutterModifierType button_state) +{ + ClutterModifierType modifiers; + + modifiers = xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE); + modifiers |= button_state; + + return modifiers; +} diff --git a/src/backends/native/meta-xkb-utils.h b/src/backends/native/meta-xkb-utils.h index 5121d08d6ed..f0fa507acee 100644 --- a/src/backends/native/meta-xkb-utils.h +++ b/src/backends/native/meta-xkb-utils.h @@ -35,5 +35,7 @@ ClutterEvent * meta_key_event_new_from_evdev (ClutterInputDevice *device, void meta_xkb_translate_state (ClutterEvent *event, struct xkb_state *xkb_state, uint32_t button_state); +ClutterModifierType meta_xkb_translate_modifiers (struct xkb_state *state, + ClutterModifierType button_state); #endif /* META_XKB_UTILS_H */ -- GitLab From cb7794c19c357b75ee17cb3a12161c12f8490165 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 5 Jun 2020 23:11:56 +0200 Subject: [PATCH 04/85] clutter: Use ClutterSeat underneath coords/modifiers input device getters This is not device state, but belonging to seat guts. Part-of: --- clutter/clutter/clutter-input-device.c | 31 +++++++++++--------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 52613317fe3..7a17f227e0e 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -579,9 +579,17 @@ _clutter_input_device_set_state (ClutterInputDevice *device, ClutterModifierType clutter_input_device_get_modifier_state (ClutterInputDevice *device) { + uint32_t modifiers; + ClutterSeat *seat; + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0); - return device->current_state; + seat = clutter_input_device_get_seat (device); + + if (!clutter_seat_query_state (seat, device, NULL, NULL, &modifiers)) + return 0; + + return modifiers; } static void @@ -859,27 +867,14 @@ clutter_input_device_get_coords (ClutterInputDevice *device, ClutterEventSequence *sequence, graphene_point_t *point) { + ClutterSeat *seat; + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); g_return_val_if_fail (point != NULL, FALSE); - if (sequence == NULL) - { - point->x = device->current_x; - point->y = device->current_y; - } - else - { - ClutterTouchInfo *info = - g_hash_table_lookup (device->touch_sequences_info, sequence); - - if (info == NULL) - return FALSE; + seat = clutter_input_device_get_seat (device); - point->x = info->current_x; - point->y = info->current_y; - } - - return TRUE; + return clutter_seat_query_state (seat, device, sequence, point, NULL); } /* -- GitLab From 7d7876880998fe7b414bb38f8094af9822020d1b Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 5 Jun 2020 23:43:54 +0200 Subject: [PATCH 05/85] backends/native: Move away from ClutterInputDevice coords Use a new set in MetaInputDeviceNative, this coexists with ClutterInputDevice coords for the time being. This API will eventually be only accessed from the input thread. Part-of: --- .../native/meta-input-device-native.c | 20 ++++++++ .../native/meta-input-device-native.h | 11 ++++ src/backends/native/meta-seat-native.c | 51 +++++++++---------- 3 files changed, 56 insertions(+), 26 deletions(-) diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index fbbe931c2cc..453b1fc945c 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -1495,3 +1495,23 @@ meta_input_device_native_set_mapping_mode (ClutterInputDevice *device, device_native->mapping_mode = mapping; } + +void +meta_input_device_native_set_coords (MetaInputDeviceNative *device_native, + float x, + float y) +{ + device_native->pointer_x = x; + device_native->pointer_y = y; +} + +void +meta_input_device_native_get_coords (MetaInputDeviceNative *device_native, + float *x, + float *y) +{ + if (x) + *x = device_native->pointer_x; + if (y) + *y = device_native->pointer_y; +} diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h index cbc33ce0d11..645d3ca749d 100644 --- a/src/backends/native/meta-input-device-native.h +++ b/src/backends/native/meta-input-device-native.h @@ -76,6 +76,10 @@ struct _MetaInputDeviceNative double output_ratio; /* w:h */ MetaInputDeviceMapping mapping_mode; + /* Pointer position */ + float pointer_x; + float pointer_y; + /* Keyboard a11y */ ClutterKeyboardA11yFlags a11y_flags; GList *slow_keys_list; @@ -137,4 +141,11 @@ void meta_input_device_native_a11y_maybe_notify_toggle_keys struct libinput_device * meta_input_device_native_get_libinput_device (ClutterInputDevice *device); +void meta_input_device_native_set_coords (MetaInputDeviceNative *device_native, + float x, + float y); +void meta_input_device_native_get_coords (MetaInputDeviceNative *device_native, + float *x, + float *y); + #endif /* META_INPUT_DEVICE_NATIVE_H */ diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 1bfac5d8640..eb8d3cbd678 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -425,10 +425,14 @@ new_absolute_motion_event (MetaSeatNative *seat, clutter_event_set_device_tool (event, device_evdev->last_tool); clutter_event_set_device (event, input_device); + meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (input_device), + x, y); } else { clutter_event_set_device (event, seat->core_pointer); + meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (seat->core_pointer), + x, y); } if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE) @@ -574,16 +578,15 @@ meta_seat_native_notify_button (MetaSeatNative *seat, if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) { - graphene_point_t point; - - clutter_input_device_get_coords (input_device, NULL, &point); - event->button.x = point.x; - event->button.y = point.y; + meta_input_device_native_get_coords (device_evdev, + &event->button.x, + &event->button.y); } else { - event->button.x = seat->pointer_x; - event->button.y = seat->pointer_y; + meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (seat->core_pointer), + &event->button.x, + &event->button.y); } clutter_event_set_device (event, seat->core_pointer); @@ -878,14 +881,11 @@ constrain_all_screen_monitors (ClutterInputDevice *device, float *x, float *y) { - graphene_point_t current; float cx, cy; GList *logical_monitors, *l; - clutter_input_device_get_coords (device, NULL, ¤t); - - cx = current.x; - cy = current.y; + meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (device), + &cx, &cy); /* if we're trying to escape, clamp to the CRTC we're coming from */ @@ -1098,8 +1098,8 @@ notify_relative_tool_motion (ClutterInputDevice *input_device, device_evdev = META_INPUT_DEVICE_NATIVE (input_device); seat = meta_input_device_native_get_seat (device_evdev); - x = input_device->current_x + dx; - y = input_device->current_y + dy; + x = device_evdev->pointer_x + dx; + y = device_evdev->pointer_y + dy; meta_seat_native_filter_relative_motion (seat, input_device, @@ -1127,20 +1127,19 @@ notify_pinch_gesture_event (ClutterInputDevice *input_device, MetaInputDeviceNative *device_evdev; MetaSeatNative *seat; ClutterEvent *event = NULL; - graphene_point_t pos; device_evdev = META_INPUT_DEVICE_NATIVE (input_device); seat = meta_input_device_native_get_seat (device_evdev); event = clutter_event_new (CLUTTER_TOUCHPAD_PINCH); - clutter_input_device_get_coords (seat->core_pointer, NULL, &pos); + meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (seat->core_pointer), + &event->touchpad_pinch.x, + &event->touchpad_pinch.y); meta_event_native_set_time_usec (event, time_us); event->touchpad_pinch.phase = phase; event->touchpad_pinch.time = us2ms (time_us); - event->touchpad_pinch.x = pos.x; - event->touchpad_pinch.y = pos.y; event->touchpad_pinch.dx = dx; event->touchpad_pinch.dy = dy; event->touchpad_pinch.angle_delta = angle_delta; @@ -1166,7 +1165,6 @@ notify_swipe_gesture_event (ClutterInputDevice *input_device, MetaInputDeviceNative *device_evdev; MetaSeatNative *seat; ClutterEvent *event = NULL; - graphene_point_t pos; device_evdev = META_INPUT_DEVICE_NATIVE (input_device); seat = meta_input_device_native_get_seat (device_evdev); @@ -1177,9 +1175,9 @@ notify_swipe_gesture_event (ClutterInputDevice *input_device, event->touchpad_swipe.phase = phase; event->touchpad_swipe.time = us2ms (time_us); - clutter_input_device_get_coords (seat->core_pointer, NULL, &pos); - event->touchpad_swipe.x = pos.x; - event->touchpad_swipe.y = pos.y; + meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (seat->core_pointer), + &event->touchpad_swipe.x, + &event->touchpad_swipe.y); event->touchpad_swipe.dx = dx; event->touchpad_swipe.dy = dy; event->touchpad_swipe.n_fingers = n_fingers; @@ -2501,8 +2499,8 @@ meta_seat_native_constructed (GObject *object) CLUTTER_INPUT_MODE_LOGICAL); seat->pointer_x = INITIAL_POINTER_X; seat->pointer_y = INITIAL_POINTER_Y; - _clutter_input_device_set_coords (device, NULL, - seat->pointer_x, seat->pointer_y); + meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (device), + seat->pointer_x, seat->pointer_y); seat->core_pointer = device; device = meta_input_device_native_new_virtual ( @@ -2840,6 +2838,7 @@ meta_seat_native_query_state (ClutterSeat *seat, graphene_point_t *coords, ClutterModifierType *modifiers) { + MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); if (sequence) @@ -2867,8 +2866,8 @@ meta_seat_native_query_state (ClutterSeat *seat, { if (coords) { - coords->x = device->current_x; - coords->y = device->current_y; + coords->x = device_native->pointer_x; + coords->y = device_native->pointer_y; } if (modifiers) -- GitLab From 932a5cab096bcb98bcddcecd39abb4fc33bd84e9 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 6 Jun 2020 00:20:46 +0200 Subject: [PATCH 06/85] clutter: Drop clutter_input_device_set_state() Nothing uses it anymore. Part-of: --- .../clutter/clutter-input-device-private.h | 3 --- clutter/clutter/clutter-input-device.c | 20 ------------------- src/backends/native/meta-seat-native.c | 14 ------------- 3 files changed, 37 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index 9ceb22c2bb2..0c566a9678e 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -176,9 +176,6 @@ void _clutter_input_device_set_coords (ClutterInputDevice *device, gfloat x, gfloat y); CLUTTER_EXPORT -void _clutter_input_device_set_state (ClutterInputDevice *device, - ClutterModifierType state); -CLUTTER_EXPORT ClutterActor * clutter_input_device_update (ClutterInputDevice *device, ClutterEventSequence *sequence, ClutterStage *stage, diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 7a17f227e0e..6a716002edb 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -489,7 +489,6 @@ clutter_input_device_init (ClutterInputDevice *self) self->current_x = self->previous_x = -1; self->current_y = self->previous_y = -1; self->current_button_number = self->previous_button_number = -1; - self->current_state = 0; self->touch_sequences_info = g_hash_table_new_full (NULL, NULL, @@ -549,22 +548,6 @@ _clutter_input_device_set_coords (ClutterInputDevice *device, } } -/*< private > - * clutter_input_device_set_state: - * @device: a #ClutterInputDevice - * @state: a bitmask of modifiers - * - * Stores the last known modifiers state of the device - */ -void -_clutter_input_device_set_state (ClutterInputDevice *device, - ClutterModifierType state) -{ - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - - device->current_state = state; -} - /** * clutter_input_device_get_modifier_state: * @device: a #ClutterInputDevice @@ -1093,19 +1076,16 @@ void clutter_input_device_update_from_event (ClutterInputDevice *device, ClutterEvent *event) { - ClutterModifierType event_state; ClutterEventSequence *sequence; gfloat event_x, event_y; g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); g_return_if_fail (event != NULL); - event_state = clutter_event_get_state (event); sequence = clutter_event_get_event_sequence (event); clutter_event_get_coords (event, &event_x, &event_y); _clutter_input_device_set_coords (device, sequence, event_x, event_y); - _clutter_input_device_set_state (device, event_state); } /*< private > diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index eb8d3cbd678..ea0cd0742c5 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -1343,20 +1343,6 @@ meta_event_dispatch (GSource *g_source, if (event) { - ClutterModifierType event_state; - ClutterInputDevice *input_device = - clutter_event_get_source_device (event); - MetaInputDeviceNative *device_evdev = - META_INPUT_DEVICE_NATIVE (input_device); - MetaSeatNative *seat = - meta_input_device_native_get_seat (device_evdev); - - /* update the device states *before* the event */ - event_state = seat->button_state | - xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_EFFECTIVE); - _clutter_input_device_set_state (seat->core_pointer, event_state); - _clutter_input_device_set_state (seat->core_keyboard, event_state); - /* forward the event into clutter for emission etc. */ _clutter_stage_queue_event (event->any.stage, event, FALSE); } -- GitLab From 730da1dbe19b1e84c36751c21a39bccfda9e66b8 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 6 Jun 2020 12:35:47 +0200 Subject: [PATCH 07/85] clutter: Pass base event to clutter_input_device_update() So we may fetch coordinates without necessarily querying the device state. Part-of: --- .../clutter/clutter-input-device-private.h | 2 +- clutter/clutter/clutter-input-device.c | 30 ++++++++++++++----- clutter/clutter/clutter-main.c | 8 ++--- clutter/clutter/clutter-stage.c | 3 +- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index 0c566a9678e..7e0055fe984 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -180,7 +180,7 @@ ClutterActor * clutter_input_device_update (ClutterInputDevice *device, ClutterEventSequence *sequence, ClutterStage *stage, gboolean emit_crossing, - uint32_t time_ms); + ClutterEvent *for_event); CLUTTER_EXPORT void _clutter_input_device_add_event_sequence (ClutterInputDevice *device, ClutterEvent *event); diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 6a716002edb..1b20a33a810 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -689,6 +689,7 @@ _clutter_input_device_set_actor (ClutterInputDevice *device, ClutterStage *stage, ClutterActor *actor, gboolean emit_crossing, + graphene_point_t coords, uint32_t time_ms) { ClutterActor *old_actor = clutter_input_device_get_actor (device, sequence); @@ -709,8 +710,8 @@ _clutter_input_device_set_actor (ClutterInputDevice *device, event->crossing.flags = 0; event->crossing.stage = stage; event->crossing.source = old_actor; - event->crossing.x = device->current_x; - event->crossing.y = device->current_y; + event->crossing.x = coords.x; + event->crossing.y = coords.y; event->crossing.related = actor; event->crossing.sequence = sequence; clutter_event_set_device (event, device); @@ -745,8 +746,8 @@ _clutter_input_device_set_actor (ClutterInputDevice *device, event->crossing.time = time_ms; event->crossing.flags = 0; event->crossing.stage = stage; - event->crossing.x = device->current_x; - event->crossing.y = device->current_y; + event->crossing.x = coords.x; + event->crossing.y = coords.y; event->crossing.source = actor; event->crossing.related = old_actor; event->crossing.sequence = sequence; @@ -879,17 +880,27 @@ clutter_input_device_update (ClutterInputDevice *device, ClutterEventSequence *sequence, ClutterStage *stage, gboolean emit_crossing, - uint32_t time_ms) + ClutterEvent *for_event) { ClutterActor *new_cursor_actor; ClutterActor *old_cursor_actor; graphene_point_t point = GRAPHENE_POINT_INIT (-1.0f, -1.0f); ClutterInputDeviceType device_type = device->device_type; + uint32_t time_ms; g_assert (device_type != CLUTTER_KEYBOARD_DEVICE && device_type != CLUTTER_PAD_DEVICE); - clutter_input_device_get_coords (device, sequence, &point); + if (for_event) + { + clutter_event_get_coords (for_event, &point.x, &point.y); + time_ms = clutter_event_get_time (for_event); + } + else + { + clutter_input_device_get_coords (device, sequence, &point); + time_ms = CLUTTER_CURRENT_TIME; + } old_cursor_actor = clutter_input_device_get_actor (device, sequence); new_cursor_actor = @@ -918,7 +929,7 @@ clutter_input_device_update (ClutterInputDevice *device, stage, new_cursor_actor, emit_crossing, - time_ms); + point, time_ms); return new_cursor_actor; } @@ -1512,12 +1523,15 @@ _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, g_hash_table_lookup (device->inv_touch_sequence_actors, info->actor); ClutterStage *stage = CLUTTER_STAGE (clutter_actor_get_stage (info->actor)); + graphene_point_t point; sequences = g_list_remove (sequences, sequence); g_hash_table_replace (device->inv_touch_sequence_actors, info->actor, sequences); - _clutter_input_device_set_actor (device, sequence, stage, NULL, TRUE, + clutter_event_get_coords (event, &point.x, &point.y); + _clutter_input_device_set_actor (device, sequence, stage, + NULL, TRUE, point, clutter_event_get_time (event)); } diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index 0606d2e4a1b..eac636e1c7f 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -1626,7 +1626,7 @@ _clutter_process_event_details (ClutterActor *stage, actor = clutter_input_device_update (device, NULL, CLUTTER_STAGE (stage), FALSE, - clutter_event_get_time (event)); + event); if (actor != stage) { ClutterEvent *crossing; @@ -1777,8 +1777,7 @@ _clutter_process_event_details (ClutterActor *stage, actor = clutter_input_device_update (device, NULL, CLUTTER_STAGE (stage), - TRUE, - clutter_event_get_time (event)); + TRUE, event); if (actor == NULL) break; @@ -1888,8 +1887,7 @@ _clutter_process_event_details (ClutterActor *stage, actor = clutter_input_device_update (device, sequence, CLUTTER_STAGE (stage), - TRUE, - clutter_event_get_time (event)); + TRUE, event); if (actor == NULL) break; diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index f4277803257..a0f9eddca41 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -996,8 +996,7 @@ clutter_stage_update_devices (ClutterStage *stage, for (l = devices; l; l = l->next) { ClutterInputDevice *device = l->data; - clutter_input_device_update (device, NULL, stage, TRUE, - CLUTTER_CURRENT_TIME); + clutter_input_device_update (device, NULL, stage, TRUE, NULL); } } -- GitLab From 3234ae2993c00364f21d726c5e64cad596f464a8 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 6 Jun 2020 12:45:48 +0200 Subject: [PATCH 08/85] clutter: Drop clutter_input_device_update_from_event() Input devices aren't "updated" anymore, but their state queried to the seat instead. This API was only meant for embedders of Clutter, and is pointless to us. Part-of: --- .../clutter/clutter-input-device-private.h | 3 - clutter/clutter/clutter-input-device.c | 77 ------------------- src/tests/clutter/performance/test-common.h | 1 - 3 files changed, 81 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index 7e0055fe984..64ae8d0768c 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -236,9 +236,6 @@ ClutterInputDeviceTool * ClutterInputDeviceToolType type); CLUTTER_EXPORT -void clutter_input_device_update_from_event (ClutterInputDevice *device, - ClutterEvent *event); -CLUTTER_EXPORT gboolean clutter_input_device_keycode_to_evdev (ClutterInputDevice *device, guint hardware_keycode, guint *evdev_keycode); diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 1b20a33a810..4968dca52e6 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -1022,83 +1022,6 @@ clutter_input_device_get_device_mode (ClutterInputDevice *device) return device->device_mode; } -/** - * clutter_input_device_update_from_event: - * @device: a #ClutterInputDevice - * @event: a #ClutterEvent - * @update_stage: whether to update the #ClutterStage of the @device - * using the stage of the event - * - * Forcibly updates the state of the @device using a #ClutterEvent - * - * This function should never be used by applications: it is meant - * for integration with embedding toolkits, like clutter-gtk - * - * Embedding toolkits that disable the event collection inside Clutter - * need to use this function to update the state of input devices depending - * on a #ClutterEvent that they are going to submit to the event handling code - * in Clutter though clutter_do_event(). Since the input devices hold the state - * that is going to be used to fill in fields like the #ClutterButtonEvent - * click count, or to emit synthesized events like %CLUTTER_ENTER and - * %CLUTTER_LEAVE, it is necessary for embedding toolkits to also be - * responsible of updating the input device state. - * - * For instance, this might be the code to translate an embedding toolkit - * native motion notification into a Clutter #ClutterMotionEvent and ask - * Clutter to process it: - * - * |[ - * ClutterEvent c_event; - * - * translate_native_event_to_clutter (native_event, &c_event); - * - * clutter_do_event (&c_event); - * ]| - * - * Before letting clutter_do_event() process the event, it is necessary to call - * clutter_input_device_update_from_event(): - * - * |[ - * ClutterEvent c_event; - * ClutterDeviceManager *manager; - * ClutterInputDevice *device; - * - * translate_native_event_to_clutter (native_event, &c_event); - * - * // get the seat - * seat = clutter_backend_get_deafult_seat (clutter_get_default_backend ()); - * - * // use the default Core Pointer that Clutter backends register by default - * device = clutter_seat_get_pointer (seat); - * - * // update the state of the input device - * clutter_input_device_update_from_event (device, &c_event); - * - * clutter_do_event (&c_event); - * ]| - * - * The @update_stage boolean argument should be used when the input device - * enters and leaves a #ClutterStage; it will use the #ClutterStage field - * of the passed @event to update the stage associated to the input device. - * - * Since: 1.2 - */ -void -clutter_input_device_update_from_event (ClutterInputDevice *device, - ClutterEvent *event) -{ - ClutterEventSequence *sequence; - gfloat event_x, event_y; - - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - g_return_if_fail (event != NULL); - - sequence = clutter_event_get_event_sequence (event); - clutter_event_get_coords (event, &event_x, &event_y); - - _clutter_input_device_set_coords (device, sequence, event_x, event_y); -} - /*< private > * clutter_input_device_reset_axes: * @device: a #ClutterInputDevice diff --git a/src/tests/clutter/performance/test-common.h b/src/tests/clutter/performance/test-common.h index ef90ce10996..ea4210ddcc7 100644 --- a/src/tests/clutter/performance/test-common.h +++ b/src/tests/clutter/performance/test-common.h @@ -110,7 +110,6 @@ static gboolean perf_fake_mouse_cb (gpointer stage) event2->crossing.related = NULL; clutter_event_set_device (event2, device); - clutter_input_device_update_from_event (device, event2); clutter_event_put (event2); clutter_event_free (event2); -- GitLab From 2411460cff2952cbe1391c4796d02593ebcaf89c Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 6 Jun 2020 12:46:47 +0200 Subject: [PATCH 09/85] clutter: Drop clutter_input_device_set_coords() Input devices aren't "updated" anymore, but their state queried to the seat. This goes nowhere. Part-of: --- .../clutter/clutter-input-device-private.h | 7 ---- clutter/clutter/clutter-input-device.c | 38 +------------------ clutter/clutter/clutter-stage.c | 18 --------- 3 files changed, 2 insertions(+), 61 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index 64ae8d0768c..35ff2596a3f 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -119,8 +119,6 @@ struct _ClutterInputDevice int click_count; /* the current state */ - float current_x; - float current_y; int current_button_number; ClutterModifierType current_state; @@ -171,11 +169,6 @@ CLUTTER_EXPORT void clutter_input_device_update_from_tool (ClutterInputDevice *device, ClutterInputDeviceTool *tool); CLUTTER_EXPORT -void _clutter_input_device_set_coords (ClutterInputDevice *device, - ClutterEventSequence *sequence, - gfloat x, - gfloat y); -CLUTTER_EXPORT ClutterActor * clutter_input_device_update (ClutterInputDevice *device, ClutterEventSequence *sequence, ClutterStage *stage, diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 4968dca52e6..2ea47900a1b 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -486,8 +486,8 @@ clutter_input_device_init (ClutterInputDevice *self) self->click_count = 0; self->previous_time = CLUTTER_CURRENT_TIME; - self->current_x = self->previous_x = -1; - self->current_y = self->previous_y = -1; + self->previous_x = -1; + self->previous_y = -1; self->current_button_number = self->previous_button_number = -1; self->touch_sequences_info = @@ -514,40 +514,6 @@ _clutter_input_device_ensure_touch_info (ClutterInputDevice *device, return info; } -/*< private > - * clutter_input_device_set_coords: - * @device: a #ClutterInputDevice - * @sequence: a #ClutterEventSequence or NULL - * @x: X coordinate of the device - * @y: Y coordinate of the device - * - * Stores the last known coordinates of the device - */ -void -_clutter_input_device_set_coords (ClutterInputDevice *device, - ClutterEventSequence *sequence, - gfloat x, - gfloat y) -{ - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - - if (sequence == NULL) - { - if (device->current_x != x) - device->current_x = x; - - if (device->current_y != y) - device->current_y = y; - } - else - { - ClutterTouchInfo *info; - info = _clutter_input_device_ensure_touch_info (device, sequence); - info->current_x = x; - info->current_y = y; - } -} - /** * clutter_input_device_get_modifier_state: * @device: a #ClutterInputDevice diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index a0f9eddca41..dbfdfecebdf 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -648,7 +648,6 @@ _clutter_stage_queue_event (ClutterStage *stage, { ClutterStagePrivate *priv; gboolean first_event; - ClutterInputDevice *device; g_return_if_fail (CLUTTER_IS_STAGE (stage)); @@ -659,23 +658,6 @@ _clutter_stage_queue_event (ClutterStage *stage, if (copy_event) event = clutter_event_copy (event); - /* if needed, update the state of the input device of the event. - * we do it here to avoid calling the same code from every backend - * event processing function - */ - device = clutter_event_get_device (event); - if (device != NULL && - event->type != CLUTTER_PROXIMITY_IN && - event->type != CLUTTER_PROXIMITY_OUT) - { - ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - gfloat event_x, event_y; - - clutter_event_get_coords (event, &event_x, &event_y); - - _clutter_input_device_set_coords (device, sequence, event_x, event_y); - } - if (first_event) { gboolean compressible = event->type == CLUTTER_MOTION || -- GitLab From dea909aea77e17425e74eb2d74e599d0966ae9c4 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 6 Jun 2020 12:48:16 +0200 Subject: [PATCH 10/85] clutter: Simplify backend-independent touch accounting Coordinates are tracked by the ClutterSeat backends, we just need to track the target actor at this level. Part-of: --- .../clutter/clutter-input-device-private.h | 16 +--- clutter/clutter/clutter-input-device.c | 89 +++---------------- clutter/clutter/clutter-main.c | 3 - 3 files changed, 14 insertions(+), 94 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index 35ff2596a3f..2b8dca60497 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -61,15 +61,6 @@ typedef struct _ClutterScrollInfo guint last_value_valid : 1; } ClutterScrollInfo; -typedef struct _ClutterTouchInfo -{ - ClutterEventSequence *sequence; - ClutterActor *actor; - - float current_x; - float current_y; -} ClutterTouchInfo; - typedef struct _ClutterPtrA11yData { int n_btn_pressed; @@ -122,8 +113,8 @@ struct _ClutterInputDevice int current_button_number; ClutterModifierType current_state; - /* the current touch points states */ - GHashTable *touch_sequences_info; + /* the current touch points targets */ + GHashTable *touch_sequence_actors; /* the previous state, used for click count generation */ int previous_x; @@ -175,9 +166,6 @@ ClutterActor * clutter_input_device_update (ClutterInputDevice *device, gboolean emit_crossing, ClutterEvent *for_event); CLUTTER_EXPORT -void _clutter_input_device_add_event_sequence (ClutterInputDevice *device, - ClutterEvent *event); -CLUTTER_EXPORT void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, ClutterEvent *event); CLUTTER_EXPORT diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 2ea47900a1b..82cc5b8b394 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -75,7 +75,6 @@ enum PROP_LAST }; -static void _clutter_input_device_free_touch_info (gpointer data); static void on_cursor_actor_destroy (ClutterActor *actor, ClutterInputDevice *device); static void on_cursor_actor_reactive_changed (ClutterActor *actor, @@ -112,7 +111,7 @@ clutter_input_device_dispose (GObject *gobject) g_clear_pointer (&device->axes, g_array_unref); g_clear_pointer (&device->keys, g_array_unref); g_clear_pointer (&device->scroll_info, g_array_unref); - g_clear_pointer (&device->touch_sequences_info, g_hash_table_unref); + g_clear_pointer (&device->touch_sequence_actors, g_hash_table_unref); if (device->cursor_actor) { @@ -490,30 +489,10 @@ clutter_input_device_init (ClutterInputDevice *self) self->previous_y = -1; self->current_button_number = self->previous_button_number = -1; - self->touch_sequences_info = - g_hash_table_new_full (NULL, NULL, - NULL, _clutter_input_device_free_touch_info); + self->touch_sequence_actors = g_hash_table_new (NULL, NULL); self->inv_touch_sequence_actors = g_hash_table_new (NULL, NULL); } -static ClutterTouchInfo * -_clutter_input_device_ensure_touch_info (ClutterInputDevice *device, - ClutterEventSequence *sequence) -{ - ClutterTouchInfo *info; - - info = g_hash_table_lookup (device->touch_sequences_info, sequence); - - if (info == NULL) - { - info = g_slice_new0 (ClutterTouchInfo); - info->sequence = sequence; - g_hash_table_insert (device->touch_sequences_info, sequence, info); - } - - return info; -} - /** * clutter_input_device_get_modifier_state: * @device: a #ClutterInputDevice @@ -541,12 +520,6 @@ clutter_input_device_get_modifier_state (ClutterInputDevice *device) return modifiers; } -static void -_clutter_input_device_free_touch_info (gpointer data) -{ - g_slice_free (ClutterTouchInfo, data); -} - static void _clutter_input_device_associate_actor (ClutterInputDevice *device, ClutterEventSequence *sequence, @@ -558,11 +531,8 @@ _clutter_input_device_associate_actor (ClutterInputDevice *device, { GList *sequences = g_hash_table_lookup (device->inv_touch_sequence_actors, actor); - ClutterTouchInfo *info; - - info = _clutter_input_device_ensure_touch_info (device, sequence); - info->actor = actor; + g_hash_table_insert (device->touch_sequence_actors, sequence, actor); g_hash_table_insert (device->inv_touch_sequence_actors, actor, g_list_prepend (sequences, sequence)); } @@ -590,13 +560,7 @@ _clutter_input_device_unassociate_actor (ClutterInputDevice *device, actor); for (l = sequences; l != NULL; l = l->next) - { - ClutterTouchInfo *info = - g_hash_table_lookup (device->touch_sequences_info, l->data); - - if (info) - info->actor = NULL; - } + g_hash_table_remove (device->touch_sequence_actors, l->data); g_list_free (sequences); g_hash_table_remove (device->inv_touch_sequence_actors, actor); @@ -916,18 +880,12 @@ ClutterActor * clutter_input_device_get_actor (ClutterInputDevice *device, ClutterEventSequence *sequence) { - ClutterTouchInfo *info; - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); if (sequence == NULL) return device->cursor_actor; - info = g_hash_table_lookup (device->touch_sequences_info, sequence); - - g_return_val_if_fail (info != NULL, NULL); - - return info->actor; + return g_hash_table_lookup (device->touch_sequence_actors, sequence); } /** @@ -1368,26 +1326,6 @@ _clutter_input_device_remove_physical_device (ClutterInputDevice *logical, logical->physical_devices = g_list_remove (logical->physical_devices, physical); } -/*< private > - * clutter_input_device_add_sequence: - * @device: a #ClutterInputDevice - * @sequence: a #ClutterEventSequence - * - * Start tracking information related to a touch point (position, - * actor underneath the touch point). - */ -void -_clutter_input_device_add_event_sequence (ClutterInputDevice *device, - ClutterEvent *event) -{ - ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - - if (sequence == NULL) - return; - - _clutter_input_device_ensure_touch_info (device, sequence); -} - /*< private > * clutter_input_device_remove_sequence: * @device: a #ClutterInputDevice @@ -1400,31 +1338,28 @@ _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, ClutterEvent *event) { ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - ClutterTouchInfo *info = - g_hash_table_lookup (device->touch_sequences_info, sequence); + ClutterActor *actor; - if (info == NULL) - return; + actor = g_hash_table_lookup (device->touch_sequence_actors, sequence); - if (info->actor != NULL) + if (actor != NULL) { GList *sequences = - g_hash_table_lookup (device->inv_touch_sequence_actors, info->actor); + g_hash_table_lookup (device->inv_touch_sequence_actors, actor); ClutterStage *stage = - CLUTTER_STAGE (clutter_actor_get_stage (info->actor)); + CLUTTER_STAGE (clutter_actor_get_stage (actor)); graphene_point_t point; sequences = g_list_remove (sequences, sequence); g_hash_table_replace (device->inv_touch_sequence_actors, - info->actor, sequences); + actor, sequences); clutter_event_get_coords (event, &point.x, &point.y); _clutter_input_device_set_actor (device, sequence, stage, NULL, TRUE, point, clutter_event_get_time (event)); + g_hash_table_remove (device->touch_sequence_actors, sequence); } - - g_hash_table_remove (device->touch_sequences_info, sequence); } /** diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index eac636e1c7f..6382d3951b7 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -1853,9 +1853,6 @@ _clutter_process_event_details (ClutterActor *stage, sequence = clutter_event_get_event_sequence (event); - if (event->type == CLUTTER_TOUCH_BEGIN) - _clutter_input_device_add_event_sequence (device, event); - clutter_event_get_coords (event, &x, &y); /* Only do a pick to find the source if source is not already set -- GitLab From efd065259d34710b053471cd6f7d9bf58f16b8fb Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 6 Jun 2020 13:04:32 +0200 Subject: [PATCH 11/85] backends: Drop GDK device querying code from MetaCursorTracker Clutter behavior is now equivalent to GDK's on X11, avoid poking to GDK here. Part-of: --- src/backends/meta-cursor-tracker.c | 58 +++--------------------------- 1 file changed, 5 insertions(+), 53 deletions(-) diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c index caac5827da3..f90fd768b05 100644 --- a/src/backends/meta-cursor-tracker.c +++ b/src/backends/meta-cursor-tracker.c @@ -31,8 +31,6 @@ #include "backends/meta-cursor-tracker-private.h" -#include -#include #include #include "backends/meta-backend-private.h" @@ -464,36 +462,10 @@ meta_cursor_tracker_update_position (MetaCursorTracker *tracker, g_signal_emit (tracker, signals[CURSOR_MOVED], 0, new_x, new_y); } -static void -get_pointer_position_gdk (graphene_point_t *point, - int *mods) -{ - GdkSeat *gseat; - GdkDevice *gdevice; - GdkScreen *gscreen; - double x, y; - - gseat = gdk_display_get_default_seat (gdk_display_get_default ()); - gdevice = gdk_seat_get_pointer (gseat); - - /* Even if point is NULL we need this to get gscreen */ - gdk_device_get_position_double (gdevice, &gscreen, &x, &y); - - if (point) - { - point->x = x; - point->y = y; - } - - if (mods) - gdk_device_get_state (gdevice, - gdk_screen_get_root_window (gscreen), - NULL, (GdkModifierType*)mods); -} - -static void -get_pointer_position_clutter (graphene_point_t *point, - int *mods) +void +meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker, + graphene_point_t *coords, + ClutterModifierType *mods) { ClutterSeat *seat; ClutterInputDevice *cdevice; @@ -501,27 +473,7 @@ get_pointer_position_clutter (graphene_point_t *point, seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); cdevice = clutter_seat_get_pointer (seat); - if (point) - clutter_input_device_get_coords (cdevice, NULL, point); - - if (mods) - *mods = clutter_input_device_get_modifier_state (cdevice); -} - -void -meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker, - graphene_point_t *coords, - ClutterModifierType *mods) -{ - /* We can't use the clutter interface when not running as a wayland compositor, - because we need to query the server, rather than using the last cached value. - OTOH, on wayland we can't use GDK, because that only sees the events - we forward to xwayland. - */ - if (meta_is_wayland_compositor ()) - get_pointer_position_clutter (coords, (int *) mods); - else - get_pointer_position_gdk (coords, (int *) mods); + clutter_seat_query_state (seat, cdevice, NULL, coords, mods); } void -- GitLab From 8a8d47725cc17ea862a7563ce99fbd780c477f2e Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 8 Jul 2020 18:17:13 +0200 Subject: [PATCH 12/85] backends: Delegate pointer confinements to an impl object Split pointer confinements in 2 objects, one set from the upper layers containing its definition, and another managed by the backend that applies it. Part-of: --- src/backends/meta-backend-private.h | 2 + src/backends/meta-backend.c | 7 +- src/backends/meta-pointer-constraint.c | 91 ++- src/backends/meta-pointer-constraint.h | 49 +- src/backends/native/meta-backend-native.c | 60 +- .../native/meta-pointer-constraint-native.c | 693 ++++++++++++++++ .../native/meta-pointer-constraint-native.h | 46 ++ src/backends/native/meta-seat-native.c | 57 +- src/backends/native/meta-seat-native.h | 38 +- src/meson.build | 2 + .../meta-pointer-confinement-wayland.c | 755 ++++-------------- .../meta-pointer-confinement-wayland.h | 23 +- src/wayland/meta-pointer-lock-wayland.c | 61 +- src/wayland/meta-pointer-lock-wayland.h | 6 +- .../meta-wayland-pointer-constraints.c | 25 +- 15 files changed, 1118 insertions(+), 797 deletions(-) create mode 100644 src/backends/native/meta-pointer-constraint-native.c create mode 100644 src/backends/native/meta-pointer-constraint-native.h diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index 0b62ed4bf2e..afce64fd7ad 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -101,6 +101,8 @@ struct _MetaBackendClass void (* set_numlock) (MetaBackend *backend, gboolean numlock_state); + void (* set_pointer_constraint) (MetaBackend *backend, + MetaPointerConstraint *constraint); }; void meta_init_backend (GType backend_gtype); diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 1770ad795a9..1e4f00a75a2 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -1313,11 +1313,8 @@ meta_backend_set_client_pointer_constraint (MetaBackend *backend, { MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); - g_assert (!constraint || !priv->client_pointer_constraint); - - g_clear_object (&priv->client_pointer_constraint); - if (constraint) - priv->client_pointer_constraint = g_object_ref (constraint); + META_BACKEND_GET_CLASS (backend)->set_pointer_constraint (backend, constraint); + g_set_object (&priv->client_pointer_constraint, constraint); } ClutterBackend * diff --git a/src/backends/meta-pointer-constraint.c b/src/backends/meta-pointer-constraint.c index 55ca9f02397..7682b14b056 100644 --- a/src/backends/meta-pointer-constraint.c +++ b/src/backends/meta-pointer-constraint.c @@ -39,10 +39,34 @@ #include "backends/meta-pointer-constraint.h" +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-pointer-constraint-native.h" +#endif + #include +struct _MetaPointerConstraint +{ + GObject parent_instance; + cairo_region_t *region; +}; + G_DEFINE_TYPE (MetaPointerConstraint, meta_pointer_constraint, G_TYPE_OBJECT); +G_DEFINE_TYPE (MetaPointerConstraintImpl, meta_pointer_constraint_impl, + G_TYPE_OBJECT); + +static void +meta_pointer_constraint_finalize (GObject *object) +{ + MetaPointerConstraint *constraint = META_POINTER_CONSTRAINT (object); + + g_clear_pointer (&constraint->region, cairo_region_destroy); + + G_OBJECT_CLASS (meta_pointer_constraint_parent_class)->finalize (object); +} + static void meta_pointer_constraint_init (MetaPointerConstraint *constraint) { @@ -50,12 +74,43 @@ meta_pointer_constraint_init (MetaPointerConstraint *constraint) static void meta_pointer_constraint_class_init (MetaPointerConstraintClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_pointer_constraint_finalize; +} + + +MetaPointerConstraint * +meta_pointer_constraint_new (const cairo_region_t *region) +{ + MetaPointerConstraint *constraint; + + constraint = g_object_new (META_TYPE_POINTER_CONSTRAINT, NULL); + constraint->region = cairo_region_copy (region); + + return constraint; +} + +cairo_region_t * +meta_pointer_constraint_get_region (MetaPointerConstraint *constraint) +{ + return constraint->region; +} + +static void +meta_pointer_constraint_impl_init (MetaPointerConstraintImpl *constraint_impl) +{ +} + +static void +meta_pointer_constraint_impl_class_init (MetaPointerConstraintImplClass *klass) { } /** - * meta_pointer_constraint_constrain: - * @constraint: a #MetaPointerConstraint. + * meta_pointer_constraint_impl_constrain: + * @constraint_impl: a #MetaPointerConstraintImpl. * @device; the device of the pointer. * @time: the timestamp (in ms) of the event. * @prev_x: X-coordinate of the previous pointer position. @@ -67,17 +122,25 @@ meta_pointer_constraint_class_init (MetaPointerConstraintClass *klass) * if needed. */ void -meta_pointer_constraint_constrain (MetaPointerConstraint *constraint, - ClutterInputDevice *device, - guint32 time, - float prev_x, - float prev_y, - float *x, - float *y) +meta_pointer_constraint_impl_constrain (MetaPointerConstraintImpl *constraint_impl, + ClutterInputDevice *device, + uint32_t time, + float prev_x, + float prev_y, + float *x, + float *y) +{ + META_POINTER_CONSTRAINT_IMPL_GET_CLASS (constraint_impl)->constrain (constraint_impl, + device, + time, + prev_x, prev_y, + x, y); +} + +void +meta_pointer_constraint_impl_ensure_constrained (MetaPointerConstraintImpl *constraint_impl, + ClutterInputDevice *device) { - META_POINTER_CONSTRAINT_GET_CLASS (constraint)->constrain (constraint, - device, - time, - prev_x, prev_y, - x, y); + META_POINTER_CONSTRAINT_IMPL_GET_CLASS (constraint_impl)->ensure_constrained (constraint_impl, + device); } diff --git a/src/backends/meta-pointer-constraint.h b/src/backends/meta-pointer-constraint.h index ed0b025b568..b47eda4903f 100644 --- a/src/backends/meta-pointer-constraint.h +++ b/src/backends/meta-pointer-constraint.h @@ -32,34 +32,45 @@ G_BEGIN_DECLS #define META_TYPE_POINTER_CONSTRAINT (meta_pointer_constraint_get_type ()) -G_DECLARE_DERIVABLE_TYPE (MetaPointerConstraint, meta_pointer_constraint, - META, POINTER_CONSTRAINT, GObject); +G_DECLARE_FINAL_TYPE (MetaPointerConstraint, meta_pointer_constraint, + META, POINTER_CONSTRAINT, GObject); + +MetaPointerConstraint * meta_pointer_constraint_new (const cairo_region_t *region); +cairo_region_t * meta_pointer_constraint_get_region (MetaPointerConstraint *constraint); + +#define META_TYPE_POINTER_CONSTRAINT_IMPL (meta_pointer_constraint_impl_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaPointerConstraintImpl, meta_pointer_constraint_impl, + META, POINTER_CONSTRAINT_IMPL, GObject); /** - * MetaPointerConstraintClass: + * MetaPointerConstraintImplClass: * @constrain: the virtual function pointer for - * meta_pointer_constraint_constrain(). + * meta_pointer_constraint_impl_constrain(). */ -struct _MetaPointerConstraintClass +struct _MetaPointerConstraintImplClass { GObjectClass parent_class; - void (*constrain) (MetaPointerConstraint *constraint, - ClutterInputDevice *device, - guint32 time, - float prev_x, - float prev_y, - float *x, - float *y); + void (* constrain) (MetaPointerConstraintImpl *constraint_impl, + ClutterInputDevice *device, + uint32_t time, + float prev_x, + float prev_y, + float *x, + float *y); + void (* ensure_constrained) (MetaPointerConstraintImpl *constraint_impl, + ClutterInputDevice *device); }; -void meta_pointer_constraint_constrain (MetaPointerConstraint *constraint, - ClutterInputDevice *device, - guint32 time, - float prev_x, - float prev_y, - float *x, - float *y); +void meta_pointer_constraint_impl_constrain (MetaPointerConstraintImpl *constraint_impl, + ClutterInputDevice *device, + uint32_t time, + float prev_x, + float prev_y, + float *x, + float *y); +void meta_pointer_constraint_impl_ensure_constrained (MetaPointerConstraintImpl *constraint_impl, + ClutterInputDevice *device); G_END_DECLS diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index 73093cb038e..bca79f82392 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -105,38 +105,6 @@ meta_backend_native_finalize (GObject *object) G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object); } -static void -constrain_to_client_constraint (ClutterInputDevice *device, - guint32 time, - float prev_x, - float prev_y, - float *x, - float *y) -{ - MetaBackend *backend = meta_get_backend (); - MetaPointerConstraint *constraint = - meta_backend_get_client_pointer_constraint (backend); - - if (!constraint) - return; - - meta_pointer_constraint_constrain (constraint, device, - time, prev_x, prev_y, x, y); -} - -static void -pointer_constrain_callback (ClutterInputDevice *device, - guint32 time, - float prev_x, - float prev_y, - float *new_x, - float *new_y, - gpointer user_data) -{ - /* Constrain to pointer lock */ - constrain_to_client_constraint (device, time, prev_x, prev_y, new_x, new_y); -} - static ClutterBackend * meta_backend_native_create_clutter_backend (MetaBackend *backend) { @@ -181,14 +149,8 @@ maybe_disable_screen_cast_dma_bufs (MetaBackendNative *native) static void meta_backend_native_post_init (MetaBackend *backend) { - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); MetaSettings *settings = meta_backend_get_settings (backend); - meta_seat_native_set_pointer_constrain_callback (META_SEAT_NATIVE (seat), - pointer_constrain_callback, - NULL, NULL); - META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend); if (meta_settings_is_experimental_feature_enabled (settings, @@ -349,6 +311,26 @@ meta_backend_native_set_numlock (MetaBackend *backend, numlock_state); } +static void +meta_backend_native_set_pointer_constraint (MetaBackend *backend, + MetaPointerConstraint *constraint) +{ + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); + MetaPointerConstraintImpl *constraint_impl = NULL; + cairo_region_t *region; + + if (constraint) + { + region = meta_pointer_constraint_get_region (constraint); + constraint_impl = meta_pointer_constraint_impl_native_new (constraint, + region); + } + + meta_seat_native_set_pointer_constraint (META_SEAT_NATIVE (seat), + constraint_impl); +} + static void meta_backend_native_update_screen_size (MetaBackend *backend, int width, int height) @@ -562,6 +544,8 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass) backend_class->lock_layout_group = meta_backend_native_lock_layout_group; backend_class->update_screen_size = meta_backend_native_update_screen_size; backend_class->set_numlock = meta_backend_native_set_numlock; + + backend_class->set_pointer_constraint = meta_backend_native_set_pointer_constraint; } static void diff --git a/src/backends/native/meta-pointer-constraint-native.c b/src/backends/native/meta-pointer-constraint-native.c new file mode 100644 index 00000000000..8ce678ae4a4 --- /dev/null +++ b/src/backends/native/meta-pointer-constraint-native.c @@ -0,0 +1,693 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015-2020 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ã…dahl + */ + +#include "config.h" + +#include +#include + +#include "core/meta-border.h" +#include "meta-pointer-constraint-native.h" + +struct _MetaPointerConstraintImplNative +{ + MetaPointerConstraintImpl parent; + MetaPointerConstraint *constraint; + cairo_region_t *region; +}; + +G_DEFINE_TYPE (MetaPointerConstraintImplNative, + meta_pointer_constraint_impl_native, + META_TYPE_POINTER_CONSTRAINT_IMPL); + +typedef struct _MetaBox +{ + int x1; + int y1; + int x2; + int y2; +} MetaBox; + +static MetaBorder * +add_border (GArray *borders, + float x1, + float y1, + float x2, + float y2, + MetaBorderMotionDirection blocking_directions) +{ + MetaBorder border; + + border = (MetaBorder) { + .line = (MetaLine2) { + .a = (MetaVector2) { + .x = x1, + .y = y1, + }, + .b = (MetaVector2) { + .x = x2, + .y = y2, + }, + }, + .blocking_directions = blocking_directions, + }; + + g_array_append_val (borders, border); + + return &g_array_index (borders, MetaBorder, borders->len - 1); +} + +static gint +compare_lines_x (gconstpointer a, + gconstpointer b) +{ + const MetaBorder *border_a = a; + const MetaBorder *border_b = b; + + if (border_a->line.a.x == border_b->line.a.x) + return border_a->line.b.x < border_b->line.b.x; + else + return border_a->line.a.x > border_b->line.a.x; +} + +static void +add_non_overlapping_edges (MetaBox *boxes, + unsigned int band_above_start, + unsigned int band_below_start, + unsigned int band_below_end, + GArray *borders) +{ + unsigned int i; + GArray *band_merge; + MetaBorder *border; + MetaBorder *prev_border; + MetaBorder *new_border; + + band_merge = g_array_new (FALSE, FALSE, sizeof *border); + + /* Add bottom band of previous row, and top band of current row, and + * sort them so lower left x coordinate comes first. If there are two + * borders with the same left x coordinate, the wider one comes first. + */ + for (i = band_above_start; i < band_below_start; i++) + { + MetaBox *box = &boxes[i]; + add_border (band_merge, box->x1, box->y2, box->x2, box->y2, + META_BORDER_MOTION_DIRECTION_POSITIVE_Y); + } + for (i = band_below_start; i < band_below_end; i++) + { + MetaBox *box= &boxes[i]; + add_border (band_merge, box->x1, box->y1, box->x2, box->y1, + META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); + } + g_array_sort (band_merge, compare_lines_x); + + /* Combine the two combined bands so that any overlapping border is + * eliminated. */ + prev_border = NULL; + for (i = 0; i < band_merge->len; i++) + { + border = &g_array_index (band_merge, MetaBorder, i); + + g_assert (border->line.a.y == border->line.b.y); + g_assert (!prev_border || + prev_border->line.a.y == border->line.a.y); + g_assert (!prev_border || + (prev_border->line.a.x != border->line.a.x || + prev_border->line.b.x != border->line.b.x)); + g_assert (!prev_border || + prev_border->line.a.x <= border->line.a.x); + + if (prev_border && + prev_border->line.a.x == border->line.a.x) + { + /* + * ------------ + + * ------- = + * [ ]----- + */ + prev_border->line.a.x = border->line.b.x; + } + else if (prev_border && + prev_border->line.b.x == border->line.b.x) + { + /* + * ------------ + + * ------ = + * ------[ ] + */ + prev_border->line.b.x = border->line.a.x; + } + else if (prev_border && + prev_border->line.b.x == border->line.a.x) + { + /* + * -------- + + * ------ = + * -------------- + */ + prev_border->line.b.x = border->line.b.x; + } + else if (prev_border && + prev_border->line.b.x >= border->line.a.x) + { + /* + * --------------- + + * ------ = + * -----[ ]---- + */ + new_border = add_border (borders, + border->line.b.x, + border->line.b.y, + prev_border->line.b.x, + prev_border->line.b.y, + prev_border->blocking_directions); + prev_border->line.b.x = border->line.a.x; + prev_border = new_border; + } + else + { + g_assert (!prev_border || + prev_border->line.b.x < border->line.a.x); + /* + * First border or non-overlapping. + * + * ----- + + * ----- = + * ----- ----- + */ + g_array_append_val (borders, *border); + prev_border = &g_array_index (borders, MetaBorder, borders->len - 1); + } + } + + g_array_free (band_merge, FALSE); +} + +static void +add_band_bottom_edges (MetaBox *boxes, + int band_start, + int band_end, + GArray *borders) +{ + int i; + + for (i = band_start; i < band_end; i++) + { + add_border (borders, + boxes[i].x1, boxes[i].y2, + boxes[i].x2, boxes[i].y2, + META_BORDER_MOTION_DIRECTION_POSITIVE_Y); + } +} + +static void +region_to_outline (cairo_region_t *region, + GArray *borders) +{ + MetaBox *boxes; + int num_boxes; + int i; + int top_most, bottom_most; + int current_roof; + int prev_top; + int band_start, prev_band_start; + + /* + * Remove any overlapping lines from the set of rectangles. Note that + * pixman regions are grouped as rows of rectangles, where rectangles + * in one row never touch or overlap and are all of the same height. + * + * -------- --- -------- --- + * | | | | | | | | + * ----------====---- --- ----------- ----- --- + * | | => | | + * ----==========--------- ----- ---------- + * | | | | + * ------------------- ------------------- + * + */ + + num_boxes = cairo_region_num_rectangles (region); + boxes = g_new (MetaBox, num_boxes); + for (i = 0; i < num_boxes; i++) + { + cairo_rectangle_int_t rect; + cairo_region_get_rectangle (region, i, &rect); + boxes[i] = (MetaBox) { + .x1 = rect.x, + .y1 = rect.y, + .x2 = rect.x + rect.width, + .y2 = rect.y + rect.height, + }; + } + prev_top = 0; + top_most = boxes[0].y1; + current_roof = top_most; + bottom_most = boxes[num_boxes - 1].y2; + band_start = 0; + prev_band_start = 0; + for (i = 0; i < num_boxes; i++) + { + /* Detect if there is a vertical empty space, and add the lower + * level of the previous band if so was the case. */ + if (i > 0 && + boxes[i].y1 != prev_top && + boxes[i].y1 != boxes[i - 1].y2) + { + current_roof = boxes[i].y1; + add_band_bottom_edges (boxes, + band_start, + i, + borders); + } + + /* Special case adding the last band, since it won't be handled + * by the band change detection below. */ + if (boxes[i].y1 != current_roof && i == num_boxes - 1) + { + if (boxes[i].y1 != prev_top) + { + /* The last band is a single box, so we don't + * have a prev_band_start to tell us when the + * previous band started. */ + add_non_overlapping_edges (boxes, + band_start, + i, + i + 1, + borders); + } + else + { + add_non_overlapping_edges (boxes, + prev_band_start, + band_start, + i + 1, + borders); + } + } + + /* Detect when passing a band and combine the top border of the + * just passed band with the bottom band of the previous band. + */ + if (boxes[i].y1 != top_most && boxes[i].y1 != prev_top) + { + /* Combine the two passed bands. */ + if (prev_top != current_roof) + { + add_non_overlapping_edges (boxes, + prev_band_start, + band_start, + i, + borders); + } + + prev_band_start = band_start; + band_start = i; + } + + /* Add the top border if the box is part of the current roof. */ + if (boxes[i].y1 == current_roof) + { + add_border (borders, + boxes[i].x1, boxes[i].y1, + boxes[i].x2, boxes[i].y1, + META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); + } + + /* Add the bottom border of the last band. */ + if (boxes[i].y2 == bottom_most) + { + add_border (borders, + boxes[i].x1, boxes[i].y2, + boxes[i].x2, boxes[i].y2, + META_BORDER_MOTION_DIRECTION_POSITIVE_Y); + } + + /* Always add the left border. */ + add_border (borders, + boxes[i].x1, boxes[i].y1, + boxes[i].x1, boxes[i].y2, + META_BORDER_MOTION_DIRECTION_NEGATIVE_X); + + /* Always add the right border. */ + add_border (borders, + boxes[i].x2, boxes[i].y1, + boxes[i].x2, boxes[i].y2, + META_BORDER_MOTION_DIRECTION_POSITIVE_X); + + prev_top = boxes[i].y1; + } + + g_free (boxes); +} + +static MetaBorder * +get_closest_border (GArray *borders, + MetaLine2 *motion, + uint32_t directions) +{ + MetaBorder *border; + MetaVector2 intersection; + MetaVector2 delta; + float distance_2; + MetaBorder *closest_border = NULL; + float closest_distance_2 = DBL_MAX; + unsigned int i; + + for (i = 0; i < borders->len; i++) + { + border = &g_array_index (borders, MetaBorder, i); + + if (!meta_border_is_blocking_directions (border, directions)) + continue; + + if (!meta_line2_intersects_with (&border->line, motion, &intersection)) + continue; + + delta = meta_vector2_subtract (intersection, motion->a); + distance_2 = delta.x*delta.x + delta.y*delta.y; + if (distance_2 < closest_distance_2) + { + closest_border = border; + closest_distance_2 = distance_2; + } + } + + return closest_border; +} + +static void +clamp_to_border (MetaBorder *border, + MetaLine2 *motion, + uint32_t *motion_dir) +{ + /* + * When clamping either rightward or downward motions, the motion needs to be + * clamped so that the destination coordinate does not end up on the border + * (see weston_pointer_clamp_event_to_region). Do this by clamping such + * motions to the border minus the smallest possible wl_fixed_t value. + * + * When clamping in either leftward or upward motion, the resulting coordinate + * needs to be clamped so that it is enough on the inside to avoid the + * inaccuracies of clutter's stage to actor transformation algorithm (the one + * used in clutter_actor_transform_stage_point) to make it end up outside the + * next motion. It also needs to be clamped so that to the wl_fixed_t + * coordinate may still be right on the border (i.e. at .0). Testing shows + * that the smallest wl_fixed_t value divided by 10 is small enough to make + * the wl_fixed_t coordinate .0 and large enough to avoid the inaccuracies of + * clutters transform algorithm. + */ + if (meta_border_is_horizontal (border)) + { + if (*motion_dir & META_BORDER_MOTION_DIRECTION_POSITIVE_Y) + motion->b.y = border->line.a.y - wl_fixed_to_double (1); + else + motion->b.y = border->line.a.y + wl_fixed_to_double (1) / 10; + *motion_dir &= ~(META_BORDER_MOTION_DIRECTION_POSITIVE_Y | + META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); + } + else + { + if (*motion_dir & META_BORDER_MOTION_DIRECTION_POSITIVE_X) + motion->b.x = border->line.a.x - wl_fixed_to_double (1); + else + motion->b.x = border->line.a.x + wl_fixed_to_double (1) / 10; + *motion_dir &= ~(META_BORDER_MOTION_DIRECTION_POSITIVE_X | + META_BORDER_MOTION_DIRECTION_NEGATIVE_X); + } +} + +static uint32_t +get_motion_directions (MetaLine2 *motion) +{ + uint32_t directions = 0; + + if (motion->a.x < motion->b.x) + directions |= META_BORDER_MOTION_DIRECTION_POSITIVE_X; + else if (motion->a.x > motion->b.x) + directions |= META_BORDER_MOTION_DIRECTION_NEGATIVE_X; + if (motion->a.y < motion->b.y) + directions |= META_BORDER_MOTION_DIRECTION_POSITIVE_Y; + else if (motion->a.y > motion->b.y) + directions |= META_BORDER_MOTION_DIRECTION_NEGATIVE_Y; + + return directions; +} + +static void +meta_pointer_constraint_impl_native_constraint (MetaPointerConstraintImpl *constraint_impl, + ClutterInputDevice *device, + uint32_t time, + float prev_x, + float prev_y, + float *x_inout, + float *y_inout) +{ + MetaPointerConstraintImplNative *constraint_impl_native; + cairo_region_t *region; + float x, y; + GArray *borders; + MetaLine2 motion; + MetaBorder *closest_border; + uint32_t directions; + + constraint_impl_native = META_POINTER_CONSTRAINT_IMPL_NATIVE (constraint_impl); + + region = cairo_region_reference (constraint_impl_native->region); + x = *x_inout; + y = *y_inout; + + /* For motions in a positive direction on any axis, append the smallest + * possible value representable in a Wayland absolute coordinate. This is + * in order to avoid not clamping motion that as a floating point number + * won't be clamped, but will be rounded up to be outside of the range + * of wl_fixed_t. */ + if (x > prev_x) + x += (float) wl_fixed_to_double(1); + if (y > prev_y) + y += (float) wl_fixed_to_double(1); + + borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder)); + + /* + * Generate borders given the confine region we are to use. The borders + * are defined to be the outer region of the allowed area. This means + * top/left borders are "within" the allowed area, while bottom/right + * borders are outside. This needs to be considered when clamping + * confined motion vectors. + */ + region_to_outline (region, borders); + cairo_region_destroy (region); + + motion = (MetaLine2) { + .a = (MetaVector2) { + .x = prev_x, + .y = prev_y, + }, + .b = (MetaVector2) { + .x = x, + .y = y, + }, + }; + directions = get_motion_directions (&motion); + + while (directions) + { + closest_border = get_closest_border (borders, + &motion, + directions); + if (closest_border) + clamp_to_border (closest_border, &motion, &directions); + else + break; + } + + *x_inout = motion.b.x; + *y_inout = motion.b.y; + g_array_free (borders, FALSE); +} + +static float +point_to_border_distance_2 (MetaBorder *border, + float x, + float y) +{ + float orig_x, orig_y; + float dx, dy; + + if (meta_border_is_horizontal (border)) + { + if (x < border->line.a.x) + orig_x = border->line.a.x; + else if (x > border->line.b.x) + orig_x = border->line.b.x; + else + orig_x = x; + orig_y = border->line.a.y; + } + else + { + if (y < border->line.a.y) + orig_y = border->line.a.y; + else if (y > border->line.b.y) + orig_y = border->line.b.y; + else + orig_y = y; + orig_x = border->line.a.x; + } + + dx = fabsf (orig_x - x); + dy = fabsf (orig_y - y); + return dx*dx + dy*dy; +} + +static void +closest_point_behind_border (MetaBorder *border, + float *sx, + float *sy) +{ + switch (border->blocking_directions) + { + case META_BORDER_MOTION_DIRECTION_POSITIVE_X: + case META_BORDER_MOTION_DIRECTION_NEGATIVE_X: + if (border->blocking_directions == META_BORDER_MOTION_DIRECTION_POSITIVE_X) + *sx = border->line.a.x - wl_fixed_to_double (1); + else + *sx = border->line.a.x + wl_fixed_to_double (1); + if (*sy < border->line.a.y) + *sy = border->line.a.y + wl_fixed_to_double (1); + else if (*sy > border->line.b.y) + *sy = border->line.b.y - wl_fixed_to_double (1); + break; + case META_BORDER_MOTION_DIRECTION_POSITIVE_Y: + case META_BORDER_MOTION_DIRECTION_NEGATIVE_Y: + if (border->blocking_directions == META_BORDER_MOTION_DIRECTION_POSITIVE_Y) + *sy = border->line.a.y - wl_fixed_to_double (1); + else + *sy = border->line.a.y + wl_fixed_to_double (1); + if (*sx < border->line.a.x) + *sx = border->line.a.x + wl_fixed_to_double (1); + else if (*sx > (border->line.b.x)) + *sx = border->line.b.x - wl_fixed_to_double (1); + break; + } +} + +static void +meta_pointer_constraint_impl_native_ensure_constrained (MetaPointerConstraintImpl *constraint_impl, + ClutterInputDevice *device) +{ + MetaPointerConstraintImplNative *constraint_impl_native; + graphene_point_t point; + cairo_region_t *region; + float x; + float y; + + constraint_impl_native = META_POINTER_CONSTRAINT_IMPL_NATIVE (constraint_impl); + region = cairo_region_reference (constraint_impl_native->region); + + clutter_input_device_get_coords (device, NULL, &point); + x = point.x; + y = point.y; + + if (!cairo_region_contains_point (region, (int) x, (int) y)) + { + GArray *borders; + float closest_distance_2 = FLT_MAX; + MetaBorder *closest_border = NULL; + ClutterSeat *seat; + unsigned int i; + + borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder)); + + region_to_outline (region, borders); + + for (i = 0; i < borders->len; i++) + { + MetaBorder *border = &g_array_index (borders, MetaBorder, i); + float distance_2; + + distance_2 = point_to_border_distance_2 (border, x, y); + if (distance_2 < closest_distance_2) + { + closest_border = border; + closest_distance_2 = distance_2; + } + } + + closest_point_behind_border (closest_border, &x, &y); + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + clutter_seat_warp_pointer (seat, x, y); + } + + cairo_region_destroy (region); +} + +static void +meta_pointer_constraint_impl_native_finalize (GObject *object) +{ + MetaPointerConstraintImplNative *constraint_impl_native; + + constraint_impl_native = META_POINTER_CONSTRAINT_IMPL_NATIVE (object); + g_clear_pointer (&constraint_impl_native->region, cairo_region_destroy); + + G_OBJECT_CLASS (meta_pointer_constraint_impl_native_parent_class)->finalize (object); +} + +static void +meta_pointer_constraint_impl_native_init (MetaPointerConstraintImplNative *constraint_impl_native) +{ +} + +static void +meta_pointer_constraint_impl_native_class_init (MetaPointerConstraintImplNativeClass *klass) +{ + MetaPointerConstraintImplClass *constraint_impl_class; + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_pointer_constraint_impl_native_finalize; + + constraint_impl_class = META_POINTER_CONSTRAINT_IMPL_CLASS (klass); + constraint_impl_class->constrain = meta_pointer_constraint_impl_native_constraint; + constraint_impl_class->ensure_constrained = + meta_pointer_constraint_impl_native_ensure_constrained; +} + + +MetaPointerConstraintImpl * +meta_pointer_constraint_impl_native_new (MetaPointerConstraint *constraint, + const cairo_region_t *region) +{ + MetaPointerConstraintImplNative *constraint_impl; + + constraint_impl = g_object_new (META_TYPE_POINTER_CONSTRAINT_IMPL_NATIVE, + NULL); + constraint_impl->constraint = constraint; + constraint_impl->region = cairo_region_copy (region); + + return META_POINTER_CONSTRAINT_IMPL (constraint_impl); +} diff --git a/src/backends/native/meta-pointer-constraint-native.h b/src/backends/native/meta-pointer-constraint-native.h new file mode 100644 index 00000000000..83a2e575d5a --- /dev/null +++ b/src/backends/native/meta-pointer-constraint-native.h @@ -0,0 +1,46 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2020 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Carlos Garnacho + */ + +#ifndef META_POINTER_CONSTRAINT_NATIVE_H +#define META_POINTER_CONSTRAINT_NATIVE_H + +#include + +#include "clutter/clutter.h" +#include "backends/meta-pointer-constraint.h" + +G_BEGIN_DECLS + +#define META_TYPE_POINTER_CONSTRAINT_IMPL_NATIVE (meta_pointer_constraint_impl_native_get_type ()) +G_DECLARE_FINAL_TYPE (MetaPointerConstraintImplNative, + meta_pointer_constraint_impl_native, + META, POINTER_CONSTRAINT_IMPL_NATIVE, + MetaPointerConstraintImpl) + +MetaPointerConstraintImpl * meta_pointer_constraint_impl_native_new (MetaPointerConstraint *constraint_impl, + const cairo_region_t *region); + +G_END_DECLS + +#endif /* META_POINTER_CONSTRAINT_NATIVE_H */ diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index ea0cd0742c5..b27e19672e9 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -934,13 +934,14 @@ meta_seat_native_constrain_pointer (MetaSeatNative *seat, us2ms (time_us), new_x, new_y); - if (seat->constrain_callback) + /* Bar to constraints */ + if (seat->pointer_constraint) { - seat->constrain_callback (core_pointer, - us2ms (time_us), - x, y, - new_x, new_y, - seat->constrain_data); + meta_pointer_constraint_impl_constrain (seat->pointer_constraint, + core_pointer, + us2ms (time_us), + x, y, + new_x, new_y); } /* if we're moving inside a monitor, we're fine */ @@ -2642,9 +2643,6 @@ meta_seat_native_finalize (GObject *object) g_list_free (seat->free_device_ids); - if (seat->constrain_data_notify != NULL) - seat->constrain_data_notify (seat->constrain_data); - g_free (seat->seat_id); G_OBJECT_CLASS (meta_seat_native_parent_class)->finalize (object); @@ -3028,33 +3026,6 @@ meta_seat_native_set_device_callbacks (MetaOpenDeviceCallback open_callback, device_callback_data = user_data; } -/** - * meta_seat_native_set_pointer_constrain_callback: - * @seat: the #ClutterSeat created by the evdev backend - * @callback: the callback - * @user_data: data to pass to the callback - * @user_data_notify: function to be called when removing the callback - * - * Sets a callback to be invoked for every pointer motion. The callback - * can then modify the new pointer coordinates to constrain movement within - * a specific region. - */ -void -meta_seat_native_set_pointer_constrain_callback (MetaSeatNative *seat, - MetaPointerConstrainCallback callback, - gpointer user_data, - GDestroyNotify user_data_notify) -{ - g_return_if_fail (META_IS_SEAT_NATIVE (seat)); - - if (seat->constrain_data_notify) - seat->constrain_data_notify (seat->constrain_data); - - seat->constrain_callback = callback; - seat->constrain_data = user_data; - seat->constrain_data_notify = user_data_notify; -} - void meta_seat_native_update_xkb_state (MetaSeatNative *seat) { @@ -3303,3 +3274,17 @@ meta_seat_native_get_barrier_manager (MetaSeatNative *seat) { return seat->barrier_manager; } + +void +meta_seat_native_set_pointer_constraint (MetaSeatNative *seat, + MetaPointerConstraintImpl *constraint_impl) +{ + if (!g_set_object (&seat->pointer_constraint, constraint_impl)) + return; + + if (constraint_impl) + { + meta_pointer_constraint_impl_ensure_constrained (constraint_impl, + seat->core_pointer); + } +} diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h index 0cc353e7d86..2a1faaee006 100644 --- a/src/backends/native/meta-seat-native.h +++ b/src/backends/native/meta-seat-native.h @@ -29,6 +29,7 @@ #include "backends/native/meta-barrier-native.h" #include "backends/native/meta-keymap-native.h" +#include "backends/native/meta-pointer-constraint-native.h" #include "backends/native/meta-xkb-utils.h" #include "clutter/clutter.h" @@ -36,30 +37,6 @@ typedef struct _MetaTouchState MetaTouchState; typedef struct _MetaSeatNative MetaSeatNative; typedef struct _MetaEventSource MetaEventSource; -/** - * MetaPointerConstrainCallback: - * @device: the core pointer device - * @time: the event time in milliseconds - * @x: (inout): the new X coordinate - * @y: (inout): the new Y coordinate - * @user_data: user data passed to this function - * - * This callback will be called for all pointer motion events, and should - * update (@x, @y) to constrain the pointer position appropriately. - * The subsequent motion event will use the updated values as the new coordinates. - * Note that the coordinates are not clamped to the stage size, and the callback - * must make sure that this happens before it returns. - * Also note that the event will be emitted even if the pointer is constrained - * to be in the same position. - */ -typedef void (* MetaPointerConstrainCallback) (ClutterInputDevice *device, - uint32_t time, - float prev_x, - float prev_y, - float *x, - float *y, - gpointer user_data); - struct _MetaTouchState { MetaSeatNative *seat; @@ -104,10 +81,7 @@ struct _MetaSeatNative GList *free_device_ids; MetaBarrierManagerNative *barrier_manager; - - MetaPointerConstrainCallback constrain_callback; - gpointer constrain_data; - GDestroyNotify constrain_data_notify; + MetaPointerConstraintImpl *pointer_constraint; MetaKeymapNative *keymap; @@ -256,11 +230,6 @@ void meta_seat_native_set_device_callbacks (MetaOpenDeviceCallback open_callba void meta_seat_native_release_devices (MetaSeatNative *seat); void meta_seat_native_reclaim_devices (MetaSeatNative *seat); -void meta_seat_native_set_pointer_constrain_callback (MetaSeatNative *seat, - MetaPointerConstrainCallback callback, - gpointer user_data, - GDestroyNotify user_data_notify); - struct xkb_state * meta_seat_native_get_xkb_state (MetaSeatNative *seat); void meta_seat_native_set_keyboard_map (MetaSeatNative *seat, @@ -286,4 +255,7 @@ void meta_seat_native_release_touch_slots (MetaSeatNative *seat, MetaBarrierManagerNative * meta_seat_native_get_barrier_manager (MetaSeatNative *seat); +void meta_seat_native_set_pointer_constraint (MetaSeatNative *seat, + MetaPointerConstraintImpl *constraint_impl); + #endif /* META_SEAT_NATIVE_H */ diff --git a/src/meson.build b/src/meson.build index cc8527beaba..df8667f5c24 100644 --- a/src/meson.build +++ b/src/meson.build @@ -697,6 +697,8 @@ if have_native_backend 'backends/native/meta-kms-utils.h', 'backends/native/meta-kms.c', 'backends/native/meta-kms.h', + 'backends/native/meta-pointer-constraint-native.c', + 'backends/native/meta-pointer-constraint-native.h', 'backends/native/meta-renderer-native-gles3.c', 'backends/native/meta-renderer-native-gles3.h', 'backends/native/meta-renderer-native.h', diff --git a/src/wayland/meta-pointer-confinement-wayland.c b/src/wayland/meta-pointer-confinement-wayland.c index 7f980054c7b..3df6ed0ab35 100644 --- a/src/wayland/meta-pointer-confinement-wayland.c +++ b/src/wayland/meta-pointer-confinement-wayland.c @@ -41,698 +41,227 @@ #include "backends/meta-backend-private.h" #include "backends/meta-pointer-constraint.h" -#include "compositor/meta-surface-actor-wayland.h" -#include "core/meta-border.h" #include "wayland/meta-wayland-pointer-constraints.h" #include "wayland/meta-wayland-pointer.h" #include "wayland/meta-wayland-seat.h" #include "wayland/meta-wayland-surface.h" -struct _MetaPointerConfinementWayland -{ - MetaPointerConstraint parent; +typedef struct _MetaPointerConfinementWaylandPrivate MetaPointerConfinementWaylandPrivate; +struct _MetaPointerConfinementWaylandPrivate +{ MetaWaylandPointerConstraint *constraint; + gboolean enabled; }; -typedef struct _MetaBox -{ - int x1; - int y1; - int x2; - int y2; -} MetaBox; - -G_DEFINE_TYPE (MetaPointerConfinementWayland, meta_pointer_confinement_wayland, - META_TYPE_POINTER_CONSTRAINT); - -static MetaBorder * -add_border (GArray *borders, - float x1, float y1, - float x2, float y2, - MetaBorderMotionDirection blocking_directions) +enum { - MetaBorder border; - - border = (MetaBorder) { - .line = (MetaLine2) { - .a = (MetaVector2) { - .x = x1, - .y = y1, - }, - .b = (MetaVector2) { - .x = x2, - .y = y2, - }, - }, - .blocking_directions = blocking_directions, - }; - - g_array_append_val (borders, border); - - return &g_array_index (borders, MetaBorder, borders->len - 1); -} + PROP_0, + PROP_WAYLAND_POINTER_CONSTRAINT, + N_PROPS, +}; -static gint -compare_lines_x (gconstpointer a, gconstpointer b) -{ - const MetaBorder *border_a = a; - const MetaBorder *border_b = b; +static GParamSpec *props[N_PROPS] = { 0 }; - if (border_a->line.a.x == border_b->line.a.x) - return border_a->line.b.x < border_b->line.b.x; - else - return border_a->line.a.x > border_b->line.a.x; -} +G_DEFINE_TYPE_WITH_PRIVATE (MetaPointerConfinementWayland, + meta_pointer_confinement_wayland, + G_TYPE_OBJECT) static void -add_non_overlapping_edges (MetaBox *boxes, - unsigned int band_above_start, - unsigned int band_below_start, - unsigned int band_below_end, - GArray *borders) +meta_pointer_confinement_wayland_update (MetaPointerConfinementWayland *self) { - unsigned int i; - GArray *band_merge; - MetaBorder *border; - MetaBorder *prev_border; - MetaBorder *new_border; - - band_merge = g_array_new (FALSE, FALSE, sizeof *border); - - /* Add bottom band of previous row, and top band of current row, and - * sort them so lower left x coordinate comes first. If there are two - * borders with the same left x coordinate, the wider one comes first. - */ - for (i = band_above_start; i < band_below_start; i++) - { - MetaBox *box = &boxes[i]; - add_border (band_merge, box->x1, box->y2, box->x2, box->y2, - META_BORDER_MOTION_DIRECTION_POSITIVE_Y); - } - for (i = band_below_start; i < band_below_end; i++) - { - MetaBox *box= &boxes[i]; - add_border (band_merge, box->x1, box->y1, box->x2, box->y1, - META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); - } - g_array_sort (band_merge, compare_lines_x); - - /* Combine the two combined bands so that any overlapping border is - * eliminated. */ - prev_border = NULL; - for (i = 0; i < band_merge->len; i++) - { - border = &g_array_index (band_merge, MetaBorder, i); - - g_assert (border->line.a.y == border->line.b.y); - g_assert (!prev_border || - prev_border->line.a.y == border->line.a.y); - g_assert (!prev_border || - (prev_border->line.a.x != border->line.a.x || - prev_border->line.b.x != border->line.b.x)); - g_assert (!prev_border || - prev_border->line.a.x <= border->line.a.x); - - if (prev_border && - prev_border->line.a.x == border->line.a.x) - { - /* - * ------------ + - * ------- = - * [ ]----- - */ - prev_border->line.a.x = border->line.b.x; - } - else if (prev_border && - prev_border->line.b.x == border->line.b.x) - { - /* - * ------------ + - * ------ = - * ------[ ] - */ - prev_border->line.b.x = border->line.a.x; - } - else if (prev_border && - prev_border->line.b.x == border->line.a.x) - { - /* - * -------- + - * ------ = - * -------------- - */ - prev_border->line.b.x = border->line.b.x; - } - else if (prev_border && - prev_border->line.b.x >= border->line.a.x) - { - /* - * --------------- + - * ------ = - * -----[ ]---- - */ - new_border = add_border (borders, - border->line.b.x, - border->line.b.y, - prev_border->line.b.x, - prev_border->line.b.y, - prev_border->blocking_directions); - prev_border->line.b.x = border->line.a.x; - prev_border = new_border; - } - else - { - g_assert (!prev_border || - prev_border->line.b.x < border->line.a.x); - /* - * First border or non-overlapping. - * - * ----- + - * ----- = - * ----- ----- - */ - g_array_append_val (borders, *border); - prev_border = &g_array_index (borders, MetaBorder, borders->len - 1); - } - } + MetaPointerConstraint *constraint; - g_array_free (band_merge, FALSE); + constraint = + META_POINTER_CONFINEMENT_WAYLAND_GET_CLASS (self)->create_constraint (self); + meta_backend_set_client_pointer_constraint (meta_get_backend (), constraint); + g_object_unref (constraint); } static void -add_band_bottom_edges (MetaBox *boxes, - int band_start, - int band_end, - GArray *borders) +surface_geometry_changed (MetaWaylandSurface *surface, + MetaPointerConfinementWayland *self) { - int i; - - for (i = band_start; i < band_end; i++) - { - add_border (borders, - boxes[i].x1, boxes[i].y2, - boxes[i].x2, boxes[i].y2, - META_BORDER_MOTION_DIRECTION_POSITIVE_Y); - } + meta_pointer_confinement_wayland_update (self); } static void -region_to_outline (cairo_region_t *region, - GArray *borders) +window_position_changed (MetaWindow *window, + MetaPointerConfinementWayland *self) { - MetaBox *boxes; - int num_boxes; - int i; - int top_most, bottom_most; - int current_roof; - int prev_top; - int band_start, prev_band_start; - - /* - * Remove any overlapping lines from the set of rectangles. Note that - * pixman regions are grouped as rows of rectangles, where rectangles - * in one row never touch or overlap and are all of the same height. - * - * -------- --- -------- --- - * | | | | | | | | - * ----------====---- --- ----------- ----- --- - * | | => | | - * ----==========--------- ----- ---------- - * | | | | - * ------------------- ------------------- - * - */ - - num_boxes = cairo_region_num_rectangles (region); - boxes = g_new (MetaBox, num_boxes); - for (i = 0; i < num_boxes; i++) - { - cairo_rectangle_int_t rect; - cairo_region_get_rectangle (region, i, &rect); - boxes[i] = (MetaBox) { - .x1 = rect.x, - .y1 = rect.y, - .x2 = rect.x + rect.width, - .y2 = rect.y + rect.height, - }; - } - prev_top = 0; - top_most = boxes[0].y1; - current_roof = top_most; - bottom_most = boxes[num_boxes - 1].y2; - band_start = 0; - prev_band_start = 0; - for (i = 0; i < num_boxes; i++) - { - /* Detect if there is a vertical empty space, and add the lower - * level of the previous band if so was the case. */ - if (i > 0 && - boxes[i].y1 != prev_top && - boxes[i].y1 != boxes[i - 1].y2) - { - current_roof = boxes[i].y1; - add_band_bottom_edges (boxes, - band_start, - i, - borders); - } - - /* Special case adding the last band, since it won't be handled - * by the band change detection below. */ - if (boxes[i].y1 != current_roof && i == num_boxes - 1) - { - if (boxes[i].y1 != prev_top) - { - /* The last band is a single box, so we don't - * have a prev_band_start to tell us when the - * previous band started. */ - add_non_overlapping_edges (boxes, - band_start, - i, - i + 1, - borders); - } - else - { - add_non_overlapping_edges (boxes, - prev_band_start, - band_start, - i + 1, - borders); - } - } - - /* Detect when passing a band and combine the top border of the - * just passed band with the bottom band of the previous band. - */ - if (boxes[i].y1 != top_most && boxes[i].y1 != prev_top) - { - /* Combine the two passed bands. */ - if (prev_top != current_roof) - { - add_non_overlapping_edges (boxes, - prev_band_start, - band_start, - i, - borders); - } - - prev_band_start = band_start; - band_start = i; - } - - /* Add the top border if the box is part of the current roof. */ - if (boxes[i].y1 == current_roof) - { - add_border (borders, - boxes[i].x1, boxes[i].y1, - boxes[i].x2, boxes[i].y1, - META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); - } - - /* Add the bottom border of the last band. */ - if (boxes[i].y2 == bottom_most) - { - add_border (borders, - boxes[i].x1, boxes[i].y2, - boxes[i].x2, boxes[i].y2, - META_BORDER_MOTION_DIRECTION_POSITIVE_Y); - } - - /* Always add the left border. */ - add_border (borders, - boxes[i].x1, boxes[i].y1, - boxes[i].x1, boxes[i].y2, - META_BORDER_MOTION_DIRECTION_NEGATIVE_X); - - /* Always add the right border. */ - add_border (borders, - boxes[i].x2, boxes[i].y1, - boxes[i].x2, boxes[i].y2, - META_BORDER_MOTION_DIRECTION_POSITIVE_X); - - prev_top = boxes[i].y1; - } - - g_free (boxes); + meta_pointer_confinement_wayland_update (self); } -static MetaBorder * -get_closest_border (GArray *borders, - MetaLine2 *motion, - uint32_t directions) +void +meta_pointer_confinement_wayland_enable (MetaPointerConfinementWayland *confinement) { - MetaBorder *border; - MetaVector2 intersection; - MetaVector2 delta; - float distance_2; - MetaBorder *closest_border = NULL; - float closest_distance_2 = DBL_MAX; - unsigned int i; - - for (i = 0; i < borders->len; i++) - { - border = &g_array_index (borders, MetaBorder, i); - - if (!meta_border_is_blocking_directions (border, directions)) - continue; + MetaPointerConfinementWaylandPrivate *priv; + MetaWaylandPointerConstraint *constraint; + MetaWaylandSurface *surface; + MetaWindow *window; - if (!meta_line2_intersects_with (&border->line, motion, &intersection)) - continue; + priv = meta_pointer_confinement_wayland_get_instance_private (confinement); + g_assert (!priv->enabled); - delta = meta_vector2_subtract (intersection, motion->a); - distance_2 = delta.x*delta.x + delta.y*delta.y; - if (distance_2 < closest_distance_2) - { - closest_border = border; - closest_distance_2 = distance_2; - } - } + priv->enabled = TRUE; + constraint = priv->constraint; - return closest_border; -} + surface = meta_wayland_pointer_constraint_get_surface (constraint); + g_signal_connect_object (surface, + "geometry-changed", + G_CALLBACK (surface_geometry_changed), + confinement, + 0); -static void -clamp_to_border (MetaBorder *border, - MetaLine2 *motion, - uint32_t *motion_dir) -{ - /* - * When clamping either rightward or downward motions, the motion needs to be - * clamped so that the destination coordinate does not end up on the border - * (see weston_pointer_clamp_event_to_region). Do this by clamping such - * motions to the border minus the smallest possible wl_fixed_t value. - * - * When clamping in either leftward or upward motion, the resulting coordinate - * needs to be clamped so that it is enough on the inside to avoid the - * inaccuracies of clutter's stage to actor transformation algorithm (the one - * used in clutter_actor_transform_stage_point) to make it end up outside the - * next motion. It also needs to be clamped so that to the wl_fixed_t - * coordinate may still be right on the border (i.e. at .0). Testing shows - * that the smallest wl_fixed_t value divided by 10 is small enough to make - * the wl_fixed_t coordinate .0 and large enough to avoid the inaccuracies of - * clutters transform algorithm. - */ - if (meta_border_is_horizontal (border)) - { - if (*motion_dir & META_BORDER_MOTION_DIRECTION_POSITIVE_Y) - motion->b.y = border->line.a.y - wl_fixed_to_double (1); - else - motion->b.y = border->line.a.y + wl_fixed_to_double (1) / 10; - *motion_dir &= ~(META_BORDER_MOTION_DIRECTION_POSITIVE_Y | - META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); - } - else + window = meta_wayland_surface_get_window (surface); + if (window) { - if (*motion_dir & META_BORDER_MOTION_DIRECTION_POSITIVE_X) - motion->b.x = border->line.a.x - wl_fixed_to_double (1); - else - motion->b.x = border->line.a.x + wl_fixed_to_double (1) / 10; - *motion_dir &= ~(META_BORDER_MOTION_DIRECTION_POSITIVE_X | - META_BORDER_MOTION_DIRECTION_NEGATIVE_X); + g_signal_connect_object (window, + "position-changed", + G_CALLBACK (window_position_changed), + confinement, + 0); } -} -static uint32_t -get_motion_directions (MetaLine2 *motion) -{ - uint32_t directions = 0; - - if (motion->a.x < motion->b.x) - directions |= META_BORDER_MOTION_DIRECTION_POSITIVE_X; - else if (motion->a.x > motion->b.x) - directions |= META_BORDER_MOTION_DIRECTION_NEGATIVE_X; - if (motion->a.y < motion->b.y) - directions |= META_BORDER_MOTION_DIRECTION_POSITIVE_Y; - else if (motion->a.y > motion->b.y) - directions |= META_BORDER_MOTION_DIRECTION_NEGATIVE_Y; - - return directions; + meta_pointer_confinement_wayland_update (confinement); } -static void -meta_pointer_confinement_wayland_constrain (MetaPointerConstraint *constraint, - ClutterInputDevice *device, - guint32 time, - float prev_x, - float prev_y, - float *x, - float *y) +void +meta_pointer_confinement_wayland_disable (MetaPointerConfinementWayland *confinement) { - MetaPointerConfinementWayland *self = - META_POINTER_CONFINEMENT_WAYLAND (constraint); + MetaPointerConfinementWaylandPrivate *priv; + MetaWaylandPointerConstraint *constraint; MetaWaylandSurface *surface; - cairo_region_t *region; - float sx, sy; - float prev_sx, prev_sy; - GArray *borders; - MetaLine2 motion; - MetaBorder *closest_border; - uint32_t directions; - - surface = meta_wayland_pointer_constraint_get_surface (self->constraint); - - meta_wayland_surface_get_relative_coordinates (surface, *x, *y, &sx, &sy); - meta_wayland_surface_get_relative_coordinates (surface, prev_x, prev_y, - &prev_sx, &prev_sy); - - /* For motions in a positive direction on any axis, append the smallest - * possible value representable in a Wayland absolute coordinate. This is - * in order to avoid not clamping motion that as a floating point number - * won't be clamped, but will be rounded up to be outside of the range - * of wl_fixed_t. */ - if (sx > prev_sx) - sx += (float)wl_fixed_to_double(1); - if (sy > prev_sy) - sy += (float)wl_fixed_to_double(1); - - borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder)); - - /* - * Generate borders given the confine region we are to use. The borders - * are defined to be the outer region of the allowed area. This means - * top/left borders are "within" the allowed area, while bottom/right - * borders are outside. This needs to be considered when clamping - * confined motion vectors. - */ - region = - meta_wayland_pointer_constraint_calculate_effective_region (self->constraint); - region_to_outline (region, borders); - cairo_region_destroy (region); + MetaWindow *window; - motion = (MetaLine2) { - .a = (MetaVector2) { - .x = prev_sx, - .y = prev_sy, - }, - .b = (MetaVector2) { - .x = sx, - .y = sy, - }, - }; - directions = get_motion_directions (&motion); - - while (directions) + priv = meta_pointer_confinement_wayland_get_instance_private (confinement); + constraint = priv->constraint; + g_assert (priv->enabled); + + priv->enabled = FALSE; + surface = meta_wayland_pointer_constraint_get_surface (constraint); + g_signal_handlers_disconnect_by_func (surface, surface_geometry_changed, + confinement); + + window = meta_wayland_surface_get_window (surface); + if (window) { - closest_border = get_closest_border (borders, - &motion, - directions); - if (closest_border) - clamp_to_border (closest_border, &motion, &directions); - else - break; + g_signal_handlers_disconnect_by_func (window, window_position_changed, + confinement); } - meta_wayland_surface_get_absolute_coordinates (surface, - motion.b.x, motion.b.y, - x, y); + meta_backend_set_client_pointer_constraint (meta_get_backend (), NULL); +} - g_array_free (borders, FALSE); +static void +meta_pointer_confinement_wayland_init (MetaPointerConfinementWayland *confinement_wayland) +{ } -static float -point_to_border_distance_2 (MetaBorder *border, - float x, - float y) +static void +meta_pointer_confinement_wayland_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - float orig_x, orig_y; - float dx, dy; + MetaPointerConfinementWayland *confinement; + MetaPointerConfinementWaylandPrivate *priv; - if (meta_border_is_horizontal (border)) - { - if (x < border->line.a.x) - orig_x = border->line.a.x; - else if (x > border->line.b.x) - orig_x = border->line.b.x; - else - orig_x = x; - orig_y = border->line.a.y; - } - else + confinement = META_POINTER_CONFINEMENT_WAYLAND (object); + priv = meta_pointer_confinement_wayland_get_instance_private (confinement); + + switch (prop_id) { - if (y < border->line.a.y) - orig_y = border->line.a.y; - else if (y > border->line.b.y) - orig_y = border->line.b.y; - else - orig_y = y; - orig_x = border->line.a.x; + case PROP_WAYLAND_POINTER_CONSTRAINT: + g_value_set_object (value, priv->constraint); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } - - dx = fabsf (orig_x - x); - dy = fabsf (orig_y - y); - return dx*dx + dy*dy; } static void -warp_to_behind_border (MetaBorder *border, - float *sx, - float *sy) +meta_pointer_confinement_wayland_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - switch (border->blocking_directions) + MetaPointerConfinementWayland *confinement; + MetaPointerConfinementWaylandPrivate *priv; + + confinement = META_POINTER_CONFINEMENT_WAYLAND (object); + priv = meta_pointer_confinement_wayland_get_instance_private (confinement); + + switch (prop_id) { - case META_BORDER_MOTION_DIRECTION_POSITIVE_X: - case META_BORDER_MOTION_DIRECTION_NEGATIVE_X: - if (border->blocking_directions == META_BORDER_MOTION_DIRECTION_POSITIVE_X) - *sx = border->line.a.x - wl_fixed_to_double (1); - else - *sx = border->line.a.x + wl_fixed_to_double (1); - if (*sy < border->line.a.y) - *sy = border->line.a.y + wl_fixed_to_double (1); - else if (*sy > border->line.b.y) - *sy = border->line.b.y - wl_fixed_to_double (1); + case PROP_WAYLAND_POINTER_CONSTRAINT: + priv->constraint = g_value_get_object (value); break; - case META_BORDER_MOTION_DIRECTION_POSITIVE_Y: - case META_BORDER_MOTION_DIRECTION_NEGATIVE_Y: - if (border->blocking_directions == META_BORDER_MOTION_DIRECTION_POSITIVE_Y) - *sy = border->line.a.y - wl_fixed_to_double (1); - else - *sy = border->line.a.y + wl_fixed_to_double (1); - if (*sx < border->line.a.x) - *sx = border->line.a.x + wl_fixed_to_double (1); - else if (*sx > (border->line.b.x)) - *sx = border->line.b.x - wl_fixed_to_double (1); + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } -static void -meta_pointer_confinement_wayland_maybe_warp (MetaPointerConfinementWayland *self) +static MetaPointerConstraint * +meta_pointer_confinement_wayland_create_constraint (MetaPointerConfinementWayland *confinement) { - MetaWaylandSeat *seat; + MetaPointerConfinementWaylandPrivate *priv; + MetaPointerConstraint *constraint; MetaWaylandSurface *surface; - graphene_point_t point; - float sx; - float sy; cairo_region_t *region; + float dx, dy; - seat = meta_wayland_pointer_constraint_get_seat (self->constraint); - surface = meta_wayland_pointer_constraint_get_surface (self->constraint); - - clutter_input_device_get_coords (seat->pointer->device, NULL, &point); - meta_wayland_surface_get_relative_coordinates (surface, - point.x, point.y, - &sx, &sy); + priv = meta_pointer_confinement_wayland_get_instance_private (confinement); + surface = meta_wayland_pointer_constraint_get_surface (priv->constraint); region = - meta_wayland_pointer_constraint_calculate_effective_region (self->constraint); - - if (!cairo_region_contains_point (region, (int)sx, (int)sy)) - { - GArray *borders; - float closest_distance_2 = FLT_MAX; - MetaBorder *closest_border = NULL; - ClutterSeat *seat; - unsigned int i; - float x; - float y; - - borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder)); - - region_to_outline (region, borders); - - for (i = 0; i < borders->len; i++) - { - MetaBorder *border = &g_array_index (borders, MetaBorder, i); - float distance_2; - - distance_2 = point_to_border_distance_2 (border, sx, sy); - if (distance_2 < closest_distance_2) - { - closest_border = border; - closest_distance_2 = distance_2; - } - } - - warp_to_behind_border (closest_border, &sx, &sy); + meta_wayland_pointer_constraint_calculate_effective_region (priv->constraint); - meta_wayland_surface_get_absolute_coordinates (surface, sx, sy, &x, &y); - - seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); - clutter_seat_warp_pointer (seat, (int)x, (int)y); - } + meta_wayland_surface_get_absolute_coordinates (surface, 0, 0, &dx, &dy); + cairo_region_translate (region, dx, dy); + constraint = meta_pointer_constraint_new (region); cairo_region_destroy (region); -} -static void -surface_geometry_changed (MetaWaylandSurface *surface, - MetaPointerConfinementWayland *self) -{ - meta_pointer_confinement_wayland_maybe_warp (self); + return constraint; } static void -window_position_changed (MetaWindow *window, - MetaPointerConfinementWayland *self) +meta_pointer_confinement_wayland_class_init (MetaPointerConfinementWaylandClass *klass) { - meta_pointer_confinement_wayland_maybe_warp (self); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = meta_pointer_confinement_wayland_set_property; + object_class->get_property = meta_pointer_confinement_wayland_get_property; + + klass->create_constraint = meta_pointer_confinement_wayland_create_constraint; + + props[PROP_WAYLAND_POINTER_CONSTRAINT] = + g_param_spec_object ("wayland-pointer-constraint", + "Wayland pointer constraint", + "Wayland pointer constraint", + META_TYPE_WAYLAND_POINTER_CONSTRAINT, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, N_PROPS, props); } -MetaPointerConstraint * +MetaPointerConfinementWayland * meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint) { - GObject *object; - MetaPointerConfinementWayland *confinement; - MetaWaylandSurface *surface; - MetaWindow *window; - - object = g_object_new (META_TYPE_POINTER_CONFINEMENT_WAYLAND, NULL); - confinement = META_POINTER_CONFINEMENT_WAYLAND (object); - - confinement->constraint = constraint; - - surface = meta_wayland_pointer_constraint_get_surface (constraint); - g_signal_connect_object (surface, - "geometry-changed", - G_CALLBACK (surface_geometry_changed), - confinement, - 0); - - window = meta_wayland_surface_get_window (surface); - if (window) - { - g_signal_connect_object (window, - "position-changed", - G_CALLBACK (window_position_changed), - confinement, - 0); - } - - return META_POINTER_CONSTRAINT (confinement); -} - -static void -meta_pointer_confinement_wayland_init (MetaPointerConfinementWayland *confinement_wayland) -{ + return g_object_new (META_TYPE_POINTER_CONFINEMENT_WAYLAND, + "wayland-pointer-constraint", constraint, + NULL); } -static void -meta_pointer_confinement_wayland_class_init (MetaPointerConfinementWaylandClass *klass) +MetaWaylandPointerConstraint * +meta_pointer_confinement_wayland_get_wayland_pointer_constraint (MetaPointerConfinementWayland *confinement) { - MetaPointerConstraintClass *pointer_constraint_class = - META_POINTER_CONSTRAINT_CLASS (klass); + MetaPointerConfinementWaylandPrivate *priv; - pointer_constraint_class->constrain = meta_pointer_confinement_wayland_constrain; + priv = meta_pointer_confinement_wayland_get_instance_private (confinement); + return priv->constraint; } diff --git a/src/wayland/meta-pointer-confinement-wayland.h b/src/wayland/meta-pointer-confinement-wayland.h index 482a25a9ae2..4f265779c46 100644 --- a/src/wayland/meta-pointer-confinement-wayland.h +++ b/src/wayland/meta-pointer-confinement-wayland.h @@ -33,12 +33,23 @@ G_BEGIN_DECLS #define META_TYPE_POINTER_CONFINEMENT_WAYLAND (meta_pointer_confinement_wayland_get_type ()) -G_DECLARE_FINAL_TYPE (MetaPointerConfinementWayland, - meta_pointer_confinement_wayland, - META, POINTER_CONFINEMENT_WAYLAND, - MetaPointerConstraint); - -MetaPointerConstraint *meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint); +G_DECLARE_DERIVABLE_TYPE (MetaPointerConfinementWayland, + meta_pointer_confinement_wayland, + META, POINTER_CONFINEMENT_WAYLAND, + GObject) + +struct _MetaPointerConfinementWaylandClass +{ + GObjectClass parent_class; + + MetaPointerConstraint * (*create_constraint) (MetaPointerConfinementWayland *confinement); +}; + +MetaPointerConfinementWayland *meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint); +MetaWaylandPointerConstraint * + meta_pointer_confinement_wayland_get_wayland_pointer_constraint (MetaPointerConfinementWayland *confinement); +void meta_pointer_confinement_wayland_enable (MetaPointerConfinementWayland *confinement); +void meta_pointer_confinement_wayland_disable (MetaPointerConfinementWayland *confinement); G_END_DECLS diff --git a/src/wayland/meta-pointer-lock-wayland.c b/src/wayland/meta-pointer-lock-wayland.c index 08c2789bc43..e8722473232 100644 --- a/src/wayland/meta-pointer-lock-wayland.c +++ b/src/wayland/meta-pointer-lock-wayland.c @@ -37,33 +37,55 @@ #include -#include "backends/meta-pointer-constraint.h" +#include "backends/meta-backend-private.h" +#include "compositor/meta-surface-actor-wayland.h" struct _MetaPointerLockWayland { - MetaPointerConstraint parent; + GObject parent; + MetaWaylandPointerConstraint *constraint; }; G_DEFINE_TYPE (MetaPointerLockWayland, meta_pointer_lock_wayland, - META_TYPE_POINTER_CONSTRAINT); + META_TYPE_POINTER_CONFINEMENT_WAYLAND) -static void -meta_pointer_lock_wayland_constrain (MetaPointerConstraint *constraint, - ClutterInputDevice *device, - guint32 time, - float prev_x, - float prev_y, - float *x, - float *y) +static MetaPointerConstraint * +meta_pointer_lock_wayland_create_constraint (MetaPointerConfinementWayland *confinement) { - *x = prev_x; - *y = prev_y; + MetaBackend *backend = meta_get_backend (); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); + ClutterInputDevice *pointer = clutter_seat_get_pointer (seat); + MetaWaylandPointerConstraint *wayland_constraint; + MetaPointerConstraint *constraint; + MetaWaylandSurface *surface; + graphene_point_t point; + cairo_region_t *region; + float sx, sy, x, y; + + clutter_input_device_get_coords (pointer, NULL, &point); + wayland_constraint = + meta_pointer_confinement_wayland_get_wayland_pointer_constraint (confinement); + surface = meta_wayland_pointer_constraint_get_surface (wayland_constraint); + meta_wayland_surface_get_relative_coordinates (surface, + point.x, point.y, + &sx, &sy); + + meta_wayland_surface_get_absolute_coordinates (surface, sx, sy, &x, &y); + region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { (int) x, (int) y, 1 , 1 }); + + constraint = meta_pointer_constraint_new (region); + cairo_region_destroy (region); + + return constraint; } -MetaPointerConstraint * -meta_pointer_lock_wayland_new (void) +MetaPointerConfinementWayland * +meta_pointer_lock_wayland_new (MetaWaylandPointerConstraint *constraint) { - return g_object_new (META_TYPE_POINTER_LOCK_WAYLAND, NULL); + return g_object_new (META_TYPE_POINTER_LOCK_WAYLAND, + "wayland-pointer-constraint", constraint, + NULL); } static void @@ -74,8 +96,9 @@ meta_pointer_lock_wayland_init (MetaPointerLockWayland *lock_wayland) static void meta_pointer_lock_wayland_class_init (MetaPointerLockWaylandClass *klass) { - MetaPointerConstraintClass *pointer_constraint_class = - META_POINTER_CONSTRAINT_CLASS (klass); + MetaPointerConfinementWaylandClass *confinement_class = + META_POINTER_CONFINEMENT_WAYLAND_CLASS (klass); - pointer_constraint_class->constrain = meta_pointer_lock_wayland_constrain; + confinement_class->create_constraint = + meta_pointer_lock_wayland_create_constraint; } diff --git a/src/wayland/meta-pointer-lock-wayland.h b/src/wayland/meta-pointer-lock-wayland.h index 787b43269d6..d52aaa30dd7 100644 --- a/src/wayland/meta-pointer-lock-wayland.h +++ b/src/wayland/meta-pointer-lock-wayland.h @@ -27,15 +27,15 @@ #include -#include "backends/meta-pointer-constraint.h" +#include "wayland/meta-pointer-confinement-wayland.h" G_BEGIN_DECLS #define META_TYPE_POINTER_LOCK_WAYLAND (meta_pointer_lock_wayland_get_type ()) G_DECLARE_FINAL_TYPE (MetaPointerLockWayland, meta_pointer_lock_wayland, - META, POINTER_LOCK_WAYLAND, MetaPointerConstraint); + META, POINTER_LOCK_WAYLAND, MetaPointerConfinementWayland) -MetaPointerConstraint *meta_pointer_lock_wayland_new (void); +MetaPointerConfinementWayland *meta_pointer_lock_wayland_new (MetaWaylandPointerConstraint *constraint); G_END_DECLS diff --git a/src/wayland/meta-wayland-pointer-constraints.c b/src/wayland/meta-wayland-pointer-constraints.c index 7547d7e13f1..3a8b8e095df 100644 --- a/src/wayland/meta-wayland-pointer-constraints.c +++ b/src/wayland/meta-wayland-pointer-constraints.c @@ -68,7 +68,7 @@ struct _MetaWaylandPointerConstraint wl_fixed_t x_hint; wl_fixed_t y_hint; - MetaPointerConstraint *constraint; + MetaPointerConfinementWayland *confinement; }; typedef struct _MetaWaylandSurfacePointerConstraintsData @@ -375,7 +375,7 @@ meta_wayland_pointer_constraint_notify_deactivated (MetaWaylandPointerConstraint zwp_confined_pointer_v1_send_unconfined (resource); } -static MetaPointerConstraint * +static MetaPointerConfinementWayland * meta_wayland_pointer_constraint_create_pointer_constraint (MetaWaylandPointerConstraint *constraint) { struct wl_resource *resource = constraint->resource; @@ -384,7 +384,7 @@ meta_wayland_pointer_constraint_create_pointer_constraint (MetaWaylandPointerCon &zwp_locked_pointer_v1_interface, &locked_pointer_interface)) { - return meta_pointer_lock_wayland_new (); + return meta_pointer_lock_wayland_new (constraint); } else if (wl_resource_instance_of (resource, &zwp_confined_pointer_v1_interface, @@ -399,8 +399,6 @@ meta_wayland_pointer_constraint_create_pointer_constraint (MetaWaylandPointerCon static void meta_wayland_pointer_constraint_enable (MetaWaylandPointerConstraint *constraint) { - MetaBackend *backend = meta_get_backend (); - g_assert (!constraint->is_enabled); constraint->is_enabled = TRUE; @@ -408,20 +406,25 @@ meta_wayland_pointer_constraint_enable (MetaWaylandPointerConstraint *constraint meta_wayland_pointer_start_grab (constraint->seat->pointer, &constraint->grab); - constraint->constraint = + constraint->confinement = meta_wayland_pointer_constraint_create_pointer_constraint (constraint); - meta_backend_set_client_pointer_constraint (backend, constraint->constraint); - g_object_add_weak_pointer (G_OBJECT (constraint->constraint), - (gpointer *) &constraint->constraint); - g_object_unref (constraint->constraint); + meta_pointer_confinement_wayland_enable (constraint->confinement); + g_object_add_weak_pointer (G_OBJECT (constraint->confinement), + (gpointer *) &constraint->confinement); } static void meta_wayland_pointer_constraint_disable (MetaWaylandPointerConstraint *constraint) { constraint->is_enabled = FALSE; + + if (constraint->confinement) + { + meta_pointer_confinement_wayland_disable (constraint->confinement); + g_object_unref (constraint->confinement); + } + meta_wayland_pointer_constraint_notify_deactivated (constraint); - meta_backend_set_client_pointer_constraint (meta_get_backend (), NULL); meta_wayland_pointer_end_grab (constraint->grab.pointer); } -- GitLab From 7a2a2445c36eb68dccc1438d0613c36c6d34a221 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 10 Jul 2020 00:40:55 +0200 Subject: [PATCH 13/85] backends: Remove x/y arguments from MetaCursorTracker::cursor-moved Make this signal a hint, the actual coordinates should be queried to the cursor tracker, the device, the seat... There's enough options. Part-of: --- src/backends/meta-cursor-tracker.c | 13 +++---------- src/backends/meta-screen-cast-area-stream-src.c | 2 -- src/backends/meta-screen-cast-monitor-stream-src.c | 2 -- src/backends/meta-screen-cast-window-stream-src.c | 2 -- src/meson.build | 8 -------- src/meta-marshal.list | 1 - 6 files changed, 3 insertions(+), 25 deletions(-) delete mode 100644 src/meta-marshal.list diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c index f90fd768b05..3c6f6a0c432 100644 --- a/src/backends/meta-cursor-tracker.c +++ b/src/backends/meta-cursor-tracker.c @@ -37,7 +37,6 @@ #include "cogl/cogl.h" #include "core/display-private.h" #include "clutter/clutter.h" -#include "meta-marshal.h" #include "meta/main.h" #include "meta/util.h" @@ -301,14 +300,8 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, - NULL, NULL, - meta_marshal_VOID__FLOAT_FLOAT, - G_TYPE_NONE, 2, - G_TYPE_FLOAT, - G_TYPE_FLOAT); - g_signal_set_va_marshaller (signals[CURSOR_MOVED], - G_TYPE_FROM_CLASS (klass), - meta_marshal_VOID__FLOAT_FLOATv); + NULL, NULL, NULL, + G_TYPE_NONE, 0); signals[VISIBILITY_CHANGED] = g_signal_new ("visibility-changed", G_TYPE_FROM_CLASS (klass), @@ -459,7 +452,7 @@ meta_cursor_tracker_update_position (MetaCursorTracker *tracker, meta_cursor_renderer_set_position (cursor_renderer, new_x, new_y); if (position_changed) - g_signal_emit (tracker, signals[CURSOR_MOVED], 0, new_x, new_y); + g_signal_emit (tracker, signals[CURSOR_MOVED], 0); } void diff --git a/src/backends/meta-screen-cast-area-stream-src.c b/src/backends/meta-screen-cast-area-stream-src.c index e7d42d432a3..d83df6dd933 100644 --- a/src/backends/meta-screen-cast-area-stream-src.c +++ b/src/backends/meta-screen-cast-area-stream-src.c @@ -181,8 +181,6 @@ sync_cursor_state (MetaScreenCastAreaStreamSrc *area_src) static void cursor_moved (MetaCursorTracker *cursor_tracker, - float x, - float y, MetaScreenCastAreaStreamSrc *area_src) { sync_cursor_state (area_src); diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c index ab3be968365..3f7584dd8a3 100644 --- a/src/backends/meta-screen-cast-monitor-stream-src.c +++ b/src/backends/meta-screen-cast-monitor-stream-src.c @@ -237,8 +237,6 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src) static void cursor_moved (MetaCursorTracker *cursor_tracker, - float x, - float y, MetaScreenCastMonitorStreamSrc *monitor_src) { sync_cursor_state (monitor_src); diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c index a00bf867ab9..ec9f873c94c 100644 --- a/src/backends/meta-screen-cast-window-stream-src.c +++ b/src/backends/meta-screen-cast-window-stream-src.c @@ -369,8 +369,6 @@ sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src) static void cursor_moved (MetaCursorTracker *cursor_tracker, - float x, - float y, MetaScreenCastWindowStreamSrc *window_src) { sync_cursor_state (window_src); diff --git a/src/meson.build b/src/meson.build index df8667f5c24..84cdabcb6a8 100644 --- a/src/meson.build +++ b/src/meson.build @@ -753,14 +753,6 @@ dbus_idle_monitor_built_sources = gnome.gdbus_codegen('meta-dbus-idle-monitor', ) mutter_built_sources += dbus_idle_monitor_built_sources -mutter_marshal = gnome.genmarshal('meta-marshal', - sources: ['meta-marshal.list'], - prefix: 'meta_marshal', - internal: true, - valist_marshallers: true, - ) -mutter_built_sources += mutter_marshal - if have_profiler mutter_sources += [ 'backends/meta-profiler.c', diff --git a/src/meta-marshal.list b/src/meta-marshal.list deleted file mode 100644 index e26b60a8ec8..00000000000 --- a/src/meta-marshal.list +++ /dev/null @@ -1 +0,0 @@ -VOID:FLOAT,FLOAT -- GitLab From e721fde25959cda29b0ac62bd984c73e7902701f Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 10 Jul 2020 12:25:12 +0200 Subject: [PATCH 14/85] backends: Add argument for best scale on MetaCursorSprite::prepare-at Instead of letting implementations poke backend internals from various places, give that information right away. Part-of: --- src/backends/meta-cursor-renderer.c | 48 +++++++++++++++++++++-- src/backends/meta-cursor.c | 12 +++--- src/backends/meta-cursor.h | 1 + src/core/display.c | 44 ++------------------- src/wayland/meta-wayland-cursor-surface.c | 1 + src/wayland/meta-wayland-tablet-tool.c | 1 + 6 files changed, 58 insertions(+), 49 deletions(-) diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c index ac81deff66c..53b1a10a2af 100644 --- a/src/backends/meta-cursor-renderer.c +++ b/src/backends/meta-cursor-renderer.c @@ -28,6 +28,8 @@ #include +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" #include "backends/meta-stage-private.h" #include "clutter/clutter.h" #include "clutter/clutter-mutter.h" @@ -332,6 +334,41 @@ meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer, }; } +static float +find_highest_logical_monitor_scale (MetaBackend *backend, + MetaCursorSprite *cursor_sprite) +{ + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (backend); + graphene_rect_t cursor_rect; + GList *logical_monitors; + GList *l; + float highest_scale = 0.0f; + + cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer, + cursor_sprite); + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + graphene_rect_t logical_monitor_rect = + meta_rectangle_to_graphene_rect (&logical_monitor->rect); + + if (!graphene_rect_intersection (&cursor_rect, + &logical_monitor_rect, + NULL)) + continue; + + highest_scale = MAX (highest_scale, logical_monitor->scale); + } + + return highest_scale; +} + static void meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer, MetaCursorSprite *cursor_sprite) @@ -340,9 +377,14 @@ meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer, gboolean handled_by_backend; if (cursor_sprite) - meta_cursor_sprite_prepare_at (cursor_sprite, - (int) priv->current_x, - (int) priv->current_y); + { + float scale = find_highest_logical_monitor_scale (priv->backend, + cursor_sprite); + meta_cursor_sprite_prepare_at (cursor_sprite, + MAX (1, scale), + (int) priv->current_x, + (int) priv->current_y); + } handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer, diff --git a/src/backends/meta-cursor.c b/src/backends/meta-cursor.c index 874593d5ad4..d0fb2ba6868 100644 --- a/src/backends/meta-cursor.c +++ b/src/backends/meta-cursor.c @@ -179,11 +179,12 @@ meta_cursor_sprite_get_texture_transform (MetaCursorSprite *sprite) } void -meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite, - int x, - int y) +meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite, + float best_scale, + int x, + int y) { - g_signal_emit (sprite, signals[PREPARE_AT], 0, x, y); + g_signal_emit (sprite, signals[PREPARE_AT], 0, best_scale, x, y); } void @@ -226,7 +227,8 @@ meta_cursor_sprite_class_init (MetaCursorSpriteClass *klass) G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, + G_TYPE_NONE, 3, + G_TYPE_FLOAT, G_TYPE_INT, G_TYPE_INT); signals[TEXTURE_CHANGED] = g_signal_new ("texture-changed", diff --git a/src/backends/meta-cursor.h b/src/backends/meta-cursor.h index 80eaa313c19..a65e128c485 100644 --- a/src/backends/meta-cursor.h +++ b/src/backends/meta-cursor.h @@ -43,6 +43,7 @@ struct _MetaCursorSpriteClass }; void meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite, + float best_scale, int x, int y); diff --git a/src/core/display.c b/src/core/display.c index 35ba540b6ae..db06990ce50 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -46,7 +46,6 @@ #include "backends/meta-idle-monitor-dbus.h" #include "backends/meta-input-device-private.h" #include "backends/meta-input-settings-private.h" -#include "backends/meta-logical-monitor.h" #include "backends/meta-stage-private.h" #include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-event-x11.h" @@ -1629,43 +1628,9 @@ meta_cursor_for_grab_op (MetaGrabOp op) return META_CURSOR_DEFAULT; } -static float -find_highest_logical_monitor_scale (MetaBackend *backend, - MetaCursorSprite *cursor_sprite) -{ - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); - MetaCursorRenderer *cursor_renderer = - meta_backend_get_cursor_renderer (backend); - graphene_rect_t cursor_rect; - GList *logical_monitors; - GList *l; - float highest_scale = 0.0; - - cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer, - cursor_sprite); - - logical_monitors = - meta_monitor_manager_get_logical_monitors (monitor_manager); - for (l = logical_monitors; l; l = l->next) - { - MetaLogicalMonitor *logical_monitor = l->data; - graphene_rect_t logical_monitor_rect = - meta_rectangle_to_graphene_rect (&logical_monitor->rect); - - if (!graphene_rect_intersection (&cursor_rect, - &logical_monitor_rect, - NULL)) - continue; - - highest_scale = MAX (highest_scale, logical_monitor->scale); - } - - return highest_scale; -} - static void root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor, + float best_scale, int x, int y, MetaDisplay *display) @@ -1675,14 +1640,11 @@ root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor, if (meta_is_stage_views_scaled ()) { - float scale; - - scale = find_highest_logical_monitor_scale (backend, cursor_sprite); - if (scale != 0.0) + if (best_scale != 0.0f) { float ceiled_scale; - ceiled_scale = ceilf (scale); + ceiled_scale = ceilf (best_scale); meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor, (int) ceiled_scale); meta_cursor_sprite_set_texture_scale (cursor_sprite, diff --git a/src/wayland/meta-wayland-cursor-surface.c b/src/wayland/meta-wayland-cursor-surface.c index 95f8186df87..af1bc170dbd 100644 --- a/src/wayland/meta-wayland-cursor-surface.c +++ b/src/wayland/meta-wayland-cursor-surface.c @@ -81,6 +81,7 @@ update_cursor_sprite_texture (MetaWaylandCursorSurface *cursor_surface) static void cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite, + float best_scale, int x, int y, MetaWaylandCursorSurface *cursor_surface) diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c index b26ad401643..c913d0a55db 100644 --- a/src/wayland/meta-wayland-tablet-tool.c +++ b/src/wayland/meta-wayland-tablet-tool.c @@ -395,6 +395,7 @@ tablet_tool_handle_cursor_surface_destroy (struct wl_listener *listener, static void tool_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor, + float best_scale, int x, int y, MetaWaylandTabletTool *tool) -- GitLab From d41dbf92ea7e67e448dd3bfd2818c8794f5f1cfd Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 10 Jul 2020 23:28:17 +0200 Subject: [PATCH 15/85] wayland: Replace cursor renderer usage with cursor tracker We just want to know the pointer position, let's use something else here. Part-of: --- src/wayland/meta-wayland-dnd-surface.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/wayland/meta-wayland-dnd-surface.c b/src/wayland/meta-wayland-dnd-surface.c index c3b0f7557b1..eb0dc85df0a 100644 --- a/src/wayland/meta-wayland-dnd-surface.c +++ b/src/wayland/meta-wayland-dnd-surface.c @@ -74,16 +74,14 @@ static MetaLogicalMonitor * dnd_surface_find_logical_monitor (MetaWaylandActorSurface *actor_surface) { MetaBackend *backend = meta_get_backend (); - MetaCursorRenderer *cursor_renderer = - meta_backend_get_cursor_renderer (backend); + MetaCursorTracker *cursor_tracker = + meta_backend_get_cursor_tracker (backend); MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); - graphene_point_t pointer_pos; + int x, y; - pointer_pos = meta_cursor_renderer_get_position (cursor_renderer); - return meta_monitor_manager_get_logical_monitor_at (monitor_manager, - pointer_pos.x, - pointer_pos.y); + meta_cursor_tracker_get_pointer (cursor_tracker, &x, &y, NULL); + return meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y); } static double -- GitLab From 35abb8ab53b61fd36f012ed7975f288fa3c2e1a2 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 10 Jul 2020 23:28:50 +0200 Subject: [PATCH 16/85] backends: Add meta_backend_get_cursor_renderer_for_device() Different devices may get standalone cursor renderers, add this API to adapt slowly to this. The meta_backend_get_cursor_renderer() call still exists, but shortcuts to the mouse pointer's renderer (as it actually did before). Part-of: --- src/backends/meta-backend-private.h | 5 +- src/backends/meta-backend.c | 72 +++++++++++++++++-- src/backends/native/meta-backend-native.c | 12 ++-- src/backends/native/meta-seat-native.c | 23 ++++++ src/backends/native/meta-seat-native.h | 5 ++ src/backends/x11/cm/meta-backend-x11-cm.c | 20 ++++-- .../x11/nested/meta-backend-x11-nested.c | 22 ++++-- 7 files changed, 139 insertions(+), 20 deletions(-) diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index afce64fd7ad..daee54c66d3 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -63,7 +63,8 @@ struct _MetaBackendClass MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend, GError **error); - MetaCursorRenderer * (* create_cursor_renderer) (MetaBackend *backend); + MetaCursorRenderer * (* get_cursor_renderer) (MetaBackend *backend, + ClutterInputDevice *device); MetaCursorTracker * (* create_cursor_tracker) (MetaBackend *backend); MetaRenderer * (* create_renderer) (MetaBackend *backend, GError **error); @@ -128,6 +129,8 @@ META_EXPORT_TEST MetaMonitorManager * meta_backend_get_monitor_manager (MetaBackend *backend); MetaOrientationManager * meta_backend_get_orientation_manager (MetaBackend *backend); MetaCursorTracker * meta_backend_get_cursor_tracker (MetaBackend *backend); +MetaCursorRenderer * meta_backend_get_cursor_renderer_for_device (MetaBackend *backend, + ClutterInputDevice *device); MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend); META_EXPORT_TEST MetaRenderer * meta_backend_get_renderer (MetaBackend *backend); diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 1e4f00a75a2..c174b260e27 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -120,7 +120,6 @@ struct _MetaBackendPrivate MetaMonitorManager *monitor_manager; MetaOrientationManager *orientation_manager; MetaCursorTracker *cursor_tracker; - MetaCursorRenderer *cursor_renderer; MetaInputSettings *input_settings; MetaRenderer *renderer; #ifdef HAVE_EGL @@ -265,6 +264,53 @@ reset_pointer_position (MetaBackend *backend) primary->rect.y + primary->rect.height * 0.9); } +static gboolean +should_have_cursor_renderer (ClutterInputDevice *device) +{ + switch (clutter_input_device_get_device_type (device)) + { + case CLUTTER_POINTER_DEVICE: + if (clutter_input_device_get_device_mode (device) == + CLUTTER_INPUT_MODE_LOGICAL) + return TRUE; + + return FALSE; + case CLUTTER_TABLET_DEVICE: + return TRUE; + default: + return FALSE; + } +} + +static void +update_cursors (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + ClutterSeat *seat = clutter_backend_get_default_seat (priv->clutter_backend); + MetaCursorRenderer *cursor_renderer; + ClutterInputDevice *pointer, *device; + GList *devices, *l; + + pointer = clutter_seat_get_pointer (seat); + devices = clutter_seat_list_devices (seat); + devices = g_list_prepend (devices, pointer); + + for (l = devices; l; l = l->next) + { + device = l->data; + + if (!should_have_cursor_renderer (device)) + continue; + + cursor_renderer = meta_backend_get_cursor_renderer_for_device (backend, + device); + if (cursor_renderer) + meta_cursor_renderer_force_update (cursor_renderer); + } + + g_list_free (devices); +} + void meta_backend_monitors_changed (MetaBackend *backend) { @@ -290,7 +336,7 @@ meta_backend_monitors_changed (MetaBackend *backend) } } - meta_cursor_renderer_force_update (priv->cursor_renderer); + update_cursors (backend); } void @@ -482,8 +528,6 @@ meta_backend_real_post_init (MetaBackend *backend) meta_backend_sync_screen_size (backend); - priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend); - priv->device_monitors = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref); @@ -1045,8 +1089,26 @@ MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend) { MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + ClutterInputDevice *pointer; + ClutterSeat *seat; + + seat = clutter_backend_get_default_seat (priv->clutter_backend); + pointer = clutter_seat_get_pointer (seat); + + return meta_backend_get_cursor_renderer_for_device (backend, pointer); +} + +MetaCursorRenderer * +meta_backend_get_cursor_renderer_for_device (MetaBackend *backend, + ClutterInputDevice *device) +{ + g_return_val_if_fail (META_IS_BACKEND (backend), NULL); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); + g_return_val_if_fail (clutter_input_device_get_device_type (device) != + CLUTTER_KEYBOARD_DEVICE, NULL); - return priv->cursor_renderer; + return META_BACKEND_GET_CLASS (backend)->get_cursor_renderer (backend, + device); } /** diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index bca79f82392..5eeb14463d3 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -49,7 +49,6 @@ #include "backends/meta-settings-private.h" #include "backends/meta-stage-private.h" #include "backends/native/meta-clutter-backend-native.h" -#include "backends/native/meta-cursor-renderer-native.h" #include "backends/native/meta-event-native.h" #include "backends/native/meta-input-settings-native.h" #include "backends/native/meta-kms.h" @@ -186,9 +185,14 @@ meta_backend_native_create_monitor_manager (MetaBackend *backend, } static MetaCursorRenderer * -meta_backend_native_create_cursor_renderer (MetaBackend *backend) +meta_backend_native_get_cursor_renderer (MetaBackend *backend, + ClutterInputDevice *device) { - return META_CURSOR_RENDERER (meta_cursor_renderer_native_new (backend)); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + MetaSeatNative *seat_native = + META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend)); + + return meta_seat_native_maybe_ensure_cursor_renderer (seat_native, device); } static MetaRenderer * @@ -532,7 +536,7 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass) backend_class->post_init = meta_backend_native_post_init; backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager; - backend_class->create_cursor_renderer = meta_backend_native_create_cursor_renderer; + backend_class->get_cursor_renderer = meta_backend_native_get_cursor_renderer; backend_class->create_renderer = meta_backend_native_create_renderer; backend_class->create_input_settings = meta_backend_native_create_input_settings; diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index b27e19672e9..9b31be6f7b3 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -2630,6 +2630,7 @@ meta_seat_native_finalize (GObject *object) g_hash_table_destroy (seat->reserved_virtual_slots); + g_object_unref (seat->cursor_renderer); g_object_unref (seat->udev_client); meta_event_source_free (seat->event_source); @@ -3288,3 +3289,25 @@ meta_seat_native_set_pointer_constraint (MetaSeatNative *seat, seat->core_pointer); } } + +MetaCursorRenderer * +meta_seat_native_maybe_ensure_cursor_renderer (MetaSeatNative *seat_native, + ClutterInputDevice *device) +{ + if (device == seat_native->core_pointer) + { + if (!seat_native->cursor_renderer) + { + MetaCursorRendererNative *cursor_renderer_native; + + cursor_renderer_native = + meta_cursor_renderer_native_new (meta_get_backend ()); + seat_native->cursor_renderer = + META_CURSOR_RENDERER (cursor_renderer_native); + } + + return seat_native->cursor_renderer; + } + + return NULL; +} diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h index 2a1faaee006..9f7f2d3a1e0 100644 --- a/src/backends/native/meta-seat-native.h +++ b/src/backends/native/meta-seat-native.h @@ -28,6 +28,7 @@ #include #include "backends/native/meta-barrier-native.h" +#include "backends/native/meta-cursor-renderer-native.h" #include "backends/native/meta-keymap-native.h" #include "backends/native/meta-pointer-constraint-native.h" #include "backends/native/meta-xkb-utils.h" @@ -63,6 +64,7 @@ struct _MetaSeatNative GHashTable *touch_states; guint virtual_touch_slot_base; GHashTable *reserved_virtual_slots; + GHashTable *cursor_renderers; struct xkb_state *xkb; xkb_led_index_t caps_lock_led; @@ -84,6 +86,7 @@ struct _MetaSeatNative MetaPointerConstraintImpl *pointer_constraint; MetaKeymapNative *keymap; + MetaCursorRenderer *cursor_renderer; GUdevClient *udev_client; guint tablet_mode_switch_state : 1; @@ -257,5 +260,7 @@ MetaBarrierManagerNative * meta_seat_native_get_barrier_manager (MetaSeatNative void meta_seat_native_set_pointer_constraint (MetaSeatNative *seat, MetaPointerConstraintImpl *constraint_impl); +MetaCursorRenderer * meta_seat_native_maybe_ensure_cursor_renderer (MetaSeatNative *seat, + ClutterInputDevice *device); #endif /* META_SEAT_NATIVE_H */ diff --git a/src/backends/x11/cm/meta-backend-x11-cm.c b/src/backends/x11/cm/meta-backend-x11-cm.c index 28726f7d7da..b00f1ca0642 100644 --- a/src/backends/x11/cm/meta-backend-x11-cm.c +++ b/src/backends/x11/cm/meta-backend-x11-cm.c @@ -41,6 +41,7 @@ struct _MetaBackendX11Cm { MetaBackendX11 parent; + MetaCursorRenderer *cursor_renderer; char *keymap_layouts; char *keymap_variants; char *keymap_options; @@ -116,11 +117,20 @@ meta_backend_x11_cm_create_monitor_manager (MetaBackend *backend, } static MetaCursorRenderer * -meta_backend_x11_cm_create_cursor_renderer (MetaBackend *backend) +meta_backend_x11_cm_get_cursor_renderer (MetaBackend *backend, + ClutterInputDevice *device) { - return g_object_new (META_TYPE_CURSOR_RENDERER_X11, - "backend", backend, - NULL); + MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (backend); + + if (!x11_cm->cursor_renderer) + { + x11_cm->cursor_renderer = + g_object_new (META_TYPE_CURSOR_RENDERER_X11, + "backend", backend, + NULL); + } + + return x11_cm->cursor_renderer; } static MetaCursorTracker * @@ -444,7 +454,7 @@ meta_backend_x11_cm_class_init (MetaBackendX11CmClass *klass) backend_class->post_init = meta_backend_x11_cm_post_init; backend_class->create_renderer = meta_backend_x11_cm_create_renderer; backend_class->create_monitor_manager = meta_backend_x11_cm_create_monitor_manager; - backend_class->create_cursor_renderer = meta_backend_x11_cm_create_cursor_renderer; + backend_class->get_cursor_renderer = meta_backend_x11_cm_get_cursor_renderer; backend_class->create_cursor_tracker = meta_backend_x11_cm_create_cursor_tracker; backend_class->create_input_settings = meta_backend_x11_cm_create_input_settings; backend_class->update_screen_size = meta_backend_x11_cm_update_screen_size; diff --git a/src/backends/x11/nested/meta-backend-x11-nested.c b/src/backends/x11/nested/meta-backend-x11-nested.c index 009a809787c..27143ce1412 100644 --- a/src/backends/x11/nested/meta-backend-x11-nested.c +++ b/src/backends/x11/nested/meta-backend-x11-nested.c @@ -31,6 +31,7 @@ typedef struct _MetaBackendX11NestedPrivate { MetaGpu *gpu; + MetaCursorRenderer *cursor_renderer; } MetaBackendX11NestedPrivate; static GInitableIface *initable_parent_iface; @@ -63,11 +64,22 @@ meta_backend_x11_nested_create_monitor_manager (MetaBackend *backend, } static MetaCursorRenderer * -meta_backend_x11_nested_create_cursor_renderer (MetaBackend *backend) +meta_backend_x11_nested_get_cursor_renderer (MetaBackend *backend, + ClutterInputDevice *device) { - return g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, - "backend", backend, - NULL); + MetaBackendX11Nested *backend_x11_nested = META_BACKEND_X11_NESTED (backend); + MetaBackendX11NestedPrivate *priv = + meta_backend_x11_nested_get_instance_private (backend_x11_nested); + + if (!priv->cursor_renderer) + { + priv->cursor_renderer = + g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, + "backend", backend, + NULL); + } + + return priv->cursor_renderer; } static MetaInputSettings * @@ -275,7 +287,7 @@ meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass) backend_class->post_init = meta_backend_x11_nested_post_init; backend_class->create_renderer = meta_backend_x11_nested_create_renderer; backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager; - backend_class->create_cursor_renderer = meta_backend_x11_nested_create_cursor_renderer; + backend_class->get_cursor_renderer = meta_backend_x11_nested_get_cursor_renderer; backend_class->create_input_settings = meta_backend_x11_nested_create_input_settings; backend_class->update_screen_size = meta_backend_x11_nested_update_screen_size; backend_class->select_stage_events = meta_backend_x11_nested_select_stage_events; -- GitLab From 0d83fcc870a3718d199756ff9f6ae436c9c27b8a Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 10 Jul 2020 23:31:26 +0200 Subject: [PATCH 17/85] wayland: Look up cursor renderer for device on MetaWaylandPointer Make it explicitly look up the pointer device, instead of implicitly relying on it. Part-of: --- src/wayland/meta-wayland-pointer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index eb46ecc1d23..c71a5eee18f 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -1168,8 +1168,13 @@ pointer_set_cursor (struct wl_client *client, if (surface) { + ClutterBackend *clutter_backend = clutter_get_default_backend (); + ClutterSeat *clutter_seat = + clutter_backend_get_default_seat (clutter_backend); + ClutterInputDevice *device = clutter_seat_get_pointer (clutter_seat); MetaCursorRenderer *cursor_renderer = - meta_backend_get_cursor_renderer (meta_get_backend ()); + meta_backend_get_cursor_renderer_for_device (meta_get_backend (), + device); MetaWaylandCursorSurface *cursor_surface; cursor_surface = META_WAYLAND_CURSOR_SURFACE (surface->role); -- GitLab From cd02286b87d86cfb43c9d8ad0bc25f476362e9f5 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 11 Jul 2020 13:47:51 +0200 Subject: [PATCH 18/85] backends/native: Manage tablet cursors in backend Instead of letting the wayland bits maintain an always-software cursor renderer, let the cursor renderer be managed by the backend, and only hook to it (as we do for pointer cursor) in the wayland bits. ATM, make the cursor renderer still always-software, although ideally we should allow moving the HW cursor management between renderers. Part-of: --- src/backends/native/meta-seat-native.c | 41 ++++++++++++++++++++++++-- src/backends/native/meta-seat-native.h | 1 + src/wayland/meta-wayland-tablet-tool.c | 9 +++++- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 9b31be6f7b3..586ac50bd6f 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -1850,6 +1850,32 @@ process_tablet_axis (MetaSeatNative *seat, } } +static void +update_tablet_cursor_state (MetaSeatNative *seat_native, + ClutterInputDevice *device, + gboolean in) +{ + if (in) + { + MetaCursorRenderer *cursor_renderer; + + if (!seat_native->tablet_cursors) + { + seat_native->tablet_cursors = g_hash_table_new_full (NULL, NULL, NULL, + g_object_unref); + } + + cursor_renderer = meta_cursor_renderer_new (meta_get_backend ()); + g_hash_table_insert (seat_native->tablet_cursors, + device, cursor_renderer); + } + else + { + if (seat_native->tablet_cursors) + g_hash_table_remove (seat_native->tablet_cursors, device); + } +} + static gboolean process_device_event (MetaSeatNative *seat, struct libinput_event *event) @@ -2257,18 +2283,22 @@ process_device_event (MetaSeatNative *seat, libinput_event_get_tablet_tool_event (event); struct libinput_tablet_tool *libinput_tool = NULL; enum libinput_tablet_tool_proximity_state state; + gboolean in; state = libinput_event_tablet_tool_get_proximity_state (tablet_event); time = libinput_event_tablet_tool_get_time_usec (tablet_event); device = libinput_device_get_user_data (libinput_device); + in = state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN; libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event); - if (state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN) + if (in) input_device_update_tool (device, libinput_tool); - notify_proximity (device, time, state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN); - if (state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT) + notify_proximity (device, time, in); + if (!in) input_device_update_tool (device, NULL); + + update_tablet_cursor_state (seat, device, in); break; } case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: @@ -2630,6 +2660,7 @@ meta_seat_native_finalize (GObject *object) g_hash_table_destroy (seat->reserved_virtual_slots); + g_clear_pointer (&seat->tablet_cursors, g_hash_table_unref); g_object_unref (seat->cursor_renderer); g_object_unref (seat->udev_client); @@ -3309,5 +3340,9 @@ meta_seat_native_maybe_ensure_cursor_renderer (MetaSeatNative *seat_native, return seat_native->cursor_renderer; } + if (seat_native->tablet_cursors && + clutter_input_device_get_device_type (device) == CLUTTER_TABLET_DEVICE) + return g_hash_table_lookup (seat_native->tablet_cursors, device); + return NULL; } diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h index 9f7f2d3a1e0..5fa0964b059 100644 --- a/src/backends/native/meta-seat-native.h +++ b/src/backends/native/meta-seat-native.h @@ -87,6 +87,7 @@ struct _MetaSeatNative MetaKeymapNative *keymap; MetaCursorRenderer *cursor_renderer; + GHashTable *tablet_cursors; GUdevClient *udev_client; guint tablet_mode_switch_state : 1; diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c index c913d0a55db..589e92ddd49 100644 --- a/src/wayland/meta-wayland-tablet-tool.c +++ b/src/wayland/meta-wayland-tablet-tool.c @@ -913,7 +913,14 @@ meta_wayland_tablet_tool_update (MetaWaylandTabletTool *tool, break; case CLUTTER_PROXIMITY_IN: if (!tool->cursor_renderer) - tool->cursor_renderer = meta_cursor_renderer_new (meta_get_backend ()); + { + MetaCursorRenderer *renderer; + + renderer = + meta_backend_get_cursor_renderer_for_device (meta_get_backend (), + clutter_event_get_source_device (event)); + g_set_object (&tool->cursor_renderer, renderer); + } tool->current_tablet = meta_wayland_tablet_seat_lookup_tablet (tool->seat, clutter_event_get_source_device (event)); -- GitLab From de0848b28b6ee210c2db0b38318bb06cef6fd8c1 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 13 Jul 2020 12:06:12 +0200 Subject: [PATCH 19/85] backends: Use graphene_point_t on meta_cursor_tracker_get_pointer() It's nicer to propagate along. Part-of: --- src/wayland/meta-wayland-dnd-surface.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/wayland/meta-wayland-dnd-surface.c b/src/wayland/meta-wayland-dnd-surface.c index eb0dc85df0a..bdd80f53a28 100644 --- a/src/wayland/meta-wayland-dnd-surface.c +++ b/src/wayland/meta-wayland-dnd-surface.c @@ -78,10 +78,11 @@ dnd_surface_find_logical_monitor (MetaWaylandActorSurface *actor_surface) meta_backend_get_cursor_tracker (backend); MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); - int x, y; + graphene_point_t point; - meta_cursor_tracker_get_pointer (cursor_tracker, &x, &y, NULL); - return meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y); + meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL); + return meta_monitor_manager_get_logical_monitor_at (monitor_manager, + point.x, point.y); } static double -- GitLab From 247613d26d0afc61e62524f4fd76fbe2dec5b7d4 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 13 Jul 2020 12:28:46 +0200 Subject: [PATCH 20/85] backends: Move away from meta_cursor_renderer_get_position() We are moving onto relying fully on the seat cursor position. As this focuses (thus far?) on mouse pointers only, use the cursor tracker as a convenient shortcut. Part-of: --- src/backends/meta-screen-cast-area-stream-src.c | 6 ++++-- src/backends/meta-screen-cast-monitor-stream-src.c | 6 ++++-- src/backends/meta-screen-cast-window-stream-src.c | 10 +++++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/backends/meta-screen-cast-area-stream-src.c b/src/backends/meta-screen-cast-area-stream-src.c index d83df6dd933..b69c26ac44d 100644 --- a/src/backends/meta-screen-cast-area-stream-src.c +++ b/src/backends/meta-screen-cast-area-stream-src.c @@ -142,9 +142,11 @@ is_cursor_in_stream (MetaScreenCastAreaStreamSrc *area_src) } else { + MetaCursorTracker *cursor_tracker = + meta_backend_get_cursor_tracker (backend); graphene_point_t cursor_position; - cursor_position = meta_cursor_renderer_get_position (cursor_renderer); + meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL); return graphene_rect_contains_point (&area_rect, &cursor_position); } } @@ -524,7 +526,7 @@ meta_screen_cast_area_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *s area = meta_screen_cast_area_stream_get_area (area_stream); scale = meta_screen_cast_area_stream_get_scale (area_stream); - cursor_position = meta_cursor_renderer_get_position (cursor_renderer); + meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL); cursor_position.x -= area->x; cursor_position.y -= area->y; cursor_position.x *= scale; diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c index 3f7584dd8a3..8675ae3424c 100644 --- a/src/backends/meta-screen-cast-monitor-stream-src.c +++ b/src/backends/meta-screen-cast-monitor-stream-src.c @@ -189,9 +189,11 @@ is_cursor_in_stream (MetaScreenCastMonitorStreamSrc *monitor_src) } else { + MetaCursorTracker *cursor_tracker = + meta_backend_get_cursor_tracker (backend); graphene_point_t cursor_position; - cursor_position = meta_cursor_renderer_get_position (cursor_renderer); + meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL); return graphene_rect_contains_point (&logical_monitor_rect, &cursor_position); } @@ -665,7 +667,7 @@ meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc else view_scale = 1.0; - cursor_position = meta_cursor_renderer_get_position (cursor_renderer); + meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL); cursor_position.x -= logical_monitor_rect.origin.x; cursor_position.y -= logical_monitor_rect.origin.y; cursor_position.x *= view_scale; diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c index ec9f873c94c..e881d80f45c 100644 --- a/src/backends/meta-screen-cast-window-stream-src.c +++ b/src/backends/meta-screen-cast-window-stream-src.c @@ -110,6 +110,8 @@ maybe_draw_cursor_sprite (MetaScreenCastWindowStreamSrc *window_src, MetaBackend *backend = get_backend (window_src); MetaCursorRenderer *cursor_renderer = meta_backend_get_cursor_renderer (backend); + MetaCursorTracker *cursor_tracker = + meta_backend_get_cursor_tracker (backend); MetaCursorSprite *cursor_sprite; CoglTexture *cursor_texture; MetaScreenCastWindow *screen_cast_window; @@ -133,7 +135,7 @@ maybe_draw_cursor_sprite (MetaScreenCastWindowStreamSrc *window_src, return; screen_cast_window = window_src->screen_cast_window; - cursor_position = meta_cursor_renderer_get_position (cursor_renderer); + meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL); if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window, cursor_sprite, &cursor_position, @@ -189,6 +191,8 @@ maybe_blit_cursor_sprite (MetaScreenCastWindowStreamSrc *window_src, clutter_backend_get_cogl_context (clutter_get_default_backend ()); MetaCursorRenderer *cursor_renderer = meta_backend_get_cursor_renderer (backend); + MetaCursorTracker *cursor_tracker = + meta_backend_get_cursor_tracker (backend); MetaScreenCastWindow *screen_cast_window; MetaCursorSprite *cursor_sprite; graphene_point_t relative_cursor_position; @@ -209,7 +213,7 @@ maybe_blit_cursor_sprite (MetaScreenCastWindowStreamSrc *window_src, return; screen_cast_window = window_src->screen_cast_window; - cursor_position = meta_cursor_renderer_get_position (cursor_renderer); + meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL); if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window, cursor_sprite, &cursor_position, @@ -524,7 +528,7 @@ meta_screen_cast_window_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc int x, y; cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer); - cursor_position = meta_cursor_renderer_get_position (cursor_renderer); + meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL); if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) || !meta_screen_cast_window_transform_cursor_position (screen_cast_window, -- GitLab From 3ade57e4e990542f6f174808920638f53de0d5c4 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 13 Jul 2020 13:32:48 +0200 Subject: [PATCH 21/85] backends: Add ::device property to MetaCursorRenderer A cursor renderer is made to invariably follow a pointer device, make it a construct-time property, and update all creators of cursor renderers to specify it. Part-of: --- src/backends/meta-cursor-renderer.c | 29 ++++++++++++++++++- src/backends/meta-cursor-renderer.h | 4 ++- .../native/meta-cursor-renderer-native.c | 4 ++- .../native/meta-cursor-renderer-native.h | 3 +- src/backends/native/meta-seat-native.c | 5 ++-- src/backends/x11/cm/meta-backend-x11-cm.c | 1 + .../x11/nested/meta-backend-x11-nested.c | 1 + 7 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c index 53b1a10a2af..095cdbe6d25 100644 --- a/src/backends/meta-cursor-renderer.c +++ b/src/backends/meta-cursor-renderer.c @@ -46,6 +46,7 @@ enum PROP_0, PROP_BACKEND, + PROP_DEVICE, N_PROPS }; @@ -59,6 +60,7 @@ struct _MetaCursorRendererPrivate float current_x; float current_y; + ClutterInputDevice *device; MetaCursorSprite *displayed_cursor; MetaCursorSprite *overlay_cursor; @@ -205,6 +207,9 @@ meta_cursor_renderer_get_property (GObject *object, case PROP_BACKEND: g_value_set_object (value, priv->backend); break; + case PROP_DEVICE: + g_value_set_object (value, priv->device); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -226,6 +231,9 @@ meta_cursor_renderer_set_property (GObject *object, case PROP_BACKEND: priv->backend = g_value_get_object (value); break; + case PROP_DEVICE: + priv->device = g_value_get_object (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -286,6 +294,14 @@ meta_cursor_renderer_class_init (MetaCursorRendererClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_props[PROP_DEVICE] = + g_param_spec_object ("device", + "device", + "Input device", + CLUTTER_TYPE_INPUT_DEVICE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, N_PROPS, obj_props); signals[CURSOR_PAINTED] = g_signal_new ("cursor-painted", @@ -396,10 +412,12 @@ meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer, } MetaCursorRenderer * -meta_cursor_renderer_new (MetaBackend *backend) +meta_cursor_renderer_new (MetaBackend *backend, + ClutterInputDevice *device) { return g_object_new (META_TYPE_CURSOR_RENDERER, "backend", backend, + "device", device, NULL); } @@ -511,3 +529,12 @@ meta_cursor_renderer_is_hw_cursors_inhibited (MetaCursorRenderer *renderer, return FALSE; } + +ClutterInputDevice * +meta_cursor_renderer_get_input_device (MetaCursorRenderer *renderer) +{ + MetaCursorRendererPrivate *priv = + meta_cursor_renderer_get_instance_private (renderer); + + return priv->device; +} diff --git a/src/backends/meta-cursor-renderer.h b/src/backends/meta-cursor-renderer.h index 7d89af48744..38621027cbc 100644 --- a/src/backends/meta-cursor-renderer.h +++ b/src/backends/meta-cursor-renderer.h @@ -54,7 +54,8 @@ struct _MetaCursorRendererClass MetaCursorSprite *cursor_sprite); }; -MetaCursorRenderer * meta_cursor_renderer_new (MetaBackend *backend); +MetaCursorRenderer * meta_cursor_renderer_new (MetaBackend *backend, + ClutterInputDevice *device); void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer, MetaCursorSprite *cursor_sprite); @@ -83,6 +84,7 @@ graphene_rect_t meta_cursor_renderer_calculate_rect (MetaCursorRenderer *rendere void meta_cursor_renderer_emit_painted (MetaCursorRenderer *renderer, MetaCursorSprite *cursor_sprite); +ClutterInputDevice * meta_cursor_renderer_get_input_device (MetaCursorRenderer *renderer); void meta_cursor_renderer_update_stage_overlay (MetaCursorRenderer *renderer, MetaCursorSprite *cursor_sprite); diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index 3c6688df426..e4b7c07c64a 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -1724,7 +1724,8 @@ init_hw_cursor_support (MetaCursorRendererNative *cursor_renderer_native) } MetaCursorRendererNative * -meta_cursor_renderer_native_new (MetaBackend *backend) +meta_cursor_renderer_native_new (MetaBackend *backend, + ClutterInputDevice *device) { MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); @@ -1733,6 +1734,7 @@ meta_cursor_renderer_native_new (MetaBackend *backend) cursor_renderer_native = g_object_new (META_TYPE_CURSOR_RENDERER_NATIVE, "backend", backend, + "device", device, NULL); priv = meta_cursor_renderer_native_get_instance_private (cursor_renderer_native); diff --git a/src/backends/native/meta-cursor-renderer-native.h b/src/backends/native/meta-cursor-renderer-native.h index d3560e48f67..26c698cda53 100644 --- a/src/backends/native/meta-cursor-renderer-native.h +++ b/src/backends/native/meta-cursor-renderer-native.h @@ -33,6 +33,7 @@ G_DECLARE_FINAL_TYPE (MetaCursorRendererNative, meta_cursor_renderer_native, META, CURSOR_RENDERER_NATIVE, MetaCursorRenderer) -MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend); +MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend, + ClutterInputDevice *device); #endif /* META_CURSOR_RENDERER_NATIVE_H */ diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 586ac50bd6f..fcf0ad96e51 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -1865,7 +1865,7 @@ update_tablet_cursor_state (MetaSeatNative *seat_native, g_object_unref); } - cursor_renderer = meta_cursor_renderer_new (meta_get_backend ()); + cursor_renderer = meta_cursor_renderer_new (meta_get_backend (), device); g_hash_table_insert (seat_native->tablet_cursors, device, cursor_renderer); } @@ -3332,7 +3332,8 @@ meta_seat_native_maybe_ensure_cursor_renderer (MetaSeatNative *seat_native, MetaCursorRendererNative *cursor_renderer_native; cursor_renderer_native = - meta_cursor_renderer_native_new (meta_get_backend ()); + meta_cursor_renderer_native_new (meta_get_backend (), + seat_native->core_pointer); seat_native->cursor_renderer = META_CURSOR_RENDERER (cursor_renderer_native); } diff --git a/src/backends/x11/cm/meta-backend-x11-cm.c b/src/backends/x11/cm/meta-backend-x11-cm.c index b00f1ca0642..35e1acf9f05 100644 --- a/src/backends/x11/cm/meta-backend-x11-cm.c +++ b/src/backends/x11/cm/meta-backend-x11-cm.c @@ -127,6 +127,7 @@ meta_backend_x11_cm_get_cursor_renderer (MetaBackend *backend, x11_cm->cursor_renderer = g_object_new (META_TYPE_CURSOR_RENDERER_X11, "backend", backend, + "device", device, NULL); } diff --git a/src/backends/x11/nested/meta-backend-x11-nested.c b/src/backends/x11/nested/meta-backend-x11-nested.c index 27143ce1412..041f4b87afa 100644 --- a/src/backends/x11/nested/meta-backend-x11-nested.c +++ b/src/backends/x11/nested/meta-backend-x11-nested.c @@ -76,6 +76,7 @@ meta_backend_x11_nested_get_cursor_renderer (MetaBackend *backend, priv->cursor_renderer = g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, "backend", backend, + "device", device, NULL); } -- GitLab From c93bea9f597838fb698d03fbcac94f11e8ed0eac Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 13 Jul 2020 13:34:59 +0200 Subject: [PATCH 22/85] wayland: Move away from meta_cursor_renderer_get_position() Fetch the cursor renderer device, and query its position instead. Part-of: --- src/wayland/meta-wayland-cursor-surface.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-cursor-surface.c b/src/wayland/meta-wayland-cursor-surface.c index af1bc170dbd..7281be8541d 100644 --- a/src/wayland/meta-wayland-cursor-surface.c +++ b/src/wayland/meta-wayland-cursor-surface.c @@ -187,6 +187,7 @@ meta_wayland_cursor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *role, META_WAYLAND_CURSOR_SURFACE (surface->role); MetaWaylandCursorSurfacePrivate *priv = meta_wayland_cursor_surface_get_instance_private (cursor_surface); + ClutterInputDevice *device; graphene_point_t point; graphene_rect_t logical_monitor_rect; @@ -196,7 +197,8 @@ meta_wayland_cursor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *role, logical_monitor_rect = meta_rectangle_to_graphene_rect (&logical_monitor->rect); - point = meta_cursor_renderer_get_position (priv->cursor_renderer); + device = meta_cursor_renderer_get_input_device (priv->cursor_renderer); + clutter_input_device_get_coords (device, NULL, &point); return graphene_rect_contains_point (&logical_monitor_rect, &point); } -- GitLab From a8e293522517fad1b1b9ef0139fe120f6675b8f3 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 13 Jul 2020 13:56:56 +0200 Subject: [PATCH 23/85] backends: Drop meta_cursor_renderer_get_position() This is now unused. Part-of: --- src/backends/meta-cursor-renderer.c | 12 ------------ src/backends/meta-cursor-renderer.h | 1 - 2 files changed, 13 deletions(-) diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c index 095cdbe6d25..ba27eb848ea 100644 --- a/src/backends/meta-cursor-renderer.c +++ b/src/backends/meta-cursor-renderer.c @@ -456,18 +456,6 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer, meta_cursor_renderer_update_cursor (renderer, priv->displayed_cursor); } -graphene_point_t -meta_cursor_renderer_get_position (MetaCursorRenderer *renderer) -{ - MetaCursorRendererPrivate *priv = - meta_cursor_renderer_get_instance_private (renderer); - - return (graphene_point_t) { - .x = priv->current_x, - .y = priv->current_y - }; -} - MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer) { diff --git a/src/backends/meta-cursor-renderer.h b/src/backends/meta-cursor-renderer.h index 38621027cbc..2156d91253f 100644 --- a/src/backends/meta-cursor-renderer.h +++ b/src/backends/meta-cursor-renderer.h @@ -63,7 +63,6 @@ void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer, void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer, float x, float y); -graphene_point_t meta_cursor_renderer_get_position (MetaCursorRenderer *renderer); void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer); MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer); -- GitLab From 00cbcb7ba1d40f415711890fa0cb1dce5f752581 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 13 Jul 2020 14:09:44 +0200 Subject: [PATCH 24/85] core: Centralize cursor renderer and tracker updates These use now more of a "pull" model, where they receive update notifications and the relevant input position is queried, instead of the coordinates being passed along. This allows to treat cursor renderers all the same independently of the device they track. This notifying of position changes should ideally be more backend-y than core-y, a better location will be figured out in future commits. Part-of: --- src/backends/meta-cursor-renderer.c | 10 ++-- src/backends/meta-cursor-renderer.h | 4 +- src/backends/meta-cursor-tracker-private.h | 4 +- src/backends/meta-cursor-tracker.c | 48 ++++--------------- .../meta-screen-cast-area-stream-src.c | 14 +++--- .../meta-screen-cast-monitor-stream-src.c | 14 +++--- .../meta-screen-cast-window-stream-src.c | 14 +++--- src/backends/native/meta-seat-native.c | 5 +- src/backends/x11/meta-cursor-tracker-x11.c | 4 +- src/core/events.c | 19 ++++---- src/wayland/meta-wayland-tablet-manager.c | 27 ----------- src/wayland/meta-wayland-tablet-manager.h | 3 -- src/wayland/meta-wayland-tablet-tool.c | 9 ---- src/wayland/meta-wayland-tablet-tool.h | 4 -- 14 files changed, 51 insertions(+), 128 deletions(-) diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c index ba27eb848ea..b80081774af 100644 --- a/src/backends/meta-cursor-renderer.c +++ b/src/backends/meta-cursor-renderer.c @@ -444,14 +444,14 @@ meta_cursor_renderer_force_update (MetaCursorRenderer *renderer) } void -meta_cursor_renderer_set_position (MetaCursorRenderer *renderer, - float x, - float y) +meta_cursor_renderer_update_position (MetaCursorRenderer *renderer) { MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); + graphene_point_t pos; - priv->current_x = x; - priv->current_y = y; + clutter_input_device_get_coords (priv->device, NULL, &pos); + priv->current_x = pos.x; + priv->current_y = pos.y; meta_cursor_renderer_update_cursor (renderer, priv->displayed_cursor); } diff --git a/src/backends/meta-cursor-renderer.h b/src/backends/meta-cursor-renderer.h index 2156d91253f..37ddb9100d8 100644 --- a/src/backends/meta-cursor-renderer.h +++ b/src/backends/meta-cursor-renderer.h @@ -60,9 +60,7 @@ MetaCursorRenderer * meta_cursor_renderer_new (MetaBackend *backend, void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer, MetaCursorSprite *cursor_sprite); -void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer, - float x, - float y); +void meta_cursor_renderer_update_position (MetaCursorRenderer *renderer); void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer); MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer); diff --git a/src/backends/meta-cursor-tracker-private.h b/src/backends/meta-cursor-tracker-private.h index 779c2fe521a..6d3c88c3559 100644 --- a/src/backends/meta-cursor-tracker-private.h +++ b/src/backends/meta-cursor-tracker-private.h @@ -41,9 +41,7 @@ void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker); void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, MetaCursorSprite *cursor_sprite); -void meta_cursor_tracker_update_position (MetaCursorTracker *tracker, - float new_x, - float new_y); +void meta_cursor_tracker_invalidate_position (MetaCursorTracker *tracker); void meta_cursor_tracker_track_position (MetaCursorTracker *tracker); diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c index 3c6f6a0c432..6b3d2289ad6 100644 --- a/src/backends/meta-cursor-tracker.c +++ b/src/backends/meta-cursor-tracker.c @@ -82,7 +82,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorTracker, meta_cursor_tracker, enum { CURSOR_CHANGED, - CURSOR_MOVED, + POSITION_INVALIDATED, VISIBILITY_CHANGED, LAST_SIGNAL }; @@ -288,20 +288,12 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 0); - /** - * MetaCursorTracker::cursor-moved: - * @cursor: The #MetaCursorTracker - * @x: The new X coordinate of the cursor - * @y: The new Y coordinate of the cursor - * - * Notifies when the cursor has moved to a new location. - */ - signals[CURSOR_MOVED] = g_signal_new ("cursor-moved", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); + signals[POSITION_INVALIDATED] = g_signal_new ("position-invalidated", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); signals[VISIBILITY_CHANGED] = g_signal_new ("visibility-changed", G_TYPE_FROM_CLASS (klass), @@ -428,31 +420,9 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, } void -meta_cursor_tracker_update_position (MetaCursorTracker *tracker, - float new_x, - float new_y) +meta_cursor_tracker_invalidate_position (MetaCursorTracker *tracker) { - MetaCursorTrackerPrivate *priv = - meta_cursor_tracker_get_instance_private (tracker); - MetaCursorRenderer *cursor_renderer = - meta_backend_get_cursor_renderer (priv->backend); - gboolean position_changed; - - if (priv->x != new_x || priv->y != new_y) - { - position_changed = TRUE; - priv->x = new_x; - priv->y = new_y; - } - else - { - position_changed = FALSE; - } - - meta_cursor_renderer_set_position (cursor_renderer, new_x, new_y); - - if (position_changed) - g_signal_emit (tracker, signals[CURSOR_MOVED], 0); + g_signal_emit (tracker, signals[POSITION_INVALIDATED], 0); } void diff --git a/src/backends/meta-screen-cast-area-stream-src.c b/src/backends/meta-screen-cast-area-stream-src.c index b69c26ac44d..6a64bcb669e 100644 --- a/src/backends/meta-screen-cast-area-stream-src.c +++ b/src/backends/meta-screen-cast-area-stream-src.c @@ -42,7 +42,7 @@ struct _MetaScreenCastAreaStreamSrc GList *watches; - gulong cursor_moved_handler_id; + gulong position_invalidated_handler_id; gulong cursor_changed_handler_id; guint maybe_record_idle_id; @@ -182,8 +182,8 @@ sync_cursor_state (MetaScreenCastAreaStreamSrc *area_src) } static void -cursor_moved (MetaCursorTracker *cursor_tracker, - MetaScreenCastAreaStreamSrc *area_src) +pointer_position_invalidated (MetaCursorTracker *cursor_tracker, + MetaScreenCastAreaStreamSrc *area_src) { sync_cursor_state (area_src); } @@ -332,9 +332,9 @@ meta_screen_cast_area_stream_src_enable (MetaScreenCastStreamSrc *src) switch (meta_screen_cast_stream_get_cursor_mode (stream)) { case META_SCREEN_CAST_CURSOR_MODE_METADATA: - area_src->cursor_moved_handler_id = - g_signal_connect_after (cursor_tracker, "cursor-moved", - G_CALLBACK (cursor_moved), + area_src->position_invalidated_handler_id = + g_signal_connect_after (cursor_tracker, "position-invalidated", + G_CALLBACK (pointer_position_invalidated), area_src); area_src->cursor_changed_handler_id = g_signal_connect_after (cursor_tracker, "cursor-changed", @@ -383,7 +383,7 @@ meta_screen_cast_area_stream_src_disable (MetaScreenCastStreamSrc *src) if (area_src->hw_cursor_inhibited) uninhibit_hw_cursor (area_src); - g_clear_signal_handler (&area_src->cursor_moved_handler_id, + g_clear_signal_handler (&area_src->position_invalidated_handler_id, cursor_tracker); g_clear_signal_handler (&area_src->cursor_changed_handler_id, cursor_tracker); diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c index 8675ae3424c..2155cc84d59 100644 --- a/src/backends/meta-screen-cast-monitor-stream-src.c +++ b/src/backends/meta-screen-cast-monitor-stream-src.c @@ -46,7 +46,7 @@ struct _MetaScreenCastMonitorStreamSrc GList *watches; - gulong cursor_moved_handler_id; + gulong position_invalidated_handler_id; gulong cursor_changed_handler_id; }; @@ -238,8 +238,8 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src) } static void -cursor_moved (MetaCursorTracker *cursor_tracker, - MetaScreenCastMonitorStreamSrc *monitor_src) +pointer_position_invalidated (MetaCursorTracker *cursor_tracker, + MetaScreenCastMonitorStreamSrc *monitor_src) { sync_cursor_state (monitor_src); } @@ -352,9 +352,9 @@ meta_screen_cast_monitor_stream_src_enable (MetaScreenCastStreamSrc *src) switch (meta_screen_cast_stream_get_cursor_mode (stream)) { case META_SCREEN_CAST_CURSOR_MODE_METADATA: - monitor_src->cursor_moved_handler_id = - g_signal_connect_after (cursor_tracker, "cursor-moved", - G_CALLBACK (cursor_moved), + monitor_src->position_invalidated_handler_id = + g_signal_connect_after (cursor_tracker, "position-invalidated", + G_CALLBACK (pointer_position_invalidated), monitor_src); monitor_src->cursor_changed_handler_id = g_signal_connect_after (cursor_tracker, "cursor-changed", @@ -408,7 +408,7 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src) if (monitor_src->hw_cursor_inhibited) uninhibit_hw_cursor (monitor_src); - g_clear_signal_handler (&monitor_src->cursor_moved_handler_id, + g_clear_signal_handler (&monitor_src->position_invalidated_handler_id, cursor_tracker); g_clear_signal_handler (&monitor_src->cursor_changed_handler_id, cursor_tracker); diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c index e881d80f45c..76f53d1600e 100644 --- a/src/backends/meta-screen-cast-window-stream-src.c +++ b/src/backends/meta-screen-cast-window-stream-src.c @@ -37,7 +37,7 @@ struct _MetaScreenCastWindowStreamSrc unsigned long screen_cast_window_damaged_handler_id; unsigned long screen_cast_window_destroyed_handler_id; - unsigned long cursor_moved_handler_id; + unsigned long position_invalidated_handler_id; unsigned long cursor_changed_handler_id; gboolean cursor_bitmap_invalid; @@ -323,7 +323,7 @@ meta_screen_cast_window_stream_src_stop (MetaScreenCastWindowStreamSrc *window_s window_src->screen_cast_window); g_clear_signal_handler (&window_src->screen_cast_window_destroyed_handler_id, window_src->screen_cast_window); - g_clear_signal_handler (&window_src->cursor_moved_handler_id, + g_clear_signal_handler (&window_src->position_invalidated_handler_id, cursor_tracker); g_clear_signal_handler (&window_src->cursor_changed_handler_id, cursor_tracker); @@ -372,8 +372,8 @@ sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src) } static void -cursor_moved (MetaCursorTracker *cursor_tracker, - MetaScreenCastWindowStreamSrc *window_src) +pointer_position_invalidated (MetaCursorTracker *cursor_tracker, + MetaScreenCastWindowStreamSrc *window_src) { sync_cursor_state (window_src); } @@ -420,9 +420,9 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src) { case META_SCREEN_CAST_CURSOR_MODE_METADATA: case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED: - window_src->cursor_moved_handler_id = - g_signal_connect_after (cursor_tracker, "cursor-moved", - G_CALLBACK (cursor_moved), + window_src->position_invalidated_handler_id = + g_signal_connect_after (cursor_tracker, "position-invalidated", + G_CALLBACK (pointer_position_invalidated), window_src); window_src->cursor_changed_handler_id = g_signal_connect_after (cursor_tracker, "cursor-changed", diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index fcf0ad96e51..45da429dcb3 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -2840,11 +2840,14 @@ meta_seat_native_warp_pointer (ClutterSeat *seat, { MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); MetaBackend *backend = meta_get_backend (); + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (backend); MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); notify_absolute_motion (seat_native->core_pointer, 0, x, y, NULL); - meta_cursor_tracker_update_position (cursor_tracker, x, y); + meta_cursor_renderer_update_position (cursor_renderer); + meta_cursor_tracker_invalidate_position (cursor_tracker); } static gboolean diff --git a/src/backends/x11/meta-cursor-tracker-x11.c b/src/backends/x11/meta-cursor-tracker-x11.c index 1e6c39e71de..7355f828ea0 100644 --- a/src/backends/x11/meta-cursor-tracker-x11.c +++ b/src/backends/x11/meta-cursor-tracker-x11.c @@ -69,10 +69,8 @@ static void update_position (MetaCursorTrackerX11 *tracker_x11) { MetaCursorTracker *tracker = META_CURSOR_TRACKER (tracker_x11); - graphene_point_t point; - meta_cursor_tracker_get_pointer (tracker, &point, NULL); - meta_cursor_tracker_update_position (tracker, point.x, point.y); + meta_cursor_tracker_invalidate_position (tracker); } static gboolean diff --git a/src/core/events.c b/src/core/events.c index 17dcaa0fe68..52828bdc930 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -288,22 +288,21 @@ meta_display_handle_event (MetaDisplay *display, #ifdef HAVE_WAYLAND if (meta_is_wayland_compositor () && event->type == CLUTTER_MOTION) { - MetaWaylandCompositor *compositor; + MetaCursorRenderer *cursor_renderer; + ClutterInputDevice *device; - compositor = meta_wayland_compositor_get_default (); + device = clutter_event_get_device (event); + cursor_renderer = meta_backend_get_cursor_renderer_for_device (backend, + device); + if (cursor_renderer) + meta_cursor_renderer_update_position (cursor_renderer); - if (meta_wayland_tablet_manager_consumes_event (compositor->tablet_manager, event)) - { - meta_wayland_tablet_manager_update_cursor_position (compositor->tablet_manager, event); - } - else + if (device == clutter_seat_get_pointer (clutter_input_device_get_seat (device))) { MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); - meta_cursor_tracker_update_position (cursor_tracker, - event->motion.x, - event->motion.y); + meta_cursor_tracker_invalidate_position (cursor_tracker); } } #endif diff --git a/src/wayland/meta-wayland-tablet-manager.c b/src/wayland/meta-wayland-tablet-manager.c index 38cec064e94..9c81d5afc2e 100644 --- a/src/wayland/meta-wayland-tablet-manager.c +++ b/src/wayland/meta-wayland-tablet-manager.c @@ -242,30 +242,3 @@ meta_wayland_tablet_manager_ensure_seat (MetaWaylandTabletManager *manager, return tablet_seat; } - -void -meta_wayland_tablet_manager_update_cursor_position (MetaWaylandTabletManager *manager, - const ClutterEvent *event) -{ - MetaWaylandTabletSeat *tablet_seat = NULL; - MetaWaylandTabletTool *tool = NULL; - ClutterInputDeviceTool *device_tool; - ClutterInputDevice *device; - - device = clutter_event_get_source_device (event); - device_tool = clutter_event_get_device_tool (event); - - if (device) - tablet_seat = meta_wayland_tablet_manager_lookup_seat (manager, device); - - if (tablet_seat && device_tool) - tool = meta_wayland_tablet_seat_lookup_tool (tablet_seat, device_tool); - - if (tool) - { - gfloat new_x, new_y; - - clutter_event_get_coords (event, &new_x, &new_y); - meta_wayland_tablet_tool_set_cursor_position (tool, new_x, new_y); - } -} diff --git a/src/wayland/meta-wayland-tablet-manager.h b/src/wayland/meta-wayland-tablet-manager.h index 5d4b28c2d61..83f9d3d0f41 100644 --- a/src/wayland/meta-wayland-tablet-manager.h +++ b/src/wayland/meta-wayland-tablet-manager.h @@ -50,7 +50,4 @@ MetaWaylandTabletSeat * meta_wayland_tablet_manager_ensure_seat (MetaWaylandTabletManager *manager, MetaWaylandSeat *seat); -void meta_wayland_tablet_manager_update_cursor_position (MetaWaylandTabletManager *manager, - const ClutterEvent *event); - #endif /* META_WAYLAND_TABLET_MANAGER_H */ diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c index 589e92ddd49..8ff2accb219 100644 --- a/src/wayland/meta-wayland-tablet-tool.c +++ b/src/wayland/meta-wayland-tablet-tool.c @@ -965,15 +965,6 @@ meta_wayland_tablet_tool_handle_event (MetaWaylandTabletTool *tool, return CLUTTER_EVENT_STOP; } -void -meta_wayland_tablet_tool_set_cursor_position (MetaWaylandTabletTool *tool, - float new_x, - float new_y) -{ - if (tool->cursor_renderer) - meta_cursor_renderer_set_position (tool->cursor_renderer, new_x, new_y); -} - static gboolean tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool, MetaWaylandSurface *surface) diff --git a/src/wayland/meta-wayland-tablet-tool.h b/src/wayland/meta-wayland-tablet-tool.h index 7cf1d907700..e9ad7db40c3 100644 --- a/src/wayland/meta-wayland-tablet-tool.h +++ b/src/wayland/meta-wayland-tablet-tool.h @@ -78,10 +78,6 @@ void meta_wayland_tablet_tool_update (MetaWaylandTabletTool *t gboolean meta_wayland_tablet_tool_handle_event (MetaWaylandTabletTool *tool, const ClutterEvent *event); -void meta_wayland_tablet_tool_set_cursor_position (MetaWaylandTabletTool *tool, - float new_x, - float new_y); - gboolean meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool, MetaWaylandSurface *surface, uint32_t serial); -- GitLab From e218b0074707cfc43c1dbc8a1b946a4426f1054d Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 13 Jul 2020 17:29:51 +0200 Subject: [PATCH 25/85] backends: Make MetaHwCursorInhibitor less about sprites Remove the sprite argument from the vfunc, it's used in no implementations and conceptually gets a bit in the middle. Part-of: --- src/backends/meta-cursor-renderer.c | 11 ++++------- src/backends/meta-cursor-renderer.h | 6 ++---- src/backends/meta-screen-cast-area-stream-src.c | 7 +++---- src/backends/meta-screen-cast-monitor-stream-src.c | 7 +++---- src/backends/native/meta-cursor-renderer-native.c | 3 +-- 5 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c index b80081774af..7d4228a35cd 100644 --- a/src/backends/meta-cursor-renderer.c +++ b/src/backends/meta-cursor-renderer.c @@ -82,13 +82,12 @@ static guint signals[LAST_SIGNAL]; G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT); static gboolean -meta_hw_cursor_inhibitor_is_cursor_sprite_inhibited (MetaHwCursorInhibitor *inhibitor, - MetaCursorSprite *cursor_sprite) +meta_hw_cursor_inhibitor_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor) { MetaHwCursorInhibitorInterface *iface = META_HW_CURSOR_INHIBITOR_GET_IFACE (inhibitor); - return iface->is_cursor_sprite_inhibited (inhibitor, cursor_sprite); + return iface->is_cursor_inhibited (inhibitor); } static void @@ -499,8 +498,7 @@ meta_cursor_renderer_remove_hw_cursor_inhibitor (MetaCursorRenderer *renderer } gboolean -meta_cursor_renderer_is_hw_cursors_inhibited (MetaCursorRenderer *renderer, - MetaCursorSprite *cursor_sprite) +meta_cursor_renderer_is_hw_cursors_inhibited (MetaCursorRenderer *renderer) { MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); @@ -510,8 +508,7 @@ meta_cursor_renderer_is_hw_cursors_inhibited (MetaCursorRenderer *renderer, { MetaHwCursorInhibitor *inhibitor = l->data; - if (meta_hw_cursor_inhibitor_is_cursor_sprite_inhibited (inhibitor, - cursor_sprite)) + if (meta_hw_cursor_inhibitor_is_cursor_inhibited (inhibitor)) return TRUE; } diff --git a/src/backends/meta-cursor-renderer.h b/src/backends/meta-cursor-renderer.h index 37ddb9100d8..b16d5cbe2e1 100644 --- a/src/backends/meta-cursor-renderer.h +++ b/src/backends/meta-cursor-renderer.h @@ -38,8 +38,7 @@ struct _MetaHwCursorInhibitorInterface { GTypeInterface parent_iface; - gboolean (* is_cursor_sprite_inhibited) (MetaHwCursorInhibitor *inhibitor, - MetaCursorSprite *cursor_sprite); + gboolean (* is_cursor_inhibited) (MetaHwCursorInhibitor *inhibitor); }; #define META_TYPE_CURSOR_RENDERER (meta_cursor_renderer_get_type ()) @@ -73,8 +72,7 @@ void meta_cursor_renderer_add_hw_cursor_inhibitor (MetaCursorRenderer *render void meta_cursor_renderer_remove_hw_cursor_inhibitor (MetaCursorRenderer *renderer, MetaHwCursorInhibitor *inhibitor); -gboolean meta_cursor_renderer_is_hw_cursors_inhibited (MetaCursorRenderer *renderer, - MetaCursorSprite *cursor_sprite); +gboolean meta_cursor_renderer_is_hw_cursors_inhibited (MetaCursorRenderer *renderer); graphene_rect_t meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer, MetaCursorSprite *cursor_sprite); diff --git a/src/backends/meta-screen-cast-area-stream-src.c b/src/backends/meta-screen-cast-area-stream-src.c index 6a64bcb669e..b837fcccb42 100644 --- a/src/backends/meta-screen-cast-area-stream-src.c +++ b/src/backends/meta-screen-cast-area-stream-src.c @@ -568,8 +568,7 @@ meta_screen_cast_area_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *s } static gboolean -meta_screen_cast_area_stream_src_is_cursor_sprite_inhibited (MetaHwCursorInhibitor *inhibitor, - MetaCursorSprite *cursor_sprite) +meta_screen_cast_area_stream_src_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor) { MetaScreenCastAreaStreamSrc *area_src = META_SCREEN_CAST_AREA_STREAM_SRC (inhibitor); @@ -580,8 +579,8 @@ meta_screen_cast_area_stream_src_is_cursor_sprite_inhibited (MetaHwCursorInhibit static void hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface) { - iface->is_cursor_sprite_inhibited = - meta_screen_cast_area_stream_src_is_cursor_sprite_inhibited; + iface->is_cursor_inhibited = + meta_screen_cast_area_stream_src_is_cursor_inhibited; } MetaScreenCastAreaStreamSrc * diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c index 2155cc84d59..a0d510067b9 100644 --- a/src/backends/meta-screen-cast-monitor-stream-src.c +++ b/src/backends/meta-screen-cast-monitor-stream-src.c @@ -709,8 +709,7 @@ meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc } static gboolean -meta_screen_cast_monitor_stream_src_is_cursor_sprite_inhibited (MetaHwCursorInhibitor *inhibitor, - MetaCursorSprite *cursor_sprite) +meta_screen_cast_monitor_stream_src_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor) { MetaScreenCastMonitorStreamSrc *monitor_src = META_SCREEN_CAST_MONITOR_STREAM_SRC (inhibitor); @@ -721,8 +720,8 @@ meta_screen_cast_monitor_stream_src_is_cursor_sprite_inhibited (MetaHwCursorInhi static void hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface) { - iface->is_cursor_sprite_inhibited = - meta_screen_cast_monitor_stream_src_is_cursor_sprite_inhibited; + iface->is_cursor_inhibited = + meta_screen_cast_monitor_stream_src_is_cursor_inhibited; } MetaScreenCastMonitorStreamSrc * diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index e4b7c07c64a..dca1d15cacb 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -880,8 +880,7 @@ should_have_hw_cursor (MetaCursorRenderer *renderer, if (!cursor_sprite) return FALSE; - if (meta_cursor_renderer_is_hw_cursors_inhibited (renderer, - cursor_sprite)) + if (meta_cursor_renderer_is_hw_cursors_inhibited (renderer)) return FALSE; for (l = gpus; l; l = l->next) -- GitLab From d6f720497ace9356ddf49089e8b4685a4784cce7 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 13 Jul 2020 17:45:41 +0200 Subject: [PATCH 26/85] backends: Move HW cursor inhibitors to MetaBackend We are aiming for a split of HW and SW cursor rendering management. Given the HW plane is a limited resource and the amount of cursor renderers may be >1 (due to tablets, even though we currently use an always-software cursor renderer there), it would ideally be able to switch between renderers. Being MetaCursorRenderer not really a singleton, having cursor inhibitor accounting here doesn't pan out. Make it MetaBackend API so all cursor renderers get the same picture. Part-of: --- src/backends/meta-backend-private.h | 8 ++++ src/backends/meta-backend.c | 39 +++++++++++++++++ src/backends/meta-cursor-renderer.c | 42 +------------------ src/backends/meta-cursor-renderer.h | 10 +---- .../meta-screen-cast-area-stream-src.c | 25 +++-------- .../meta-screen-cast-monitor-stream-src.c | 25 +++-------- .../native/meta-cursor-renderer-native.c | 6 ++- 7 files changed, 67 insertions(+), 88 deletions(-) diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index daee54c66d3..9a40430fbee 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -195,4 +195,12 @@ GList * meta_backend_get_gpus (MetaBackend *backend); WacomDeviceDatabase * meta_backend_get_wacom_database (MetaBackend *backend); #endif +void meta_backend_add_hw_cursor_inhibitor (MetaBackend *backend, + MetaHwCursorInhibitor *inhibitor); + +void meta_backend_remove_hw_cursor_inhibitor (MetaBackend *backend, + MetaHwCursorInhibitor *inhibitor); + +gboolean meta_backend_is_hw_cursors_inhibited (MetaBackend *backend); + #endif /* META_BACKEND_PRIVATE_H */ diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index c174b260e27..124ea74c09c 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -53,6 +53,7 @@ #include +#include "backends/meta-cursor-renderer.h" #include "backends/meta-cursor-tracker-private.h" #include "backends/meta-idle-monitor-private.h" #include "backends/meta-input-settings-private.h" @@ -149,6 +150,7 @@ struct _MetaBackendPrivate ClutterActor *stage; GList *gpus; + GList *hw_cursor_inhibitors; gboolean is_pointer_position_initialized; @@ -1514,3 +1516,40 @@ meta_backend_get_wacom_database (MetaBackend *backend) return priv->wacom_db; } #endif + +void +meta_backend_add_hw_cursor_inhibitor (MetaBackend *backend, + MetaHwCursorInhibitor *inhibitor) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + priv->hw_cursor_inhibitors = g_list_prepend (priv->hw_cursor_inhibitors, + inhibitor); +} + +void +meta_backend_remove_hw_cursor_inhibitor (MetaBackend *backend, + MetaHwCursorInhibitor *inhibitor) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + priv->hw_cursor_inhibitors = g_list_remove (priv->hw_cursor_inhibitors, + inhibitor); +} + +gboolean +meta_backend_is_hw_cursors_inhibited (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + GList *l; + + for (l = priv->hw_cursor_inhibitors; l; l = l->next) + { + MetaHwCursorInhibitor *inhibitor = l->data; + + if (meta_hw_cursor_inhibitor_is_cursor_inhibited (inhibitor)) + return TRUE; + } + + return FALSE; +} diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c index 7d4228a35cd..a0b09c77884 100644 --- a/src/backends/meta-cursor-renderer.c +++ b/src/backends/meta-cursor-renderer.c @@ -81,7 +81,7 @@ static guint signals[LAST_SIGNAL]; G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT); -static gboolean +gboolean meta_hw_cursor_inhibitor_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor) { MetaHwCursorInhibitorInterface *iface = @@ -475,46 +475,6 @@ meta_cursor_renderer_is_overlay_visible (MetaCursorRenderer *renderer) return meta_overlay_is_visible (priv->stage_overlay); } -void -meta_cursor_renderer_add_hw_cursor_inhibitor (MetaCursorRenderer *renderer, - MetaHwCursorInhibitor *inhibitor) -{ - MetaCursorRendererPrivate *priv = - meta_cursor_renderer_get_instance_private (renderer); - - priv->hw_cursor_inhibitors = g_list_prepend (priv->hw_cursor_inhibitors, - inhibitor); -} - -void -meta_cursor_renderer_remove_hw_cursor_inhibitor (MetaCursorRenderer *renderer, - MetaHwCursorInhibitor *inhibitor) -{ - MetaCursorRendererPrivate *priv = - meta_cursor_renderer_get_instance_private (renderer); - - priv->hw_cursor_inhibitors = g_list_remove (priv->hw_cursor_inhibitors, - inhibitor); -} - -gboolean -meta_cursor_renderer_is_hw_cursors_inhibited (MetaCursorRenderer *renderer) -{ - MetaCursorRendererPrivate *priv = - meta_cursor_renderer_get_instance_private (renderer); - GList *l; - - for (l = priv->hw_cursor_inhibitors; l; l = l->next) - { - MetaHwCursorInhibitor *inhibitor = l->data; - - if (meta_hw_cursor_inhibitor_is_cursor_inhibited (inhibitor)) - return TRUE; - } - - return FALSE; -} - ClutterInputDevice * meta_cursor_renderer_get_input_device (MetaCursorRenderer *renderer) { diff --git a/src/backends/meta-cursor-renderer.h b/src/backends/meta-cursor-renderer.h index b16d5cbe2e1..8d23cc6f564 100644 --- a/src/backends/meta-cursor-renderer.h +++ b/src/backends/meta-cursor-renderer.h @@ -41,6 +41,8 @@ struct _MetaHwCursorInhibitorInterface gboolean (* is_cursor_inhibited) (MetaHwCursorInhibitor *inhibitor); }; +gboolean meta_hw_cursor_inhibitor_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor); + #define META_TYPE_CURSOR_RENDERER (meta_cursor_renderer_get_type ()) G_DECLARE_DERIVABLE_TYPE (MetaCursorRenderer, meta_cursor_renderer, META, CURSOR_RENDERER, GObject); @@ -66,14 +68,6 @@ MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer gboolean meta_cursor_renderer_is_overlay_visible (MetaCursorRenderer *renderer); -void meta_cursor_renderer_add_hw_cursor_inhibitor (MetaCursorRenderer *renderer, - MetaHwCursorInhibitor *inhibitor); - -void meta_cursor_renderer_remove_hw_cursor_inhibitor (MetaCursorRenderer *renderer, - MetaHwCursorInhibitor *inhibitor); - -gboolean meta_cursor_renderer_is_hw_cursors_inhibited (MetaCursorRenderer *renderer); - graphene_rect_t meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer, MetaCursorSprite *cursor_sprite); diff --git a/src/backends/meta-screen-cast-area-stream-src.c b/src/backends/meta-screen-cast-area-stream-src.c index b837fcccb42..1b0da7be2ef 100644 --- a/src/backends/meta-screen-cast-area-stream-src.c +++ b/src/backends/meta-screen-cast-area-stream-src.c @@ -83,19 +83,6 @@ get_backend (MetaScreenCastAreaStreamSrc *area_src) return meta_screen_cast_get_backend (screen_cast); } -static MetaCursorRenderer * -get_cursor_renderer (MetaScreenCastAreaStreamSrc *area_src) -{ - MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src); - MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src); - MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream); - MetaScreenCast *screen_cast = - meta_screen_cast_session_get_screen_cast (session); - MetaBackend *backend = meta_screen_cast_get_backend (screen_cast); - - return meta_backend_get_cursor_renderer (backend); -} - static void meta_screen_cast_area_stream_src_get_specs (MetaScreenCastStreamSrc *src, int *width, @@ -199,14 +186,14 @@ cursor_changed (MetaCursorTracker *cursor_tracker, static void inhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src) { - MetaCursorRenderer *cursor_renderer; MetaHwCursorInhibitor *inhibitor; + MetaBackend *backend; g_return_if_fail (!area_src->hw_cursor_inhibited); - cursor_renderer = get_cursor_renderer (area_src); + backend = get_backend (area_src); inhibitor = META_HW_CURSOR_INHIBITOR (area_src); - meta_cursor_renderer_add_hw_cursor_inhibitor (cursor_renderer, inhibitor); + meta_backend_add_hw_cursor_inhibitor (backend, inhibitor); area_src->hw_cursor_inhibited = TRUE; } @@ -214,14 +201,14 @@ inhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src) static void uninhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src) { - MetaCursorRenderer *cursor_renderer; MetaHwCursorInhibitor *inhibitor; + MetaBackend *backend; g_return_if_fail (area_src->hw_cursor_inhibited); - cursor_renderer = get_cursor_renderer (area_src); + backend = get_backend (area_src); inhibitor = META_HW_CURSOR_INHIBITOR (area_src); - meta_cursor_renderer_remove_hw_cursor_inhibitor (cursor_renderer, inhibitor); + meta_backend_remove_hw_cursor_inhibitor (backend, inhibitor); area_src->hw_cursor_inhibited = FALSE; } diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c index a0d510067b9..52661033d0a 100644 --- a/src/backends/meta-screen-cast-monitor-stream-src.c +++ b/src/backends/meta-screen-cast-monitor-stream-src.c @@ -252,30 +252,17 @@ cursor_changed (MetaCursorTracker *cursor_tracker, sync_cursor_state (monitor_src); } -static MetaCursorRenderer * -get_cursor_renderer (MetaScreenCastMonitorStreamSrc *monitor_src) -{ - MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src); - MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src); - MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream); - MetaScreenCast *screen_cast = - meta_screen_cast_session_get_screen_cast (session); - MetaBackend *backend = meta_screen_cast_get_backend (screen_cast); - - return meta_backend_get_cursor_renderer (backend); -} - static void inhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src) { - MetaCursorRenderer *cursor_renderer; MetaHwCursorInhibitor *inhibitor; + MetaBackend *backend; g_return_if_fail (!monitor_src->hw_cursor_inhibited); - cursor_renderer = get_cursor_renderer (monitor_src); + backend = get_backend (monitor_src); inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src); - meta_cursor_renderer_add_hw_cursor_inhibitor (cursor_renderer, inhibitor); + meta_backend_add_hw_cursor_inhibitor (backend, inhibitor); monitor_src->hw_cursor_inhibited = TRUE; } @@ -283,14 +270,14 @@ inhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src) static void uninhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src) { - MetaCursorRenderer *cursor_renderer; MetaHwCursorInhibitor *inhibitor; + MetaBackend *backend; g_return_if_fail (monitor_src->hw_cursor_inhibited); - cursor_renderer = get_cursor_renderer (monitor_src); + backend = get_backend (monitor_src); inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src); - meta_cursor_renderer_remove_hw_cursor_inhibitor (cursor_renderer, inhibitor); + meta_backend_remove_hw_cursor_inhibitor (backend, inhibitor); monitor_src->hw_cursor_inhibited = FALSE; } diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index dca1d15cacb..ccf0434ee74 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -872,6 +872,10 @@ should_have_hw_cursor (MetaCursorRenderer *renderer, MetaCursorSprite *cursor_sprite, GList *gpus) { + MetaCursorRendererNative *cursor_renderer_native = + META_CURSOR_RENDERER_NATIVE (renderer); + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (cursor_renderer_native); CoglTexture *texture; MetaMonitorTransform transform; float scale; @@ -880,7 +884,7 @@ should_have_hw_cursor (MetaCursorRenderer *renderer, if (!cursor_sprite) return FALSE; - if (meta_cursor_renderer_is_hw_cursors_inhibited (renderer)) + if (meta_backend_is_hw_cursors_inhibited (priv->backend)) return FALSE; for (l = gpus; l; l = l->next) -- GitLab From 5f30d1b8ace7e412cd48d6dd5bde81f70372d08e Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 15 Jul 2020 22:38:00 +0200 Subject: [PATCH 27/85] backends: Split pad action mapping to a separate object This now lives in the core, and will get updated from events in the UI thread. Part-of: --- src/backends/meta-input-settings-private.h | 11 - src/backends/meta-input-settings.c | 638 --------------- src/core/display-private.h | 2 + src/core/display.c | 9 +- src/core/events.c | 3 +- src/core/meta-pad-action-mapper.c | 858 +++++++++++++++++++++ src/core/meta-pad-action-mapper.h | 46 ++ src/meson.build | 1 + src/wayland/meta-wayland-tablet-pad.c | 17 +- 9 files changed, 922 insertions(+), 663 deletions(-) create mode 100644 src/core/meta-pad-action-mapper.c create mode 100644 src/core/meta-pad-action-mapper.h diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h index 3cf7b5f0e43..79bac8e07ab 100644 --- a/src/backends/meta-input-settings-private.h +++ b/src/backends/meta-input-settings-private.h @@ -143,17 +143,6 @@ GSettings * meta_input_settings_get_tablet_settings (MetaInputSettings MetaLogicalMonitor * meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings, ClutterInputDevice *device); -gboolean meta_input_settings_is_pad_button_grabbed (MetaInputSettings *input_settings, - ClutterInputDevice *pad, - guint button); - -gboolean meta_input_settings_handle_pad_event (MetaInputSettings *input_settings, - const ClutterEvent *event); -gchar * meta_input_settings_get_pad_action_label (MetaInputSettings *input_settings, - ClutterInputDevice *pad, - MetaPadActionType action, - guint number); - void meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings); void meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings); diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 0fcac9095cc..6c0040ec235 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -81,18 +81,8 @@ struct _MetaInputSettingsPrivate GHashTable *current_tools; - ClutterVirtualInputDevice *virtual_pad_keyboard; - GHashTable *two_finger_devices; - /* Pad ring/strip emission */ - struct { - ClutterInputDevice *pad; - MetaPadActionType action; - guint number; - gdouble value; - } last_pad_action_info; - /* For absolute devices with no mapping in settings */ MetaInputMapper *input_mapper; }; @@ -111,15 +101,6 @@ typedef void (*ConfigUintFunc) (MetaInputSettings *input_settings, ClutterInputDevice *device, guint value); -typedef enum -{ - META_PAD_DIRECTION_NONE = -1, - META_PAD_DIRECTION_UP = 0, - META_PAD_DIRECTION_DOWN, - META_PAD_DIRECTION_CW, - META_PAD_DIRECTION_CCW, -} MetaPadDirection; - G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettings, meta_input_settings, G_TYPE_OBJECT) static GSList * @@ -155,8 +136,6 @@ meta_input_settings_dispose (GObject *object) g_signal_handlers_disconnect_by_data (priv->seat, settings); - g_clear_object (&priv->virtual_pad_keyboard); - g_clear_object (&priv->mouse_settings); g_clear_object (&priv->touchpad_settings); g_clear_object (&priv->trackball_settings); @@ -1587,63 +1566,6 @@ lookup_tool_settings (ClutterInputDeviceTool *tool, return tool_settings; } -static GSettings * -lookup_pad_action_settings (ClutterInputDevice *device, - MetaPadActionType action, - guint number, - MetaPadDirection direction, - gint mode) -{ - const gchar *vendor, *product, *action_type, *detail_type = NULL; - GSettings *settings; - GString *path; - gchar action_label; - - vendor = clutter_input_device_get_vendor_id (device); - product = clutter_input_device_get_product_id (device); - - action_label = 'A' + number; - - switch (action) - { - case META_PAD_ACTION_BUTTON: - action_type = "button"; - break; - case META_PAD_ACTION_RING: - g_assert (direction == META_PAD_DIRECTION_CW || - direction == META_PAD_DIRECTION_CCW); - action_type = "ring"; - detail_type = (direction == META_PAD_DIRECTION_CW) ? "cw" : "ccw"; - break; - case META_PAD_ACTION_STRIP: - g_assert (direction == META_PAD_DIRECTION_UP || - direction == META_PAD_DIRECTION_DOWN); - action_type = "strip"; - detail_type = (direction == META_PAD_DIRECTION_UP) ? "up" : "down"; - break; - default: - return NULL; - } - - path = g_string_new (NULL); - g_string_append_printf (path, "/org/gnome/desktop/peripherals/tablets/%s:%s/%s%c", - vendor, product, action_type, action_label); - - if (detail_type) - g_string_append_printf (path, "-%s", detail_type); - - if (mode >= 0) - g_string_append_printf (path, "-mode-%d", mode); - - g_string_append_c (path, '/'); - - settings = g_settings_new_with_path ("org.gnome.desktop.peripherals.tablet.pad-button", - path->str); - g_string_free (path, TRUE); - - return settings; -} - static void monitors_changed_cb (MetaMonitorManager *monitor_manager, MetaInputSettings *input_settings) @@ -2196,566 +2118,6 @@ meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings, return logical_monitor; } -static GDesktopPadButtonAction -meta_input_settings_get_pad_button_action (MetaInputSettings *input_settings, - ClutterInputDevice *pad, - guint button) -{ - GDesktopPadButtonAction action; - GSettings *settings; - - g_return_val_if_fail (META_IS_INPUT_SETTINGS (input_settings), - G_DESKTOP_PAD_BUTTON_ACTION_NONE); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad), - G_DESKTOP_PAD_BUTTON_ACTION_NONE); - - settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON, - button, META_PAD_DIRECTION_NONE, -1); - action = g_settings_get_enum (settings, "action"); - g_object_unref (settings); - - return action; -} - -static gboolean -cycle_logical_monitors (MetaInputSettings *settings, - gboolean skip_all_monitors, - MetaLogicalMonitor *current_logical_monitor, - MetaLogicalMonitor **next_logical_monitor) -{ - MetaInputSettingsPrivate *priv = - meta_input_settings_get_instance_private (settings); - MetaMonitorManager *monitor_manager = priv->monitor_manager; - GList *logical_monitors; - - /* We cycle between: - * - the span of all monitors (current_logical_monitor = NULL), only for - * non-integrated devices. - * - each monitor individually. - */ - - logical_monitors = - meta_monitor_manager_get_logical_monitors (monitor_manager); - - if (!current_logical_monitor) - { - *next_logical_monitor = logical_monitors->data; - } - else - { - GList *l; - - l = g_list_find (logical_monitors, current_logical_monitor); - if (l->next) - *next_logical_monitor = l->next->data; - else if (skip_all_monitors) - *next_logical_monitor = logical_monitors->data; - else - *next_logical_monitor = NULL; - } - - return TRUE; -} - -static void -meta_input_settings_cycle_tablet_output (MetaInputSettings *input_settings, - ClutterInputDevice *device) -{ - MetaInputSettingsPrivate *priv; - DeviceMappingInfo *info; - MetaLogicalMonitor *logical_monitor = NULL; - const gchar *edid[4] = { 0 }, *pretty_name = NULL; - gboolean is_integrated_device = FALSE; -#ifdef HAVE_LIBWACOM - WacomDevice *wacom_device; -#endif - - g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings)); - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - g_return_if_fail (clutter_input_device_get_device_type (device) == CLUTTER_TABLET_DEVICE || - clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE); - - priv = meta_input_settings_get_instance_private (input_settings); - info = g_hash_table_lookup (priv->mappable_devices, device); - g_return_if_fail (info != NULL); - -#ifdef HAVE_LIBWACOM - wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); - - if (wacom_device) - { - pretty_name = libwacom_get_name (wacom_device); - is_integrated_device = - libwacom_get_integration_flags (wacom_device) != WACOM_DEVICE_INTEGRATED_NONE; - } -#endif - - meta_input_settings_find_monitor (input_settings, info->settings, device, - NULL, &logical_monitor); - - if (!cycle_logical_monitors (input_settings, - is_integrated_device, - logical_monitor, - &logical_monitor)) - return; - - if (logical_monitor) - { - MetaMonitor *monitor; - - /* Pick an arbitrary monitor in the logical monitor to represent it. */ - monitor = meta_logical_monitor_get_monitors (logical_monitor)->data; - edid[0] = meta_monitor_get_vendor (monitor); - edid[1] = meta_monitor_get_product (monitor); - edid[2] = meta_monitor_get_serial (monitor); - } - else - { - edid[0] = ""; - edid[1] = ""; - edid[2] = ""; - } - g_settings_set_strv (info->settings, "output", edid); - - meta_display_show_tablet_mapping_notification (meta_get_display (), - device, pretty_name); -} - -static void -emulate_modifiers (ClutterVirtualInputDevice *device, - ClutterModifierType mods, - ClutterKeyState state) -{ - guint i; - struct { - ClutterModifierType mod; - guint keyval; - } mod_map[] = { - { CLUTTER_SHIFT_MASK, CLUTTER_KEY_Shift_L }, - { CLUTTER_CONTROL_MASK, CLUTTER_KEY_Control_L }, - { CLUTTER_MOD1_MASK, CLUTTER_KEY_Meta_L } - }; - - for (i = 0; i < G_N_ELEMENTS (mod_map); i++) - { - if ((mods & mod_map[i].mod) == 0) - continue; - - clutter_virtual_input_device_notify_keyval (device, - clutter_get_current_event_time (), - mod_map[i].keyval, state); - } -} - -static void -meta_input_settings_emulate_keybinding (MetaInputSettings *input_settings, - const gchar *accel, - gboolean is_press) -{ - MetaInputSettingsPrivate *priv; - ClutterKeyState state; - guint key, mods; - - if (!accel || !*accel) - return; - - priv = meta_input_settings_get_instance_private (input_settings); - - /* FIXME: This is appalling */ - gtk_accelerator_parse (accel, &key, &mods); - - if (!priv->virtual_pad_keyboard) - { - ClutterBackend *backend; - ClutterSeat *seat; - - backend = clutter_get_default_backend (); - seat = clutter_backend_get_default_seat (backend); - - priv->virtual_pad_keyboard = - clutter_seat_create_virtual_device (seat, - CLUTTER_KEYBOARD_DEVICE); - } - - state = is_press ? CLUTTER_KEY_STATE_PRESSED : CLUTTER_KEY_STATE_RELEASED; - - if (is_press) - emulate_modifiers (priv->virtual_pad_keyboard, mods, state); - - clutter_virtual_input_device_notify_keyval (priv->virtual_pad_keyboard, - clutter_get_current_event_time (), - key, state); - if (!is_press) - emulate_modifiers (priv->virtual_pad_keyboard, mods, state); -} - -gboolean -meta_input_settings_is_pad_button_grabbed (MetaInputSettings *input_settings, - ClutterInputDevice *pad, - guint button) -{ - g_return_val_if_fail (META_IS_INPUT_SETTINGS (input_settings), FALSE); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad), FALSE); - g_return_val_if_fail (clutter_input_device_get_device_type (pad) == - CLUTTER_PAD_DEVICE, FALSE); - - return (meta_input_settings_get_pad_button_action (input_settings, pad, button) != - G_DESKTOP_PAD_BUTTON_ACTION_NONE); -} - -static gboolean -meta_input_settings_handle_pad_button (MetaInputSettings *input_settings, - ClutterInputDevice *pad, - const ClutterPadButtonEvent *event) -{ - GDesktopPadButtonAction action; - gint button, group, mode; - gboolean is_press; - GSettings *settings; - gchar *accel; - - g_return_val_if_fail (META_IS_INPUT_SETTINGS (input_settings), FALSE); - g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS || - event->type == CLUTTER_PAD_BUTTON_RELEASE, FALSE); - - button = event->button; - mode = event->mode; - group = clutter_input_device_get_mode_switch_button_group (pad, button); - is_press = event->type == CLUTTER_PAD_BUTTON_PRESS; - - if (is_press && group >= 0) - { - guint n_modes = clutter_input_device_get_group_n_modes (pad, group); - const gchar *pretty_name = NULL; - MetaInputSettingsPrivate *priv; - DeviceMappingInfo *info; -#ifdef HAVE_LIBWACOM - WacomDevice *wacom_device; -#endif - - priv = meta_input_settings_get_instance_private (input_settings); - info = g_hash_table_lookup (priv->mappable_devices, pad); - -#ifdef HAVE_LIBWACOM - wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (pad)); - - if (wacom_device) - pretty_name = libwacom_get_name (wacom_device); -#endif - meta_display_notify_pad_group_switch (meta_get_display (), pad, - pretty_name, group, mode, n_modes); - info->group_modes[group] = mode; - } - - action = meta_input_settings_get_pad_button_action (input_settings, pad, button); - - switch (action) - { - case G_DESKTOP_PAD_BUTTON_ACTION_SWITCH_MONITOR: - if (is_press) - meta_input_settings_cycle_tablet_output (input_settings, pad); - return TRUE; - case G_DESKTOP_PAD_BUTTON_ACTION_HELP: - if (is_press) - meta_display_request_pad_osd (meta_get_display (), pad, FALSE); - return TRUE; - case G_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING: - settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON, - button, META_PAD_DIRECTION_NONE, -1); - accel = g_settings_get_string (settings, "keybinding"); - meta_input_settings_emulate_keybinding (input_settings, accel, is_press); - g_object_unref (settings); - g_free (accel); - return TRUE; - case G_DESKTOP_PAD_BUTTON_ACTION_NONE: - default: - return FALSE; - } -} - -static gboolean -meta_input_settings_handle_pad_action (MetaInputSettings *input_settings, - ClutterInputDevice *pad, - MetaPadActionType action, - guint number, - MetaPadDirection direction, - guint mode) -{ - GSettings *settings; - gboolean handled = FALSE; - gchar *accel; - - settings = lookup_pad_action_settings (pad, action, number, direction, mode); - accel = g_settings_get_string (settings, "keybinding"); - - if (accel && *accel) - { - meta_input_settings_emulate_keybinding (input_settings, accel, TRUE); - meta_input_settings_emulate_keybinding (input_settings, accel, FALSE); - handled = TRUE; - } - - g_object_unref (settings); - g_free (accel); - - return handled; -} - -static gboolean -meta_input_settings_get_pad_action_direction (MetaInputSettings *input_settings, - const ClutterEvent *event, - MetaPadDirection *direction) -{ - MetaInputSettingsPrivate *priv; - ClutterInputDevice *pad = clutter_event_get_device (event); - MetaPadActionType pad_action; - gboolean has_direction = FALSE; - MetaPadDirection inc_dir, dec_dir; - guint number; - gdouble value; - - priv = meta_input_settings_get_instance_private (input_settings); - *direction = META_PAD_DIRECTION_NONE; - - switch (event->type) - { - case CLUTTER_PAD_RING: - pad_action = META_PAD_ACTION_RING; - number = event->pad_ring.ring_number; - value = event->pad_ring.angle; - inc_dir = META_PAD_DIRECTION_CW; - dec_dir = META_PAD_DIRECTION_CCW; - break; - case CLUTTER_PAD_STRIP: - pad_action = META_PAD_ACTION_STRIP; - number = event->pad_strip.strip_number; - value = event->pad_strip.value; - inc_dir = META_PAD_DIRECTION_DOWN; - dec_dir = META_PAD_DIRECTION_UP; - break; - default: - return FALSE; - } - - if (priv->last_pad_action_info.pad == pad && - priv->last_pad_action_info.action == pad_action && - priv->last_pad_action_info.number == number && - value >= 0 && priv->last_pad_action_info.value >= 0) - { - *direction = (value - priv->last_pad_action_info.value) > 0 ? - inc_dir : dec_dir; - has_direction = TRUE; - } - - priv->last_pad_action_info.pad = pad; - priv->last_pad_action_info.action = pad_action; - priv->last_pad_action_info.number = number; - priv->last_pad_action_info.value = value; - return has_direction; -} - -gboolean -meta_input_settings_handle_pad_event (MetaInputSettings *input_settings, - const ClutterEvent *event) -{ - ClutterInputDevice *pad; - MetaPadDirection direction = META_PAD_DIRECTION_NONE; - - pad = clutter_event_get_source_device ((ClutterEvent *) event); - - switch (event->type) - { - case CLUTTER_PAD_BUTTON_PRESS: - case CLUTTER_PAD_BUTTON_RELEASE: - return meta_input_settings_handle_pad_button (input_settings, pad, - &event->pad_button); - case CLUTTER_PAD_RING: - if (!meta_input_settings_get_pad_action_direction (input_settings, - event, &direction)) - return FALSE; - return meta_input_settings_handle_pad_action (input_settings, pad, - META_PAD_ACTION_RING, - event->pad_ring.ring_number, - direction, - event->pad_ring.mode); - case CLUTTER_PAD_STRIP: - if (!meta_input_settings_get_pad_action_direction (input_settings, - event, &direction)) - return FALSE; - return meta_input_settings_handle_pad_action (input_settings, pad, - META_PAD_ACTION_STRIP, - event->pad_strip.strip_number, - direction, - event->pad_strip.mode); - default: - return FALSE; - } -} - -static gchar * -compose_directional_action_label (GSettings *direction1, - GSettings *direction2) -{ - gchar *accel1, *accel2, *str = NULL; - - accel1 = g_settings_get_string (direction1, "keybinding"); - accel2 = g_settings_get_string (direction2, "keybinding"); - - if (accel1 && *accel1 && accel2 && *accel2) - str = g_strdup_printf ("%s / %s", accel1, accel2); - - g_free (accel1); - g_free (accel2); - - return str; -} - -static gchar * -meta_input_settings_get_ring_label (MetaInputSettings *settings, - ClutterInputDevice *pad, - guint number, - guint mode) -{ - GSettings *settings1, *settings2; - gchar *label; - - /* We only allow keybinding actions with those */ - settings1 = lookup_pad_action_settings (pad, META_PAD_ACTION_RING, number, - META_PAD_DIRECTION_CW, mode); - settings2 = lookup_pad_action_settings (pad, META_PAD_ACTION_RING, number, - META_PAD_DIRECTION_CCW, mode); - label = compose_directional_action_label (settings1, settings2); - g_object_unref (settings1); - g_object_unref (settings2); - - return label; -} - -static gchar * -meta_input_settings_get_strip_label (MetaInputSettings *settings, - ClutterInputDevice *pad, - guint number, - guint mode) -{ - GSettings *settings1, *settings2; - gchar *label; - - /* We only allow keybinding actions with those */ - settings1 = lookup_pad_action_settings (pad, META_PAD_ACTION_STRIP, number, - META_PAD_DIRECTION_UP, mode); - settings2 = lookup_pad_action_settings (pad, META_PAD_ACTION_STRIP, number, - META_PAD_DIRECTION_DOWN, mode); - label = compose_directional_action_label (settings1, settings2); - g_object_unref (settings1); - g_object_unref (settings2); - - return label; -} - -static gchar * -meta_input_settings_get_button_label (MetaInputSettings *input_settings, - ClutterInputDevice *pad, - guint button) -{ - GDesktopPadButtonAction action; - gint group; - - g_return_val_if_fail (META_IS_INPUT_SETTINGS (input_settings), NULL); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad), NULL); - g_return_val_if_fail (clutter_input_device_get_device_type (pad) == - CLUTTER_PAD_DEVICE, NULL); - - group = clutter_input_device_get_mode_switch_button_group (pad, button); - - if (group >= 0) - { - /* TRANSLATORS: This string refers to a button that switches between - * different modes. - */ - return g_strdup_printf (_("Mode Switch (Group %d)"), group); - } - - action = meta_input_settings_get_pad_button_action (input_settings, pad, button); - - switch (action) - { - case G_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING: - { - GSettings *settings; - gchar *accel; - - settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON, - button, META_PAD_DIRECTION_NONE, -1); - accel = g_settings_get_string (settings, "keybinding"); - g_object_unref (settings); - - return accel; - } - case G_DESKTOP_PAD_BUTTON_ACTION_SWITCH_MONITOR: - /* TRANSLATORS: This string refers to an action, cycles drawing tablets' - * mapping through the available outputs. - */ - return g_strdup (_("Switch monitor")); - case G_DESKTOP_PAD_BUTTON_ACTION_HELP: - return g_strdup (_("Show on-screen help")); - case G_DESKTOP_PAD_BUTTON_ACTION_NONE: - default: - return NULL; - } -} - -static guint -get_current_pad_mode (MetaInputSettings *input_settings, - ClutterInputDevice *pad, - MetaPadActionType action_type, - guint number) -{ - MetaInputSettingsPrivate *priv; - DeviceMappingInfo *info; - guint group = 0, n_groups; - - priv = meta_input_settings_get_instance_private (input_settings); - info = g_hash_table_lookup (priv->mappable_devices, pad); - n_groups = clutter_input_device_get_n_mode_groups (pad); - - if (!info->group_modes || n_groups == 0) - return 0; - - if (action_type == META_PAD_ACTION_RING || - action_type == META_PAD_ACTION_STRIP) - { - /* Assume features are evenly distributed in groups */ - group = number % n_groups; - } - - return info->group_modes[group]; -} - -gchar * -meta_input_settings_get_pad_action_label (MetaInputSettings *input_settings, - ClutterInputDevice *pad, - MetaPadActionType action_type, - guint number) -{ - guint mode; - - switch (action_type) - { - case META_PAD_ACTION_BUTTON: - return meta_input_settings_get_button_label (input_settings, pad, number); - case META_PAD_ACTION_RING: - mode = get_current_pad_mode (input_settings, pad, action_type, number); - return meta_input_settings_get_ring_label (input_settings, pad, - number, mode); - case META_PAD_ACTION_STRIP: - mode = get_current_pad_mode (input_settings, pad, action_type, number); - return meta_input_settings_get_strip_label (input_settings, pad, - number, mode); - } - - return NULL; -} - void meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings) { diff --git a/src/core/display-private.h b/src/core/display-private.h index 78f25fdb6c7..3d690fcb66b 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -38,6 +38,7 @@ #include "clutter/clutter.h" #include "core/keybindings-private.h" #include "core/meta-gesture-tracker-private.h" +#include "core/meta-pad-action-mapper.h" #include "core/stack-tracker.h" #include "core/startup-notification-private.h" #include "meta/barrier.h" @@ -211,6 +212,7 @@ struct _MetaDisplay ClutterEventSequence *pointer_emulating_sequence; ClutterActor *current_pad_osd; + MetaPadActionMapper *pad_action_mapper; MetaStartupNotification *startup_notification; diff --git a/src/core/display.c b/src/core/display.c index db06990ce50..7bb47d4b3bc 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -854,6 +854,8 @@ meta_display_open (void) g_signal_connect (monitor_manager, "monitors-changed-internal", G_CALLBACK (on_monitors_changed_internal), display); + display->pad_action_mapper = meta_pad_action_mapper_new (monitor_manager); + settings = meta_backend_get_settings (backend); g_signal_connect (settings, "ui-scaling-factor-changed", G_CALLBACK (on_ui_scaling_factor_changed), display); @@ -1119,6 +1121,7 @@ meta_display_close (MetaDisplay *display, meta_clipboard_manager_shutdown (display); g_clear_object (&display->selection); + g_clear_object (&display->pad_action_mapper); g_object_unref (display); the_display = NULL; @@ -2961,12 +2964,12 @@ meta_display_get_pad_action_label (MetaDisplay *display, MetaPadActionType action_type, guint action_number) { - MetaInputSettings *settings; gchar *label; /* First, lookup the action, as imposed by settings */ - settings = meta_backend_get_input_settings (meta_get_backend ()); - label = meta_input_settings_get_pad_action_label (settings, pad, action_type, action_number); + label = meta_pad_action_mapper_get_action_label (display->pad_action_mapper, + pad, action_type, + action_number); if (label) return label; diff --git a/src/core/events.c b/src/core/events.c index 52828bdc930..fdc0bd8b516 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -265,8 +265,7 @@ meta_display_handle_event (MetaDisplay *display, handle_pad_event = !display->current_pad_osd || is_mode_switch; if (handle_pad_event && - meta_input_settings_handle_pad_event (meta_backend_get_input_settings (backend), - event)) + meta_pad_action_mapper_handle_event (display->pad_action_mapper, event)) { bypass_wayland = bypass_clutter = TRUE; goto out; diff --git a/src/core/meta-pad-action-mapper.c b/src/core/meta-pad-action-mapper.c new file mode 100644 index 00000000000..e5331e1dd23 --- /dev/null +++ b/src/core/meta-pad-action-mapper.c @@ -0,0 +1,858 @@ +/* + * Copyright (C) 2014-2020 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Carlos Garnacho + */ + +#include "config.h" + +#include +#include + +#ifdef HAVE_LIBWACOM +#include +#endif + +#include "core/meta-pad-action-mapper.h" +#include "backends/meta-input-device-private.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor.h" +#include "core/display-private.h" + +typedef struct _PadMappingInfo PadMappingInfo; + +struct _PadMappingInfo +{ + ClutterInputDevice *device; + GSettings *settings; + guint *group_modes; +}; + +typedef enum +{ + META_PAD_DIRECTION_NONE = -1, + META_PAD_DIRECTION_UP = 0, + META_PAD_DIRECTION_DOWN, + META_PAD_DIRECTION_CW, + META_PAD_DIRECTION_CCW, +} MetaPadDirection; + +struct _MetaPadActionMapper +{ + GObject parent_class; + + GHashTable *pads; + ClutterSeat *seat; + ClutterVirtualInputDevice *virtual_pad_keyboard; + MetaMonitorManager *monitor_manager; + + /* Pad ring/strip emission */ + struct { + ClutterInputDevice *pad; + MetaPadActionType action; + guint number; + double value; + } last_pad_action_info; +}; + +G_DEFINE_TYPE (MetaPadActionMapper, meta_pad_action_mapper, G_TYPE_OBJECT) + +static void +meta_pad_action_mapper_finalize (GObject *object) +{ + MetaPadActionMapper *mapper = META_PAD_ACTION_MAPPER (object); + + g_hash_table_unref (mapper->pads); + g_object_unref (mapper->monitor_manager); + g_clear_object (&mapper->virtual_pad_keyboard); + + G_OBJECT_CLASS (meta_pad_action_mapper_parent_class)->finalize (object); +} + +static void +meta_pad_action_mapper_class_init (MetaPadActionMapperClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_pad_action_mapper_finalize; +} + +static GSettings * +lookup_device_settings (ClutterInputDevice *device) +{ + const char *vendor, *product; + GSettings *settings; + char *path; + + vendor = clutter_input_device_get_vendor_id (device); + product = clutter_input_device_get_product_id (device); + path = g_strdup_printf ("/org/gnome/desktop/peripherals/tablets/%s:%s/", + vendor, product); + + settings = g_settings_new_with_path ("org.gnome.desktop.peripherals.tablet", + path); + g_free (path); + + return settings; +} + +static PadMappingInfo * +pad_mapping_info_new (ClutterInputDevice *pad) +{ + PadMappingInfo *info; + + info = g_new0 (PadMappingInfo, 1); + info->device = pad; + info->settings = lookup_device_settings (pad); + info->group_modes = + g_new0 (guint, clutter_input_device_get_n_mode_groups (pad)); + + return info; +} + +static void +pad_mapping_info_free (PadMappingInfo *info) +{ + g_object_unref (info->settings); + g_free (info->group_modes); + g_free (info); +} + +static void +device_added (ClutterSeat *seat, + ClutterInputDevice *device, + MetaPadActionMapper *mapper) +{ + PadMappingInfo *info; + + if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE) + { + info = pad_mapping_info_new (device); + g_hash_table_insert (mapper->pads, device, info); + } +} + +static void +device_removed (ClutterSeat *seat, + ClutterInputDevice *device, + MetaPadActionMapper *mapper) +{ + g_hash_table_remove (mapper->pads, device); +} + +static void +meta_pad_action_mapper_init (MetaPadActionMapper *mapper) +{ + mapper->pads = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) pad_mapping_info_free); + + mapper->seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + g_signal_connect (mapper->seat, "device-added", + G_CALLBACK (device_added), mapper); + g_signal_connect (mapper->seat, "device-removed", + G_CALLBACK (device_removed), mapper); +} + +MetaPadActionMapper * +meta_pad_action_mapper_new (MetaMonitorManager *monitor_manager) +{ + MetaPadActionMapper *action_mapper; + + action_mapper = g_object_new (META_TYPE_PAD_ACTION_MAPPER, NULL); + g_set_object (&action_mapper->monitor_manager, monitor_manager); + + return action_mapper; +} + +static GSettings * +lookup_pad_action_settings (ClutterInputDevice *device, + MetaPadActionType action, + guint number, + MetaPadDirection direction, + int mode) +{ + const char *vendor, *product, *action_type, *detail_type = NULL; + GSettings *settings; + GString *path; + char action_label; + + vendor = clutter_input_device_get_vendor_id (device); + product = clutter_input_device_get_product_id (device); + + action_label = 'A' + number; + + switch (action) + { + case META_PAD_ACTION_BUTTON: + action_type = "button"; + break; + case META_PAD_ACTION_RING: + g_assert (direction == META_PAD_DIRECTION_CW || + direction == META_PAD_DIRECTION_CCW); + action_type = "ring"; + detail_type = (direction == META_PAD_DIRECTION_CW) ? "cw" : "ccw"; + break; + case META_PAD_ACTION_STRIP: + g_assert (direction == META_PAD_DIRECTION_UP || + direction == META_PAD_DIRECTION_DOWN); + action_type = "strip"; + detail_type = (direction == META_PAD_DIRECTION_UP) ? "up" : "down"; + break; + default: + return NULL; + } + + path = g_string_new (NULL); + g_string_append_printf (path, "/org/gnome/desktop/peripherals/tablets/%s:%s/%s%c", + vendor, product, action_type, action_label); + + if (detail_type) + g_string_append_printf (path, "-%s", detail_type); + + if (mode >= 0) + g_string_append_printf (path, "-mode-%d", mode); + + g_string_append_c (path, '/'); + + settings = g_settings_new_with_path ("org.gnome.desktop.peripherals.tablet.pad-button", + path->str); + g_string_free (path, TRUE); + + return settings; +} + +static GDesktopPadButtonAction +meta_pad_action_mapper_get_button_action (MetaPadActionMapper *mapper, + ClutterInputDevice *pad, + guint button) +{ + GDesktopPadButtonAction action; + GSettings *settings; + + g_return_val_if_fail (META_IS_PAD_ACTION_MAPPER (mapper), + G_DESKTOP_PAD_BUTTON_ACTION_NONE); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad), + G_DESKTOP_PAD_BUTTON_ACTION_NONE); + + settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON, + button, META_PAD_DIRECTION_NONE, -1); + action = g_settings_get_enum (settings, "action"); + g_object_unref (settings); + + return action; +} + +static gboolean +cycle_logical_monitors (MetaPadActionMapper *mapper, + gboolean skip_all_monitors, + MetaLogicalMonitor *current_logical_monitor, + MetaLogicalMonitor **next_logical_monitor) +{ + MetaMonitorManager *monitor_manager = mapper->monitor_manager; + GList *logical_monitors; + + /* We cycle between: + * - the span of all monitors (current_output = NULL), only for + * non-integrated devices. + * - each monitor individually. + */ + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + + if (!current_logical_monitor) + { + *next_logical_monitor = logical_monitors->data; + } + else + { + GList *l; + + l = g_list_find (logical_monitors, current_logical_monitor); + if (l->next) + *next_logical_monitor = l->next->data; + else if (skip_all_monitors) + *next_logical_monitor = logical_monitors->data; + else + *next_logical_monitor = NULL; + } + + return TRUE; +} + +static MetaMonitor * +logical_monitor_find_monitor (MetaLogicalMonitor *logical_monitor, + const char *vendor, + const char *product, + const char *serial) +{ + GList *monitors; + GList *l; + + monitors = meta_logical_monitor_get_monitors (logical_monitor); + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + + if (g_strcmp0 (meta_monitor_get_vendor (monitor), vendor) == 0 && + g_strcmp0 (meta_monitor_get_product (monitor), product) == 0 && + g_strcmp0 (meta_monitor_get_serial (monitor), serial) == 0) + return monitor; + } + + return NULL; +} + +static void +meta_pad_action_mapper_find_monitor (MetaPadActionMapper *mapper, + GSettings *settings, + ClutterInputDevice *device, + MetaMonitor **out_monitor, + MetaLogicalMonitor **out_logical_monitor) +{ + MetaMonitorManager *monitor_manager; + MetaMonitor *monitor; + guint n_values; + GList *logical_monitors; + GList *l; + char **edid; + + edid = g_settings_get_strv (settings, "output"); + n_values = g_strv_length (edid); + + if (n_values != 3) + { + g_warning ("EDID configuration for device '%s' " + "is incorrect, must have 3 values", + clutter_input_device_get_device_name (device)); + goto out; + } + + if (!*edid[0] && !*edid[1] && !*edid[2]) + goto out; + + monitor_manager = mapper->monitor_manager; + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + + monitor = logical_monitor_find_monitor (logical_monitor, + edid[0], edid[1], edid[2]); + if (monitor) + { + if (out_monitor) + *out_monitor = monitor; + if (out_logical_monitor) + *out_logical_monitor = logical_monitor; + break; + } + } + +out: + g_strfreev (edid); +} + +static void +meta_pad_action_mapper_cycle_tablet_output (MetaPadActionMapper *mapper, + ClutterInputDevice *device) +{ + PadMappingInfo *info; + MetaLogicalMonitor *logical_monitor = NULL; + const char *edid[4] = { 0 }, *pretty_name = NULL; + gboolean is_integrated_device = FALSE; +#ifdef HAVE_LIBWACOM + WacomDevice *wacom_device; +#endif + + g_return_if_fail (META_IS_PAD_ACTION_MAPPER (mapper)); + g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); + g_return_if_fail (clutter_input_device_get_device_type (device) == CLUTTER_TABLET_DEVICE || + clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE); + + info = g_hash_table_lookup (mapper->pads, device); + g_return_if_fail (info != NULL); + +#ifdef HAVE_LIBWACOM + wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); + + if (wacom_device) + { + pretty_name = libwacom_get_name (wacom_device); + is_integrated_device = + libwacom_get_integration_flags (wacom_device) != WACOM_DEVICE_INTEGRATED_NONE; + } +#endif + + meta_pad_action_mapper_find_monitor (mapper, info->settings, device, + NULL, &logical_monitor); + + if (!cycle_logical_monitors (mapper, + is_integrated_device, + logical_monitor, + &logical_monitor)) + return; + + if (logical_monitor) + { + MetaMonitor *monitor; + + /* Pick an arbitrary monitor in the logical monitor to represent it. */ + monitor = meta_logical_monitor_get_monitors (logical_monitor)->data; + edid[0] = meta_monitor_get_vendor (monitor); + edid[1] = meta_monitor_get_product (monitor); + edid[2] = meta_monitor_get_serial (monitor); + } + else + { + edid[0] = ""; + edid[1] = ""; + edid[2] = ""; + } + + g_settings_set_strv (info->settings, "output", edid); + meta_display_show_tablet_mapping_notification (meta_get_display (), + device, pretty_name); +} + +gboolean +meta_pad_action_mapper_is_button_grabbed (MetaPadActionMapper *mapper, + ClutterInputDevice *pad, + guint button) +{ + g_return_val_if_fail (META_IS_PAD_ACTION_MAPPER (mapper), FALSE); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad), FALSE); + g_return_val_if_fail (clutter_input_device_get_device_type (pad) == + CLUTTER_PAD_DEVICE, FALSE); + + return (meta_pad_action_mapper_get_button_action (mapper, pad, button) != + G_DESKTOP_PAD_BUTTON_ACTION_NONE); +} + +static void +emulate_modifiers (ClutterVirtualInputDevice *device, + ClutterModifierType mods, + ClutterKeyState state) +{ + guint i; + struct { + ClutterModifierType mod; + guint keyval; + } mod_map[] = { + { CLUTTER_SHIFT_MASK, CLUTTER_KEY_Shift_L }, + { CLUTTER_CONTROL_MASK, CLUTTER_KEY_Control_L }, + { CLUTTER_MOD1_MASK, CLUTTER_KEY_Meta_L } + }; + + for (i = 0; i < G_N_ELEMENTS (mod_map); i++) + { + if ((mods & mod_map[i].mod) == 0) + continue; + + clutter_virtual_input_device_notify_keyval (device, + clutter_get_current_event_time (), + mod_map[i].keyval, state); + } +} + +static void +meta_pad_action_mapper_emulate_keybinding (MetaPadActionMapper *mapper, + const char *accel, + gboolean is_press) +{ + ClutterKeyState state; + guint key, mods; + + if (!accel || !*accel) + return; + + /* FIXME: This is appalling */ + gtk_accelerator_parse (accel, &key, &mods); + + if (!mapper->virtual_pad_keyboard) + { + ClutterBackend *backend; + ClutterSeat *seat; + + backend = clutter_get_default_backend (); + seat = clutter_backend_get_default_seat (backend); + + mapper->virtual_pad_keyboard = + clutter_seat_create_virtual_device (seat, + CLUTTER_KEYBOARD_DEVICE); + } + + state = is_press ? CLUTTER_KEY_STATE_PRESSED : CLUTTER_KEY_STATE_RELEASED; + + if (is_press) + emulate_modifiers (mapper->virtual_pad_keyboard, mods, state); + + clutter_virtual_input_device_notify_keyval (mapper->virtual_pad_keyboard, + clutter_get_current_event_time (), + key, state); + if (!is_press) + emulate_modifiers (mapper->virtual_pad_keyboard, mods, state); +} + +static gboolean +meta_pad_action_mapper_handle_button (MetaPadActionMapper *mapper, + ClutterInputDevice *pad, + const ClutterPadButtonEvent *event) +{ + GDesktopPadButtonAction action; + int button, group, mode; + gboolean is_press; + GSettings *settings; + char *accel; + + g_return_val_if_fail (META_IS_PAD_ACTION_MAPPER (mapper), FALSE); + g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS || + event->type == CLUTTER_PAD_BUTTON_RELEASE, FALSE); + + button = event->button; + mode = event->mode; + group = clutter_input_device_get_mode_switch_button_group (pad, button); + is_press = event->type == CLUTTER_PAD_BUTTON_PRESS; + + if (is_press && group >= 0) + { + guint n_modes = clutter_input_device_get_group_n_modes (pad, group); + const char *pretty_name = NULL; + PadMappingInfo *info; +#ifdef HAVE_LIBWACOM + WacomDevice *wacom_device; +#endif + + info = g_hash_table_lookup (mapper->pads, pad); + +#ifdef HAVE_LIBWACOM + wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (pad)); + + if (wacom_device) + pretty_name = libwacom_get_name (wacom_device); +#endif + meta_display_notify_pad_group_switch (meta_get_display (), pad, + pretty_name, group, mode, n_modes); + info->group_modes[group] = mode; + } + + action = meta_pad_action_mapper_get_button_action (mapper, pad, button); + + switch (action) + { + case G_DESKTOP_PAD_BUTTON_ACTION_SWITCH_MONITOR: + if (is_press) + meta_pad_action_mapper_cycle_tablet_output (mapper, pad); + return TRUE; + case G_DESKTOP_PAD_BUTTON_ACTION_HELP: + if (is_press) + meta_display_request_pad_osd (meta_get_display (), pad, FALSE); + return TRUE; + case G_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING: + settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON, + button, META_PAD_DIRECTION_NONE, -1); + accel = g_settings_get_string (settings, "keybinding"); + meta_pad_action_mapper_emulate_keybinding (mapper, accel, is_press); + g_object_unref (settings); + g_free (accel); + return TRUE; + case G_DESKTOP_PAD_BUTTON_ACTION_NONE: + default: + return FALSE; + } +} + +static gboolean +meta_pad_action_mapper_handle_action (MetaPadActionMapper *mapper, + ClutterInputDevice *pad, + MetaPadActionType action, + guint number, + MetaPadDirection direction, + guint mode) +{ + GSettings *settings; + gboolean handled = FALSE; + char *accel; + + settings = lookup_pad_action_settings (pad, action, number, direction, mode); + accel = g_settings_get_string (settings, "keybinding"); + + if (accel && *accel) + { + meta_pad_action_mapper_emulate_keybinding (mapper, accel, TRUE); + meta_pad_action_mapper_emulate_keybinding (mapper, accel, FALSE); + handled = TRUE; + } + + g_object_unref (settings); + g_free (accel); + + return handled; +} + +static gboolean +meta_pad_action_mapper_get_action_direction (MetaPadActionMapper *mapper, + const ClutterEvent *event, + MetaPadDirection *direction) +{ + ClutterInputDevice *pad = clutter_event_get_device (event); + MetaPadActionType pad_action; + gboolean has_direction = FALSE; + MetaPadDirection inc_dir, dec_dir; + guint number; + double value; + + *direction = META_PAD_DIRECTION_NONE; + + switch (event->type) + { + case CLUTTER_PAD_RING: + pad_action = META_PAD_ACTION_RING; + number = event->pad_ring.ring_number; + value = event->pad_ring.angle; + inc_dir = META_PAD_DIRECTION_CW; + dec_dir = META_PAD_DIRECTION_CCW; + break; + case CLUTTER_PAD_STRIP: + pad_action = META_PAD_ACTION_STRIP; + number = event->pad_strip.strip_number; + value = event->pad_strip.value; + inc_dir = META_PAD_DIRECTION_DOWN; + dec_dir = META_PAD_DIRECTION_UP; + break; + default: + return FALSE; + } + + if (mapper->last_pad_action_info.pad == pad && + mapper->last_pad_action_info.action == pad_action && + mapper->last_pad_action_info.number == number && + value >= 0 && mapper->last_pad_action_info.value >= 0) + { + *direction = (value - mapper->last_pad_action_info.value) > 0 ? + inc_dir : dec_dir; + has_direction = TRUE; + } + + mapper->last_pad_action_info.pad = pad; + mapper->last_pad_action_info.action = pad_action; + mapper->last_pad_action_info.number = number; + mapper->last_pad_action_info.value = value; + return has_direction; +} + +gboolean +meta_pad_action_mapper_handle_event (MetaPadActionMapper *mapper, + const ClutterEvent *event) +{ + ClutterInputDevice *pad; + MetaPadDirection direction = META_PAD_DIRECTION_NONE; + + pad = clutter_event_get_source_device ((ClutterEvent *) event); + + switch (event->type) + { + case CLUTTER_PAD_BUTTON_PRESS: + case CLUTTER_PAD_BUTTON_RELEASE: + return meta_pad_action_mapper_handle_button (mapper, pad, + &event->pad_button); + case CLUTTER_PAD_RING: + if (!meta_pad_action_mapper_get_action_direction (mapper, + event, &direction)) + return FALSE; + return meta_pad_action_mapper_handle_action (mapper, pad, + META_PAD_ACTION_RING, + event->pad_ring.ring_number, + direction, + event->pad_ring.mode); + case CLUTTER_PAD_STRIP: + if (!meta_pad_action_mapper_get_action_direction (mapper, + event, &direction)) + return FALSE; + return meta_pad_action_mapper_handle_action (mapper, pad, + META_PAD_ACTION_STRIP, + event->pad_strip.strip_number, + direction, + event->pad_strip.mode); + default: + return FALSE; + } +} + + +static char * +compose_directional_action_label (GSettings *direction1, + GSettings *direction2) +{ + char *accel1, *accel2, *str = NULL; + + accel1 = g_settings_get_string (direction1, "keybinding"); + accel2 = g_settings_get_string (direction2, "keybinding"); + + if (accel1 && *accel1 && accel2 && *accel2) + str = g_strdup_printf ("%s / %s", accel1, accel2); + + g_free (accel1); + g_free (accel2); + + return str; +} + +static char * +meta_pad_action_mapper_get_ring_label (MetaPadActionMapper *mapper, + ClutterInputDevice *pad, + guint number, + guint mode) +{ + GSettings *settings1, *settings2; + char *label; + + /* We only allow keybinding actions with those */ + settings1 = lookup_pad_action_settings (pad, META_PAD_ACTION_RING, number, + META_PAD_DIRECTION_CW, mode); + settings2 = lookup_pad_action_settings (pad, META_PAD_ACTION_RING, number, + META_PAD_DIRECTION_CCW, mode); + label = compose_directional_action_label (settings1, settings2); + g_object_unref (settings1); + g_object_unref (settings2); + + return label; +} + +static char * +meta_pad_action_mapper_get_strip_label (MetaPadActionMapper *mapper, + ClutterInputDevice *pad, + guint number, + guint mode) +{ + GSettings *settings1, *settings2; + char *label; + + /* We only allow keybinding actions with those */ + settings1 = lookup_pad_action_settings (pad, META_PAD_ACTION_STRIP, number, + META_PAD_DIRECTION_UP, mode); + settings2 = lookup_pad_action_settings (pad, META_PAD_ACTION_STRIP, number, + META_PAD_DIRECTION_DOWN, mode); + label = compose_directional_action_label (settings1, settings2); + g_object_unref (settings1); + g_object_unref (settings2); + + return label; +} + +static char * +meta_pad_action_mapper_get_button_label (MetaPadActionMapper *mapper, + ClutterInputDevice *pad, + guint button) +{ + GDesktopPadButtonAction action; + int group; + + g_return_val_if_fail (META_IS_PAD_ACTION_MAPPER (mapper), NULL); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad), NULL); + g_return_val_if_fail (clutter_input_device_get_device_type (pad) == + CLUTTER_PAD_DEVICE, NULL); + + group = clutter_input_device_get_mode_switch_button_group (pad, button); + + if (group >= 0) + { + /* TRANSLATORS: This string refers to a button that switches between + * different modes. + */ + return g_strdup_printf (_("Mode Switch (Group %d)"), group); + } + + action = meta_pad_action_mapper_get_button_action (mapper, pad, button); + + switch (action) + { + case G_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING: + { + GSettings *settings; + char *accel; + + settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON, + button, META_PAD_DIRECTION_NONE, -1); + accel = g_settings_get_string (settings, "keybinding"); + g_object_unref (settings); + + return accel; + } + case G_DESKTOP_PAD_BUTTON_ACTION_SWITCH_MONITOR: + /* TRANSLATORS: This string refers to an action, cycles drawing tablets' + * mapping through the available outputs. + */ + return g_strdup (_("Switch monitor")); + case G_DESKTOP_PAD_BUTTON_ACTION_HELP: + return g_strdup (_("Show on-screen help")); + case G_DESKTOP_PAD_BUTTON_ACTION_NONE: + default: + return NULL; + } +} + +static guint +get_current_pad_mode (MetaPadActionMapper *mapper, + ClutterInputDevice *pad, + MetaPadActionType action_type, + guint number) +{ + PadMappingInfo *info; + guint group = 0, n_groups; + + info = g_hash_table_lookup (mapper->pads, pad); + n_groups = clutter_input_device_get_n_mode_groups (pad); + + if (!info->group_modes || n_groups == 0) + return 0; + + if (action_type == META_PAD_ACTION_RING || + action_type == META_PAD_ACTION_STRIP) + { + /* Assume features are evenly distributed in groups */ + group = number % n_groups; + } + + return info->group_modes[group]; +} + +char * +meta_pad_action_mapper_get_action_label (MetaPadActionMapper *mapper, + ClutterInputDevice *pad, + MetaPadActionType action_type, + guint number) +{ + guint mode; + + switch (action_type) + { + case META_PAD_ACTION_BUTTON: + return meta_pad_action_mapper_get_button_label (mapper, pad, number); + case META_PAD_ACTION_RING: + mode = get_current_pad_mode (mapper, pad, action_type, number); + return meta_pad_action_mapper_get_ring_label (mapper, pad, number, mode); + case META_PAD_ACTION_STRIP: + mode = get_current_pad_mode (mapper, pad, action_type, number); + return meta_pad_action_mapper_get_strip_label (mapper, pad, number, mode); + } + + return NULL; +} diff --git a/src/core/meta-pad-action-mapper.h b/src/core/meta-pad-action-mapper.h new file mode 100644 index 00000000000..63fc2261b51 --- /dev/null +++ b/src/core/meta-pad-action-mapper.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Carlos Garnacho + */ + +#ifndef META_PAD_ACTION_MAPPER_H +#define META_PAD_ACTION_MAPPER_H + +#include "clutter/clutter.h" +#include "meta/display.h" +#include "meta/meta-monitor-manager.h" + +#define META_TYPE_PAD_ACTION_MAPPER (meta_pad_action_mapper_get_type ()) +G_DECLARE_FINAL_TYPE (MetaPadActionMapper, meta_pad_action_mapper, + META, PAD_ACTION_MAPPER, GObject) + +MetaPadActionMapper * meta_pad_action_mapper_new (MetaMonitorManager *monitor_manager); + +gboolean meta_pad_action_mapper_is_button_grabbed (MetaPadActionMapper *mapper, + ClutterInputDevice *pad, + guint button); +gboolean meta_pad_action_mapper_handle_event (MetaPadActionMapper *mapper, + const ClutterEvent *event); +gchar * meta_pad_action_mapper_get_action_label (MetaPadActionMapper *mapper, + ClutterInputDevice *pad, + MetaPadActionType action, + guint number); + +#endif /* META_PAD_ACTION_MAPPER_H */ diff --git a/src/meson.build b/src/meson.build index 84cdabcb6a8..51eeef7def5 100644 --- a/src/meson.build +++ b/src/meson.build @@ -374,6 +374,7 @@ mutter_sources = [ 'core/meta-inhibit-shortcuts-dialog-default.c', 'core/meta-inhibit-shortcuts-dialog-default-private.h', 'core/meta-launch-context.c', + 'core/meta-pad-action-mapper.c', 'core/meta-selection.c', 'core/meta-selection-source.c', 'core/meta-selection-source-memory.c', diff --git a/src/wayland/meta-wayland-tablet-pad.c b/src/wayland/meta-wayland-tablet-pad.c index 167d45948f6..d96bdfed45f 100644 --- a/src/wayland/meta-wayland-tablet-pad.c +++ b/src/wayland/meta-wayland-tablet-pad.c @@ -28,6 +28,7 @@ #include #include "backends/meta-input-settings-private.h" +#include "core/display-private.h" #include "compositor/meta-surface-actor-wayland.h" #include "wayland/meta-wayland-private.h" #include "wayland/meta-wayland-tablet-pad-group.h" @@ -244,15 +245,14 @@ tablet_pad_set_feedback (struct wl_client *client, { MetaWaylandTabletPad *pad = wl_resource_get_user_data (resource); MetaWaylandTabletPadGroup *group = tablet_pad_lookup_button_group (pad, button); - MetaInputSettings *input_settings; + MetaPadActionMapper *mapper; if (!group || group->mode_switch_serial != serial) return; - input_settings = meta_backend_get_input_settings (meta_get_backend ()); + mapper = meta_get_display ()->pad_action_mapper; - if (input_settings && - meta_input_settings_is_pad_button_grabbed (input_settings, pad->device, button)) + if (meta_pad_action_mapper_is_button_grabbed (mapper, pad->device, button)) return; if (meta_wayland_tablet_pad_group_is_mode_switch_button (group, button)) @@ -367,15 +367,14 @@ static gboolean meta_wayland_tablet_pad_handle_event_action (MetaWaylandTabletPad *pad, const ClutterEvent *event) { - MetaInputSettings *input_settings; + MetaPadActionMapper *mapper; ClutterInputDevice *device; device = clutter_event_get_source_device (event); - input_settings = meta_backend_get_input_settings (meta_get_backend ()); + mapper = meta_get_display ()->pad_action_mapper; - if (input_settings && - meta_input_settings_is_pad_button_grabbed (input_settings, device, - event->pad_button.button)) + if (meta_pad_action_mapper_is_button_grabbed (mapper, device, + event->pad_button.button)) return TRUE; return FALSE; -- GitLab From c2940efe8b6fb19e6ccdf1f37c4c18d2342ffed7 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 16 Jul 2020 12:07:20 +0200 Subject: [PATCH 28/85] backends: Move away from clutter_input_device_set_enabled() We actually have a set_send_events() vfunc that can enable or disable devices at the libinput and X11 input driver level, so use that. A positive side effect is that those layers will leave the device at a consistent idle state (as opposed to going mute maybe amid user input). Part-of: --- src/backends/meta-input-settings.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 6c0040ec235..846c58a0389 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -1906,16 +1906,18 @@ static void power_save_mode_changed_cb (MetaMonitorManager *manager, gpointer user_data) { + MetaInputSettings *input_settings = user_data; MetaInputSettingsPrivate *priv; ClutterInputDevice *device; MetaLogicalMonitor *logical_monitor; MetaMonitor *builtin; MetaPowerSave power_save_mode; + GDesktopDeviceSendEvents send_events; gboolean on; power_save_mode = meta_monitor_manager_get_power_save_mode (manager); on = power_save_mode == META_POWER_SAVE_ON; - priv = meta_input_settings_get_instance_private (user_data); + priv = meta_input_settings_get_instance_private (input_settings); builtin = meta_monitor_manager_get_laptop_panel (manager); if (!builtin) @@ -1932,7 +1934,13 @@ power_save_mode_changed_cb (MetaMonitorManager *manager, if (!device) return; - clutter_input_device_set_enabled (device, on); + send_events = on ? + G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED : + G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED; + + META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_send_events (input_settings, + device, + send_events); } static void -- GitLab From b1d12a994d0ee9af1fee355e0bc6938ee946905e Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 16 Jul 2020 12:13:04 +0200 Subject: [PATCH 29/85] clutter: Drop ClutterInputDevice::enabled and setter/getter This is unused now, and not something we generally allow. Part-of: --- clutter/clutter/clutter-event.c | 11 --- clutter/clutter/clutter-input-device.c | 78 ------------------- clutter/clutter/clutter-input-device.h | 5 -- .../native/meta-input-device-native.c | 2 - src/backends/x11/meta-seat-x11.c | 10 +-- src/tests/clutter/interactive/test-devices.c | 4 - 6 files changed, 1 insertion(+), 109 deletions(-) diff --git a/clutter/clutter/clutter-event.c b/clutter/clutter/clutter-event.c index 44a6651ddbb..ac1d2cfd349 100644 --- a/clutter/clutter/clutter-event.c +++ b/clutter/clutter/clutter-event.c @@ -1460,23 +1460,12 @@ _clutter_event_push (const ClutterEvent *event, gboolean do_copy) { ClutterMainContext *context = _clutter_context_get_default (); - ClutterInputDevice *device; g_assert (context != NULL); if (context->events_queue == NULL) context->events_queue = g_queue_new (); - /* disabled devices don't propagate events */ - device = clutter_event_get_device (event); - if (device != NULL) - { - if (event->type != CLUTTER_DEVICE_ADDED && - event->type != CLUTTER_DEVICE_REMOVED && - !clutter_input_device_get_enabled (device)) - return; - } - if (do_copy) { ClutterEvent *copy; diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 82cc5b8b394..9a69dd6246a 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -60,7 +60,6 @@ enum PROP_DEVICE_MODE, PROP_HAS_CURSOR, - PROP_ENABLED, PROP_N_AXES, @@ -184,10 +183,6 @@ clutter_input_device_set_property (GObject *gobject, self->has_cursor = g_value_get_boolean (value); break; - case PROP_ENABLED: - clutter_input_device_set_enabled (self, g_value_get_boolean (value)); - break; - case PROP_VENDOR_ID: self->vendor_id = g_value_dup_string (value); break; @@ -256,10 +251,6 @@ clutter_input_device_get_property (GObject *gobject, g_value_set_uint (value, clutter_input_device_get_n_axes (self)); break; - case PROP_ENABLED: - g_value_set_boolean (value, self->is_enabled); - break; - case PROP_VENDOR_ID: g_value_set_string (value, self->vendor_id); break; @@ -367,25 +358,6 @@ clutter_input_device_class_init (ClutterInputDeviceClass *klass) FALSE, CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); - /** - * ClutterInputDevice:enabled: - * - * Whether the device is enabled. - * - * A device with the #ClutterInputDevice:device-mode property set - * to %CLUTTER_INPUT_MODE_LOGICAL cannot be disabled. - * - * A device must be enabled in order to receive events from it. - * - * Since: 1.6 - */ - obj_props[PROP_ENABLED] = - g_param_spec_boolean ("enabled", - P_("Enabled"), - P_("Whether the device is enabled"), - FALSE, - CLUTTER_PARAM_READWRITE); - /** * ClutterInputDevice:n-axes: * @@ -710,56 +682,6 @@ clutter_input_device_get_device_type (ClutterInputDevice *device) return device->device_type; } -/** - * clutter_input_device_set_enabled: - * @device: a #ClutterInputDevice - * @enabled: %TRUE to enable the @device - * - * Enables or disables a #ClutterInputDevice. - * - * Only devices with a #ClutterInputDevice:device-mode property set - * to %CLUTTER_INPUT_MODE_PHYSICAL or %CLUTTER_INPUT_MODE_FLOATING can - * be disabled. - * - * Since: 1.6 - */ -void -clutter_input_device_set_enabled (ClutterInputDevice *device, - gboolean enabled) -{ - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - - enabled = !!enabled; - - if (!enabled && device->device_mode == CLUTTER_INPUT_MODE_LOGICAL) - return; - - if (device->is_enabled == enabled) - return; - - device->is_enabled = enabled; - - g_object_notify_by_pspec (G_OBJECT (device), obj_props[PROP_ENABLED]); -} - -/** - * clutter_input_device_get_enabled: - * @device: a #ClutterInputDevice - * - * Retrieves whether @device is enabled. - * - * Return value: %TRUE if the device is enabled - * - * Since: 1.6 - */ -gboolean -clutter_input_device_get_enabled (ClutterInputDevice *device) -{ - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - - return device->is_enabled; -} - /** * clutter_input_device_get_coords: * @device: a #ClutterInputDevice diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index 51f67583c9b..e95909b5758 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -98,11 +98,6 @@ CLUTTER_EXPORT ClutterInputMode clutter_input_device_get_device_mode (ClutterInputDevice *device); CLUTTER_EXPORT gboolean clutter_input_device_get_has_cursor (ClutterInputDevice *device); -CLUTTER_EXPORT -void clutter_input_device_set_enabled (ClutterInputDevice *device, - gboolean enabled); -CLUTTER_EXPORT -gboolean clutter_input_device_get_enabled (ClutterInputDevice *device); CLUTTER_EXPORT guint clutter_input_device_get_n_axes (ClutterInputDevice *device); diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index 453b1fc945c..af209222d6a 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -1295,7 +1295,6 @@ meta_input_device_native_new (MetaSeatNative *seat, "name", libinput_device_get_name (libinput_device), "device-type", type, "device-mode", CLUTTER_INPUT_MODE_PHYSICAL, - "enabled", TRUE, "vendor-id", vendor, "product-id", product, "n-rings", n_rings, @@ -1355,7 +1354,6 @@ meta_input_device_native_new_virtual (MetaSeatNative *seat, "name", name, "device-type", type, "device-mode", mode, - "enabled", TRUE, "seat", seat, NULL); diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index f50c4fd8b39..59ee0f6f87d 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -474,7 +474,6 @@ create_device (MetaSeatX11 *seat_x11, ClutterInputDeviceType source, touch_source; ClutterInputDevice *retval; ClutterInputMode mode; - gboolean is_enabled; uint32_t num_touches = 0, num_rings = 0, num_strips = 0; char *vendor_id = NULL, *product_id = NULL, *node_path = NULL; @@ -520,19 +519,16 @@ create_device (MetaSeatX11 *seat_x11, case XIMasterKeyboard: case XIMasterPointer: mode = CLUTTER_INPUT_MODE_LOGICAL; - is_enabled = TRUE; break; case XISlaveKeyboard: case XISlavePointer: mode = CLUTTER_INPUT_MODE_PHYSICAL; - is_enabled = FALSE; break; case XIFloatingSlave: default: mode = CLUTTER_INPUT_MODE_FLOATING; - is_enabled = FALSE; break; } @@ -544,10 +540,7 @@ create_device (MetaSeatX11 *seat_x11, } if (source == CLUTTER_PAD_DEVICE) - { - is_enabled = TRUE; - get_pad_features (info, &num_rings, &num_strips); - } + get_pad_features (info, &num_rings, &num_strips); retval = g_object_new (META_TYPE_INPUT_DEVICE_X11, "name", info->name, @@ -556,7 +549,6 @@ create_device (MetaSeatX11 *seat_x11, "device-type", source, "device-mode", mode, "backend", backend, - "enabled", is_enabled, "vendor-id", vendor_id, "product-id", product_id, "device-node", node_path, diff --git a/src/tests/clutter/interactive/test-devices.c b/src/tests/clutter/interactive/test-devices.c index 9a63f731e99..e5b894b871c 100644 --- a/src/tests/clutter/interactive/test-devices.c +++ b/src/tests/clutter/interactive/test-devices.c @@ -171,8 +171,6 @@ seat_device_added_cb (ClutterSeat *seat, g_print ("*** enabling device '%s' ***\n", clutter_input_device_get_device_name (device)); - clutter_input_device_set_enabled (device, TRUE); - hand = clutter_test_utils_create_texture_from_file (TESTS_DATADIR G_DIR_SEPARATOR_S "redhand.png", @@ -268,8 +266,6 @@ test_devices_main (int argc, char **argv) g_print ("*** enabling device '%s' ***\n", clutter_input_device_get_device_name (device)); - clutter_input_device_set_enabled (device, TRUE); - hand = clutter_test_utils_create_texture_from_file (TESTS_DATADIR G_DIR_SEPARATOR_S "redhand.png", -- GitLab From 0c1d48bd08be2102ea3b6f4949ebf33c5d781caf Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 16 Jul 2020 13:52:39 +0200 Subject: [PATCH 30/85] backends: Add simple object to delegate logical monitor layout queries This object can be passed to random places, and be trusted to remain unchanged till replaced. Makes it an ideal replacement for MetaMonitorManager across threads. Part-of: --- src/backends/meta-monitor-manager-private.h | 3 + src/backends/meta-monitor-manager.c | 34 ++++ src/backends/meta-viewport-info.c | 189 ++++++++++++++++++++ src/backends/meta-viewport-info.h | 54 ++++++ src/meson.build | 2 + 5 files changed, 282 insertions(+) create mode 100644 src/backends/meta-viewport-info.c create mode 100644 src/backends/meta-viewport-info.h diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h index b9c68aad473..eaad2c4ce79 100644 --- a/src/backends/meta-monitor-manager-private.h +++ b/src/backends/meta-monitor-manager-private.h @@ -31,6 +31,7 @@ #include "backends/meta-cursor.h" #include "backends/meta-display-config-shared.h" #include "backends/meta-monitor-transform.h" +#include "backends/meta-viewport-info.h" #include "core/util-private.h" #include "meta/display.h" #include "meta/meta-monitor-manager.h" @@ -404,4 +405,6 @@ meta_find_output_assignment (MetaOutputAssignment **outputs, void meta_monitor_manager_post_init (MetaMonitorManager *manager); +MetaViewportInfo * meta_monitor_manager_get_viewports (MetaMonitorManager *manager); + #endif /* META_MONITOR_MANAGER_PRIVATE_H */ diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 4488ab32ac8..dbf799975f3 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -3250,3 +3250,37 @@ meta_monitor_manager_post_init (MetaMonitorManager *manager) G_CALLBACK (update_panel_orientation_managed), manager, G_CONNECT_SWAPPED); } + +MetaViewportInfo * +meta_monitor_manager_get_viewports (MetaMonitorManager *manager) +{ + MetaViewportInfo *info; + GArray *views, *scales; + GList *logical_monitors, *l; + + views = g_array_new (FALSE, FALSE, sizeof (cairo_rectangle_int_t)); + scales = g_array_new (FALSE, FALSE, sizeof (float)); + + logical_monitors = meta_monitor_manager_get_logical_monitors (manager); + + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + cairo_rectangle_int_t rect; + float scale; + + rect = logical_monitor->rect; + g_array_append_val (views, rect); + + scale = logical_monitor->scale; + g_array_append_val (scales, scale); + } + + info = meta_viewport_info_new ((cairo_rectangle_int_t *) views->data, + (float *) scales->data, + views->len); + g_array_unref (views); + g_array_unref (scales); + + return info; +} diff --git a/src/backends/meta-viewport-info.c b/src/backends/meta-viewport-info.c new file mode 100644 index 00000000000..922475c994b --- /dev/null +++ b/src/backends/meta-viewport-info.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2020 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Carlos Garnacho + */ + +#include "config.h" + +#include "backends/meta-viewport-info.h" +#include "core/main-private.h" +#include "core/boxes-private.h" + +typedef struct _ViewInfo ViewInfo; + +struct _ViewInfo +{ + MetaRectangle rect; + float scale; +}; + +struct _MetaViewportInfo +{ + GObject parent; + GArray *views; +}; + +G_DEFINE_TYPE (MetaViewportInfo, meta_viewport_info, G_TYPE_OBJECT) + +static void +meta_viewport_info_finalize (GObject *object) +{ + MetaViewportInfo *info = META_VIEWPORT_INFO (object); + + g_array_unref (info->views); + + G_OBJECT_CLASS (meta_viewport_info_parent_class)->finalize (object); +} + +static void +meta_viewport_info_class_init (MetaViewportInfoClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_viewport_info_finalize; +} + +static void +meta_viewport_info_init (MetaViewportInfo *info) +{ + info->views = g_array_new (FALSE, FALSE, sizeof (ViewInfo)); +} + +MetaViewportInfo * +meta_viewport_info_new (cairo_rectangle_int_t *views, + float *scales, + int n_views) +{ + MetaViewportInfo *viewport_info; + int i; + + viewport_info = g_object_new (META_TYPE_VIEWPORT_INFO, NULL); + + for (i = 0; i < n_views; i++) + { + ViewInfo info; + + info.rect = views[i]; + info.scale = scales[i]; + g_array_append_val (viewport_info->views, info); + } + + return viewport_info; +} + +int +meta_viewport_info_get_view_at (MetaViewportInfo *viewport_info, + float x, + float y) +{ + int i; + + for (i = 0; i < viewport_info->views->len; i++) + { + ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i); + + if (META_POINT_IN_RECT (x, y, info->rect)) + return i; + } + + return -1; +} + +gboolean +meta_viewport_info_get_view_info (MetaViewportInfo *viewport_info, + int idx, + cairo_rectangle_int_t *rect, + float *scale) +{ + ViewInfo *info; + + if (idx < 0 || idx >= viewport_info->views->len) + return FALSE; + + info = &g_array_index (viewport_info->views, ViewInfo, idx); + if (rect) + *rect = info->rect; + if (scale) + *scale = info->scale; + + return TRUE; +} + +static gboolean +view_has_neighbor (cairo_rectangle_int_t *view, + cairo_rectangle_int_t *neighbor, + MetaDisplayDirection neighbor_direction) +{ + switch (neighbor_direction) + { + case META_DISPLAY_RIGHT: + if (neighbor->x == (view->x + view->width) && + meta_rectangle_vert_overlap (neighbor, view)) + return TRUE; + break; + case META_DISPLAY_LEFT: + if (view->x == (neighbor->x + neighbor->width) && + meta_rectangle_vert_overlap (neighbor, view)) + return TRUE; + break; + case META_DISPLAY_UP: + if (view->y == (neighbor->y + neighbor->height) && + meta_rectangle_horiz_overlap (neighbor, view)) + return TRUE; + break; + case META_DISPLAY_DOWN: + if (neighbor->y == (view->y + view->height) && + meta_rectangle_horiz_overlap (neighbor, view)) + return TRUE; + break; + } + + return FALSE; +} + +int +meta_viewport_info_get_neighbor (MetaViewportInfo *viewport_info, + int idx, + MetaDisplayDirection direction) +{ + cairo_rectangle_int_t rect; + int i; + + if (!meta_viewport_info_get_view_info (viewport_info, idx, &rect, NULL)) + return -1; + + for (i = 0; i < viewport_info->views->len; i++) + { + ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i); + + if (idx == i) + continue; + if (view_has_neighbor (&rect, &info->rect, direction)) + return i; + } + + return -1; +} + +int +meta_viewport_info_get_num_views (MetaViewportInfo *info) +{ + return info->views->len; +} diff --git a/src/backends/meta-viewport-info.h b/src/backends/meta-viewport-info.h new file mode 100644 index 00000000000..0701c432aa1 --- /dev/null +++ b/src/backends/meta-viewport-info.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Carlos Garnacho + */ + +#ifndef META_VIEWPORT_INFO_H +#define META_VIEWPORT_INFO_H + +#include +#include + +#include "meta/display.h" + +#define META_TYPE_VIEWPORT_INFO (meta_viewport_info_get_type ()) +G_DECLARE_FINAL_TYPE (MetaViewportInfo, meta_viewport_info, + META, VIEWPORT_INFO, GObject) + +MetaViewportInfo * meta_viewport_info_new (cairo_rectangle_int_t *views, + float *scales, + int n_views); + +int meta_viewport_info_get_view_at (MetaViewportInfo *info, + float x, + float y); + +gboolean meta_viewport_info_get_view_info (MetaViewportInfo *viewport_info, + int idx, + cairo_rectangle_int_t *rect, + float *scale); + +int meta_viewport_info_get_neighbor (MetaViewportInfo *info, + int idx, + MetaDisplayDirection direction); + +int meta_viewport_info_get_num_views (MetaViewportInfo *info); + +#endif /* META_VIEWPORT_INFO_H */ diff --git a/src/meson.build b/src/meson.build index 51eeef7def5..dd0167cb876 100644 --- a/src/meson.build +++ b/src/meson.build @@ -233,6 +233,8 @@ mutter_sources = [ 'backends/meta-settings-private.h', 'backends/meta-stage.c', 'backends/meta-stage-private.h', + 'backends/meta-viewport-info.c', + 'backends/meta-viewport-info.h', 'backends/x11/cm/meta-backend-x11-cm.c', 'backends/x11/cm/meta-backend-x11-cm.h', 'backends/x11/cm/meta-cursor-sprite-xfixes.c', -- GitLab From 727e64dddffb8f1b4eadc8d91f3a7d4f59f379d0 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 16 Jul 2020 16:41:02 +0200 Subject: [PATCH 31/85] backends: Use MetaViewportInfo to keep MetaSeatNative informed of layout Use this for the calculations to keep absolute motion properly constrained, and relative motion properly scaled. Part-of: --- src/backends/native/meta-backend-native.c | 29 +++++- src/backends/native/meta-seat-native.c | 110 ++++++++++++---------- src/backends/native/meta-seat-native.h | 6 ++ 3 files changed, 91 insertions(+), 54 deletions(-) diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index 5eeb14463d3..8ecc24e2ae3 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -145,6 +145,21 @@ maybe_disable_screen_cast_dma_bufs (MetaBackendNative *native) } #endif /* HAVE_REMOTE_DESKTOP */ +static void +update_viewports (MetaBackend *backend) +{ + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + MetaSeatNative *seat = + META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend)); + MetaViewportInfo *viewports; + + viewports = meta_monitor_manager_get_viewports (monitor_manager); + meta_seat_native_set_viewports (seat, viewports); + g_object_unref (viewports); +} + static void meta_backend_native_post_init (MetaBackend *backend) { @@ -170,6 +185,8 @@ meta_backend_native_post_init (MetaBackend *backend) maybe_disable_screen_cast_dma_bufs (META_BACKEND_NATIVE (backend)); #endif + update_viewports (backend); + #ifdef HAVE_WAYLAND meta_backend_init_wayland (backend); #endif @@ -179,9 +196,15 @@ static MetaMonitorManager * meta_backend_native_create_monitor_manager (MetaBackend *backend, GError **error) { - return g_initable_new (META_TYPE_MONITOR_MANAGER_KMS, NULL, error, - "backend", backend, - NULL); + MetaMonitorManager *manager; + + manager = g_initable_new (META_TYPE_MONITOR_MANAGER_KMS, NULL, error, + "backend", backend, + NULL); + g_signal_connect_swapped (manager, "monitors-changed-internal", + G_CALLBACK (update_viewports), backend); + + return manager; } static MetaCursorRenderer * diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 45da429dcb3..93c15318ffb 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -877,29 +877,31 @@ constrain_to_barriers (MetaSeatNative *seat, static void constrain_all_screen_monitors (ClutterInputDevice *device, - MetaMonitorManager *monitor_manager, + MetaViewportInfo *viewports, float *x, float *y) { float cx, cy; - GList *logical_monitors, *l; + int i, n_views; meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (device), &cx, &cy); /* if we're trying to escape, clamp to the CRTC we're coming from */ - logical_monitors = - meta_monitor_manager_get_logical_monitors (monitor_manager); - for (l = logical_monitors; l; l = l->next) + n_views = meta_viewport_info_get_num_views (viewports); + + for (i = 0; i < n_views; i++) { - MetaLogicalMonitor *logical_monitor = l->data; int left, right, top, bottom; + cairo_rectangle_int_t rect; + + meta_viewport_info_get_view_info (viewports, i, &rect, NULL); - left = logical_monitor->rect.x; - right = left + logical_monitor->rect.width; - top = logical_monitor->rect.y; - bottom = top + logical_monitor->rect.height; + left = rect.x; + right = left + rect.width; + top = rect.y; + bottom = top + rect.height; if ((cx >= left) && (cx < right) && (cy >= top) && (cy < bottom)) { @@ -926,10 +928,6 @@ meta_seat_native_constrain_pointer (MetaSeatNative *seat, float *new_x, float *new_y) { - MetaBackend *backend = meta_get_backend (); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); - constrain_to_barriers (seat, core_pointer, us2ms (time_us), new_x, new_y); @@ -944,53 +942,59 @@ meta_seat_native_constrain_pointer (MetaSeatNative *seat, new_x, new_y); } - /* if we're moving inside a monitor, we're fine */ - if (meta_monitor_manager_get_logical_monitor_at (monitor_manager, - *new_x, *new_y)) - return; + if (seat->viewports) + { + /* if we're moving inside a monitor, we're fine */ + if (meta_viewport_info_get_view_at (seat->viewports, *new_x, *new_y) >= 0) + return; - /* if we're trying to escape, clamp to the CRTC we're coming from */ - constrain_all_screen_monitors (core_pointer, monitor_manager, new_x, new_y); + /* if we're trying to escape, clamp to the CRTC we're coming from */ + constrain_all_screen_monitors (core_pointer, seat->viewports, new_x, new_y); + } } static void -relative_motion_across_outputs (MetaMonitorManager *monitor_manager, - MetaLogicalMonitor *current, +relative_motion_across_outputs (MetaViewportInfo *viewports, + int view, float cur_x, float cur_y, float *dx_inout, float *dy_inout) { - MetaLogicalMonitor *cur = current; + int cur_view = view; float x = cur_x, y = cur_y; float target_x = cur_x, target_y = cur_y; float dx = *dx_inout, dy = *dy_inout; MetaDisplayDirection direction = -1; - while (cur) + while (cur_view >= 0) { MetaLine2 left, right, top, bottom, motion; MetaVector2 intersection; + cairo_rectangle_int_t rect; + float scale; + + meta_viewport_info_get_view_info (viewports, cur_view, &rect, &scale); motion = (MetaLine2) { .a = { x, y }, - .b = { x + (dx * cur->scale), y + (dy * cur->scale) } + .b = { x + (dx * scale), y + (dy * scale) } }; left = (MetaLine2) { - { cur->rect.x, cur->rect.y }, - { cur->rect.x, cur->rect.y + cur->rect.height } + { rect.x, rect.y }, + { rect.x, rect.y + rect.height } }; right = (MetaLine2) { - { cur->rect.x + cur->rect.width, cur->rect.y }, - { cur->rect.x + cur->rect.width, cur->rect.y + cur->rect.height } + { rect.x + rect.width, rect.y }, + { rect.x + rect.width, rect.y + rect.height } }; top = (MetaLine2) { - { cur->rect.x, cur->rect.y }, - { cur->rect.x + cur->rect.width, cur->rect.y } + { rect.x, rect.y }, + { rect.x + rect.width, rect.y } }; bottom = (MetaLine2) { - { cur->rect.x, cur->rect.y + cur->rect.height }, - { cur->rect.x + cur->rect.width, cur->rect.y + cur->rect.height } + { rect.x, rect.y + rect.height }, + { rect.x + rect.width, rect.y + rect.height } }; target_x = motion.b.x; @@ -1017,8 +1021,8 @@ relative_motion_across_outputs (MetaMonitorManager *monitor_manager, dx -= intersection.x - motion.a.x; dy -= intersection.y - motion.a.y; - cur = meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager, - cur, direction); + cur_view = meta_viewport_info_get_neighbor (viewports, cur_view, + direction); } *dx_inout = target_x - cur_x; @@ -1033,35 +1037,32 @@ meta_seat_native_filter_relative_motion (MetaSeatNative *seat, float *dx, float *dy) { - MetaBackend *backend = meta_get_backend (); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); - MetaLogicalMonitor *logical_monitor, *dest_logical_monitor; - float new_dx, new_dy; + int view = -1, dest_view; + float new_dx, new_dy, scale; if (meta_is_stage_views_scaled ()) return; - logical_monitor = meta_monitor_manager_get_logical_monitor_at (monitor_manager, - x, y); - if (!logical_monitor) + if (seat->viewports) + view = meta_viewport_info_get_view_at (seat->viewports, x, y); + if (view < 0) return; - new_dx = (*dx) * logical_monitor->scale; - new_dy = (*dy) * logical_monitor->scale; + meta_viewport_info_get_view_info (seat->viewports, view, NULL, &scale); + new_dx = (*dx) * scale; + new_dy = (*dy) * scale; - dest_logical_monitor = meta_monitor_manager_get_logical_monitor_at (monitor_manager, - x + new_dx, - y + new_dy); - if (dest_logical_monitor && - dest_logical_monitor != logical_monitor) + dest_view = meta_viewport_info_get_view_at (seat->viewports, + x + new_dx, + y + new_dy); + if (dest_view >= 0 && dest_view != view) { /* If we are crossing monitors, attempt to bisect the distance on each * axis and apply the relative scale for each of them. */ new_dx = *dx; new_dy = *dy; - relative_motion_across_outputs (monitor_manager, logical_monitor, + relative_motion_across_outputs (seat->viewports, view, x, y, &new_dx, &new_dy); } @@ -3350,3 +3351,10 @@ meta_seat_native_maybe_ensure_cursor_renderer (MetaSeatNative *seat_native, return NULL; } + +void +meta_seat_native_set_viewports (MetaSeatNative *seat, + MetaViewportInfo *viewports) +{ + g_set_object (&seat->viewports, viewports); +} diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h index 5fa0964b059..08095b24010 100644 --- a/src/backends/native/meta-seat-native.h +++ b/src/backends/native/meta-seat-native.h @@ -27,6 +27,7 @@ #include #include +#include "backends/meta-viewport-info.h" #include "backends/native/meta-barrier-native.h" #include "backends/native/meta-cursor-renderer-native.h" #include "backends/native/meta-keymap-native.h" @@ -89,6 +90,8 @@ struct _MetaSeatNative MetaCursorRenderer *cursor_renderer; GHashTable *tablet_cursors; + MetaViewportInfo *viewports; + GUdevClient *udev_client; guint tablet_mode_switch_state : 1; guint has_touchscreen : 1; @@ -264,4 +267,7 @@ void meta_seat_native_set_pointer_constraint (MetaSeatNative *seat, MetaCursorRenderer * meta_seat_native_maybe_ensure_cursor_renderer (MetaSeatNative *seat, ClutterInputDevice *device); +void meta_seat_native_set_viewports (MetaSeatNative *seat, + MetaViewportInfo *viewports); + #endif /* META_SEAT_NATIVE_H */ -- GitLab From 165b7369c88644867a7c0c2791c48826240b63b5 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 31 Jul 2020 18:35:19 +0200 Subject: [PATCH 32/85] backends: Use also a native cursor renderer for tablets This will resort to SW rendering if this cursor renderer does not own the MetaKmsCursorRenderer, so it's pretty much equivalent thus far, except we may now implement logic to flip the kms cursor renderer around. Part-of: --- src/backends/native/meta-seat-native.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 93c15318ffb..33412de5f27 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -1858,7 +1858,7 @@ update_tablet_cursor_state (MetaSeatNative *seat_native, { if (in) { - MetaCursorRenderer *cursor_renderer; + MetaCursorRendererNative *cursor_renderer_native; if (!seat_native->tablet_cursors) { @@ -1866,9 +1866,10 @@ update_tablet_cursor_state (MetaSeatNative *seat_native, g_object_unref); } - cursor_renderer = meta_cursor_renderer_new (meta_get_backend (), device); + cursor_renderer_native = + meta_cursor_renderer_native_new (meta_get_backend (), device); g_hash_table_insert (seat_native->tablet_cursors, - device, cursor_renderer); + device, cursor_renderer_native); } else { -- GitLab From 1377c2a97e82af8f2bbc08130c34f29b0564979b Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 31 Jul 2020 19:10:53 +0200 Subject: [PATCH 33/85] backends: Add method to get extents from viewport info This way we know the stage extents without poking the stage. Part-of: --- src/backends/meta-viewport-info.c | 25 +++++++++++++++++++++++++ src/backends/meta-viewport-info.h | 4 ++++ 2 files changed, 29 insertions(+) diff --git a/src/backends/meta-viewport-info.c b/src/backends/meta-viewport-info.c index 922475c994b..c8474f3fad1 100644 --- a/src/backends/meta-viewport-info.c +++ b/src/backends/meta-viewport-info.c @@ -187,3 +187,28 @@ meta_viewport_info_get_num_views (MetaViewportInfo *info) { return info->views->len; } + +void +meta_viewport_info_get_extents (MetaViewportInfo *viewport_info, + float *width, + float *height) +{ + int min_x = G_MAXINT, min_y = G_MAXINT, max_x = G_MININT, max_y = G_MININT, i; + + g_return_if_fail (viewport_info != NULL); + + for (i = 0; i < viewport_info->views->len; i++) + { + ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i); + + min_x = MIN (min_x, info->rect.x); + max_x = MAX (max_x, info->rect.x + info->rect.width); + min_y = MIN (min_y, info->rect.y); + max_y = MAX (max_y, info->rect.y + info->rect.height); + } + + if (width) + *width = (float) max_x - min_x; + if (height) + *height = (float) max_y - min_y; +} diff --git a/src/backends/meta-viewport-info.h b/src/backends/meta-viewport-info.h index 0701c432aa1..ea9b8af80ce 100644 --- a/src/backends/meta-viewport-info.h +++ b/src/backends/meta-viewport-info.h @@ -51,4 +51,8 @@ int meta_viewport_info_get_neighbor (MetaViewportInfo *info, int meta_viewport_info_get_num_views (MetaViewportInfo *info); +void meta_viewport_info_get_extents (MetaViewportInfo *info, + float *width, + float *height); + #endif /* META_VIEWPORT_INFO_H */ -- GitLab From c362bc4b514940c5dcad846d504909df7ca9a170 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 31 Jul 2020 19:11:32 +0200 Subject: [PATCH 34/85] backends/native: Use viewport info to find out stage extents This information is equivalent to the stage extents, this just leaves meta_seat_native_get_stage() used for setting event->any.stage, which is a tiny lame excuse. Part-of: --- .../native/meta-input-device-native.c | 7 ++-- .../native/meta-input-device-native.h | 2 +- src/backends/native/meta-seat-native.c | 39 +++++++++---------- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index af209222d6a..8d4b835deae 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -1425,17 +1425,16 @@ meta_input_device_native_get_libinput_device (ClutterInputDevice *device) void meta_input_device_native_translate_coordinates (ClutterInputDevice *device, - ClutterStage *stage, + MetaViewportInfo *viewports, float *x, float *y) { MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device); double min_x = 0, min_y = 0, max_x = 1, max_y = 1; - double stage_width, stage_height; + float stage_width, stage_height; double x_d, y_d; - stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); - stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); + meta_viewport_info_get_extents (viewports, &stage_width, &stage_height); x_d = *x / stage_width; y_d = *y / stage_height; diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h index 645d3ca749d..da23b1778cc 100644 --- a/src/backends/native/meta-input-device-native.h +++ b/src/backends/native/meta-input-device-native.h @@ -126,7 +126,7 @@ ClutterInputDeviceType meta_input_device_native_determine_type (struct libin void meta_input_device_native_translate_coordinates (ClutterInputDevice *device, - ClutterStage *stage, + MetaViewportInfo *viewports, float *x, float *y); diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 33412de5f27..cf6da1f37e4 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -391,7 +391,6 @@ new_absolute_motion_event (MetaSeatNative *seat, float y, double *axes) { - ClutterStage *stage = meta_seat_native_get_stage (seat); ClutterEvent *event; event = clutter_event_new (CLUTTER_MOTION); @@ -411,9 +410,16 @@ new_absolute_motion_event (MetaSeatNative *seat, meta_xkb_translate_state (event, seat->xkb, seat->button_state); event->motion.x = x; event->motion.y = y; - meta_input_device_native_translate_coordinates (input_device, stage, - &event->motion.x, - &event->motion.y); + + /* This may happen early at startup */ + if (seat->viewports) + { + meta_input_device_native_translate_coordinates (input_device, + seat->viewports, + &event->motion.x, + &event->motion.y); + } + event->motion.axes = axes; clutter_event_set_device (event, seat->core_pointer); clutter_event_set_source_device (event, input_device); @@ -798,7 +804,6 @@ meta_seat_native_notify_touch_event (MetaSeatNative *seat, double x, double y) { - ClutterStage *stage = meta_seat_native_get_stage (seat); ClutterEvent *event = NULL; event = clutter_event_new (evtype); @@ -807,7 +812,8 @@ meta_seat_native_notify_touch_event (MetaSeatNative *seat, event->touch.time = us2ms (time_us); event->touch.x = x; event->touch.y = y; - meta_input_device_native_translate_coordinates (input_device, stage, + meta_input_device_native_translate_coordinates (input_device, + seat->viewports, &event->touch.x, &event->touch.y); @@ -1813,7 +1819,6 @@ process_tablet_axis (MetaSeatNative *seat, struct libinput_event *event) { struct libinput_device *libinput_device = libinput_event_get_device (event); - ClutterStage *stage = meta_seat_native_get_stage (seat); uint64_t time; double x, y, dx, dy, *axes; float stage_width, stage_height; @@ -1830,8 +1835,7 @@ process_tablet_axis (MetaSeatNative *seat, if (!axes) return; - stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); - stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); + meta_viewport_info_get_extents (seat->viewports, &stage_width, &stage_height); time = libinput_event_tablet_tool_get_time_usec (tablet_event); @@ -1956,13 +1960,12 @@ process_device_event (MetaSeatNative *seat, uint64_t time_us; double x, y; float stage_width, stage_height; - ClutterStage *stage = meta_seat_native_get_stage (seat); struct libinput_event_pointer *motion_event = libinput_event_get_pointer_event (event); device = libinput_device_get_user_data (libinput_device); - stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); - stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); + meta_viewport_info_get_extents (seat->viewports, + &stage_width, &stage_height); time_us = libinput_event_pointer_get_time_usec (motion_event); x = libinput_event_pointer_get_absolute_x_transformed (motion_event, @@ -2057,7 +2060,6 @@ process_device_event (MetaSeatNative *seat, double x, y; float stage_width, stage_height; MetaSeatNative *seat; - ClutterStage *stage; MetaTouchState *touch_state; struct libinput_event_touch *touch_event = libinput_event_get_touch_event (event); @@ -2065,10 +2067,9 @@ process_device_event (MetaSeatNative *seat, device = libinput_device_get_user_data (libinput_device); device_evdev = META_INPUT_DEVICE_NATIVE (device); seat = meta_input_device_native_get_seat (device_evdev); - stage = meta_seat_native_get_stage (seat); - stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); - stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); + meta_viewport_info_get_extents (seat->viewports, + &stage_width, &stage_height); seat_slot = libinput_event_touch_get_seat_slot (touch_event); time_us = libinput_event_touch_get_time_usec (touch_event); @@ -2125,7 +2126,6 @@ process_device_event (MetaSeatNative *seat, double x, y; float stage_width, stage_height; MetaSeatNative *seat; - ClutterStage *stage; MetaTouchState *touch_state; struct libinput_event_touch *touch_event = libinput_event_get_touch_event (event); @@ -2133,10 +2133,9 @@ process_device_event (MetaSeatNative *seat, device = libinput_device_get_user_data (libinput_device); device_evdev = META_INPUT_DEVICE_NATIVE (device); seat = meta_input_device_native_get_seat (device_evdev); - stage = meta_seat_native_get_stage (seat); - stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); - stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); + meta_viewport_info_get_extents (seat->viewports, + &stage_width, &stage_height); seat_slot = libinput_event_touch_get_seat_slot (touch_event); time_us = libinput_event_touch_get_time_usec (touch_event); -- GitLab From 05edf4815b604216bfafdb0bacce5a1ceeb3c1e4 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 31 Jul 2020 20:15:44 +0200 Subject: [PATCH 35/85] backends/native: Drop early processing of ClutterEvents We have 2 sources (this one in MetaSeatNative, and the one in MetaBackend) dispatching ClutterEvents to the stage. Make the MetaSeatNative one exclusively about dispatching the libinput queue, and leave ClutterEvents to the other. Part-of: --- src/backends/native/meta-seat-native.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index cf6da1f37e4..5bf93ea5a0d 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -1347,13 +1347,6 @@ meta_event_dispatch (GSource *g_source, dispatch_libinput (seat); queue_event: - event = clutter_event_get (); - - if (event) - { - /* forward the event into clutter for emission etc. */ - _clutter_stage_queue_event (event->any.stage, event, FALSE); - } return TRUE; } -- GitLab From 0cb0dd3538c925ce28c9d3eec92beffd0be59967 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 31 Jul 2020 20:17:31 +0200 Subject: [PATCH 36/85] backends: Assign stage to events in MetaBackend Don't do this in the MetaSeatNative, this should be detached from the stage. Part-of: --- src/backends/meta-backend.c | 16 +++++++++++++++- src/backends/native/meta-seat-native.c | 11 ----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 124ea74c09c..ddcf29aafe6 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -174,6 +174,14 @@ struct _MetaBackendPrivate }; typedef struct _MetaBackendPrivate MetaBackendPrivate; +typedef struct _MetaBackendSource MetaBackendSource; + +struct _MetaBackendSource +{ + GSource parent; + MetaBackend *backend; +}; + static void initable_iface_init (GInitableIface *initable_iface); @@ -926,10 +934,13 @@ clutter_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) { + MetaBackendSource *backend_source = (MetaBackendSource *) source; ClutterEvent *event = clutter_event_get (); if (event) { + event->any.stage = + CLUTTER_STAGE (meta_backend_get_stage (backend_source->backend)); clutter_do_event (event); clutter_event_free (event); } @@ -955,6 +966,7 @@ static gboolean init_clutter (MetaBackend *backend, GError **error) { + MetaBackendSource *backend_source; GSource *source; clutter_set_custom_backend_func (meta_get_clutter_backend); @@ -966,7 +978,9 @@ init_clutter (MetaBackend *backend, return FALSE; } - source = g_source_new (&clutter_source_funcs, sizeof (GSource)); + source = g_source_new (&clutter_source_funcs, sizeof (MetaBackendSource)); + backend_source = (MetaBackendSource *) source; + backend_source->backend = backend; g_source_attach (source, NULL); g_source_unref (source); diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 5bf93ea5a0d..9fd88c92d10 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -248,16 +248,6 @@ static void queue_event (MetaSeatNative *seat, ClutterEvent *event) { - ClutterStage *stage = meta_seat_native_get_stage (seat); - - if (!stage) - { - /* No stage yet, drop this event on the floor */ - clutter_event_free (event); - return; - } - - event->any.stage = stage; _clutter_event_push (event, FALSE); } @@ -1335,7 +1325,6 @@ meta_event_dispatch (GSource *g_source, { MetaEventSource *source = (MetaEventSource *) g_source; MetaSeatNative *seat; - ClutterEvent *event; seat = source->seat; -- GitLab From 1dc534ea9e0a911c540bde60ba6ae9e4b59db112 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 31 Jul 2020 20:20:43 +0200 Subject: [PATCH 37/85] backends/native: Drop meta_seat_native_[gs]et_stage() This is now unused. Part-of: --- src/backends/native/meta-seat-native.c | 111 +------------------------ src/backends/native/meta-seat-native.h | 9 -- 2 files changed, 4 insertions(+), 116 deletions(-) diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 9fd88c92d10..967113d2c9f 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -1542,34 +1542,22 @@ process_base_event (MetaSeatNative *seat, ClutterInputDevice *device = NULL; ClutterEvent *device_event = NULL; struct libinput_device *libinput_device; - ClutterStage *stage; - - stage = meta_seat_native_get_stage (seat); switch (libinput_event_get_type (event)) { case LIBINPUT_EVENT_DEVICE_ADDED: libinput_device = libinput_event_get_device (event); device = evdev_add_device (seat, libinput_device); - - if (stage) - { - device_event = clutter_event_new (CLUTTER_DEVICE_ADDED); - clutter_event_set_device (device_event, device); - } + device_event = clutter_event_new (CLUTTER_DEVICE_ADDED); + clutter_event_set_device (device_event, device); break; case LIBINPUT_EVENT_DEVICE_REMOVED: libinput_device = libinput_event_get_device (event); device = libinput_device_get_user_data (libinput_device); - - if (stage) - { - device_event = clutter_event_new (CLUTTER_DEVICE_REMOVED); - clutter_event_set_device (device_event, device); - } - + device_event = clutter_event_new (CLUTTER_DEVICE_REMOVED); + clutter_event_set_device (device_event, device); evdev_remove_device (seat, META_INPUT_DEVICE_NATIVE (device)); break; @@ -2606,15 +2594,6 @@ meta_seat_native_dispose (GObject *object) { MetaSeatNative *seat = META_SEAT_NATIVE (object); - g_clear_signal_handler (&seat->stage_added_handler, seat->stage_manager); - g_clear_signal_handler (&seat->stage_removed_handler, seat->stage_manager); - - if (seat->stage_manager) - { - g_object_unref (seat->stage_manager); - seat->stage_manager = NULL; - } - if (seat->libinput) { libinput_unref (seat->libinput); @@ -2923,58 +2902,9 @@ meta_seat_native_class_init (MetaSeatNativeClass *klass) "touch-mode"); } -static void -meta_seat_native_stage_added_cb (ClutterStageManager *manager, - ClutterStage *stage, - MetaSeatNative *seat) -{ - /* NB: Currently we can only associate a single stage with all evdev - * devices. - * - * We save a pointer to the stage so if we release/reclaim input - * devices due to switching virtual terminals then we know what - * stage to re associate the devices with. - */ - meta_seat_native_set_stage (seat, stage); - - /* We only want to do this once so we can catch the default - stage. If the application has multiple stages then it will need - to manage the stage of the input devices itself */ - g_clear_signal_handler (&seat->stage_added_handler, seat->stage_manager); -} - -static void -meta_seat_native_stage_removed_cb (ClutterStageManager *manager, - ClutterStage *stage, - MetaSeatNative *seat) -{ - meta_seat_native_set_stage (seat, NULL); -} - static void meta_seat_native_init (MetaSeatNative *seat) { - seat->stage_manager = clutter_stage_manager_get_default (); - g_object_ref (seat->stage_manager); - - /* evdev doesn't have any way to link an event to a particular stage - so we'll have to leave it up to applications to set the - corresponding stage for an input device. However to make it - easier for applications that are only using one fullscreen stage - (which is probably the most frequent use-case for the evdev - backend) we'll associate any input devices that don't have a - stage with the first stage created. */ - seat->stage_added_handler = - g_signal_connect (seat->stage_manager, - "stage-added", - G_CALLBACK (meta_seat_native_stage_added_cb), - seat); - seat->stage_removed_handler = - g_signal_connect (seat->stage_manager, - "stage-removed", - G_CALLBACK (meta_seat_native_stage_removed_cb), - seat); - seat->device_id_next = INITIAL_DEVICE_ID; seat->repeat = TRUE; @@ -2986,39 +2916,6 @@ meta_seat_native_init (MetaSeatNative *seat) seat->reserved_virtual_slots = g_hash_table_new (NULL, NULL); } -void -meta_seat_native_set_stage (MetaSeatNative *seat, - ClutterStage *stage) -{ - GSList *l; - - if (seat->stage == stage) - return; - - seat->stage = stage; - - for (l = seat->devices; l; l = l->next) - { - ClutterInputDevice *device = l->data; - - if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_PHYSICAL) - { - ClutterEvent *device_event; - - device_event = clutter_event_new (CLUTTER_DEVICE_ADDED); - clutter_event_set_device (device_event, device); - device_event->device.stage = stage; - queue_event (seat, device_event); - } - } -} - -ClutterStage * -meta_seat_native_get_stage (MetaSeatNative *seat) -{ - return seat->stage; -} - /** * meta_seat_native_set_device_callbacks: (skip) * @open_callback: the user replacement for open() diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h index 08095b24010..1f64b60a813 100644 --- a/src/backends/native/meta-seat-native.h +++ b/src/backends/native/meta-seat-native.h @@ -75,11 +75,6 @@ struct _MetaSeatNative uint32_t button_state; int button_count[KEY_CNT]; - ClutterStage *stage; - ClutterStageManager *stage_manager; - gulong stage_added_handler; - gulong stage_removed_handler; - int device_id_next; GList *free_device_ids; @@ -185,10 +180,6 @@ MetaTouchState * meta_seat_native_lookup_touch_state (MetaSeatNative *seat, void meta_seat_native_release_touch_state (MetaSeatNative *seat, int seat_slot); -void meta_seat_native_set_stage (MetaSeatNative *seat, - ClutterStage *stage); -ClutterStage * meta_seat_native_get_stage (MetaSeatNative *seat); - void meta_seat_native_clear_repeat_timer (MetaSeatNative *seat); gint meta_seat_native_acquire_device_id (MetaSeatNative *seat); -- GitLab From b56d31ef4857ff803e92b08cfc0cbb047c306727 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 3 Aug 2020 18:31:19 +0200 Subject: [PATCH 38/85] backends: Simplify MetaInputSettings vfunc Rename the set_tablet_keep_aspect() vfunc into a set_tablet_aspect_ratio() one that takes an aspect ratio double, instead of leaking monitor info into subclasses to let them all figure out this number themselves. Part-of: --- src/backends/meta-input-settings-private.h | 5 +-- src/backends/meta-input-settings.c | 31 ++++++++++++++- .../native/meta-input-settings-native.c | 38 +++---------------- src/backends/x11/meta-input-settings-x11.c | 33 ++++------------ 4 files changed, 43 insertions(+), 64 deletions(-) diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h index 79bac8e07ab..3d35e5d0650 100644 --- a/src/backends/meta-input-settings-private.h +++ b/src/backends/meta-input-settings-private.h @@ -93,10 +93,9 @@ struct _MetaInputSettingsClass void (* set_tablet_mapping) (MetaInputSettings *settings, ClutterInputDevice *device, GDesktopTabletMapping mapping); - void (* set_tablet_keep_aspect) (MetaInputSettings *settings, + void (* set_tablet_aspect_ratio) (MetaInputSettings *settings, ClutterInputDevice *device, - MetaLogicalMonitor *logical_monitor, - gboolean keep_aspect); + double ratio); void (* set_tablet_area) (MetaInputSettings *settings, ClutterInputDevice *device, gdouble padding_left, diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 846c58a0389..96c50afeca2 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -1012,6 +1012,7 @@ update_tablet_keep_aspect (MetaInputSettings *input_settings, MetaInputSettingsClass *input_settings_class; MetaLogicalMonitor *logical_monitor = NULL; gboolean keep_aspect; + double aspect_ratio; if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE && clutter_input_device_get_device_type (device) != CLUTTER_PEN_DEVICE && @@ -1037,8 +1038,34 @@ update_tablet_keep_aspect (MetaInputSettings *input_settings, meta_input_settings_find_monitor (input_settings, settings, device, NULL, &logical_monitor); - input_settings_class->set_tablet_keep_aspect (input_settings, device, - logical_monitor, keep_aspect); + if (keep_aspect) + { + int width, height; + + if (logical_monitor) + { + width = logical_monitor->rect.width; + height = logical_monitor->rect.height; + } + else + { + MetaMonitorManager *monitor_manager; + MetaBackend *backend; + + backend = meta_get_backend (); + monitor_manager = meta_backend_get_monitor_manager (backend); + meta_monitor_manager_get_screen_size (monitor_manager, + &width, &height); + } + + aspect_ratio = (double) width / height; + } + else + { + aspect_ratio = 0; + } + + input_settings_class->set_tablet_aspect_ratio (input_settings, device, aspect_ratio); } static void diff --git a/src/backends/native/meta-input-settings-native.c b/src/backends/native/meta-input-settings-native.c index 7129eb6560b..fc435942954 100644 --- a/src/backends/native/meta-input-settings-native.c +++ b/src/backends/native/meta-input-settings-native.c @@ -26,7 +26,6 @@ #include #include -#include "backends/meta-logical-monitor.h" #include "backends/native/meta-backend-native.h" #include "backends/native/meta-input-device-native.h" #include "backends/native/meta-input-device-tool-native.h" @@ -549,40 +548,13 @@ meta_input_settings_native_set_tablet_mapping (MetaInputSettings *settings, } static void -meta_input_settings_native_set_tablet_keep_aspect (MetaInputSettings *settings, - ClutterInputDevice *device, - MetaLogicalMonitor *logical_monitor, - gboolean keep_aspect) +meta_input_settings_native_set_tablet_aspect_ratio (MetaInputSettings *settings, + ClutterInputDevice *device, + gdouble aspect_ratio) { - double aspect_ratio = 0; - if (meta_input_device_native_get_mapping_mode (device) == META_INPUT_DEVICE_MAPPING_RELATIVE) - keep_aspect = FALSE; - - if (keep_aspect) - { - int width, height; - - if (logical_monitor) - { - width = logical_monitor->rect.width; - height = logical_monitor->rect.height; - } - else - { - MetaMonitorManager *monitor_manager; - MetaBackend *backend; - - backend = meta_get_backend (); - monitor_manager = meta_backend_get_monitor_manager (backend); - meta_monitor_manager_get_screen_size (monitor_manager, - &width, - &height); - } - - aspect_ratio = (double) width / height; - } + aspect_ratio = 0; g_object_set (device, "output-aspect-ratio", aspect_ratio, NULL); } @@ -745,7 +717,7 @@ meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass) input_settings_class->set_disable_while_typing = meta_input_settings_native_set_disable_while_typing; input_settings_class->set_tablet_mapping = meta_input_settings_native_set_tablet_mapping; - input_settings_class->set_tablet_keep_aspect = meta_input_settings_native_set_tablet_keep_aspect; + input_settings_class->set_tablet_aspect_ratio = meta_input_settings_native_set_tablet_aspect_ratio; input_settings_class->set_tablet_area = meta_input_settings_native_set_tablet_area; input_settings_class->set_mouse_accel_profile = meta_input_settings_native_set_mouse_accel_profile; diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c index 36ae21e9fed..a8b366315d3 100644 --- a/src/backends/x11/meta-input-settings-x11.c +++ b/src/backends/x11/meta-input-settings-x11.c @@ -35,7 +35,6 @@ #include #endif -#include "backends/meta-logical-monitor.h" #include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-input-device-x11.h" #include "core/display-private.h" @@ -735,37 +734,19 @@ meta_input_settings_x11_set_tablet_area (MetaInputSettings *settings, } static void -meta_input_settings_x11_set_tablet_keep_aspect (MetaInputSettings *settings, - ClutterInputDevice *device, - MetaLogicalMonitor *logical_monitor, - gboolean keep_aspect) +meta_input_settings_x11_set_tablet_aspect_ratio (MetaInputSettings *settings, + ClutterInputDevice *device, + gdouble aspect_ratio) { - gint32 width, height, dev_x, dev_y, dev_width, dev_height, area[4] = { 0 }; + int32_t dev_x, dev_y, dev_width, dev_height, area[4] = { 0 }; if (!device_query_area (device, &dev_x, &dev_y, &dev_width, &dev_height)) return; - if (keep_aspect) + if (aspect_ratio > 0) { - double aspect_ratio, dev_aspect; + double dev_aspect; - if (logical_monitor) - { - width = logical_monitor->rect.width; - height = logical_monitor->rect.height; - } - else - { - MetaMonitorManager *monitor_manager; - MetaBackend *backend; - - backend = meta_get_backend (); - monitor_manager = meta_backend_get_monitor_manager (backend); - meta_monitor_manager_get_screen_size (monitor_manager, - &width, &height); - } - - aspect_ratio = (double) width / height; dev_aspect = (double) dev_width / dev_height; if (dev_aspect > aspect_ratio) @@ -937,7 +918,7 @@ meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass) input_settings_class->set_keyboard_repeat = meta_input_settings_x11_set_keyboard_repeat; input_settings_class->set_tablet_mapping = meta_input_settings_x11_set_tablet_mapping; - input_settings_class->set_tablet_keep_aspect = meta_input_settings_x11_set_tablet_keep_aspect; + input_settings_class->set_tablet_aspect_ratio = meta_input_settings_x11_set_tablet_aspect_ratio; input_settings_class->set_tablet_area = meta_input_settings_x11_set_tablet_area; input_settings_class->set_mouse_accel_profile = meta_input_settings_x11_set_mouse_accel_profile; -- GitLab From 9a21482fef8a1040a333fcaba5d2835fff6704b7 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 4 Aug 2020 13:33:37 +0200 Subject: [PATCH 39/85] backends: Move all output management to MetaInputMapper Delegate on the MetaInputMapper all matching of inputs and outputs, including configuration. Other secondary aspects, like output aspect ratio for tablet letterbox mode, or toggling attached devices with power saving changes, are also moved here. This makes MetaInputSettings independent of MetaMonitorManager, all interaction with it happens indirectly via public API entrypoints. Part-of: --- src/backends/meta-input-mapper-private.h | 8 +- src/backends/meta-input-mapper.c | 279 +++++++++++++- src/backends/meta-input-settings-private.h | 10 + src/backends/meta-input-settings.c | 424 +++++---------------- 4 files changed, 373 insertions(+), 348 deletions(-) diff --git a/src/backends/meta-input-mapper-private.h b/src/backends/meta-input-mapper-private.h index cdfdccde9fb..67ffbe56521 100644 --- a/src/backends/meta-input-mapper-private.h +++ b/src/backends/meta-input-mapper-private.h @@ -33,10 +33,9 @@ G_DECLARE_FINAL_TYPE (MetaInputMapper, meta_input_mapper, MetaInputMapper * meta_input_mapper_new (void); void meta_input_mapper_add_device (MetaInputMapper *mapper, - ClutterInputDevice *device, - gboolean builtin); + ClutterInputDevice *device); void meta_input_mapper_remove_device (MetaInputMapper *mapper, - ClutterInputDevice *device); + ClutterInputDevice *device); ClutterInputDevice * meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper, @@ -46,4 +45,7 @@ MetaLogicalMonitor * meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper, ClutterInputDevice *device); +GSettings * meta_input_mapper_get_tablet_settings (MetaInputMapper *mapper, + ClutterInputDevice *device); + #endif /* META_INPUT_MAPPER_H */ diff --git a/src/backends/meta-input-mapper.c b/src/backends/meta-input-mapper.c index db85d0926eb..756cd1126f4 100644 --- a/src/backends/meta-input-mapper.c +++ b/src/backends/meta-input-mapper.c @@ -24,6 +24,7 @@ #include #endif +#include "backends/meta-input-device-private.h" #include "meta-input-mapper-private.h" #include "meta-monitor-manager-private.h" #include "meta-logical-monitor.h" @@ -65,6 +66,7 @@ typedef enum META_MATCH_EDID_FULL, /* Full EDID model match, eg. "Cintiq 12WX" */ META_MATCH_SIZE, /* Size from input device and output match */ META_MATCH_IS_BUILTIN, /* Output is builtin, applies mainly to system-integrated devices */ + META_MATCH_CONFIG, /* Specified by config */ N_OUTPUT_MATCHES } MetaOutputMatchType; @@ -73,6 +75,7 @@ struct _MetaMapperInputInfo ClutterInputDevice *device; MetaInputMapper *mapper; MetaMapperOutputInfo *output; + GSettings *settings; guint builtin : 1; }; @@ -106,24 +109,79 @@ struct _DeviceCandidates enum { DEVICE_MAPPED, + DEVICE_ENABLED, + DEVICE_ASPECT_RATIO, N_SIGNALS }; static guint signals[N_SIGNALS] = { 0, }; +static void mapper_recalculate_input (MetaInputMapper *mapper, + MetaMapperInputInfo *input); + G_DEFINE_TYPE (MetaInputMapper, meta_input_mapper, G_TYPE_OBJECT) +static GSettings * +get_device_settings (ClutterInputDevice *device) +{ + const char *group, *schema, *vendor, *product; + ClutterInputDeviceType type; + GSettings *settings; + char *path; + + type = clutter_input_device_get_device_type (device); + + if (type == CLUTTER_TOUCHSCREEN_DEVICE) + { + group = "touchscreens"; + schema = "org.gnome.desktop.peripherals.touchscreen"; + } + else if (type == CLUTTER_TABLET_DEVICE || + type == CLUTTER_PEN_DEVICE || + type == CLUTTER_ERASER_DEVICE || + type == CLUTTER_CURSOR_DEVICE || + type == CLUTTER_PAD_DEVICE) + { + group = "tablets"; + schema = "org.gnome.desktop.peripherals.tablet"; + } + else + { + return NULL; + } + + vendor = clutter_input_device_get_vendor_id (device); + product = clutter_input_device_get_product_id (device); + path = g_strdup_printf ("/org/gnome/desktop/peripherals/%s/%s:%s/", + group, vendor, product); + + settings = g_settings_new_with_path (schema, path); + g_free (path); + + return settings; +} + +static void +settings_output_changed_cb (GSettings *settings, + const char *key, + MetaMapperInputInfo *info) +{ + mapper_recalculate_input (info->mapper, info); +} + static MetaMapperInputInfo * mapper_input_info_new (ClutterInputDevice *device, - MetaInputMapper *mapper, - gboolean builtin) + MetaInputMapper *mapper) { MetaMapperInputInfo *info; info = g_new0 (MetaMapperInputInfo, 1); info->mapper = mapper; info->device = device; - info->builtin = builtin; + info->settings = get_device_settings (device); + + g_signal_connect (info->settings, "changed::output", + G_CALLBACK (settings_output_changed_cb), info); return info; } @@ -131,6 +189,7 @@ mapper_input_info_new (ClutterInputDevice *device, static void mapper_input_info_free (MetaMapperInputInfo *info) { + g_object_unref (info->settings); g_free (info); } @@ -181,13 +240,36 @@ mapper_input_info_set_output (MetaMapperInputInfo *input, MetaMapperOutputInfo *output, MetaMonitor *monitor) { + MetaInputMapper *mapper = input->mapper; + float matrix[6] = { 1, 0, 0, 0, 1, 0 }; + double aspect_ratio; + int width, height; + if (input->output == output) return; input->output = output; + + if (output && monitor) + { + meta_monitor_manager_get_monitor_matrix (mapper->monitor_manager, + monitor, + output->logical_monitor, + matrix); + meta_monitor_get_current_resolution (monitor, &width, &height); + } + else + { + meta_monitor_manager_get_screen_size (mapper->monitor_manager, + &width, &height); + } + + aspect_ratio = (double) width / height; + g_signal_emit (input->mapper, signals[DEVICE_MAPPED], 0, - input->device, - output ? output->logical_monitor : NULL, monitor); + input->device, matrix); + g_signal_emit (input->mapper, signals[DEVICE_ASPECT_RATIO], 0, + input->device, aspect_ratio); } static void @@ -346,6 +428,38 @@ match_builtin (MetaInputMapper *mapper, return monitor == meta_monitor_manager_get_laptop_panel (mapper->monitor_manager); } +static gboolean +match_config (MetaMapperInputInfo *info, + MetaMonitor *monitor) +{ + gboolean match = FALSE; + char **edid; + guint n_values; + + edid = g_settings_get_strv (info->settings, "output"); + n_values = g_strv_length (edid); + + if (n_values != 3) + { + g_warning ("EDID configuration for device '%s' " + "is incorrect, must have 3 values", + clutter_input_device_get_device_name (info->device)); + goto out; + } + + if (!*edid[0] && !*edid[1] && !*edid[2]) + goto out; + + match = (g_strcmp0 (meta_monitor_get_vendor (monitor), edid[0]) == 0 && + g_strcmp0 (meta_monitor_get_product (monitor), edid[1]) == 0 && + g_strcmp0 (meta_monitor_get_serial (monitor), edid[2]) == 0); + + out: + g_strfreev (edid); + + return match; +} + static int sort_by_score (DeviceMatch *match1, DeviceMatch *match2) @@ -359,6 +473,32 @@ guess_candidates (MetaInputMapper *mapper, DeviceCandidates *info) { GList *monitors, *l; + gboolean builtin = FALSE; + gboolean integrated = TRUE; + +#ifdef HAVE_LIBWACOM + if (clutter_input_device_get_device_type (input->device) != CLUTTER_TOUCHSCREEN_DEVICE) + { + WacomDevice *wacom_device; + WacomIntegrationFlags flags = 0; + + wacom_device = + meta_input_device_get_wacom_device (META_INPUT_DEVICE (input->device)); + + if (wacom_device) + { + flags = libwacom_get_integration_flags (wacom_device); + + if ((flags & (WACOM_DEVICE_INTEGRATED_SYSTEM | + WACOM_DEVICE_INTEGRATED_DISPLAY)) == 0) + return; + + integrated = (flags & (WACOM_DEVICE_INTEGRATED_SYSTEM | + WACOM_DEVICE_INTEGRATED_DISPLAY)) != 0; + builtin = (flags & WACOM_DEVICE_INTEGRATED_SYSTEM) != 0; + } + } +#endif monitors = meta_monitor_manager_get_monitors (mapper->monitor_manager); @@ -372,12 +512,15 @@ guess_candidates (MetaInputMapper *mapper, if (match_edid (input, l->data, &edid_match)) match.score |= 1 << edid_match; - if (match_size (input, l->data)) + if (integrated && match_size (input, l->data)) match.score |= 1 << META_MATCH_SIZE; - if (input->builtin && match_builtin (mapper, l->data)) + if (builtin && match_builtin (mapper, l->data)) match.score |= 1 << META_MATCH_IS_BUILTIN; + if (match_config (input, l->data)) + match.score |= 1 << META_MATCH_CONFIG; + if (match.score > 0) g_array_append_val (info->matches, match); } @@ -547,6 +690,38 @@ input_mapper_monitors_changed_cb (MetaMonitorManager *monitor_manager, mapper_update_outputs (mapper); } +static void +input_mapper_power_save_mode_changed_cb (MetaMonitorManager *monitor_manager, + MetaInputMapper *mapper) +{ + ClutterInputDevice *device; + MetaLogicalMonitor *logical_monitor; + MetaMonitor *builtin; + MetaPowerSave power_save_mode; + gboolean on; + + power_save_mode = + meta_monitor_manager_get_power_save_mode (mapper->monitor_manager); + on = power_save_mode == META_POWER_SAVE_ON; + + builtin = meta_monitor_manager_get_laptop_panel (monitor_manager); + if (!builtin) + return; + + logical_monitor = meta_monitor_get_logical_monitor (builtin); + if (!logical_monitor) + return; + + device = + meta_input_mapper_get_logical_monitor_device (mapper, + logical_monitor, + CLUTTER_TOUCHSCREEN_DEVICE); + if (!device) + return; + + g_signal_emit (mapper, signals[DEVICE_ENABLED], 0, device, on); +} + static void input_mapper_device_removed_cb (ClutterSeat *seat, ClutterInputDevice *device, @@ -599,6 +774,9 @@ meta_input_mapper_constructed (GObject *object) mapper->monitor_manager = meta_backend_get_monitor_manager (backend); g_signal_connect (mapper->monitor_manager, "monitors-changed-internal", G_CALLBACK (input_mapper_monitors_changed_cb), mapper); + g_signal_connect (mapper->monitor_manager, "power-save-mode-changed", + G_CALLBACK (input_mapper_power_save_mode_changed_cb), + mapper); mapper_update_outputs (mapper); } @@ -617,9 +795,27 @@ meta_input_mapper_class_init (MetaInputMapperClass *klass) G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, - G_TYPE_NONE, 3, + G_TYPE_NONE, 2, CLUTTER_TYPE_INPUT_DEVICE, - G_TYPE_POINTER, G_TYPE_POINTER); + G_TYPE_POINTER); + signals[DEVICE_ENABLED] = + g_signal_new ("device-enabled", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 2, + CLUTTER_TYPE_INPUT_DEVICE, + G_TYPE_BOOLEAN); + signals[DEVICE_ASPECT_RATIO] = + g_signal_new ("device-aspect-ratio", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 2, + CLUTTER_TYPE_INPUT_DEVICE, + G_TYPE_DOUBLE); } static void @@ -641,8 +837,7 @@ meta_input_mapper_new (void) void meta_input_mapper_add_device (MetaInputMapper *mapper, - ClutterInputDevice *device, - gboolean builtin) + ClutterInputDevice *device) { MetaMapperInputInfo *info; @@ -652,7 +847,7 @@ meta_input_mapper_add_device (MetaInputMapper *mapper, if (g_hash_table_contains (mapper->input_devices, device)) return; - info = mapper_input_info_new (device, mapper, builtin); + info = mapper_input_info_new (device, mapper); g_hash_table_insert (mapper->input_devices, device, info); mapper_recalculate_input (mapper, info); } @@ -699,6 +894,43 @@ meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper, return NULL; } +static ClutterInputDevice * +find_grouped_pen (ClutterInputDevice *device) +{ + GList *l, *devices; + ClutterInputDeviceType device_type; + ClutterInputDevice *pen = NULL; + ClutterSeat *seat; + + device_type = clutter_input_device_get_device_type (device); + + if (device_type == CLUTTER_TABLET_DEVICE || + device_type == CLUTTER_PEN_DEVICE) + return device; + + seat = clutter_input_device_get_seat (device); + devices = clutter_seat_list_devices (seat); + + for (l = devices; l; l = l->next) + { + ClutterInputDevice *other_device = l->data; + + device_type = clutter_input_device_get_device_type (other_device); + + if ((device_type == CLUTTER_TABLET_DEVICE || + device_type == CLUTTER_PEN_DEVICE) && + clutter_input_device_is_grouped (device, other_device)) + { + pen = other_device; + break; + } + } + + g_list_free (devices); + + return pen; +} + MetaLogicalMonitor * meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper, ClutterInputDevice *device) @@ -708,6 +940,13 @@ meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper, GHashTableIter iter; GList *l; + if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE) + { + device = find_grouped_pen (device); + if (!device) + return NULL; + } + g_hash_table_iter_init (&iter, mapper->output_devices); while (g_hash_table_iter_next (&iter, (gpointer *) &logical_monitor, @@ -724,3 +963,19 @@ meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper, return NULL; } + +GSettings * +meta_input_mapper_get_tablet_settings (MetaInputMapper *mapper, + ClutterInputDevice *device) +{ + MetaMapperInputInfo *input; + + g_return_val_if_fail (META_IS_INPUT_MAPPER (mapper), NULL); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); + + input = g_hash_table_lookup (mapper->input_devices, device); + if (!input) + return NULL; + + return input->settings; +} diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h index 3d35e5d0650..cfaf6bcfde2 100644 --- a/src/backends/meta-input-settings-private.h +++ b/src/backends/meta-input-settings-private.h @@ -145,4 +145,14 @@ MetaLogicalMonitor * meta_input_settings_get_tablet_logical_monitor (MetaInputS void meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings); void meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings); +void meta_input_settings_set_device_matrix (MetaInputSettings *input_settings, + ClutterInputDevice *device, + float matrix[6]); +void meta_input_settings_set_device_enabled (MetaInputSettings *input_settings, + ClutterInputDevice *device, + gboolean enabled); +void meta_input_settings_set_device_aspect_ratio (MetaInputSettings *input_settings, + ClutterInputDevice *device, + double aspect_ratio); + #endif /* META_INPUT_SETTINGS_PRIVATE_H */ diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 96c50afeca2..38028e27720 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -61,12 +61,12 @@ struct _DeviceMappingInfo GSettings *settings; gulong changed_id; guint *group_modes; + double aspect_ratio; }; struct _MetaInputSettingsPrivate { ClutterSeat *seat; - MetaMonitorManager *monitor_manager; gulong monitors_changed_id; GSettings *mouse_settings; @@ -147,11 +147,6 @@ meta_input_settings_dispose (GObject *object) g_clear_pointer (&priv->mappable_devices, g_hash_table_unref); g_clear_pointer (&priv->current_tools, g_hash_table_unref); - if (priv->monitor_manager) - g_clear_signal_handler (&priv->monitors_changed_id, priv->monitor_manager); - - g_clear_object (&priv->monitor_manager); - g_clear_pointer (&priv->two_finger_devices, g_hash_table_destroy); G_OBJECT_CLASS (meta_input_settings_parent_class)->dispose (object); @@ -893,124 +888,14 @@ update_keyboard_repeat (MetaInputSettings *input_settings) repeat, delay, interval); } -static MetaMonitor * -logical_monitor_find_monitor (MetaLogicalMonitor *logical_monitor, - const char *vendor, - const char *product, - const char *serial) -{ - GList *monitors; - GList *l; - - monitors = meta_logical_monitor_get_monitors (logical_monitor); - for (l = monitors; l; l = l->next) - { - MetaMonitor *monitor = l->data; - - if (g_strcmp0 (meta_monitor_get_vendor (monitor), vendor) == 0 && - g_strcmp0 (meta_monitor_get_product (monitor), product) == 0 && - g_strcmp0 (meta_monitor_get_serial (monitor), serial) == 0) - return monitor; - } - - return NULL; -} - -static void -meta_input_settings_find_monitor (MetaInputSettings *input_settings, - GSettings *settings, - ClutterInputDevice *device, - MetaMonitor **out_monitor, - MetaLogicalMonitor **out_logical_monitor) -{ - MetaInputSettingsPrivate *priv; - MetaMonitorManager *monitor_manager; - MetaMonitor *monitor; - guint n_values; - GList *logical_monitors; - GList *l; - gchar **edid; - - priv = meta_input_settings_get_instance_private (input_settings); - edid = g_settings_get_strv (settings, "output"); - n_values = g_strv_length (edid); - - if (n_values != 3) - { - g_warning ("EDID configuration for device '%s' " - "is incorrect, must have 3 values", - clutter_input_device_get_device_name (device)); - goto out; - } - - if (!*edid[0] && !*edid[1] && !*edid[2]) - goto out; - - monitor_manager = priv->monitor_manager; - logical_monitors = - meta_monitor_manager_get_logical_monitors (monitor_manager); - for (l = logical_monitors; l; l = l->next) - { - MetaLogicalMonitor *logical_monitor = l->data; - - monitor = logical_monitor_find_monitor (logical_monitor, - edid[0], edid[1], edid[2]); - if (monitor) - { - if (out_monitor) - *out_monitor = monitor; - if (out_logical_monitor) - *out_logical_monitor = logical_monitor; - break; - } - } - -out: - g_strfreev (edid); -} - -static gboolean -meta_input_settings_delegate_on_mapper (MetaInputSettings *input_settings, - ClutterInputDevice *device) -{ - MetaInputSettingsPrivate *priv; - gboolean builtin = FALSE; - - priv = meta_input_settings_get_instance_private (input_settings); - -#ifdef HAVE_LIBWACOM - if (clutter_input_device_get_device_type (device) != CLUTTER_TOUCHSCREEN_DEVICE) - { - WacomDevice *wacom_device; - WacomIntegrationFlags flags = 0; - - wacom_device = - meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); - - if (wacom_device) - { - flags = libwacom_get_integration_flags (wacom_device); - - if ((flags & (WACOM_DEVICE_INTEGRATED_SYSTEM | - WACOM_DEVICE_INTEGRATED_DISPLAY)) == 0) - return FALSE; - - builtin = (flags & WACOM_DEVICE_INTEGRATED_SYSTEM) != 0; - } - } -#endif - - meta_input_mapper_add_device (priv->input_mapper, device, builtin); - return TRUE; -} - static void update_tablet_keep_aspect (MetaInputSettings *input_settings, GSettings *settings, ClutterInputDevice *device) { + MetaInputSettingsPrivate *priv; MetaInputSettingsClass *input_settings_class; - MetaLogicalMonitor *logical_monitor = NULL; + DeviceMappingInfo *info; gboolean keep_aspect; double aspect_ratio; @@ -1019,6 +904,12 @@ update_tablet_keep_aspect (MetaInputSettings *input_settings, clutter_input_device_get_device_type (device) != CLUTTER_ERASER_DEVICE) return; + priv = meta_input_settings_get_instance_private (input_settings); + + info = g_hash_table_lookup (priv->mappable_devices, device); + if (!info) + return; + #ifdef HAVE_LIBWACOM { WacomDevice *wacom_device; @@ -1032,81 +923,15 @@ update_tablet_keep_aspect (MetaInputSettings *input_settings, } #endif - input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); - keep_aspect = g_settings_get_boolean (settings, "keep-aspect"); - meta_input_settings_find_monitor (input_settings, settings, device, - NULL, &logical_monitor); if (keep_aspect) - { - int width, height; - - if (logical_monitor) - { - width = logical_monitor->rect.width; - height = logical_monitor->rect.height; - } - else - { - MetaMonitorManager *monitor_manager; - MetaBackend *backend; - - backend = meta_get_backend (); - monitor_manager = meta_backend_get_monitor_manager (backend); - meta_monitor_manager_get_screen_size (monitor_manager, - &width, &height); - } - - aspect_ratio = (double) width / height; - } + aspect_ratio = info->aspect_ratio; else - { - aspect_ratio = 0; - } - - input_settings_class->set_tablet_aspect_ratio (input_settings, device, aspect_ratio); -} - -static void -update_device_display (MetaInputSettings *input_settings, - GSettings *settings, - ClutterInputDevice *device) -{ - MetaInputSettingsClass *input_settings_class; - MetaInputSettingsPrivate *priv; - gfloat matrix[6] = { 1, 0, 0, 0, 1, 0 }; - MetaMonitor *monitor = NULL; - MetaLogicalMonitor *logical_monitor = NULL; - - if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE && - clutter_input_device_get_device_type (device) != CLUTTER_PEN_DEVICE && - clutter_input_device_get_device_type (device) != CLUTTER_ERASER_DEVICE && - clutter_input_device_get_device_type (device) != CLUTTER_TOUCHSCREEN_DEVICE) - return; + aspect_ratio = 0; - priv = meta_input_settings_get_instance_private (input_settings); input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); - - meta_input_settings_find_monitor (input_settings, settings, device, - &monitor, &logical_monitor); - if (monitor) - { - meta_input_mapper_remove_device (priv->input_mapper, device); - meta_monitor_manager_get_monitor_matrix (priv->monitor_manager, - monitor, logical_monitor, - matrix); - } - else - { - if (meta_input_settings_delegate_on_mapper (input_settings, device)) - return; - } - - input_settings_class->set_matrix (input_settings, device, matrix); - - /* Ensure the keep-aspect mapping is updated */ - update_tablet_keep_aspect (input_settings, settings, device); + input_settings_class->set_tablet_aspect_ratio (input_settings, device, aspect_ratio); } static void @@ -1141,10 +966,6 @@ update_tablet_mapping (MetaInputSettings *input_settings, settings_device_set_uint_setting (input_settings, device, input_settings_class->set_tablet_mapping, mapping); - - /* Relative mapping disables keep-aspect/display */ - update_tablet_keep_aspect (input_settings, settings, device); - update_device_display (input_settings, settings, device); } static void @@ -1301,9 +1122,7 @@ mapped_device_changed_cb (GSettings *settings, const gchar *key, DeviceMappingInfo *info) { - if (strcmp (key, "output") == 0) - update_device_display (info->input_settings, settings, info->device); - else if (strcmp (key, "mapping") == 0) + if (strcmp (key, "mapping") == 0) update_tablet_mapping (info->input_settings, settings, info->device); else if (strcmp (key, "area") == 0) update_tablet_area (info->input_settings, settings, info->device); @@ -1319,7 +1138,6 @@ apply_mappable_device_settings (MetaInputSettings *input_settings, { ClutterInputDeviceType device_type; - update_device_display (input_settings, info->settings, info->device); device_type = clutter_input_device_get_device_type (info->device); if (device_type == CLUTTER_TABLET_DEVICE || @@ -1593,44 +1411,31 @@ lookup_tool_settings (ClutterInputDeviceTool *tool, return tool_settings; } -static void -monitors_changed_cb (MetaMonitorManager *monitor_manager, - MetaInputSettings *input_settings) -{ - MetaInputSettingsPrivate *priv; - ClutterInputDevice *device; - DeviceMappingInfo *info; - GHashTableIter iter; - - priv = meta_input_settings_get_instance_private (input_settings); - g_hash_table_iter_init (&iter, priv->mappable_devices); - - while (g_hash_table_iter_next (&iter, (gpointer *) &device, - (gpointer *) &info)) - update_device_display (input_settings, info->settings, device); -} - static void input_mapper_device_mapped_cb (MetaInputMapper *mapper, ClutterInputDevice *device, - MetaLogicalMonitor *logical_monitor, - MetaMonitor *monitor, + float matrix[6], MetaInputSettings *input_settings) { - MetaInputSettingsPrivate *priv; - float matrix[6] = { 1, 0, 0, 0, 1, 0 }; - - priv = meta_input_settings_get_instance_private (input_settings); + meta_input_settings_set_device_matrix (input_settings, device, matrix); +} - if (monitor && logical_monitor) - { - meta_monitor_manager_get_monitor_matrix (priv->monitor_manager, - monitor, logical_monitor, - matrix); - } +static void +input_mapper_device_enabled_cb (MetaInputMapper *mapper, + ClutterInputDevice *device, + gboolean enabled, + MetaInputSettings *input_settings) +{ + meta_input_settings_set_device_enabled (input_settings, device, enabled); +} - META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_matrix (input_settings, - device, matrix); +static void +input_mapper_device_aspect_ratio_cb (MetaInputMapper *mapper, + ClutterInputDevice *device, + double aspect_ratio, + MetaInputSettings *input_settings) +{ + meta_input_settings_set_device_aspect_ratio (input_settings, device, aspect_ratio); } static void @@ -1665,6 +1470,8 @@ check_add_mappable_device (MetaInputSettings *input_settings, if (!settings) return FALSE; + meta_input_mapper_add_device (priv->input_mapper, device); + priv = meta_input_settings_get_instance_private (input_settings); info = g_slice_new0 (DeviceMappingInfo); @@ -1929,47 +1736,6 @@ check_mappable_devices (MetaInputSettings *input_settings) g_list_free (devices); } -static void -power_save_mode_changed_cb (MetaMonitorManager *manager, - gpointer user_data) -{ - MetaInputSettings *input_settings = user_data; - MetaInputSettingsPrivate *priv; - ClutterInputDevice *device; - MetaLogicalMonitor *logical_monitor; - MetaMonitor *builtin; - MetaPowerSave power_save_mode; - GDesktopDeviceSendEvents send_events; - gboolean on; - - power_save_mode = meta_monitor_manager_get_power_save_mode (manager); - on = power_save_mode == META_POWER_SAVE_ON; - priv = meta_input_settings_get_instance_private (input_settings); - - builtin = meta_monitor_manager_get_laptop_panel (manager); - if (!builtin) - return; - - logical_monitor = meta_monitor_get_logical_monitor (builtin); - if (!logical_monitor) - return; - - device = - meta_input_mapper_get_logical_monitor_device (priv->input_mapper, - logical_monitor, - CLUTTER_TOUCHSCREEN_DEVICE); - if (!device) - return; - - send_events = on ? - G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED : - G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED; - - META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_send_events (input_settings, - device, - send_events); -} - static void meta_input_settings_constructed (GObject *object) { @@ -2051,17 +1817,15 @@ meta_input_settings_init (MetaInputSettings *settings) priv->current_tools = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) current_tool_info_free); - priv->monitor_manager = g_object_ref (meta_monitor_manager_get ()); - g_signal_connect (priv->monitor_manager, "monitors-changed-internal", - G_CALLBACK (monitors_changed_cb), settings); - g_signal_connect (priv->monitor_manager, "power-save-mode-changed", - G_CALLBACK (power_save_mode_changed_cb), settings); - priv->two_finger_devices = g_hash_table_new (NULL, NULL); priv->input_mapper = meta_input_mapper_new (); g_signal_connect (priv->input_mapper, "device-mapped", G_CALLBACK (input_mapper_device_mapped_cb), settings); + g_signal_connect (priv->input_mapper, "device-enabled", + G_CALLBACK (input_mapper_device_enabled_cb), settings); + g_signal_connect (priv->input_mapper, "device-aspect-ratio", + G_CALLBACK (input_mapper_device_aspect_ratio_cb), settings); } GSettings * @@ -2080,77 +1844,18 @@ meta_input_settings_get_tablet_settings (MetaInputSettings *settings, return info ? g_object_ref (info->settings) : NULL; } -static ClutterInputDevice * -find_grouped_pen (MetaInputSettings *settings, - ClutterInputDevice *device) -{ - MetaInputSettingsPrivate *priv; - GList *l, *devices; - ClutterInputDeviceType device_type; - ClutterInputDevice *pen = NULL; - - device_type = clutter_input_device_get_device_type (device); - - if (device_type == CLUTTER_TABLET_DEVICE || - device_type == CLUTTER_PEN_DEVICE) - return device; - - priv = meta_input_settings_get_instance_private (settings); - devices = clutter_seat_list_devices (priv->seat); - - for (l = devices; l; l = l->next) - { - ClutterInputDevice *other_device = l->data; - - device_type = clutter_input_device_get_device_type (other_device); - - if ((device_type == CLUTTER_TABLET_DEVICE || - device_type == CLUTTER_PEN_DEVICE) && - clutter_input_device_is_grouped (device, other_device)) - { - pen = other_device; - break; - } - } - - g_list_free (devices); - - return pen; -} - MetaLogicalMonitor * meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings, ClutterInputDevice *device) { - MetaLogicalMonitor *logical_monitor = NULL; MetaInputSettingsPrivate *priv; - DeviceMappingInfo *info; g_return_val_if_fail (META_IS_INPUT_SETTINGS (settings), NULL); g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE) - { - device = find_grouped_pen (settings, device); - if (!device) - return NULL; - } - priv = meta_input_settings_get_instance_private (settings); - info = g_hash_table_lookup (priv->mappable_devices, device); - if (!info) - return NULL; - logical_monitor = - meta_input_mapper_get_device_logical_monitor (priv->input_mapper, device); - - if (!logical_monitor) - { - meta_input_settings_find_monitor (settings, info->settings, device, - NULL, &logical_monitor); - } - - return logical_monitor; + return meta_input_mapper_get_device_logical_monitor (priv->input_mapper, device); } void @@ -2190,3 +1895,56 @@ meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settin numlock_state = g_settings_get_boolean (priv->keyboard_settings, "numlock-state"); meta_backend_set_numlock (meta_get_backend (), numlock_state); } + +void +meta_input_settings_set_device_matrix (MetaInputSettings *input_settings, + ClutterInputDevice *device, + float matrix[6]) +{ + g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings)); + g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); + + META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_matrix (input_settings, + device, + matrix); +} + +void +meta_input_settings_set_device_enabled (MetaInputSettings *input_settings, + ClutterInputDevice *device, + gboolean enabled) +{ + GDesktopDeviceSendEvents mode; + + g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings)); + g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); + + mode = enabled ? + G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED : + G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED; + + META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_send_events (input_settings, + device, + mode); +} + +void +meta_input_settings_set_device_aspect_ratio (MetaInputSettings *input_settings, + ClutterInputDevice *device, + double aspect_ratio) +{ + MetaInputSettingsPrivate *priv; + DeviceMappingInfo *info; + + g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings)); + g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); + + priv = meta_input_settings_get_instance_private (input_settings); + + info = g_hash_table_lookup (priv->mappable_devices, device); + if (!info) + return; + + info->aspect_ratio = aspect_ratio; + update_tablet_keep_aspect (input_settings, info->settings, device); +} -- GitLab From 4013bed6e43f15d29dfab659872a3f51d47130ff Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 4 Aug 2020 14:17:39 +0200 Subject: [PATCH 40/85] backends: Make MetaInputMapper take over MetaInputSettings public API Banish MetaInputSettings from MetaBackend "public" API, it's now meant to spend the rest of its days in the backend dungeons, maybe hanging off a thread. MetaInputMapper replaces all external uses. Part-of: --- src/backends/meta-backend-private.h | 2 + src/backends/meta-backend.c | 67 ++++++++++++++++++++ src/backends/meta-input-mapper-private.h | 3 +- src/backends/meta-input-settings-private.h | 5 -- src/backends/meta-input-settings.c | 72 ---------------------- src/backends/native/meta-backend-native.c | 16 +++-- src/core/display.c | 22 +++---- 7 files changed, 93 insertions(+), 94 deletions(-) diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index 9a40430fbee..3d32f05a397 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -34,6 +34,7 @@ #include "backends/meta-backend-types.h" #include "backends/meta-cursor-renderer.h" #include "backends/meta-egl.h" +#include "backends/meta-input-mapper-private.h" #include "backends/meta-input-settings-private.h" #include "backends/meta-monitor-manager-private.h" #include "backends/meta-orientation-manager.h" @@ -175,6 +176,7 @@ gboolean meta_is_stage_views_enabled (void); gboolean meta_is_stage_views_scaled (void); +MetaInputMapper *meta_backend_get_input_mapper (MetaBackend *backend); MetaInputSettings *meta_backend_get_input_settings (MetaBackend *backend); void meta_backend_notify_keymap_changed (MetaBackend *backend); diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index ddcf29aafe6..e1638660507 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -56,6 +56,7 @@ #include "backends/meta-cursor-renderer.h" #include "backends/meta-cursor-tracker-private.h" #include "backends/meta-idle-monitor-private.h" +#include "backends/meta-input-mapper-private.h" #include "backends/meta-input-settings-private.h" #include "backends/meta-logical-monitor.h" #include "backends/meta-monitor-manager-dummy.h" @@ -122,6 +123,7 @@ struct _MetaBackendPrivate MetaOrientationManager *orientation_manager; MetaCursorTracker *cursor_tracker; MetaInputSettings *input_settings; + MetaInputMapper *input_mapper; MetaRenderer *renderer; #ifdef HAVE_EGL MetaEgl *egl; @@ -447,11 +449,22 @@ on_device_added (ClutterSeat *seat, { MetaBackend *backend = META_BACKEND (user_data); MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + ClutterInputDeviceType device_type; create_device_monitor (backend, device); if (device_is_physical_touchscreen (device)) meta_cursor_tracker_set_pointer_visible (priv->cursor_tracker, FALSE); + + device_type = clutter_input_device_get_device_type (device); + + if (device_type == CLUTTER_TOUCHSCREEN_DEVICE || + device_type == CLUTTER_TABLET_DEVICE || + device_type == CLUTTER_PEN_DEVICE || + device_type == CLUTTER_ERASER_DEVICE || + device_type == CLUTTER_CURSOR_DEVICE || + device_type == CLUTTER_PAD_DEVICE) + meta_input_mapper_add_device (priv->input_mapper, device); } static void @@ -464,6 +477,8 @@ on_device_removed (ClutterSeat *seat, destroy_device_monitor (backend, device); + meta_input_mapper_remove_device (priv->input_mapper, device); + /* If the device the user last interacted goes away, check again pointer * visibility. */ @@ -523,6 +538,42 @@ meta_backend_create_input_settings (MetaBackend *backend) return META_BACKEND_GET_CLASS (backend)->create_input_settings (backend); } +static void +input_mapper_device_mapped_cb (MetaInputMapper *mapper, + ClutterInputDevice *device, + float matrix[6], + MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + MetaInputSettings *input_settings = priv->input_settings; + + meta_input_settings_set_device_matrix (input_settings, device, matrix); +} + +static void +input_mapper_device_enabled_cb (MetaInputMapper *mapper, + ClutterInputDevice *device, + gboolean enabled, + MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + MetaInputSettings *input_settings = priv->input_settings; + + meta_input_settings_set_device_enabled (input_settings, device, enabled); +} + +static void +input_mapper_device_aspect_ratio_cb (MetaInputMapper *mapper, + ClutterInputDevice *device, + double aspect_ratio, + MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + MetaInputSettings *input_settings = priv->input_settings; + + meta_input_settings_set_device_aspect_ratio (input_settings, device, aspect_ratio); +} + static void meta_backend_real_post_init (MetaBackend *backend) { @@ -560,6 +611,14 @@ meta_backend_real_post_init (MetaBackend *backend) meta_input_settings_maybe_restore_numlock_state (priv->input_settings); } + priv->input_mapper = meta_input_mapper_new (); + g_signal_connect (priv->input_mapper, "device-mapped", + G_CALLBACK (input_mapper_device_mapped_cb), backend); + g_signal_connect (priv->input_mapper, "device-enabled", + G_CALLBACK (input_mapper_device_enabled_cb), backend); + g_signal_connect (priv->input_mapper, "device-aspect-ratio", + G_CALLBACK (input_mapper_device_aspect_ratio_cb), backend); + #ifdef HAVE_REMOTE_DESKTOP priv->dbus_session_watcher = g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL); priv->screen_cast = meta_screen_cast_new (backend, @@ -1464,6 +1523,14 @@ meta_is_stage_views_scaled (void) return layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL; } +MetaInputMapper * +meta_backend_get_input_mapper (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->input_mapper; +} + MetaInputSettings * meta_backend_get_input_settings (MetaBackend *backend) { diff --git a/src/backends/meta-input-mapper-private.h b/src/backends/meta-input-mapper-private.h index 67ffbe56521..63d480dba77 100644 --- a/src/backends/meta-input-mapper-private.h +++ b/src/backends/meta-input-mapper-private.h @@ -23,7 +23,8 @@ #define META_INPUT_MAPPER_H #include -#include "meta-monitor-manager-private.h" + +#include "backends/meta-backend-types.h" #define META_TYPE_INPUT_MAPPER (meta_input_mapper_get_type ()) diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h index cfaf6bcfde2..17f41a7c620 100644 --- a/src/backends/meta-input-settings-private.h +++ b/src/backends/meta-input-settings-private.h @@ -137,11 +137,6 @@ struct _MetaInputSettingsClass ClutterInputDevice *device); }; -GSettings * meta_input_settings_get_tablet_settings (MetaInputSettings *settings, - ClutterInputDevice *device); -MetaLogicalMonitor * meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings, - ClutterInputDevice *device); - void meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings); void meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings); diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 38028e27720..4cc68bb3231 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -82,9 +82,6 @@ struct _MetaInputSettingsPrivate GHashTable *current_tools; GHashTable *two_finger_devices; - - /* For absolute devices with no mapping in settings */ - MetaInputMapper *input_mapper; }; typedef gboolean (* ConfigBoolMappingFunc) (MetaInputSettings *input_settings, @@ -143,7 +140,6 @@ meta_input_settings_dispose (GObject *object) g_clear_object (&priv->gsd_settings); g_clear_object (&priv->keyboard_a11y_settings); g_clear_object (&priv->mouse_a11y_settings); - g_clear_object (&priv->input_mapper); g_clear_pointer (&priv->mappable_devices, g_hash_table_unref); g_clear_pointer (&priv->current_tools, g_hash_table_unref); @@ -1411,33 +1407,6 @@ lookup_tool_settings (ClutterInputDeviceTool *tool, return tool_settings; } -static void -input_mapper_device_mapped_cb (MetaInputMapper *mapper, - ClutterInputDevice *device, - float matrix[6], - MetaInputSettings *input_settings) -{ - meta_input_settings_set_device_matrix (input_settings, device, matrix); -} - -static void -input_mapper_device_enabled_cb (MetaInputMapper *mapper, - ClutterInputDevice *device, - gboolean enabled, - MetaInputSettings *input_settings) -{ - meta_input_settings_set_device_enabled (input_settings, device, enabled); -} - -static void -input_mapper_device_aspect_ratio_cb (MetaInputMapper *mapper, - ClutterInputDevice *device, - double aspect_ratio, - MetaInputSettings *input_settings) -{ - meta_input_settings_set_device_aspect_ratio (input_settings, device, aspect_ratio); -} - static void device_mapping_info_free (DeviceMappingInfo *info) { @@ -1470,8 +1439,6 @@ check_add_mappable_device (MetaInputSettings *input_settings, if (!settings) return FALSE; - meta_input_mapper_add_device (priv->input_mapper, device); - priv = meta_input_settings_get_instance_private (input_settings); info = g_slice_new0 (DeviceMappingInfo); @@ -1645,7 +1612,6 @@ meta_input_settings_device_removed (ClutterSeat *seat, MetaInputSettingsPrivate *priv; priv = meta_input_settings_get_instance_private (input_settings); - meta_input_mapper_remove_device (priv->input_mapper, device); g_hash_table_remove (priv->mappable_devices, device); g_hash_table_remove (priv->current_tools, device); @@ -1818,44 +1784,6 @@ meta_input_settings_init (MetaInputSettings *settings) g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) current_tool_info_free); priv->two_finger_devices = g_hash_table_new (NULL, NULL); - - priv->input_mapper = meta_input_mapper_new (); - g_signal_connect (priv->input_mapper, "device-mapped", - G_CALLBACK (input_mapper_device_mapped_cb), settings); - g_signal_connect (priv->input_mapper, "device-enabled", - G_CALLBACK (input_mapper_device_enabled_cb), settings); - g_signal_connect (priv->input_mapper, "device-aspect-ratio", - G_CALLBACK (input_mapper_device_aspect_ratio_cb), settings); -} - -GSettings * -meta_input_settings_get_tablet_settings (MetaInputSettings *settings, - ClutterInputDevice *device) -{ - MetaInputSettingsPrivate *priv; - DeviceMappingInfo *info; - - g_return_val_if_fail (META_IS_INPUT_SETTINGS (settings), NULL); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - - priv = meta_input_settings_get_instance_private (settings); - info = g_hash_table_lookup (priv->mappable_devices, device); - - return info ? g_object_ref (info->settings) : NULL; -} - -MetaLogicalMonitor * -meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings, - ClutterInputDevice *device) -{ - MetaInputSettingsPrivate *priv; - - g_return_val_if_fail (META_IS_INPUT_SETTINGS (settings), NULL); - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - - priv = meta_input_settings_get_instance_private (settings); - - return meta_input_mapper_get_device_logical_monitor (priv->input_mapper, device); } void diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index 8ecc24e2ae3..2db207d8056 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -73,6 +73,7 @@ struct _MetaBackendNative MetaLauncher *launcher; MetaUdev *udev; MetaKms *kms; + MetaInputSettings *input_settings; gulong udev_device_added_handler_id; }; @@ -100,6 +101,7 @@ meta_backend_native_finalize (GObject *object) g_clear_object (&native->udev); g_clear_object (&native->kms); meta_launcher_free (native->launcher); + g_clear_object (&native->input_settings); G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object); } @@ -235,7 +237,15 @@ meta_backend_native_create_renderer (MetaBackend *backend, static MetaInputSettings * meta_backend_native_create_input_settings (MetaBackend *backend) { - return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + + if (!backend_native->input_settings) + { + backend_native->input_settings = + g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL); + } + + return backend_native->input_settings; } static MetaLogicalMonitor * @@ -669,7 +679,6 @@ void meta_backend_native_resume (MetaBackendNative *native) meta_backend_get_monitor_manager (backend); MetaMonitorManagerKms *monitor_manager_kms = META_MONITOR_MANAGER_KMS (monitor_manager); - MetaInputSettings *input_settings; MetaIdleMonitor *idle_monitor; ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); MetaSeatNative *seat = @@ -691,8 +700,7 @@ void meta_backend_native_resume (MetaBackendNative *native) idle_monitor = meta_idle_monitor_get_core (); meta_idle_monitor_reset_idletime (idle_monitor); - input_settings = meta_backend_get_input_settings (backend); - meta_input_settings_maybe_restore_numlock_state (input_settings); + meta_input_settings_maybe_restore_numlock_state (native->input_settings); clutter_seat_ensure_a11y_state (CLUTTER_SEAT (seat)); } diff --git a/src/core/display.c b/src/core/display.c index 7bb47d4b3bc..2d256623f1f 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -45,7 +45,7 @@ #include "backends/meta-cursor-tracker-private.h" #include "backends/meta-idle-monitor-dbus.h" #include "backends/meta-input-device-private.h" -#include "backends/meta-input-settings-private.h" +#include "backends/meta-input-mapper-private.h" #include "backends/meta-stage-private.h" #include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-event-x11.h" @@ -2909,7 +2909,7 @@ meta_display_request_pad_osd (MetaDisplay *display, gboolean edition_mode) { MetaBackend *backend = meta_get_backend (); - MetaInputSettings *input_settings; + MetaInputMapper *input_mapper; const gchar *layout_path = NULL; ClutterActor *osd; MetaLogicalMonitor *logical_monitor; @@ -2925,13 +2925,13 @@ meta_display_request_pad_osd (MetaDisplay *display, if (display->current_pad_osd) return; - input_settings = meta_backend_get_input_settings (meta_get_backend ()); + input_mapper = meta_backend_get_input_mapper (meta_get_backend ()); - if (input_settings) + if (input_mapper) { - settings = meta_input_settings_get_tablet_settings (input_settings, pad); + settings = meta_input_mapper_get_tablet_settings (input_mapper, pad); logical_monitor = - meta_input_settings_get_tablet_logical_monitor (input_settings, pad); + meta_input_mapper_get_device_logical_monitor (input_mapper, pad); #ifdef HAVE_LIBWACOM wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (pad)); layout_path = libwacom_get_layout_filename (wacom_device); @@ -2954,8 +2954,6 @@ meta_display_request_pad_osd (MetaDisplay *display, g_object_add_weak_pointer (G_OBJECT (display->current_pad_osd), (gpointer *) &display->current_pad_osd); } - - g_object_unref (settings); } gchar * @@ -3015,15 +3013,15 @@ static gint lookup_tablet_monitor (MetaDisplay *display, ClutterInputDevice *device) { - MetaInputSettings *input_settings; + MetaInputMapper *input_mapper; MetaLogicalMonitor *monitor; gint monitor_idx = -1; - input_settings = meta_backend_get_input_settings (meta_get_backend ()); - if (!input_settings) + input_mapper = meta_backend_get_input_mapper (meta_get_backend ()); + if (!input_mapper) return -1; - monitor = meta_input_settings_get_tablet_logical_monitor (input_settings, device); + monitor = meta_input_mapper_get_device_logical_monitor (input_mapper, device); if (monitor) { -- GitLab From c3acaeb25127a7520ecc0d3edbb3d0cc53b5634e Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 5 Aug 2020 16:40:04 +0200 Subject: [PATCH 41/85] backends: Move keyboard a11y into backends And out of Clutter API. This is mainly set via settings, or the windowing itself, so we don't need to leak these details up our own backend. Part-of: --- clutter/clutter/clutter-enums.h | 38 --------- clutter/clutter/clutter-seat.c | 40 --------- clutter/clutter/clutter-seat.h | 28 ------ src/backends/meta-input-settings-private.h | 39 +++++++++ src/backends/meta-input-settings.c | 85 ++++++++++++------- src/backends/native/meta-backend-native.c | 18 ++++ .../native/meta-input-device-native.c | 85 ++++++++++--------- .../native/meta-input-device-native.h | 7 +- src/backends/native/meta-seat-native.c | 13 --- src/backends/x11/meta-backend-x11.c | 22 +++++ src/backends/x11/meta-seat-x11.c | 9 +- src/backends/x11/meta-xkb-a11y-x11.c | 73 ++++++++-------- src/backends/x11/meta-xkb-a11y-x11.h | 5 +- 13 files changed, 227 insertions(+), 235 deletions(-) diff --git a/clutter/clutter/clutter-enums.h b/clutter/clutter/clutter-enums.h index 04cc52a271b..cd058b3e75d 100644 --- a/clutter/clutter/clutter-enums.h +++ b/clutter/clutter/clutter-enums.h @@ -387,44 +387,6 @@ typedef enum CLUTTER_MODIFIER_MASK = 0x5c001fff } ClutterModifierType; -/** - * ClutterKeyboardA11yFlags: - * @CLUTTER_A11Y_KEYBOARD_ENABLED: - * @CLUTTER_A11Y_TIMEOUT_ENABLED: - * @CLUTTER_A11Y_MOUSE_KEYS_ENABLED: - * @CLUTTER_A11Y_SLOW_KEYS_ENABLED: - * @CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS: - * @CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT: - * @CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT: - * @CLUTTER_A11Y_BOUNCE_KEYS_ENABLED: - * @CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT: - * @CLUTTER_A11Y_TOGGLE_KEYS_ENABLED: - * @CLUTTER_A11Y_STICKY_KEYS_ENABLED: - * @CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF: - * @CLUTTER_A11Y_STICKY_KEYS_BEEP: - * @CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP: - * - * Keyboard accessibility features applied to a ClutterInputDevice keyboard. - * - */ -typedef enum -{ - CLUTTER_A11Y_KEYBOARD_ENABLED = 1 << 0, - CLUTTER_A11Y_TIMEOUT_ENABLED = 1 << 1, - CLUTTER_A11Y_MOUSE_KEYS_ENABLED = 1 << 2, - CLUTTER_A11Y_SLOW_KEYS_ENABLED = 1 << 3, - CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS = 1 << 4, - CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT = 1 << 5, - CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT = 1 << 6, - CLUTTER_A11Y_BOUNCE_KEYS_ENABLED = 1 << 7, - CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT = 1 << 8, - CLUTTER_A11Y_TOGGLE_KEYS_ENABLED = 1 << 9, - CLUTTER_A11Y_STICKY_KEYS_ENABLED = 1 << 10, - CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF = 1 << 11, - CLUTTER_A11Y_STICKY_KEYS_BEEP = 1 << 12, - CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13, -} ClutterKeyboardA11yFlags; - /** * ClutterPointerA11yFlags: * @CLUTTER_A11Y_POINTER_ENABLED: diff --git a/clutter/clutter/clutter-seat.c b/clutter/clutter/clutter-seat.c index 77d8d523123..d3e2eaa2456 100644 --- a/clutter/clutter/clutter-seat.c +++ b/clutter/clutter/clutter-seat.c @@ -65,9 +65,6 @@ struct _ClutterSeatPrivate unsigned int inhibit_unfocus_count; - /* Keyboard a11y */ - ClutterKbdA11ySettings kbd_a11y_settings; - /* Pointer a11y */ ClutterPointerA11ySettings pointer_a11y_settings; }; @@ -404,43 +401,6 @@ clutter_seat_get_keymap (ClutterSeat *seat) return CLUTTER_SEAT_GET_CLASS (seat)->get_keymap (seat); } -static gboolean -are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a, - ClutterKbdA11ySettings *b) -{ - return (memcmp (a, b, sizeof (ClutterKbdA11ySettings)) == 0); -} - -void -clutter_seat_set_kbd_a11y_settings (ClutterSeat *seat, - ClutterKbdA11ySettings *settings) -{ - ClutterSeatClass *seat_class; - ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); - - g_return_if_fail (CLUTTER_IS_SEAT (seat)); - - if (are_kbd_a11y_settings_equal (&priv->kbd_a11y_settings, settings)) - return; - - priv->kbd_a11y_settings = *settings; - - seat_class = CLUTTER_SEAT_GET_CLASS (seat); - if (seat_class->apply_kbd_a11y_settings) - seat_class->apply_kbd_a11y_settings (seat, settings); -} - -void -clutter_seat_get_kbd_a11y_settings (ClutterSeat *seat, - ClutterKbdA11ySettings *settings) -{ - ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); - - g_return_if_fail (CLUTTER_IS_SEAT (seat)); - - *settings = priv->kbd_a11y_settings; -} - void clutter_seat_ensure_a11y_state (ClutterSeat *seat) { diff --git a/clutter/clutter/clutter-seat.h b/clutter/clutter/clutter-seat.h index 36bcd49cb30..cb2ebf97791 100644 --- a/clutter/clutter/clutter-seat.h +++ b/clutter/clutter/clutter-seat.h @@ -37,24 +37,6 @@ CLUTTER_EXPORT G_DECLARE_DERIVABLE_TYPE (ClutterSeat, clutter_seat, CLUTTER, SEAT, GObject) -/** - * ClutterKbdA11ySettings: - * - * The #ClutterKbdA11ySettings structure contains keyboard accessibility - * settings - * - */ -typedef struct _ClutterKbdA11ySettings -{ - ClutterKeyboardA11yFlags controls; - gint slowkeys_delay; - gint debounce_delay; - gint timeout_delay; - gint mousekeys_init_delay; - gint mousekeys_max_speed; - gint mousekeys_accel_time; -} ClutterKbdA11ySettings; - /** * ClutterPointerA11ySettings: * @@ -126,10 +108,6 @@ struct _ClutterSeatClass void (* free_event_data) (ClutterSeat *seat, ClutterEvent *event); - /* Keyboard accessibility */ - void (* apply_kbd_a11y_settings) (ClutterSeat *seat, - ClutterKbdA11ySettings *settings); - /* Virtual devices */ ClutterVirtualInputDevice * (* create_virtual_device) (ClutterSeat *seat, ClutterInputDeviceType device_type); @@ -149,12 +127,6 @@ void clutter_seat_bell_notify (ClutterSeat *seat); CLUTTER_EXPORT ClutterKeymap * clutter_seat_get_keymap (ClutterSeat *seat); -CLUTTER_EXPORT -void clutter_seat_set_kbd_a11y_settings (ClutterSeat *seat, - ClutterKbdA11ySettings *settings); -CLUTTER_EXPORT -void clutter_seat_get_kbd_a11y_settings (ClutterSeat *seat, - ClutterKbdA11ySettings *settings); CLUTTER_EXPORT void clutter_seat_ensure_a11y_state (ClutterSeat *seat); diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h index 17f41a7c620..f6e928dc450 100644 --- a/src/backends/meta-input-settings-private.h +++ b/src/backends/meta-input-settings-private.h @@ -36,6 +36,42 @@ G_DECLARE_DERIVABLE_TYPE (MetaInputSettings, meta_input_settings, META, INPUT_SETTINGS, GObject) +typedef enum +{ + META_A11Y_KEYBOARD_ENABLED = 1 << 0, + META_A11Y_TIMEOUT_ENABLED = 1 << 1, + META_A11Y_MOUSE_KEYS_ENABLED = 1 << 2, + META_A11Y_SLOW_KEYS_ENABLED = 1 << 3, + META_A11Y_SLOW_KEYS_BEEP_PRESS = 1 << 4, + META_A11Y_SLOW_KEYS_BEEP_ACCEPT = 1 << 5, + META_A11Y_SLOW_KEYS_BEEP_REJECT = 1 << 6, + META_A11Y_BOUNCE_KEYS_ENABLED = 1 << 7, + META_A11Y_BOUNCE_KEYS_BEEP_REJECT = 1 << 8, + META_A11Y_TOGGLE_KEYS_ENABLED = 1 << 9, + META_A11Y_STICKY_KEYS_ENABLED = 1 << 10, + META_A11Y_STICKY_KEYS_TWO_KEY_OFF = 1 << 11, + META_A11Y_STICKY_KEYS_BEEP = 1 << 12, + META_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13, +} MetaKeyboardA11yFlags; + +/** + * MetaKbdA11ySettings: + * + * The #MetaKbdA11ySettings structure contains keyboard accessibility + * settings + * + */ +typedef struct _MetaKbdA11ySettings +{ + MetaKeyboardA11yFlags controls; + int slowkeys_delay; + int debounce_delay; + int timeout_delay; + int mousekeys_init_delay; + int mousekeys_max_speed; + int mousekeys_accel_time; +} MetaKbdA11ySettings; + struct _MetaInputSettingsClass { GObjectClass parent_class; @@ -150,4 +186,7 @@ void meta_input_settings_set_device_aspect_ratio (MetaInputSettings *input_sett ClutterInputDevice *device, double aspect_ratio); +void meta_input_settings_get_kbd_a11y_settings (MetaInputSettings *input_settings, + MetaKbdA11ySettings *a11y_settings); + #endif /* META_INPUT_SETTINGS_PRIVATE_H */ diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 4cc68bb3231..6feb5469043 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -82,6 +82,8 @@ struct _MetaInputSettingsPrivate GHashTable *current_tools; GHashTable *two_finger_devices; + + MetaKbdA11ySettings kbd_a11y_settings; }; typedef gboolean (* ConfigBoolMappingFunc) (MetaInputSettings *input_settings, @@ -100,6 +102,14 @@ typedef void (*ConfigUintFunc) (MetaInputSettings *input_settings, G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettings, meta_input_settings, G_TYPE_OBJECT) +enum +{ + KBD_A11Y_CHANGED, + N_SIGNALS +}; + +static guint signals[N_SIGNALS] = { 0 }; + static GSList * meta_input_settings_get_devices (MetaInputSettings *settings, ClutterInputDeviceType type) @@ -1150,39 +1160,31 @@ apply_mappable_device_settings (MetaInputSettings *input_settings, struct _keyboard_a11y_settings_flags_pair { const char *name; - ClutterKeyboardA11yFlags flag; + MetaKeyboardA11yFlags flag; } keyboard_a11y_settings_flags_pair[] = { - { "enable", CLUTTER_A11Y_KEYBOARD_ENABLED }, - { "timeout-enable", CLUTTER_A11Y_TIMEOUT_ENABLED }, - { "mousekeys-enable", CLUTTER_A11Y_MOUSE_KEYS_ENABLED }, - { "slowkeys-enable", CLUTTER_A11Y_SLOW_KEYS_ENABLED }, - { "slowkeys-beep-press", CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS }, - { "slowkeys-beep-accept", CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT }, - { "slowkeys-beep-reject", CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT }, - { "bouncekeys-enable", CLUTTER_A11Y_BOUNCE_KEYS_ENABLED }, - { "bouncekeys-beep-reject", CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT }, - { "togglekeys-enable", CLUTTER_A11Y_TOGGLE_KEYS_ENABLED }, - { "stickykeys-enable", CLUTTER_A11Y_STICKY_KEYS_ENABLED }, - { "stickykeys-modifier-beep", CLUTTER_A11Y_STICKY_KEYS_BEEP }, - { "stickykeys-two-key-off", CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF }, - { "feature-state-change-beep", CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP }, + { "enable", META_A11Y_KEYBOARD_ENABLED }, + { "timeout-enable", META_A11Y_TIMEOUT_ENABLED }, + { "mousekeys-enable", META_A11Y_MOUSE_KEYS_ENABLED }, + { "slowkeys-enable", META_A11Y_SLOW_KEYS_ENABLED }, + { "slowkeys-beep-press", META_A11Y_SLOW_KEYS_BEEP_PRESS }, + { "slowkeys-beep-accept", META_A11Y_SLOW_KEYS_BEEP_ACCEPT }, + { "slowkeys-beep-reject", META_A11Y_SLOW_KEYS_BEEP_REJECT }, + { "bouncekeys-enable", META_A11Y_BOUNCE_KEYS_ENABLED }, + { "bouncekeys-beep-reject", META_A11Y_BOUNCE_KEYS_BEEP_REJECT }, + { "togglekeys-enable", META_A11Y_TOGGLE_KEYS_ENABLED }, + { "stickykeys-enable", META_A11Y_STICKY_KEYS_ENABLED }, + { "stickykeys-modifier-beep", META_A11Y_STICKY_KEYS_BEEP }, + { "stickykeys-two-key-off", META_A11Y_STICKY_KEYS_TWO_KEY_OFF }, + { "feature-state-change-beep", META_A11Y_FEATURE_STATE_CHANGE_BEEP }, }; static void -load_keyboard_a11y_settings (MetaInputSettings *input_settings, - ClutterInputDevice *device) +load_keyboard_a11y_settings (MetaInputSettings *input_settings) { MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings); - ClutterKbdA11ySettings kbd_a11y_settings = { 0 }; - ClutterInputDevice *core_keyboard; - ClutterBackend *backend = clutter_get_default_backend (); - ClutterSeat *seat = clutter_backend_get_default_seat (backend); + MetaKbdA11ySettings kbd_a11y_settings = { 0 }; guint i; - core_keyboard = clutter_seat_get_keyboard (priv->seat); - if (device && device != core_keyboard) - return; - kbd_a11y_settings.controls = 0; for (i = 0; i < G_N_ELEMENTS (keyboard_a11y_settings_flags_pair); i++) { @@ -1203,13 +1205,14 @@ load_keyboard_a11y_settings (MetaInputSettings *input_settings, kbd_a11y_settings.mousekeys_accel_time = g_settings_get_int (priv->keyboard_a11y_settings, "mousekeys-accel-time"); - clutter_seat_set_kbd_a11y_settings (seat, &kbd_a11y_settings); + priv->kbd_a11y_settings = kbd_a11y_settings; + g_signal_emit (input_settings, signals[KBD_A11Y_CHANGED], 0, &priv->kbd_a11y_settings); } static void on_keyboard_a11y_settings_changed (ClutterSeat *seat, - ClutterKeyboardA11yFlags new_flags, - ClutterKeyboardA11yFlags what_changed, + MetaKeyboardA11yFlags new_flags, + MetaKeyboardA11yFlags what_changed, MetaInputSettings *input_settings) { MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings); @@ -1231,7 +1234,7 @@ meta_input_keyboard_a11y_settings_changed (GSettings *settings, { MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data); - load_keyboard_a11y_settings (input_settings, NULL); + load_keyboard_a11y_settings (input_settings); } struct _pointer_a11y_settings_flags_pair { @@ -1493,7 +1496,6 @@ apply_device_settings (MetaInputSettings *input_settings, update_pointer_accel_profile (input_settings, priv->trackball_settings, device); - load_keyboard_a11y_settings (input_settings, device); load_pointer_a11y_settings (input_settings, device); update_middle_click_emulation (input_settings, priv->mouse_settings, device); @@ -1717,6 +1719,8 @@ meta_input_settings_constructed (GObject *object) apply_device_settings (input_settings, NULL); update_keyboard_repeat (input_settings); check_mappable_devices (input_settings); + + load_keyboard_a11y_settings (input_settings); } static void @@ -1729,6 +1733,14 @@ meta_input_settings_class_init (MetaInputSettingsClass *klass) quark_tool_settings = g_quark_from_static_string ("meta-input-settings-tool-settings"); + + signals[KBD_A11Y_CHANGED] = + g_signal_new ("kbd-a11y-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_POINTER); } static void @@ -1876,3 +1888,16 @@ meta_input_settings_set_device_aspect_ratio (MetaInputSettings *input_settings, info->aspect_ratio = aspect_ratio; update_tablet_keep_aspect (input_settings, info->settings, device); } + +void +meta_input_settings_get_kbd_a11y_settings (MetaInputSettings *input_settings, + MetaKbdA11ySettings *a11y_settings) +{ + MetaInputSettingsPrivate *priv; + + g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings)); + + priv = meta_input_settings_get_instance_private (input_settings); + + *a11y_settings = priv->kbd_a11y_settings; +} diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index 2db207d8056..17fb6f67875 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -50,6 +50,7 @@ #include "backends/meta-stage-private.h" #include "backends/native/meta-clutter-backend-native.h" #include "backends/native/meta-event-native.h" +#include "backends/native/meta-input-device-native.h" #include "backends/native/meta-input-settings-native.h" #include "backends/native/meta-kms.h" #include "backends/native/meta-kms-device.h" @@ -234,6 +235,21 @@ meta_backend_native_create_renderer (MetaBackend *backend, return META_RENDERER (renderer_native); } +static void +kbd_a11y_changed_cb (MetaInputSettings *input_settings, + MetaKbdA11ySettings *a11y_settings, + MetaBackend *backend) +{ + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); + ClutterInputDevice *device; + + device = clutter_seat_get_keyboard (seat); + if (device) + meta_input_device_native_apply_kbd_a11y_settings (META_INPUT_DEVICE_NATIVE (device), + a11y_settings); +} + static MetaInputSettings * meta_backend_native_create_input_settings (MetaBackend *backend) { @@ -243,6 +259,8 @@ meta_backend_native_create_input_settings (MetaBackend *backend) { backend_native->input_settings = g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL); + g_signal_connect_object (backend_native->input_settings, "kbd-a11y-changed", + G_CALLBACK (kbd_a11y_changed_cb), backend, 0); } return backend_native->input_settings; diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index 8d4b835deae..3117402cfa7 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -24,6 +24,7 @@ #include #include +#include "backends/meta-backend-private.h" #include "backends/native/meta-input-device-tool-native.h" #include "backends/native/meta-input-device-native.h" #include "backends/native/meta-seat-native.h" @@ -238,11 +239,11 @@ clear_slow_keys (MetaInputDeviceNative *device) static guint get_slow_keys_delay (ClutterInputDevice *device) { - MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); - ClutterKbdA11ySettings a11y_settings; + MetaKbdA11ySettings a11y_settings; + MetaInputSettings *input_settings; - clutter_seat_get_kbd_a11y_settings (CLUTTER_SEAT (device_native->seat), - &a11y_settings); + input_settings = meta_backend_get_input_settings (meta_get_backend ()); + meta_input_settings_get_kbd_a11y_settings (input_settings, &a11y_settings); /* Settings use int, we use uint, make sure we dont go negative */ return MAX (0, a11y_settings.slowkeys_delay); } @@ -263,7 +264,7 @@ trigger_slow_keys (gpointer data) device->slow_keys_list = g_list_remove (device->slow_keys_list, slow_keys_event); meta_input_device_native_free_pending_slow_key (slow_keys_event); - if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT) + if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_ACCEPT) meta_input_device_native_bell_notify (device); return G_SOURCE_REMOVE; @@ -301,7 +302,7 @@ start_slow_keys (ClutterEvent *event, slow_keys_event); device->slow_keys_list = g_list_append (device->slow_keys_list, slow_keys_event); - if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS) + if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_PRESS) meta_input_device_native_bell_notify (device); } @@ -321,7 +322,7 @@ stop_slow_keys (ClutterEvent *event, device->slow_keys_list = g_list_delete_link (device->slow_keys_list, item); meta_input_device_native_free_pending_slow_key (slow_keys_event); - if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT) + if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_REJECT) meta_input_device_native_bell_notify (device); return; @@ -334,11 +335,11 @@ stop_slow_keys (ClutterEvent *event, static guint get_debounce_delay (ClutterInputDevice *device) { - MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); - ClutterKbdA11ySettings a11y_settings; + MetaKbdA11ySettings a11y_settings; + MetaInputSettings *input_settings; - clutter_seat_get_kbd_a11y_settings (CLUTTER_SEAT (device_native->seat), - &a11y_settings); + input_settings = meta_backend_get_input_settings (meta_get_backend ()); + meta_input_settings_get_kbd_a11y_settings (input_settings, &a11y_settings); /* Settings use int, we use uint, make sure we dont go negative */ return MAX (0, a11y_settings.debounce_delay); } @@ -376,7 +377,7 @@ stop_bounce_keys (MetaInputDeviceNative *device) static void notify_bounce_keys_reject (MetaInputDeviceNative *device) { - if (device->a11y_flags & CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT) + if (device->a11y_flags & META_A11Y_BOUNCE_KEYS_BEEP_REJECT) meta_input_device_native_bell_notify (device); } @@ -490,20 +491,20 @@ notify_stickykeys_change (MetaInputDeviceNative *device) g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->seat, "kbd-a11y-flags-changed", device->a11y_flags, - CLUTTER_A11Y_STICKY_KEYS_ENABLED); + META_A11Y_STICKY_KEYS_ENABLED); } static void set_stickykeys_off (MetaInputDeviceNative *device) { - device->a11y_flags &= ~CLUTTER_A11Y_STICKY_KEYS_ENABLED; + device->a11y_flags &= ~META_A11Y_STICKY_KEYS_ENABLED; notify_stickykeys_change (device); } static void set_stickykeys_on (MetaInputDeviceNative *device) { - device->a11y_flags |= CLUTTER_A11Y_STICKY_KEYS_ENABLED; + device->a11y_flags |= META_A11Y_STICKY_KEYS_ENABLED; notify_stickykeys_change (device); } @@ -518,23 +519,23 @@ clear_stickykeys_event (ClutterEvent *event, static void set_slowkeys_off (MetaInputDeviceNative *device) { - device->a11y_flags &= ~CLUTTER_A11Y_SLOW_KEYS_ENABLED; + device->a11y_flags &= ~META_A11Y_SLOW_KEYS_ENABLED; g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->seat, "kbd-a11y-flags-changed", device->a11y_flags, - CLUTTER_A11Y_SLOW_KEYS_ENABLED); + META_A11Y_SLOW_KEYS_ENABLED); } static void set_slowkeys_on (MetaInputDeviceNative *device) { - device->a11y_flags |= CLUTTER_A11Y_SLOW_KEYS_ENABLED; + device->a11y_flags |= META_A11Y_SLOW_KEYS_ENABLED; g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->seat, "kbd-a11y-flags-changed", device->a11y_flags, - CLUTTER_A11Y_SLOW_KEYS_ENABLED); + META_A11Y_SLOW_KEYS_ENABLED); } static void @@ -550,7 +551,7 @@ handle_stickykeys_press (ClutterEvent *event, return; if (device->stickykeys_depressed_mask && - (device->a11y_flags & CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF)) + (device->a11y_flags & META_A11Y_STICKY_KEYS_TWO_KEY_OFF)) { clear_stickykeys_event (event, device); return; @@ -596,7 +597,7 @@ handle_stickykeys_release (ClutterEvent *event, if (key_event_is_modifier (event)) { - if (device->a11y_flags & CLUTTER_A11Y_STICKY_KEYS_BEEP) + if (device->a11y_flags & META_A11Y_STICKY_KEYS_BEEP) meta_input_device_native_bell_notify (device); return; @@ -615,10 +616,10 @@ trigger_toggle_slowkeys (gpointer data) device->toggle_slowkeys_timer = 0; - if (device->a11y_flags & CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP) + if (device->a11y_flags & META_A11Y_FEATURE_STATE_CHANGE_BEEP) meta_input_device_native_bell_notify (device); - if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_ENABLED) + if (device->a11y_flags & META_A11Y_SLOW_KEYS_ENABLED) set_slowkeys_off (device); else set_slowkeys_on (device); @@ -677,10 +678,10 @@ handle_enablekeys_release (ClutterEvent *event, { device->shift_count = 0; - if (device->a11y_flags & CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP) + if (device->a11y_flags & META_A11Y_FEATURE_STATE_CHANGE_BEEP) meta_input_device_native_bell_notify (device); - if (device->a11y_flags & CLUTTER_A11Y_STICKY_KEYS_ENABLED) + if (device->a11y_flags & META_A11Y_STICKY_KEYS_ENABLED) set_stickykeys_off (device); else set_stickykeys_on (device); @@ -747,8 +748,8 @@ emulate_button_click (MetaInputDeviceNative *device) #define MOUSEKEYS_CURVE (1.0 + (((double) 50.0) * 0.001)) static void -update_mousekeys_params (MetaInputDeviceNative *device, - ClutterKbdA11ySettings *settings) +update_mousekeys_params (MetaInputDeviceNative *device, + MetaKbdA11ySettings *settings) { /* Prevent us from broken settings values */ device->mousekeys_max_speed = MAX (1, settings->mousekeys_max_speed); @@ -1117,7 +1118,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD) goto emit_event; - if (device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED) + if (device_evdev->a11y_flags & META_A11Y_KEYBOARD_ENABLED) { if (event->type == CLUTTER_KEY_PRESS) handle_enablekeys_press (event, device_evdev); @@ -1125,7 +1126,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve handle_enablekeys_release (event, device_evdev); } - if (device_evdev->a11y_flags & CLUTTER_A11Y_MOUSE_KEYS_ENABLED) + if (device_evdev->a11y_flags & META_A11Y_MOUSE_KEYS_ENABLED) { if (event->type == CLUTTER_KEY_PRESS && handle_mousekeys_press (event, device_evdev)) @@ -1135,7 +1136,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve return; /* swallow event */ } - if ((device_evdev->a11y_flags & CLUTTER_A11Y_BOUNCE_KEYS_ENABLED) && + if ((device_evdev->a11y_flags & META_A11Y_BOUNCE_KEYS_ENABLED) && (get_debounce_delay (device) != 0)) { if ((event->type == CLUTTER_KEY_PRESS) && debounce_key (event, device_evdev)) @@ -1148,7 +1149,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve start_bounce_keys (event, device_evdev); } - if ((device_evdev->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_ENABLED) && + if ((device_evdev->a11y_flags & META_A11Y_SLOW_KEYS_ENABLED) && (get_slow_keys_delay (device) != 0)) { if (event->type == CLUTTER_KEY_PRESS) @@ -1159,7 +1160,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve return; } - if (device_evdev->a11y_flags & CLUTTER_A11Y_STICKY_KEYS_ENABLED) + if (device_evdev->a11y_flags & META_A11Y_STICKY_KEYS_ENABLED) { if (event->type == CLUTTER_KEY_PRESS) handle_stickykeys_press (event, device_evdev); @@ -1172,34 +1173,34 @@ emit_event: } void -meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device, - ClutterKbdA11ySettings *settings) +meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device, + MetaKbdA11ySettings *settings) { - ClutterKeyboardA11yFlags changed_flags = (device->a11y_flags ^ settings->controls); + MetaKeyboardA11yFlags changed_flags = (device->a11y_flags ^ settings->controls); - if (changed_flags & (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_SLOW_KEYS_ENABLED)) + if (changed_flags & (META_A11Y_KEYBOARD_ENABLED | META_A11Y_SLOW_KEYS_ENABLED)) clear_slow_keys (device); - if (changed_flags & (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_BOUNCE_KEYS_ENABLED)) + if (changed_flags & (META_A11Y_KEYBOARD_ENABLED | META_A11Y_BOUNCE_KEYS_ENABLED)) device->debounce_key = 0; - if (changed_flags & (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_STICKY_KEYS_ENABLED)) + if (changed_flags & (META_A11Y_KEYBOARD_ENABLED | META_A11Y_STICKY_KEYS_ENABLED)) { device->stickykeys_depressed_mask = 0; update_internal_xkb_state (device, 0, 0); } - if (changed_flags & CLUTTER_A11Y_KEYBOARD_ENABLED) + if (changed_flags & META_A11Y_KEYBOARD_ENABLED) { device->toggle_slowkeys_timer = 0; device->shift_count = 0; device->last_shift_time = 0; } - if (changed_flags & (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_MOUSE_KEYS_ENABLED)) + if (changed_flags & (META_A11Y_KEYBOARD_ENABLED | META_A11Y_MOUSE_KEYS_ENABLED)) { if (settings->controls & - (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_MOUSE_KEYS_ENABLED)) + (META_A11Y_KEYBOARD_ENABLED | META_A11Y_MOUSE_KEYS_ENABLED)) enable_mousekeys (device); else disable_mousekeys (device); @@ -1213,7 +1214,7 @@ meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device void meta_input_device_native_a11y_maybe_notify_toggle_keys (MetaInputDeviceNative *device) { - if (device->a11y_flags & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED) + if (device->a11y_flags & META_A11Y_TOGGLE_KEYS_ENABLED) meta_input_device_native_bell_notify (device); } diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h index da23b1778cc..0586e93d41c 100644 --- a/src/backends/native/meta-input-device-native.h +++ b/src/backends/native/meta-input-device-native.h @@ -29,6 +29,7 @@ #include #include "backends/meta-input-device-private.h" +#include "backends/meta-input-settings-private.h" #include "backends/native/meta-seat-native.h" #include "clutter/clutter-mutter.h" @@ -81,7 +82,7 @@ struct _MetaInputDeviceNative float pointer_y; /* Keyboard a11y */ - ClutterKeyboardA11yFlags a11y_flags; + MetaKeyboardA11yFlags a11y_flags; GList *slow_keys_list; guint debounce_timer; uint16_t debounce_key; @@ -134,8 +135,8 @@ MetaInputDeviceMapping meta_input_device_native_get_mapping_mode (ClutterInpu void meta_input_device_native_set_mapping_mode (ClutterInputDevice *device, MetaInputDeviceMapping mapping); -void meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device, - ClutterKbdA11ySettings *settings); +void meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device, + MetaKbdA11ySettings *settings); void meta_input_device_native_a11y_maybe_notify_toggle_keys (MetaInputDeviceNative *device_evdev); diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 967113d2c9f..6a4c3fe68eb 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -2705,18 +2705,6 @@ meta_seat_native_free_event_data (ClutterSeat *seat, meta_event_native_free (event_evdev); } -static void -meta_seat_native_apply_kbd_a11y_settings (ClutterSeat *seat, - ClutterKbdA11ySettings *settings) -{ - ClutterInputDevice *device; - - device = clutter_seat_get_keyboard (seat); - if (device) - meta_input_device_native_apply_kbd_a11y_settings (META_INPUT_DEVICE_NATIVE (device), - settings); -} - static guint bump_virtual_touch_slot_base (MetaSeatNative *seat_native) { @@ -2880,7 +2868,6 @@ meta_seat_native_class_init (MetaSeatNativeClass *klass) seat_class->get_keymap = meta_seat_native_get_keymap; seat_class->copy_event_data = meta_seat_native_copy_event_data; seat_class->free_event_data = meta_seat_native_free_event_data; - seat_class->apply_kbd_a11y_settings = meta_seat_native_apply_kbd_a11y_settings; seat_class->create_virtual_device = meta_seat_native_create_virtual_device; seat_class->get_supported_virtual_device_types = meta_seat_native_get_supported_virtual_device_types; seat_class->compress_motion = meta_seat_native_compress_motion; diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c index d53deb38615..068f138c659 100644 --- a/src/backends/x11/meta-backend-x11.c +++ b/src/backends/x11/meta-backend-x11.c @@ -50,6 +50,7 @@ #include "backends/x11/meta-seat-x11.h" #include "backends/x11/meta-stage-x11.h" #include "backends/x11/meta-renderer-x11.h" +#include "backends/x11/meta-xkb-a11y-x11.h" #include "clutter/clutter.h" #include "clutter/x11/clutter-x11.h" #include "compositor/compositor-private.h" @@ -519,6 +520,17 @@ on_monitors_changed (MetaMonitorManager *manager, priv->cached_current_logical_monitor = NULL; } +static void +on_kbd_a11y_changed (MetaInputSettings *input_settings, + MetaKbdA11ySettings *a11y_settings, + MetaBackend *backend) +{ + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); + + meta_seat_x11_apply_kbd_a11y_settings (seat, a11y_settings); +} + static void meta_backend_x11_post_init (MetaBackend *backend) { @@ -527,6 +539,7 @@ meta_backend_x11_post_init (MetaBackend *backend) MetaMonitorManager *monitor_manager; ClutterBackend *clutter_backend; ClutterSeat *seat; + MetaInputSettings *input_settings; int major, minor; gboolean has_xi = FALSE; @@ -584,6 +597,15 @@ meta_backend_x11_post_init (MetaBackend *backend) seat = clutter_backend_get_default_seat (clutter_backend); meta_seat_x11_notify_devices (META_SEAT_X11 (seat), CLUTTER_STAGE (meta_backend_get_stage (backend))); + + input_settings = meta_backend_get_input_settings (backend); + + if (input_settings) + { + g_signal_connect_object (meta_backend_get_input_settings (backend), + "kbd-a11y-changed", + G_CALLBACK (on_kbd_a11y_changed), backend, 0); + } } static ClutterBackend * diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index 59ee0f6f87d..79e744d1197 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -1325,13 +1325,15 @@ static void on_keymap_state_change (MetaKeymapX11 *keymap_x11, gpointer data) { - ClutterSeat *seat = CLUTTER_SEAT (data); - ClutterKbdA11ySettings kbd_a11y_settings; + ClutterSeat *seat = data; + MetaInputSettings *input_settings; + MetaKbdA11ySettings kbd_a11y_settings; /* On keymaps state change, just reapply the current settings, it'll * take care of enabling/disabling mousekeys based on NumLock state. */ - clutter_seat_get_kbd_a11y_settings (seat, &kbd_a11y_settings); + input_settings = meta_backend_get_input_settings (meta_get_backend ()); + meta_input_settings_get_kbd_a11y_settings (input_settings, &kbd_a11y_settings); meta_seat_x11_apply_kbd_a11y_settings (seat, &kbd_a11y_settings); } @@ -1755,7 +1757,6 @@ meta_seat_x11_class_init (MetaSeatX11Class *klass) seat_class->get_keymap = meta_seat_x11_get_keymap; seat_class->copy_event_data = meta_seat_x11_copy_event_data; seat_class->free_event_data = meta_seat_x11_free_event_data; - seat_class->apply_kbd_a11y_settings = meta_seat_x11_apply_kbd_a11y_settings; seat_class->create_virtual_device = meta_seat_x11_create_virtual_device; seat_class->get_supported_virtual_device_types = meta_seat_x11_get_supported_virtual_device_types; seat_class->warp_pointer = meta_seat_x11_warp_pointer; diff --git a/src/backends/x11/meta-xkb-a11y-x11.c b/src/backends/x11/meta-xkb-a11y-x11.c index 5deb6f3ff89..024618be6bd 100644 --- a/src/backends/x11/meta-xkb-a11y-x11.c +++ b/src/backends/x11/meta-xkb-a11y-x11.c @@ -78,40 +78,43 @@ static void check_settings_changed (ClutterSeat *seat) { Display *xdisplay = clutter_x11_get_default_display (); - ClutterKbdA11ySettings kbd_a11y_settings; - ClutterKeyboardA11yFlags what_changed = 0; + MetaKbdA11ySettings kbd_a11y_settings; + MetaKeyboardA11yFlags what_changed = 0; + MetaInputSettings *input_settings; XkbDescRec *desc; desc = get_xkb_desc_rec (xdisplay); if (!desc) return; - clutter_seat_get_kbd_a11y_settings (seat, &kbd_a11y_settings); + input_settings = meta_backend_get_input_settings (meta_get_backend ()); + meta_input_settings_get_kbd_a11y_settings (input_settings, + &kbd_a11y_settings); if (desc->ctrls->enabled_ctrls & XkbSlowKeysMask && - !(kbd_a11y_settings.controls & CLUTTER_A11Y_SLOW_KEYS_ENABLED)) + !(kbd_a11y_settings.controls & META_A11Y_SLOW_KEYS_ENABLED)) { - what_changed |= CLUTTER_A11Y_SLOW_KEYS_ENABLED; - kbd_a11y_settings.controls |= CLUTTER_A11Y_SLOW_KEYS_ENABLED; + what_changed |= META_A11Y_SLOW_KEYS_ENABLED; + kbd_a11y_settings.controls |= META_A11Y_SLOW_KEYS_ENABLED; } else if (!(desc->ctrls->enabled_ctrls & XkbSlowKeysMask) && - kbd_a11y_settings.controls & CLUTTER_A11Y_SLOW_KEYS_ENABLED) + kbd_a11y_settings.controls & META_A11Y_SLOW_KEYS_ENABLED) { - what_changed |= CLUTTER_A11Y_SLOW_KEYS_ENABLED; - kbd_a11y_settings.controls &= ~CLUTTER_A11Y_SLOW_KEYS_ENABLED; + what_changed |= META_A11Y_SLOW_KEYS_ENABLED; + kbd_a11y_settings.controls &= ~META_A11Y_SLOW_KEYS_ENABLED; } if (desc->ctrls->enabled_ctrls & XkbStickyKeysMask && - !(kbd_a11y_settings.controls & CLUTTER_A11Y_STICKY_KEYS_ENABLED)) + !(kbd_a11y_settings.controls & META_A11Y_STICKY_KEYS_ENABLED)) { - what_changed |= CLUTTER_A11Y_STICKY_KEYS_ENABLED; - kbd_a11y_settings.controls |= CLUTTER_A11Y_STICKY_KEYS_ENABLED; + what_changed |= META_A11Y_STICKY_KEYS_ENABLED; + kbd_a11y_settings.controls |= META_A11Y_STICKY_KEYS_ENABLED; } else if (!(desc->ctrls->enabled_ctrls & XkbStickyKeysMask) && - kbd_a11y_settings.controls & CLUTTER_A11Y_STICKY_KEYS_ENABLED) + kbd_a11y_settings.controls & META_A11Y_STICKY_KEYS_ENABLED) { - what_changed |= CLUTTER_A11Y_STICKY_KEYS_ENABLED; - kbd_a11y_settings.controls &= ~CLUTTER_A11Y_STICKY_KEYS_ENABLED; + what_changed |= META_A11Y_STICKY_KEYS_ENABLED; + kbd_a11y_settings.controls &= ~META_A11Y_STICKY_KEYS_ENABLED; } if (what_changed) @@ -182,10 +185,10 @@ set_value_mask (gboolean flag, } static gboolean -set_xkb_ctrl (XkbDescRec *desc, - ClutterKeyboardA11yFlags settings, - ClutterKeyboardA11yFlags flag, - unsigned long mask) +set_xkb_ctrl (XkbDescRec *desc, + MetaKeyboardA11yFlags settings, + MetaKeyboardA11yFlags flag, + unsigned long mask) { gboolean result = (settings & flag) == flag; desc->ctrls->enabled_ctrls = set_value_mask (result, desc->ctrls->enabled_ctrls, mask); @@ -194,8 +197,8 @@ set_xkb_ctrl (XkbDescRec *desc, } void -meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat, - ClutterKbdA11ySettings *kbd_a11y_settings) +meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat, + MetaKbdA11ySettings *kbd_a11y_settings) { Display *xdisplay = clutter_x11_get_default_display (); XkbDescRec *desc; @@ -206,13 +209,13 @@ meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat, return; /* general */ - enable_accessX = kbd_a11y_settings->controls & CLUTTER_A11Y_KEYBOARD_ENABLED; + enable_accessX = kbd_a11y_settings->controls & META_A11Y_KEYBOARD_ENABLED; desc->ctrls->enabled_ctrls = set_value_mask (enable_accessX, desc->ctrls->enabled_ctrls, XkbAccessXKeysMask); - if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, CLUTTER_A11Y_TIMEOUT_ENABLED, + if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, META_A11Y_TIMEOUT_ENABLED, XkbAccessXTimeoutMask)) { desc->ctrls->ax_timeout = kbd_a11y_settings->timeout_delay; @@ -226,17 +229,17 @@ meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat, } desc->ctrls->ax_options = - set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP, + set_value_mask (kbd_a11y_settings->controls & META_A11Y_FEATURE_STATE_CHANGE_BEEP, desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_FeatureFBMask | XkbAX_SlowWarnFBMask); /* bounce keys */ if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, - CLUTTER_A11Y_BOUNCE_KEYS_ENABLED, XkbBounceKeysMask)) + META_A11Y_BOUNCE_KEYS_ENABLED, XkbBounceKeysMask)) { desc->ctrls->debounce_delay = kbd_a11y_settings->debounce_delay; desc->ctrls->ax_options = - set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT, + set_value_mask (kbd_a11y_settings->controls & META_A11Y_BOUNCE_KEYS_BEEP_REJECT, desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_BKRejectFBMask); } @@ -248,7 +251,7 @@ meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat, desc->ctrls->enabled_ctrls &= ~(XkbMouseKeysMask | XkbMouseKeysAccelMask); } else if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, - CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask)) + META_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask)) { int mk_max_speed; int mk_accel_time; @@ -273,16 +276,16 @@ meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat, /* slow keys */ if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, - CLUTTER_A11Y_SLOW_KEYS_ENABLED, XkbSlowKeysMask)) + META_A11Y_SLOW_KEYS_ENABLED, XkbSlowKeysMask)) { desc->ctrls->ax_options = - set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS, + set_value_mask (kbd_a11y_settings->controls & META_A11Y_SLOW_KEYS_BEEP_PRESS, desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKPressFBMask); desc->ctrls->ax_options = - set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT, + set_value_mask (kbd_a11y_settings->controls & META_A11Y_SLOW_KEYS_BEEP_ACCEPT, desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKAcceptFBMask); desc->ctrls->ax_options = - set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT, + set_value_mask (kbd_a11y_settings->controls & META_A11Y_SLOW_KEYS_BEEP_REJECT, desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKRejectFBMask); desc->ctrls->slow_keys_delay = kbd_a11y_settings->slowkeys_delay; /* anything larger than 500 seems to loose all keyboard input */ @@ -292,20 +295,20 @@ meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat, /* sticky keys */ if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, - CLUTTER_A11Y_STICKY_KEYS_ENABLED, XkbStickyKeysMask)) + META_A11Y_STICKY_KEYS_ENABLED, XkbStickyKeysMask)) { desc->ctrls->ax_options |= XkbAX_LatchToLockMask; desc->ctrls->ax_options = - set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF, + set_value_mask (kbd_a11y_settings->controls & META_A11Y_STICKY_KEYS_TWO_KEY_OFF, desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_TwoKeysMask); desc->ctrls->ax_options = - set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_STICKY_KEYS_BEEP, + set_value_mask (kbd_a11y_settings->controls & META_A11Y_STICKY_KEYS_BEEP, desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_StickyKeysFBMask); } /* toggle keys */ desc->ctrls->ax_options = - set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED, + set_value_mask (kbd_a11y_settings->controls & META_A11Y_TOGGLE_KEYS_ENABLED, desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_IndicatorFBMask); set_xkb_desc_rec (xdisplay, desc); diff --git a/src/backends/x11/meta-xkb-a11y-x11.h b/src/backends/x11/meta-xkb-a11y-x11.h index 7f11bf7b0a5..58a4e176611 100644 --- a/src/backends/x11/meta-xkb-a11y-x11.h +++ b/src/backends/x11/meta-xkb-a11y-x11.h @@ -26,11 +26,12 @@ #include +#include "backends/meta-input-settings-private.h" #include "clutter/clutter.h" void -meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat, - ClutterKbdA11ySettings *kbd_a11y_settings); +meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat, + MetaKbdA11ySettings *kbd_a11y_settings); gboolean meta_seat_x11_a11y_init (ClutterSeat *seat); -- GitLab From 2ceac4a2967dc34a2d1ebc88c3f9796fd108272b Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 11 Aug 2020 11:27:18 +0200 Subject: [PATCH 42/85] clutter: Make ClutterSeat::handle_device_event vfunc more generic Make it able to handle not just device added/removed events, but perform any kind of post-processing that needed to be done on ClutterEvents at the seat level. Part-of: --- clutter/clutter/clutter-main.c | 8 +------- clutter/clutter/clutter-mutter.h | 3 +++ clutter/clutter/clutter-seat.c | 15 +++++---------- clutter/clutter/clutter-seat.h | 7 ++----- src/backends/meta-backend.c | 5 +++++ src/backends/native/meta-seat-native.c | 6 +++--- src/backends/x11/meta-seat-x11.c | 13 +++++++++---- 7 files changed, 28 insertions(+), 29 deletions(-) diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index 6382d3951b7..9ac6d53bff4 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -1938,13 +1938,7 @@ _clutter_process_event_details (ClutterActor *stage, case CLUTTER_DEVICE_ADDED: case CLUTTER_DEVICE_REMOVED: - if (!_clutter_event_process_filters (event)) - { - ClutterSeat *seat; - - seat = clutter_backend_get_default_seat (context->backend); - clutter_seat_handle_device_event (seat, event); - } + _clutter_event_process_filters (event); break; case CLUTTER_EVENT_LAST: diff --git a/clutter/clutter/clutter-mutter.h b/clutter/clutter/clutter-mutter.h index 654c6dac0ed..9c75ad6a256 100644 --- a/clutter/clutter/clutter-mutter.h +++ b/clutter/clutter/clutter-mutter.h @@ -71,6 +71,9 @@ gboolean clutter_actor_has_transitions (ClutterActor *actor); CLUTTER_EXPORT ClutterFrameClock * clutter_actor_pick_frame_clock (ClutterActor *self, ClutterActor **out_actor); +CLUTTER_EXPORT +gboolean clutter_seat_handle_event_post (ClutterSeat *seat, + const ClutterEvent *event); #undef __CLUTTER_H_INSIDE__ diff --git a/clutter/clutter/clutter-seat.c b/clutter/clutter/clutter-seat.c index d3e2eaa2456..ed78f43a598 100644 --- a/clutter/clutter/clutter-seat.c +++ b/clutter/clutter/clutter-seat.c @@ -27,6 +27,7 @@ #include "clutter-input-device-tool.h" #include "clutter-input-pointer-a11y-private.h" #include "clutter-marshal.h" +#include "clutter-mutter.h" #include "clutter-private.h" #include "clutter-seat.h" #include "clutter-virtual-input-device.h" @@ -635,8 +636,8 @@ clutter_seat_compress_motion (ClutterSeat *seat, } gboolean -clutter_seat_handle_device_event (ClutterSeat *seat, - ClutterEvent *event) +clutter_seat_handle_event_post (ClutterSeat *seat, + const ClutterEvent *event) { ClutterSeatClass *seat_class; ClutterInputDevice *device; @@ -644,16 +645,10 @@ clutter_seat_handle_device_event (ClutterSeat *seat, g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE); g_return_val_if_fail (event, FALSE); - g_assert (event->type == CLUTTER_DEVICE_ADDED || - event->type == CLUTTER_DEVICE_REMOVED); - seat_class = CLUTTER_SEAT_GET_CLASS (seat); - if (seat_class->handle_device_event) - { - if (!seat_class->handle_device_event (seat, event)) - return FALSE; - } + if (seat_class->handle_event_post) + seat_class->handle_event_post (seat, event); device = clutter_event_get_source_device (event); g_assert_true (CLUTTER_IS_INPUT_DEVICE (device)); diff --git a/clutter/clutter/clutter-seat.h b/clutter/clutter/clutter-seat.h index cb2ebf97791..6ef748fddd0 100644 --- a/clutter/clutter/clutter-seat.h +++ b/clutter/clutter/clutter-seat.h @@ -88,8 +88,8 @@ struct _ClutterSeatClass ClutterEvent *event, const ClutterEvent *to_discard); - gboolean (* handle_device_event) (ClutterSeat *seat, - ClutterEvent *event); + gboolean (* handle_event_post) (ClutterSeat *seat, + const ClutterEvent *event); void (* warp_pointer) (ClutterSeat *seat, int x, @@ -162,9 +162,6 @@ void clutter_seat_compress_motion (ClutterSeat *seat, ClutterEvent *event, const ClutterEvent *to_discard); -gboolean clutter_seat_handle_device_event (ClutterSeat *seat, - ClutterEvent *event); - CLUTTER_EXPORT void clutter_seat_warp_pointer (ClutterSeat *seat, int x, diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index e1638660507..ba964c58b76 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -994,12 +994,17 @@ clutter_source_dispatch (GSource *source, gpointer user_data) { MetaBackendSource *backend_source = (MetaBackendSource *) source; + MetaBackendPrivate *priv = + meta_backend_get_instance_private (backend_source->backend); ClutterEvent *event = clutter_event_get (); + ClutterSeat *seat; if (event) { event->any.stage = CLUTTER_STAGE (meta_backend_get_stage (backend_source->backend)); + seat = clutter_backend_get_default_seat (priv->clutter_backend); + clutter_seat_handle_event_post (seat, event); clutter_do_event (event); clutter_event_free (event); } diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 6a4c3fe68eb..13aa4b58857 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -1488,8 +1488,8 @@ evdev_remove_device (MetaSeatNative *seat, } static gboolean -meta_seat_native_handle_device_event (ClutterSeat *seat, - ClutterEvent *event) +meta_seat_native_handle_event_post (ClutterSeat *seat, + const ClutterEvent *event) { MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); ClutterInputDevice *device = event->device.device; @@ -2872,7 +2872,7 @@ meta_seat_native_class_init (MetaSeatNativeClass *klass) seat_class->get_supported_virtual_device_types = meta_seat_native_get_supported_virtual_device_types; seat_class->compress_motion = meta_seat_native_compress_motion; seat_class->warp_pointer = meta_seat_native_warp_pointer; - seat_class->handle_device_event = meta_seat_native_handle_device_event; + seat_class->handle_event_post = meta_seat_native_handle_event_post; seat_class->query_state = meta_seat_native_query_state; props[PROP_SEAT_ID] = diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index 79e744d1197..f437ef16d5c 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -720,13 +720,18 @@ remove_device (MetaSeatX11 *seat_x11, } static gboolean -meta_seat_x11_handle_device_event (ClutterSeat *seat, - ClutterEvent *event) +meta_seat_x11_handle_event_post (ClutterSeat *seat, + const ClutterEvent *event) { MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - ClutterInputDevice *device = event->device.device; + ClutterInputDevice *device; gboolean is_touch; + if (event->type != CLUTTER_DEVICE_ADDED && + event->type != CLUTTER_DEVICE_REMOVED) + return TRUE; + + device = clutter_event_get_device (event); is_touch = clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE; @@ -1760,7 +1765,7 @@ meta_seat_x11_class_init (MetaSeatX11Class *klass) seat_class->create_virtual_device = meta_seat_x11_create_virtual_device; seat_class->get_supported_virtual_device_types = meta_seat_x11_get_supported_virtual_device_types; seat_class->warp_pointer = meta_seat_x11_warp_pointer; - seat_class->handle_device_event = meta_seat_x11_handle_device_event; + seat_class->handle_event_post = meta_seat_x11_handle_event_post; seat_class->query_state = meta_seat_x11_query_state; props[PROP_OPCODE] = -- GitLab From 59059e17305c16f6d8145fb6cf324f6ed9926509 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 7 Aug 2020 15:13:51 +0200 Subject: [PATCH 43/85] backends/native: Spin MetaSeatImpl off MetaSeatNative Move most of the functional bits (those meant to run on a standalone thread) to a MetaSeatImpl object. This object is managed by the MetaSeatImpl and not exposed outside the friend MetaSeatNative/MetaInputDeviceNative/ MetaInputSettings classes. Part-of: --- .../native/meta-backend-native-types.h | 1 + .../native/meta-input-device-native.c | 72 +- .../native/meta-input-device-native.h | 8 +- .../native/meta-input-settings-native.c | 4 +- src/backends/native/meta-keymap-native.c | 4 +- src/backends/native/meta-launcher.c | 21 +- src/backends/native/meta-seat-impl.c | 3022 +++++++++++++++++ src/backends/native/meta-seat-impl.h | 242 ++ src/backends/native/meta-seat-native.c | 2778 +-------------- src/backends/native/meta-seat-native.h | 144 +- .../native/meta-virtual-input-device-native.c | 172 +- src/meson.build | 2 + 12 files changed, 3482 insertions(+), 2988 deletions(-) create mode 100644 src/backends/native/meta-seat-impl.c create mode 100644 src/backends/native/meta-seat-impl.h diff --git a/src/backends/native/meta-backend-native-types.h b/src/backends/native/meta-backend-native-types.h index 3112e915d69..bfc506788a6 100644 --- a/src/backends/native/meta-backend-native-types.h +++ b/src/backends/native/meta-backend-native-types.h @@ -22,5 +22,6 @@ #define META_BACKEND_NATIVE_TYPES_H typedef struct _MetaBackendNative MetaBackendNative; +typedef struct _MetaSeatNative MetaSeatNative; #endif /* META_BACKEND_NATIVE_TYPES_H */ diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index 3117402cfa7..ec41afc08c4 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -215,7 +215,7 @@ meta_input_device_native_is_grouped (ClutterInputDevice *device, static void meta_input_device_native_bell_notify (MetaInputDeviceNative *device) { - clutter_seat_bell_notify (CLUTTER_SEAT (device->seat)); + clutter_seat_bell_notify (CLUTTER_SEAT (device->seat_impl->seat_native)); } static void @@ -416,7 +416,7 @@ key_event_is_modifier (ClutterEvent *event) static void notify_stickykeys_mask (MetaInputDeviceNative *device) { - g_signal_emit_by_name (device->seat, + g_signal_emit_by_name (device->seat_impl->seat_native, "kbd-a11y-mods-state-changed", device->stickykeys_latched_mask, device->stickykeys_locked_mask); @@ -427,15 +427,17 @@ update_internal_xkb_state (MetaInputDeviceNative *device, xkb_mod_mask_t new_latched_mask, xkb_mod_mask_t new_locked_mask) { - MetaSeatNative *seat = device->seat; + MetaSeatImpl *seat_impl = device->seat_impl; xkb_mod_mask_t depressed_mods; xkb_mod_mask_t latched_mods; xkb_mod_mask_t locked_mods; xkb_mod_mask_t group_mods; + struct xkb_state *xkb_state; - depressed_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED); - latched_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LATCHED); - locked_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LOCKED); + xkb_state = meta_seat_impl_get_xkb_state (seat_impl); + depressed_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED); + latched_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LATCHED); + locked_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LOCKED); latched_mods &= ~device->stickykeys_latched_mask; locked_mods &= ~device->stickykeys_locked_mask; @@ -446,9 +448,9 @@ update_internal_xkb_state (MetaInputDeviceNative *device, latched_mods |= device->stickykeys_latched_mask; locked_mods |= device->stickykeys_locked_mask; - group_mods = xkb_state_serialize_layout (seat->xkb, XKB_STATE_LAYOUT_EFFECTIVE); + group_mods = xkb_state_serialize_layout (xkb_state, XKB_STATE_LAYOUT_EFFECTIVE); - xkb_state_update_mask (seat->xkb, + xkb_state_update_mask (xkb_state, depressed_mods, latched_mods, locked_mods, @@ -462,23 +464,25 @@ update_stickykeys_event (ClutterEvent *event, xkb_mod_mask_t new_latched_mask, xkb_mod_mask_t new_locked_mask) { - MetaSeatNative *seat = device->seat; + MetaSeatImpl *seat_impl = device->seat_impl; xkb_mod_mask_t effective_mods; xkb_mod_mask_t latched_mods; xkb_mod_mask_t locked_mods; + struct xkb_state *xkb_state; update_internal_xkb_state (device, new_latched_mask, new_locked_mask); - effective_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_EFFECTIVE); - latched_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LATCHED); - locked_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LOCKED); + xkb_state = meta_seat_impl_get_xkb_state (seat_impl); + effective_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE); + latched_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LATCHED); + locked_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LOCKED); _clutter_event_set_state_full (event, - seat->button_state, + seat_impl->button_state, device->stickykeys_depressed_mask, latched_mods, locked_mods, - effective_mods | seat->button_state); + effective_mods | seat_impl->button_state); } static void @@ -542,10 +546,11 @@ static void handle_stickykeys_press (ClutterEvent *event, MetaInputDeviceNative *device) { - MetaSeatNative *seat = device->seat; + MetaSeatImpl *seat_impl = device->seat_impl; xkb_mod_mask_t depressed_mods; xkb_mod_mask_t new_latched_mask; xkb_mod_mask_t new_locked_mask; + struct xkb_state *xkb_state; if (!key_event_is_modifier (event)) return; @@ -557,7 +562,8 @@ handle_stickykeys_press (ClutterEvent *event, return; } - depressed_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED); + xkb_state = meta_seat_impl_get_xkb_state (seat_impl); + depressed_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED); /* Ignore the lock modifier mask, that one cannot be sticky, yet the * CAPS_LOCK key itself counts as a modifier as it might be remapped * to some other modifier which can be sticky. @@ -590,10 +596,12 @@ static void handle_stickykeys_release (ClutterEvent *event, MetaInputDeviceNative *device) { - MetaSeatNative *seat = device->seat; + MetaSeatImpl *seat_impl = device->seat_impl; + struct xkb_state *xkb_state; + xkb_state = meta_seat_impl_get_xkb_state (seat_impl); device->stickykeys_depressed_mask = - xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED); + xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED); if (key_event_is_modifier (event)) { @@ -831,8 +839,12 @@ emulate_pointer_motion (MetaInputDeviceNative *device_evdev, static gboolean is_numlock_active (MetaInputDeviceNative *device) { - MetaSeatNative *seat = device->seat; - return xkb_state_mod_name_is_active (seat->xkb, + MetaSeatImpl *seat_impl = device->seat_impl; + struct xkb_state *xkb_state; + + xkb_state = meta_seat_impl_get_xkb_state (seat_impl); + + return xkb_state_mod_name_is_active (xkb_state, "Mod2", XKB_STATE_MODS_LOCKED); } @@ -852,7 +864,7 @@ enable_mousekeys (MetaInputDeviceNative *device_evdev) return; device->accessibility_virtual_device = - clutter_seat_create_virtual_device (CLUTTER_SEAT (device_evdev->seat), + clutter_seat_create_virtual_device (clutter_input_device_get_seat (device), CLUTTER_POINTER_DEVICE); } @@ -1269,7 +1281,7 @@ meta_input_device_native_init (MetaInputDeviceNative *self) * it with the provided seat. */ ClutterInputDevice * -meta_input_device_native_new (MetaSeatNative *seat, +meta_input_device_native_new (MetaSeatImpl *seat_impl, struct libinput_device *libinput_device) { MetaInputDeviceNative *device; @@ -1302,10 +1314,10 @@ meta_input_device_native_new (MetaSeatNative *seat, "n-strips", n_strips, "n-mode-groups", n_groups, "device-node", node_path, - "seat", seat, + "seat", seat_impl->seat_native, NULL); - device->seat = seat; + device->seat_impl = seat_impl; device->libinput_device = libinput_device; libinput_device_set_user_data (libinput_device, device); @@ -1328,7 +1340,7 @@ meta_input_device_native_new (MetaSeatNative *seat, * Create a new virtual ClutterInputDevice of the given type. */ ClutterInputDevice * -meta_input_device_native_new_virtual (MetaSeatNative *seat, +meta_input_device_native_new_virtual (MetaSeatImpl *seat_impl, ClutterInputDeviceType type, ClutterInputMode mode) { @@ -1355,18 +1367,18 @@ meta_input_device_native_new_virtual (MetaSeatNative *seat, "name", name, "device-type", type, "device-mode", mode, - "seat", seat, + "seat", seat_impl->seat_native, NULL); - device->seat = seat; + device->seat_impl = seat_impl; return CLUTTER_INPUT_DEVICE (device); } -MetaSeatNative * -meta_input_device_native_get_seat (MetaInputDeviceNative *device) +MetaSeatImpl * +meta_input_device_native_get_seat_impl (MetaInputDeviceNative *device) { - return device->seat; + return device->seat_impl; } void diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h index 0586e93d41c..e76aade71b0 100644 --- a/src/backends/native/meta-input-device-native.h +++ b/src/backends/native/meta-input-device-native.h @@ -69,7 +69,7 @@ struct _MetaInputDeviceNative ClutterInputDevice parent; struct libinput_device *libinput_device; - MetaSeatNative *seat; + MetaSeatImpl *seat_impl; ClutterInputDeviceTool *last_tool; cairo_matrix_t device_matrix; @@ -111,14 +111,14 @@ struct _MetaInputDeviceNativeClass GType meta_input_device_native_get_type (void) G_GNUC_CONST; -ClutterInputDevice * meta_input_device_native_new (MetaSeatNative *seat, +ClutterInputDevice * meta_input_device_native_new (MetaSeatImpl *seat_impl, struct libinput_device *libinput_device); -ClutterInputDevice * meta_input_device_native_new_virtual (MetaSeatNative *seat, +ClutterInputDevice * meta_input_device_native_new_virtual (MetaSeatImpl *seat_impl, ClutterInputDeviceType type, ClutterInputMode mode); -MetaSeatNative * meta_input_device_native_get_seat (MetaInputDeviceNative *device); +MetaSeatImpl * meta_input_device_native_get_seat_impl (MetaInputDeviceNative *device); void meta_input_device_native_update_leds (MetaInputDeviceNative *device, enum libinput_led leds); diff --git a/src/backends/native/meta-input-settings-native.c b/src/backends/native/meta-input-settings-native.c index fc435942954..f16fbd9c10a 100644 --- a/src/backends/native/meta-input-settings-native.c +++ b/src/backends/native/meta-input-settings-native.c @@ -412,8 +412,8 @@ meta_input_settings_native_set_keyboard_repeat (MetaInputSettings *settings, ClutterSeat *seat; seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); - meta_seat_native_set_keyboard_repeat (META_SEAT_NATIVE (seat), - enabled, delay, interval); + meta_seat_impl_set_keyboard_repeat (META_SEAT_NATIVE (seat)->impl, + enabled, delay, interval); } static void diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c index 3b0da0d1fa2..d1990353229 100644 --- a/src/backends/native/meta-keymap-native.c +++ b/src/backends/native/meta-keymap-native.c @@ -58,7 +58,7 @@ meta_keymap_native_get_num_lock_state (ClutterKeymap *keymap) ClutterSeat *seat; seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); - xkb_state = meta_seat_native_get_xkb_state (META_SEAT_NATIVE (seat)); + xkb_state = meta_seat_impl_get_xkb_state (META_SEAT_NATIVE (seat)->impl); return xkb_state_mod_name_is_active (xkb_state, XKB_MOD_NAME_NUM, @@ -73,7 +73,7 @@ meta_keymap_native_get_caps_lock_state (ClutterKeymap *keymap) ClutterSeat *seat; seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); - xkb_state = meta_seat_native_get_xkb_state (META_SEAT_NATIVE (seat)); + xkb_state = meta_seat_impl_get_xkb_state (META_SEAT_NATIVE (seat)->impl); return xkb_state_mod_name_is_active (xkb_state, XKB_MOD_NAME_CAPS, diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c index 61fe19be09d..3f20fbc74c5 100644 --- a/src/backends/native/meta-launcher.c +++ b/src/backends/native/meta-launcher.c @@ -51,7 +51,9 @@ struct _MetaLauncher Login1Seat *seat_proxy; char *seat_id; - GHashTable *sysfs_fds; + struct { + GHashTable *sysfs_fds; + } impl; gboolean session_active; }; @@ -410,7 +412,7 @@ on_evdev_device_open (const char *path, return -1; } - g_hash_table_add (self->sysfs_fds, GINT_TO_POINTER (fd)); + g_hash_table_add (self->impl.sysfs_fds, GINT_TO_POINTER (fd)); return fd; } @@ -423,10 +425,10 @@ on_evdev_device_close (int fd, { MetaLauncher *self = user_data; - if (g_hash_table_lookup (self->sysfs_fds, GINT_TO_POINTER (fd))) + if (g_hash_table_lookup (self->impl.sysfs_fds, GINT_TO_POINTER (fd))) { /* /sys/ paths just need close() here */ - g_hash_table_remove (self->sysfs_fds, GINT_TO_POINTER (fd)); + g_hash_table_remove (self->impl.sysfs_fds, GINT_TO_POINTER (fd)); close (fd); return; } @@ -523,14 +525,14 @@ meta_launcher_new (GError **error) self->session_proxy = g_object_ref (session_proxy); self->seat_proxy = g_object_ref (seat_proxy); self->seat_id = g_steal_pointer (&seat_id); - self->sysfs_fds = g_hash_table_new (NULL, NULL); + self->impl.sysfs_fds = g_hash_table_new (NULL, NULL); self->session_active = TRUE; meta_clutter_backend_native_set_seat_id (self->seat_id); - meta_seat_native_set_device_callbacks (on_evdev_device_open, - on_evdev_device_close, - self); + meta_seat_impl_set_device_callbacks (on_evdev_device_open, + on_evdev_device_close, + self); g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self); @@ -545,10 +547,11 @@ meta_launcher_new (GError **error) void meta_launcher_free (MetaLauncher *self) { + meta_seat_impl_set_device_callbacks (NULL, NULL, NULL); g_free (self->seat_id); g_object_unref (self->seat_proxy); g_object_unref (self->session_proxy); - g_hash_table_destroy (self->sysfs_fds); + g_hash_table_destroy (self->impl.sysfs_fds); g_slice_free (MetaLauncher, self); } diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c new file mode 100644 index 00000000000..f3eb6efe114 --- /dev/null +++ b/src/backends/native/meta-seat-impl.c @@ -0,0 +1,3022 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2010 Intel Corp. + * Copyright (C) 2014 Jonas Ã…dahl + * Copyright (C) 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Damien Lespiau + * Author: Jonas Ã…dahl + * Author: Carlos Garnacho + */ + +#include "config.h" + +#include "backends/native/meta-seat-impl.h" + +#include +#include +#include +#include +#include + +#include "backends/meta-cursor-tracker-private.h" +#include "backends/native/meta-barrier-native.h" +#include "backends/native/meta-event-native.h" +#include "backends/native/meta-input-device-native.h" +#include "backends/native/meta-input-device-tool-native.h" +#include "backends/native/meta-keymap-native.h" +#include "backends/native/meta-virtual-input-device-native.h" +#include "clutter/clutter-mutter.h" +#include "core/bell.h" + +/* + * Clutter makes the assumption that two core devices have ID's 2 and 3 (core + * pointer and core keyboard). + * + * Since the two first devices that will ever be created will be the virtual + * pointer and virtual keyboard of the first seat, we fulfill the made + * assumptions by having the first device having ID 2 and following 3. + */ +#define INITIAL_DEVICE_ID 2 + +/* Try to keep the pointer inside the stage. Hopefully no one is using + * this backend with stages smaller than this. */ +#define INITIAL_POINTER_X 16 +#define INITIAL_POINTER_Y 16 + +#define AUTOREPEAT_VALUE 2 + +#define DISCRETE_SCROLL_STEP 10.0 + +#ifndef BTN_STYLUS3 +#define BTN_STYLUS3 0x149 /* Linux 4.15 */ +#endif + +struct _MetaEventSource +{ + GSource source; + + MetaSeatImpl *seat_impl; + GPollFD event_poll_fd; +}; + +static MetaOpenDeviceCallback device_open_callback; +static MetaCloseDeviceCallback device_close_callback; +static gpointer device_callback_data; + +#ifdef CLUTTER_ENABLE_DEBUG +static const char *device_type_str[] = { + "pointer", /* CLUTTER_POINTER_DEVICE */ + "keyboard", /* CLUTTER_KEYBOARD_DEVICE */ + "extension", /* CLUTTER_EXTENSION_DEVICE */ + "joystick", /* CLUTTER_JOYSTICK_DEVICE */ + "tablet", /* CLUTTER_TABLET_DEVICE */ + "touchpad", /* CLUTTER_TOUCHPAD_DEVICE */ + "touchscreen", /* CLUTTER_TOUCHSCREEN_DEVICE */ + "pen", /* CLUTTER_PEN_DEVICE */ + "eraser", /* CLUTTER_ERASER_DEVICE */ + "cursor", /* CLUTTER_CURSOR_DEVICE */ + "pad", /* CLUTTER_PAD_DEVICE */ +}; +#endif /* CLUTTER_ENABLE_DEBUG */ + +enum +{ + PROP_0, + PROP_SEAT, + PROP_SEAT_ID, + N_PROPS, +}; + +static GParamSpec *props[N_PROPS] = { NULL }; + +G_DEFINE_TYPE (MetaSeatImpl, meta_seat_impl, G_TYPE_OBJECT) + +static void process_events (MetaSeatImpl *seat_impl); +void meta_seat_impl_constrain_pointer (MetaSeatImpl *seat_impl, + ClutterInputDevice *core_pointer, + uint64_t time_us, + float x, + float y, + float *new_x, + float *new_y); +void meta_seat_impl_filter_relative_motion (MetaSeatImpl *seat_impl, + ClutterInputDevice *device, + float x, + float y, + float *dx, + float *dy); +void meta_seat_impl_clear_repeat_timer (MetaSeatImpl *seat_impl); + +void +meta_seat_impl_sync_leds (MetaSeatImpl *seat_impl) +{ + GSList *iter; + MetaInputDeviceNative *device_native; + int caps_lock, num_lock, scroll_lock; + enum libinput_led leds = 0; + + caps_lock = xkb_state_led_index_is_active (seat_impl->xkb, + seat_impl->caps_lock_led); + num_lock = xkb_state_led_index_is_active (seat_impl->xkb, + seat_impl->num_lock_led); + scroll_lock = xkb_state_led_index_is_active (seat_impl->xkb, + seat_impl->scroll_lock_led); + + if (caps_lock) + leds |= LIBINPUT_LED_CAPS_LOCK; + if (num_lock) + leds |= LIBINPUT_LED_NUM_LOCK; + if (scroll_lock) + leds |= LIBINPUT_LED_SCROLL_LOCK; + + for (iter = seat_impl->devices; iter; iter = iter->next) + { + device_native = iter->data; + meta_input_device_native_update_leds (device_native, leds); + } +} + +MetaTouchState * +meta_seat_impl_lookup_touch_state (MetaSeatImpl *seat_impl, + int seat_slot) +{ + if (!seat_impl->touch_states) + return NULL; + + return g_hash_table_lookup (seat_impl->touch_states, + GINT_TO_POINTER (seat_slot)); +} + +static void +meta_touch_state_free (MetaTouchState *state) +{ + g_slice_free (MetaTouchState, state); +} + +MetaTouchState * +meta_seat_impl_acquire_touch_state (MetaSeatImpl *seat_impl, + int seat_slot) +{ + MetaTouchState *touch_state; + + if (!seat_impl->touch_states) + { + seat_impl->touch_states = + g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) meta_touch_state_free); + } + + g_assert (!g_hash_table_contains (seat_impl->touch_states, + GINT_TO_POINTER (seat_slot))); + + touch_state = g_slice_new0 (MetaTouchState); + *touch_state = (MetaTouchState) { + .seat_impl = seat_impl, + .seat_slot = seat_slot, + }; + + g_hash_table_insert (seat_impl->touch_states, GINT_TO_POINTER (seat_slot), + touch_state); + + return touch_state; +} + +void +meta_seat_impl_release_touch_state (MetaSeatImpl *seat_impl, + int seat_slot) +{ + if (!seat_impl->touch_states) + return; + g_hash_table_remove (seat_impl->touch_states, GINT_TO_POINTER (seat_slot)); +} + +void +meta_seat_impl_clear_repeat_timer (MetaSeatImpl *seat_impl) +{ + if (seat_impl->repeat_timer) + { + g_clear_handle_id (&seat_impl->repeat_timer, g_source_remove); + g_clear_object (&seat_impl->repeat_device); + } +} + +static void +dispatch_libinput (MetaSeatImpl *seat_impl) +{ + libinput_dispatch (seat_impl->libinput); + process_events (seat_impl); +} + +static gboolean +keyboard_repeat (gpointer data) +{ + MetaSeatImpl *seat_impl = data; + GSource *source; + + /* There might be events queued in libinput that could cancel the + repeat timer. */ + dispatch_libinput (seat_impl); + if (!seat_impl->repeat_timer) + return G_SOURCE_REMOVE; + + g_return_val_if_fail (seat_impl->repeat_device != NULL, G_SOURCE_REMOVE); + source = g_main_context_find_source_by_id (NULL, seat_impl->repeat_timer); + + meta_seat_impl_notify_key (seat_impl, + seat_impl->repeat_device, + g_source_get_time (source), + seat_impl->repeat_key, + AUTOREPEAT_VALUE, + FALSE); + + return G_SOURCE_CONTINUE; +} + +static void +queue_event (MetaSeatImpl *seat_impl, + ClutterEvent *event) +{ + _clutter_event_push (event, FALSE); +} + +static int +update_button_count (MetaSeatImpl *seat_impl, + uint32_t button, + uint32_t state) +{ + if (state) + { + return ++seat_impl->button_count[button]; + } + else + { + /* Handle cases where we newer saw the initial pressed event. */ + if (seat_impl->button_count[button] == 0) + { + meta_topic (META_DEBUG_INPUT, + "Counting release of key 0x%x and count is already 0", + button); + return 0; + } + + return --seat_impl->button_count[button]; + } +} + +void +meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, + ClutterInputDevice *device, + uint64_t time_us, + uint32_t key, + uint32_t state, + gboolean update_keys) +{ + ClutterEvent *event = NULL; + enum xkb_state_component changed_state; + + if (state != AUTOREPEAT_VALUE) + { + /* Drop any repeated button press (for example from virtual devices. */ + int count = update_button_count (seat_impl, key, state); + if ((state && count > 1) || + (!state && count != 0)) + { + meta_topic (META_DEBUG_INPUT, + "Dropping repeated %s of key 0x%x, count %d, state %d", + state ? "press" : "release", key, count, state); + return; + } + } + + event = meta_key_event_new_from_evdev (device, + seat_impl->core_keyboard, + seat_impl->xkb, + seat_impl->button_state, + us2ms (time_us), key, state); + meta_event_native_set_event_code (event, key); + + /* We must be careful and not pass multiple releases to xkb, otherwise it gets + confused and locks the modifiers */ + if (state != AUTOREPEAT_VALUE) + { + changed_state = xkb_state_update_key (seat_impl->xkb, + event->key.hardware_keycode, + state ? XKB_KEY_DOWN : XKB_KEY_UP); + } + else + { + changed_state = 0; + clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_REPEATED); + } + + queue_event (seat_impl, event); + + if (update_keys && (changed_state & XKB_STATE_LEDS)) + { + MetaInputDeviceNative *keyboard_native; + + g_signal_emit_by_name (seat_impl->keymap, "state-changed"); + meta_seat_impl_sync_leds (seat_impl); + keyboard_native = META_INPUT_DEVICE_NATIVE (seat_impl->core_keyboard); + meta_input_device_native_a11y_maybe_notify_toggle_keys (keyboard_native); + } + + if (state == 0 || /* key release */ + !seat_impl->repeat || + !xkb_keymap_key_repeats (xkb_state_get_keymap (seat_impl->xkb), + event->key.hardware_keycode)) + { + meta_seat_impl_clear_repeat_timer (seat_impl); + return; + } + + if (state == 1) /* key press */ + seat_impl->repeat_count = 0; + + seat_impl->repeat_count += 1; + seat_impl->repeat_key = key; + + switch (seat_impl->repeat_count) + { + case 1: + case 2: + { + uint32_t interval; + + meta_seat_impl_clear_repeat_timer (seat_impl); + seat_impl->repeat_device = g_object_ref (device); + + if (seat_impl->repeat_count == 1) + interval = seat_impl->repeat_delay; + else + interval = seat_impl->repeat_interval; + + seat_impl->repeat_timer = + clutter_threads_add_timeout_full (CLUTTER_PRIORITY_EVENTS, + interval, + keyboard_repeat, + seat_impl, + NULL); + return; + } + default: + return; + } +} + +static ClutterEvent * +new_absolute_motion_event (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + float x, + float y, + double *axes) +{ + ClutterEvent *event; + + event = clutter_event_new (CLUTTER_MOTION); + + if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE) + { + meta_seat_impl_constrain_pointer (seat_impl, + seat_impl->core_pointer, + time_us, + seat_impl->pointer_x, + seat_impl->pointer_y, + &x, &y); + } + + meta_event_native_set_time_usec (event, time_us); + event->motion.time = us2ms (time_us); + meta_xkb_translate_state (event, seat_impl->xkb, seat_impl->button_state); + event->motion.x = x; + event->motion.y = y; + + /* This may happen early at startup */ + if (seat_impl->viewports) + { + meta_input_device_native_translate_coordinates (input_device, + seat_impl->viewports, + &event->motion.x, + &event->motion.y); + } + + event->motion.axes = axes; + clutter_event_set_device (event, seat_impl->core_pointer); + clutter_event_set_source_device (event, input_device); + + if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) + { + MetaInputDeviceNative *device_native = + META_INPUT_DEVICE_NATIVE (input_device); + + clutter_event_set_device_tool (event, device_native->last_tool); + clutter_event_set_device (event, input_device); + meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (input_device), + x, y); + } + else + { + clutter_event_set_device (event, seat_impl->core_pointer); + meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), + x, y); + } + + if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE) + { + seat_impl->pointer_x = x; + seat_impl->pointer_y = y; + } + + return event; +} + +void +meta_seat_impl_notify_relative_motion (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + float dx, + float dy, + float dx_unaccel, + float dy_unaccel) +{ + float new_x, new_y; + ClutterEvent *event; + + meta_seat_impl_filter_relative_motion (seat_impl, + input_device, + seat_impl->pointer_x, + seat_impl->pointer_y, + &dx, + &dy); + + new_x = seat_impl->pointer_x + dx; + new_y = seat_impl->pointer_y + dy; + event = new_absolute_motion_event (seat_impl, input_device, + time_us, new_x, new_y, NULL); + + meta_event_native_set_relative_motion (event, + dx, dy, + dx_unaccel, dy_unaccel); + + queue_event (seat_impl, event); +} + +void +meta_seat_impl_notify_absolute_motion (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + float x, + float y, + double *axes) +{ + ClutterEvent *event; + + event = new_absolute_motion_event (seat_impl, input_device, time_us, x, y, axes); + + queue_event (seat_impl, event); +} + +void +meta_seat_impl_notify_button (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + uint32_t button, + uint32_t state) +{ + MetaInputDeviceNative *device_native = (MetaInputDeviceNative *) input_device; + ClutterEvent *event = NULL; + int button_nr; + static int maskmap[8] = + { + CLUTTER_BUTTON1_MASK, CLUTTER_BUTTON3_MASK, CLUTTER_BUTTON2_MASK, + CLUTTER_BUTTON4_MASK, CLUTTER_BUTTON5_MASK, 0, 0, 0 + }; + int button_count; + + /* Drop any repeated button press (for example from virtual devices. */ + button_count = update_button_count (seat_impl, button, state); + if ((state && button_count > 1) || + (!state && button_count != 0)) + { + meta_topic (META_DEBUG_INPUT, + "Dropping repeated %s of button 0x%x, count %d", + state ? "press" : "release", button, button_count); + return; + } + + /* The evdev button numbers don't map sequentially to clutter button + * numbers (the right and middle mouse buttons are in the opposite + * order) so we'll map them directly with a switch statement */ + switch (button) + { + case BTN_LEFT: + case BTN_TOUCH: + button_nr = CLUTTER_BUTTON_PRIMARY; + break; + + case BTN_RIGHT: + case BTN_STYLUS: + button_nr = CLUTTER_BUTTON_SECONDARY; + break; + + case BTN_MIDDLE: + case BTN_STYLUS2: + button_nr = CLUTTER_BUTTON_MIDDLE; + break; + + case 0x149: /* BTN_STYLUS3 */ + button_nr = 8; + break; + + default: + /* For compatibility reasons, all additional buttons go after the old 4-7 scroll ones */ + if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) + button_nr = button - BTN_TOOL_PEN + 4; + else + button_nr = button - (BTN_LEFT - 1) + 4; + break; + } + + if (button_nr < 1 || button_nr > 12) + { + g_warning ("Unhandled button event 0x%x", button); + return; + } + + if (state) + event = clutter_event_new (CLUTTER_BUTTON_PRESS); + else + event = clutter_event_new (CLUTTER_BUTTON_RELEASE); + + if (button_nr < G_N_ELEMENTS (maskmap)) + { + /* Update the modifiers */ + if (state) + seat_impl->button_state |= maskmap[button_nr - 1]; + else + seat_impl->button_state &= ~maskmap[button_nr - 1]; + } + + meta_event_native_set_time_usec (event, time_us); + event->button.time = us2ms (time_us); + meta_xkb_translate_state (event, seat_impl->xkb, seat_impl->button_state); + event->button.button = button_nr; + + if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) + { + meta_input_device_native_get_coords (device_native, + &event->button.x, + &event->button.y); + } + else + { + meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), + &event->button.x, + &event->button.y); + } + + clutter_event_set_device (event, seat_impl->core_pointer); + clutter_event_set_source_device (event, input_device); + + if (device_native->last_tool) + { + /* Apply the button event code as per the tool mapping */ + uint32_t mapped_button; + + mapped_button = meta_input_device_tool_native_get_button_code (device_native->last_tool, + button_nr); + if (mapped_button != 0) + button = mapped_button; + } + + meta_event_native_set_event_code (event, button); + + if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) + { + clutter_event_set_device_tool (event, device_native->last_tool); + clutter_event_set_device (event, input_device); + } + else + { + clutter_event_set_device (event, seat_impl->core_pointer); + } + + queue_event (seat_impl, event); +} + +static MetaSeatImpl * +seat_impl_from_device (ClutterInputDevice *device) +{ + MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); + + return meta_input_device_native_get_seat_impl (device_native); +} + +static void +notify_scroll (ClutterInputDevice *input_device, + uint64_t time_us, + double dx, + double dy, + ClutterScrollSource scroll_source, + ClutterScrollFinishFlags flags, + gboolean emulated) +{ + MetaSeatImpl *seat_impl; + ClutterEvent *event = NULL; + double scroll_factor; + + seat_impl = seat_impl_from_device (input_device); + + event = clutter_event_new (CLUTTER_SCROLL); + + meta_event_native_set_time_usec (event, time_us); + event->scroll.time = us2ms (time_us); + meta_xkb_translate_state (event, seat_impl->xkb, seat_impl->button_state); + + /* libinput pointer axis events are in pointer motion coordinate space. + * To convert to Xi2 discrete step coordinate space, multiply the factor + * 1/10. */ + event->scroll.direction = CLUTTER_SCROLL_SMOOTH; + scroll_factor = 1.0 / DISCRETE_SCROLL_STEP; + clutter_event_set_scroll_delta (event, + scroll_factor * dx, + scroll_factor * dy); + + event->scroll.x = seat_impl->pointer_x; + event->scroll.y = seat_impl->pointer_y; + clutter_event_set_device (event, seat_impl->core_pointer); + clutter_event_set_source_device (event, input_device); + event->scroll.scroll_source = scroll_source; + event->scroll.finish_flags = flags; + + _clutter_event_set_pointer_emulated (event, emulated); + + queue_event (seat_impl, event); +} + +static void +notify_discrete_scroll (ClutterInputDevice *input_device, + uint64_t time_us, + ClutterScrollDirection direction, + ClutterScrollSource scroll_source, + gboolean emulated) +{ + MetaSeatImpl *seat_impl; + ClutterEvent *event = NULL; + + if (direction == CLUTTER_SCROLL_SMOOTH) + return; + + seat_impl = seat_impl_from_device (input_device); + + event = clutter_event_new (CLUTTER_SCROLL); + + meta_event_native_set_time_usec (event, time_us); + event->scroll.time = us2ms (time_us); + meta_xkb_translate_state (event, seat_impl->xkb, seat_impl->button_state); + + event->scroll.direction = direction; + + event->scroll.x = seat_impl->pointer_x; + event->scroll.y = seat_impl->pointer_y; + clutter_event_set_device (event, seat_impl->core_pointer); + clutter_event_set_source_device (event, input_device); + event->scroll.scroll_source = scroll_source; + + _clutter_event_set_pointer_emulated (event, emulated); + + queue_event (seat_impl, event); +} + +static void +check_notify_discrete_scroll (MetaSeatImpl *seat_impl, + ClutterInputDevice *device, + uint64_t time_us, + ClutterScrollSource scroll_source) +{ + int i, n_xscrolls, n_yscrolls; + + n_xscrolls = floor (fabs (seat_impl->accum_scroll_dx) / DISCRETE_SCROLL_STEP); + n_yscrolls = floor (fabs (seat_impl->accum_scroll_dy) / DISCRETE_SCROLL_STEP); + + for (i = 0; i < n_xscrolls; i++) + { + notify_discrete_scroll (device, time_us, + seat_impl->accum_scroll_dx > 0 ? + CLUTTER_SCROLL_RIGHT : CLUTTER_SCROLL_LEFT, + scroll_source, TRUE); + } + + for (i = 0; i < n_yscrolls; i++) + { + notify_discrete_scroll (device, time_us, + seat_impl->accum_scroll_dy > 0 ? + CLUTTER_SCROLL_DOWN : CLUTTER_SCROLL_UP, + scroll_source, TRUE); + } + + seat_impl->accum_scroll_dx = + fmodf (seat_impl->accum_scroll_dx, DISCRETE_SCROLL_STEP); + seat_impl->accum_scroll_dy = + fmodf (seat_impl->accum_scroll_dy, DISCRETE_SCROLL_STEP); +} + +void +meta_seat_impl_notify_scroll_continuous (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + double dx, + double dy, + ClutterScrollSource scroll_source, + ClutterScrollFinishFlags finish_flags) +{ + if (finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL) + seat_impl->accum_scroll_dx = 0; + else + seat_impl->accum_scroll_dx += dx; + + if (finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL) + seat_impl->accum_scroll_dy = 0; + else + seat_impl->accum_scroll_dy += dy; + + notify_scroll (input_device, time_us, dx, dy, scroll_source, + finish_flags, FALSE); + check_notify_discrete_scroll (seat_impl, input_device, time_us, scroll_source); +} + +static ClutterScrollDirection +discrete_to_direction (double discrete_dx, + double discrete_dy) +{ + if (discrete_dx > 0) + return CLUTTER_SCROLL_RIGHT; + else if (discrete_dx < 0) + return CLUTTER_SCROLL_LEFT; + else if (discrete_dy > 0) + return CLUTTER_SCROLL_DOWN; + else if (discrete_dy < 0) + return CLUTTER_SCROLL_UP; + else + g_assert_not_reached (); + return 0; +} + +void +meta_seat_impl_notify_discrete_scroll (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + double discrete_dx, + double discrete_dy, + ClutterScrollSource scroll_source) +{ + notify_scroll (input_device, time_us, + discrete_dx * DISCRETE_SCROLL_STEP, + discrete_dy * DISCRETE_SCROLL_STEP, + scroll_source, CLUTTER_SCROLL_FINISHED_NONE, + TRUE); + notify_discrete_scroll (input_device, time_us, + discrete_to_direction (discrete_dx, discrete_dy), + scroll_source, FALSE); + +} + +void +meta_seat_impl_notify_touch_event (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + ClutterEventType evtype, + uint64_t time_us, + int slot, + double x, + double y) +{ + ClutterEvent *event = NULL; + + event = clutter_event_new (evtype); + + meta_event_native_set_time_usec (event, time_us); + event->touch.time = us2ms (time_us); + event->touch.x = x; + event->touch.y = y; + meta_input_device_native_translate_coordinates (input_device, + seat_impl->viewports, + &event->touch.x, + &event->touch.y); + + /* "NULL" sequences are special cased in clutter */ + event->touch.sequence = GINT_TO_POINTER (MAX (1, slot + 1)); + meta_xkb_translate_state (event, seat_impl->xkb, seat_impl->button_state); + + if (evtype == CLUTTER_TOUCH_BEGIN || + evtype == CLUTTER_TOUCH_UPDATE) + event->touch.modifier_state |= CLUTTER_BUTTON1_MASK; + + clutter_event_set_device (event, seat_impl->core_pointer); + clutter_event_set_source_device (event, input_device); + + queue_event (seat_impl, event); +} + +/* + * MetaEventSource for reading input devices + */ +static gboolean +meta_event_prepare (GSource *source, + int *timeout) +{ + gboolean retval; + + *timeout = -1; + retval = clutter_events_pending (); + + return retval; +} + +static gboolean +meta_event_check (GSource *source) +{ + MetaEventSource *event_source = (MetaEventSource *) source; + gboolean retval; + + retval = ((event_source->event_poll_fd.revents & G_IO_IN) || + clutter_events_pending ()); + + return retval; +} + +static void +constrain_to_barriers (MetaSeatImpl *seat_impl, + ClutterInputDevice *device, + uint32_t time, + float *new_x, + float *new_y) +{ + meta_barrier_manager_native_process (seat_impl->barrier_manager, + device, + time, + new_x, new_y); +} + +/* + * The pointer constrain code is mostly a rip-off of the XRandR code from Xorg. + * (from xserver/randr/rrcrtc.c, RRConstrainCursorHarder) + * + * Copyright © 2006 Keith Packard + * Copyright 2010 Red Hat, Inc + * + */ + +static void +constrain_all_screen_monitors (ClutterInputDevice *device, + MetaViewportInfo *viewports, + float *x, + float *y) +{ + float cx, cy; + int i, n_views; + + meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (device), + &cx, &cy); + + /* if we're trying to escape, clamp to the CRTC we're coming from */ + + n_views = meta_viewport_info_get_num_views (viewports); + + for (i = 0; i < n_views; i++) + { + int left, right, top, bottom; + cairo_rectangle_int_t rect; + + meta_viewport_info_get_view_info (viewports, i, &rect, NULL); + + left = rect.x; + right = left + rect.width; + top = rect.y; + bottom = top + rect.height; + + if ((cx >= left) && (cx < right) && (cy >= top) && (cy < bottom)) + { + if (*x < left) + *x = left; + if (*x >= right) + *x = right - 1; + if (*y < top) + *y = top; + if (*y >= bottom) + *y = bottom - 1; + + return; + } + } +} + +void +meta_seat_impl_constrain_pointer (MetaSeatImpl *seat_impl, + ClutterInputDevice *core_pointer, + uint64_t time_us, + float x, + float y, + float *new_x, + float *new_y) +{ + /* Constrain to barriers */ + constrain_to_barriers (seat_impl, core_pointer, + us2ms (time_us), + new_x, new_y); + + /* Bar to constraints */ + if (seat_impl->pointer_constraint) + { + meta_pointer_constraint_impl_constrain (seat_impl->pointer_constraint, + core_pointer, + us2ms (time_us), + x, y, + new_x, new_y); + } + + if (seat_impl->viewports) + { + /* if we're moving inside a monitor, we're fine */ + if (meta_viewport_info_get_view_at (seat_impl->viewports, + *new_x, *new_y) >= 0) + return; + + /* if we're trying to escape, clamp to the CRTC we're coming from */ + constrain_all_screen_monitors (core_pointer, seat_impl->viewports, + new_x, new_y); + } +} + +static void +relative_motion_across_outputs (MetaViewportInfo *viewports, + int view, + float cur_x, + float cur_y, + float *dx_inout, + float *dy_inout) +{ + int cur_view = view; + float x = cur_x, y = cur_y; + float target_x = cur_x, target_y = cur_y; + float dx = *dx_inout, dy = *dy_inout; + MetaDisplayDirection direction = -1; + + while (cur_view >= 0) + { + MetaLine2 left, right, top, bottom, motion; + MetaVector2 intersection; + cairo_rectangle_int_t rect; + float scale; + + meta_viewport_info_get_view_info (viewports, cur_view, &rect, &scale); + + motion = (MetaLine2) { + .a = { x, y }, + .b = { x + (dx * scale), y + (dy * scale) } + }; + left = (MetaLine2) { + { rect.x, rect.y }, + { rect.x, rect.y + rect.height } + }; + right = (MetaLine2) { + { rect.x + rect.width, rect.y }, + { rect.x + rect.width, rect.y + rect.height } + }; + top = (MetaLine2) { + { rect.x, rect.y }, + { rect.x + rect.width, rect.y } + }; + bottom = (MetaLine2) { + { rect.x, rect.y + rect.height }, + { rect.x + rect.width, rect.y + rect.height } + }; + + target_x = motion.b.x; + target_y = motion.b.y; + + if (direction != META_DISPLAY_RIGHT && + meta_line2_intersects_with (&motion, &left, &intersection)) + direction = META_DISPLAY_LEFT; + else if (direction != META_DISPLAY_LEFT && + meta_line2_intersects_with (&motion, &right, &intersection)) + direction = META_DISPLAY_RIGHT; + else if (direction != META_DISPLAY_DOWN && + meta_line2_intersects_with (&motion, &top, &intersection)) + direction = META_DISPLAY_UP; + else if (direction != META_DISPLAY_UP && + meta_line2_intersects_with (&motion, &bottom, &intersection)) + direction = META_DISPLAY_DOWN; + else + /* We reached the dest logical monitor */ + break; + + x = intersection.x; + y = intersection.y; + dx -= intersection.x - motion.a.x; + dy -= intersection.y - motion.a.y; + + cur_view = meta_viewport_info_get_neighbor (viewports, cur_view, + direction); + } + + *dx_inout = target_x - cur_x; + *dy_inout = target_y - cur_y; +} + +void +meta_seat_impl_filter_relative_motion (MetaSeatImpl *seat_impl, + ClutterInputDevice *device, + float x, + float y, + float *dx, + float *dy) +{ + int view = -1, dest_view; + float new_dx, new_dy, scale; + + if (meta_is_stage_views_scaled ()) + return; + + if (seat_impl->viewports) + view = meta_viewport_info_get_view_at (seat_impl->viewports, x, y); + if (view < 0) + return; + + meta_viewport_info_get_view_info (seat_impl->viewports, view, NULL, &scale); + new_dx = (*dx) * scale; + new_dy = (*dy) * scale; + + dest_view = meta_viewport_info_get_view_at (seat_impl->viewports, + x + new_dx, + y + new_dy); + if (dest_view >= 0 && dest_view != view) + { + /* If we are crossing monitors, attempt to bisect the distance on each + * axis and apply the relative scale for each of them. + */ + new_dx = *dx; + new_dy = *dy; + relative_motion_across_outputs (seat_impl->viewports, view, + x, y, &new_dx, &new_dy); + } + + *dx = new_dx; + *dy = new_dy; +} + +static void +notify_absolute_motion (ClutterInputDevice *input_device, + uint64_t time_us, + float x, + float y, + double *axes) +{ + MetaSeatImpl *seat_impl; + ClutterEvent *event; + + seat_impl = seat_impl_from_device (input_device); + event = new_absolute_motion_event (seat_impl, input_device, time_us, x, y, axes); + + queue_event (seat_impl, event); +} + +static void +notify_relative_tool_motion (ClutterInputDevice *input_device, + uint64_t time_us, + float dx, + float dy, + double *axes) +{ + MetaInputDeviceNative *device_native; + ClutterEvent *event; + MetaSeatImpl *seat_impl; + float x, y; + + device_native = META_INPUT_DEVICE_NATIVE (input_device); + seat_impl = seat_impl_from_device (input_device); + x = device_native->pointer_x + dx; + y = device_native->pointer_y + dy; + + meta_seat_impl_filter_relative_motion (seat_impl, + input_device, + seat_impl->pointer_x, + seat_impl->pointer_y, + &dx, + &dy); + + event = new_absolute_motion_event (seat_impl, input_device, time_us, + x, y, axes); + meta_event_native_set_relative_motion (event, dx, dy, 0, 0); + + queue_event (seat_impl, event); +} + +static void +notify_pinch_gesture_event (ClutterInputDevice *input_device, + ClutterTouchpadGesturePhase phase, + uint64_t time_us, + double dx, + double dy, + double angle_delta, + double scale, + uint32_t n_fingers) +{ + MetaSeatImpl *seat_impl; + ClutterEvent *event = NULL; + + seat_impl = seat_impl_from_device (input_device); + + event = clutter_event_new (CLUTTER_TOUCHPAD_PINCH); + + meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), + &event->touchpad_pinch.x, + &event->touchpad_pinch.y); + + meta_event_native_set_time_usec (event, time_us); + event->touchpad_pinch.phase = phase; + event->touchpad_pinch.time = us2ms (time_us); + event->touchpad_pinch.dx = dx; + event->touchpad_pinch.dy = dy; + event->touchpad_pinch.angle_delta = angle_delta; + event->touchpad_pinch.scale = scale; + event->touchpad_pinch.n_fingers = n_fingers; + + meta_xkb_translate_state (event, seat_impl->xkb, seat_impl->button_state); + + clutter_event_set_device (event, seat_impl->core_pointer); + clutter_event_set_source_device (event, input_device); + + queue_event (seat_impl, event); +} + +static void +notify_swipe_gesture_event (ClutterInputDevice *input_device, + ClutterTouchpadGesturePhase phase, + uint64_t time_us, + uint32_t n_fingers, + double dx, + double dy) +{ + MetaSeatImpl *seat_impl; + ClutterEvent *event = NULL; + + seat_impl = seat_impl_from_device (input_device); + + event = clutter_event_new (CLUTTER_TOUCHPAD_SWIPE); + + meta_event_native_set_time_usec (event, time_us); + event->touchpad_swipe.phase = phase; + event->touchpad_swipe.time = us2ms (time_us); + + meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), + &event->touchpad_swipe.x, + &event->touchpad_swipe.y); + event->touchpad_swipe.dx = dx; + event->touchpad_swipe.dy = dy; + event->touchpad_swipe.n_fingers = n_fingers; + + meta_xkb_translate_state (event, seat_impl->xkb, seat_impl->button_state); + + clutter_event_set_device (event, seat_impl->core_pointer); + clutter_event_set_source_device (event, input_device); + + queue_event (seat_impl, event); +} + +static void +notify_proximity (ClutterInputDevice *input_device, + uint64_t time_us, + gboolean in) +{ + MetaInputDeviceNative *device_native; + MetaSeatImpl *seat_impl; + ClutterEvent *event = NULL; + + device_native = META_INPUT_DEVICE_NATIVE (input_device); + seat_impl = seat_impl_from_device (input_device); + + if (in) + event = clutter_event_new (CLUTTER_PROXIMITY_IN); + else + event = clutter_event_new (CLUTTER_PROXIMITY_OUT); + + meta_event_native_set_time_usec (event, time_us); + + event->proximity.time = us2ms (time_us); + clutter_event_set_device_tool (event, device_native->last_tool); + clutter_event_set_device (event, seat_impl->core_pointer); + clutter_event_set_source_device (event, input_device); + + queue_event (seat_impl, event); +} + +static void +notify_pad_button (ClutterInputDevice *input_device, + uint64_t time_us, + uint32_t button, + uint32_t mode_group, + uint32_t mode, + uint32_t pressed) +{ + MetaSeatImpl *seat_impl; + ClutterEvent *event; + + seat_impl = seat_impl_from_device (input_device); + + if (pressed) + event = clutter_event_new (CLUTTER_PAD_BUTTON_PRESS); + else + event = clutter_event_new (CLUTTER_PAD_BUTTON_RELEASE); + + meta_event_native_set_time_usec (event, time_us); + event->pad_button.button = button; + event->pad_button.group = mode_group; + event->pad_button.mode = mode; + clutter_event_set_device (event, input_device); + clutter_event_set_source_device (event, input_device); + clutter_event_set_time (event, us2ms (time_us)); + + queue_event (seat_impl, event); +} + +static void +notify_pad_strip (ClutterInputDevice *input_device, + uint64_t time_us, + uint32_t strip_number, + uint32_t strip_source, + uint32_t mode_group, + uint32_t mode, + double value) +{ + ClutterInputDevicePadSource source; + MetaSeatImpl *seat_impl; + ClutterEvent *event; + + seat_impl = seat_impl_from_device (input_device); + + if (strip_source == LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER) + source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER; + else + source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN; + + event = clutter_event_new (CLUTTER_PAD_STRIP); + meta_event_native_set_time_usec (event, time_us); + event->pad_strip.strip_source = source; + event->pad_strip.strip_number = strip_number; + event->pad_strip.value = value; + event->pad_strip.group = mode_group; + event->pad_strip.mode = mode; + clutter_event_set_device (event, input_device); + clutter_event_set_source_device (event, input_device); + clutter_event_set_time (event, us2ms (time_us)); + + queue_event (seat_impl, event); +} + +static void +notify_pad_ring (ClutterInputDevice *input_device, + uint64_t time_us, + uint32_t ring_number, + uint32_t ring_source, + uint32_t mode_group, + uint32_t mode, + double angle) +{ + ClutterInputDevicePadSource source; + MetaSeatImpl *seat_impl; + ClutterEvent *event; + + seat_impl = seat_impl_from_device (input_device); + + if (ring_source == LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER) + source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER; + else + source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN; + + event = clutter_event_new (CLUTTER_PAD_RING); + meta_event_native_set_time_usec (event, time_us); + event->pad_ring.ring_source = source; + event->pad_ring.ring_number = ring_number; + event->pad_ring.angle = angle; + event->pad_ring.group = mode_group; + event->pad_ring.mode = mode; + clutter_event_set_device (event, input_device); + clutter_event_set_source_device (event, input_device); + clutter_event_set_time (event, us2ms (time_us)); + + queue_event (seat_impl, event); +} + +static gboolean +meta_event_dispatch (GSource *g_source, + GSourceFunc callback, + gpointer user_data) +{ + MetaEventSource *source = (MetaEventSource *) g_source; + MetaSeatImpl *seat_impl; + + seat_impl = source->seat_impl; + + /* Don't queue more events if we haven't finished handling the previous batch + */ + if (clutter_events_pending ()) + goto queue_event; + + dispatch_libinput (seat_impl); + + queue_event: + + return TRUE; +} +static GSourceFuncs event_funcs = { + meta_event_prepare, + meta_event_check, + meta_event_dispatch, + NULL +}; + +static MetaEventSource * +meta_event_source_new (MetaSeatImpl *seat_impl) +{ + GSource *source; + MetaEventSource *event_source; + int fd; + + source = g_source_new (&event_funcs, sizeof (MetaEventSource)); + event_source = (MetaEventSource *) source; + + /* setup the source */ + event_source->seat_impl = seat_impl; + + fd = libinput_get_fd (seat_impl->libinput); + event_source->event_poll_fd.fd = fd; + event_source->event_poll_fd.events = G_IO_IN; + + /* and finally configure and attach the GSource */ + g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS); + g_source_add_poll (source, &event_source->event_poll_fd); + g_source_set_can_recurse (source, TRUE); + g_source_attach (source, NULL); + + return event_source; +} + +static void +meta_event_source_free (MetaEventSource *source) +{ + GSource *g_source = (GSource *) source; + + /* ignore the return value of close, it's not like we can do something + * about it */ + close (source->event_poll_fd.fd); + + g_source_destroy (g_source); + g_source_unref (g_source); +} + +static gboolean +has_touchscreen (MetaSeatImpl *seat_impl) +{ + GSList *l; + + for (l = seat_impl->devices; l; l = l->next) + { + ClutterInputDeviceType device_type; + + device_type = clutter_input_device_get_device_type (l->data); + + if (device_type == CLUTTER_TOUCHSCREEN_DEVICE) + return TRUE; + } + + return FALSE; +} + +static gboolean +device_is_tablet_switch (MetaInputDeviceNative *device_native) +{ + if (libinput_device_has_capability (device_native->libinput_device, + LIBINPUT_DEVICE_CAP_SWITCH) && + libinput_device_switch_has_switch (device_native->libinput_device, + LIBINPUT_SWITCH_TABLET_MODE)) + return TRUE; + + return FALSE; +} + +static gboolean +has_tablet_switch (MetaSeatImpl *seat_impl) +{ + GSList *l; + + for (l = seat_impl->devices; l; l = l->next) + { + MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (l->data); + + if (device_is_tablet_switch (device_native)) + return TRUE; + } + + return FALSE; +} + +static void +update_touch_mode (MetaSeatImpl *seat_impl) +{ + gboolean touch_mode; + + /* No touch mode if we don't have a touchscreen, easy */ + if (!seat_impl->has_touchscreen) + touch_mode = FALSE; + /* If we have a tablet mode switch, honor it being unset */ + else if (seat_impl->has_tablet_switch && !seat_impl->tablet_mode_switch_state) + touch_mode = FALSE; + /* If tablet mode is enabled, or if there is no tablet mode switch + * (eg. kiosk machines), assume touch-mode. + */ + else + touch_mode = TRUE; + + if (seat_impl->touch_mode != touch_mode) + { + seat_impl->touch_mode = touch_mode; + g_object_notify (G_OBJECT (seat_impl->seat_native), "touch-mode"); + } +} + +static ClutterInputDevice * +evdev_add_device (MetaSeatImpl *seat_impl, + struct libinput_device *libinput_device) +{ + ClutterInputDeviceType type; + ClutterInputDevice *device, *master = NULL; + gboolean is_touchscreen, is_tablet_switch; + + device = meta_input_device_native_new (seat_impl, libinput_device); + + seat_impl->devices = g_slist_prepend (seat_impl->devices, device); + + /* Clutter assumes that device types are exclusive in the + * ClutterInputDevice API */ + type = meta_input_device_native_determine_type (libinput_device); + + if (type == CLUTTER_KEYBOARD_DEVICE) + master = seat_impl->core_keyboard; + else if (type == CLUTTER_POINTER_DEVICE) + master = seat_impl->core_pointer; + + if (master) + { + _clutter_input_device_set_associated_device (device, master); + _clutter_input_device_add_physical_device (master, device); + } + + is_touchscreen = type == CLUTTER_TOUCHSCREEN_DEVICE; + is_tablet_switch = + device_is_tablet_switch (META_INPUT_DEVICE_NATIVE (device)); + + seat_impl->has_touchscreen |= is_touchscreen; + seat_impl->has_tablet_switch |= is_tablet_switch; + + if (is_touchscreen || is_tablet_switch) + update_touch_mode (seat_impl); + + return device; +} + +static void +evdev_remove_device (MetaSeatImpl *seat_impl, + MetaInputDeviceNative *device_native) +{ + ClutterInputDevice *device; + ClutterInputDeviceType device_type; + gboolean is_touchscreen, is_tablet_switch; + + device = CLUTTER_INPUT_DEVICE (device_native); + seat_impl->devices = g_slist_remove (seat_impl->devices, device); + + device_type = clutter_input_device_get_device_type (device); + + is_touchscreen = device_type == CLUTTER_TOUCHSCREEN_DEVICE; + is_tablet_switch = device_is_tablet_switch (device_native); + + if (is_touchscreen) + seat_impl->has_touchscreen = has_touchscreen (seat_impl); + if (is_tablet_switch) + seat_impl->has_tablet_switch = has_tablet_switch (seat_impl); + + if (is_touchscreen || is_tablet_switch) + update_touch_mode (seat_impl); + + if (seat_impl->repeat_timer && seat_impl->repeat_device == device) + meta_seat_impl_clear_repeat_timer (seat_impl); + + g_object_unref (device); +} + +static gboolean +process_base_event (MetaSeatImpl *seat_impl, + struct libinput_event *event) +{ + ClutterInputDevice *device; + ClutterEvent *device_event = NULL; + struct libinput_device *libinput_device; + + switch (libinput_event_get_type (event)) + { + case LIBINPUT_EVENT_DEVICE_ADDED: + libinput_device = libinput_event_get_device (event); + + device = evdev_add_device (seat_impl, libinput_device); + device_event = clutter_event_new (CLUTTER_DEVICE_ADDED); + clutter_event_set_device (device_event, device); + break; + + case LIBINPUT_EVENT_DEVICE_REMOVED: + libinput_device = libinput_event_get_device (event); + + device = libinput_device_get_user_data (libinput_device); + device_event = clutter_event_new (CLUTTER_DEVICE_REMOVED); + clutter_event_set_device (device_event, device); + evdev_remove_device (seat_impl, + META_INPUT_DEVICE_NATIVE (device)); + break; + + default: + break; + } + + if (device_event) + { + queue_event (seat_impl, device_event); + return TRUE; + } + + return FALSE; +} + +static ClutterScrollSource +translate_scroll_source (enum libinput_pointer_axis_source source) +{ + switch (source) + { + case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: + return CLUTTER_SCROLL_SOURCE_WHEEL; + case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: + return CLUTTER_SCROLL_SOURCE_FINGER; + case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: + return CLUTTER_SCROLL_SOURCE_CONTINUOUS; + default: + return CLUTTER_SCROLL_SOURCE_UNKNOWN; + } +} + +static ClutterInputDeviceToolType +translate_tool_type (struct libinput_tablet_tool *libinput_tool) +{ + enum libinput_tablet_tool_type tool; + + tool = libinput_tablet_tool_get_type (libinput_tool); + + switch (tool) + { + case LIBINPUT_TABLET_TOOL_TYPE_PEN: + return CLUTTER_INPUT_DEVICE_TOOL_PEN; + case LIBINPUT_TABLET_TOOL_TYPE_ERASER: + return CLUTTER_INPUT_DEVICE_TOOL_ERASER; + case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: + return CLUTTER_INPUT_DEVICE_TOOL_BRUSH; + case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: + return CLUTTER_INPUT_DEVICE_TOOL_PENCIL; + case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: + return CLUTTER_INPUT_DEVICE_TOOL_AIRBRUSH; + case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: + return CLUTTER_INPUT_DEVICE_TOOL_MOUSE; + case LIBINPUT_TABLET_TOOL_TYPE_LENS: + return CLUTTER_INPUT_DEVICE_TOOL_LENS; + default: + return CLUTTER_INPUT_DEVICE_TOOL_NONE; + } +} + +static void +input_device_update_tool (ClutterInputDevice *input_device, + struct libinput_tablet_tool *libinput_tool) +{ + MetaInputDeviceNative *evdev_device = META_INPUT_DEVICE_NATIVE (input_device); + MetaSeatImpl *seat_impl = seat_impl_from_device (input_device); + ClutterInputDeviceTool *tool = NULL; + ClutterInputDeviceToolType tool_type; + uint64_t tool_serial; + + if (libinput_tool) + { + tool_serial = libinput_tablet_tool_get_serial (libinput_tool); + tool_type = translate_tool_type (libinput_tool); + tool = clutter_input_device_lookup_tool (input_device, + tool_serial, tool_type); + + if (!tool) + { + tool = meta_input_device_tool_native_new (libinput_tool, + tool_serial, tool_type); + clutter_input_device_add_tool (input_device, tool); + } + } + + if (evdev_device->last_tool != tool) + { + evdev_device->last_tool = tool; + g_signal_emit_by_name (seat_impl->seat_native, "tool-changed", + input_device, tool); + } +} + +static double * +translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event, + ClutterInputDeviceTool *tool) +{ + GArray *axes = g_array_new (FALSE, FALSE, sizeof (double)); + struct libinput_tablet_tool *libinput_tool; + double value; + + libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event); + + value = libinput_event_tablet_tool_get_x (tablet_event); + g_array_append_val (axes, value); + value = libinput_event_tablet_tool_get_y (tablet_event); + g_array_append_val (axes, value); + + if (libinput_tablet_tool_has_distance (libinput_tool)) + { + value = libinput_event_tablet_tool_get_distance (tablet_event); + g_array_append_val (axes, value); + } + + if (libinput_tablet_tool_has_pressure (libinput_tool)) + { + value = libinput_event_tablet_tool_get_pressure (tablet_event); + value = meta_input_device_tool_native_translate_pressure (tool, value); + g_array_append_val (axes, value); + } + + if (libinput_tablet_tool_has_tilt (libinput_tool)) + { + value = libinput_event_tablet_tool_get_tilt_x (tablet_event); + g_array_append_val (axes, value); + value = libinput_event_tablet_tool_get_tilt_y (tablet_event); + g_array_append_val (axes, value); + } + + if (libinput_tablet_tool_has_rotation (libinput_tool)) + { + value = libinput_event_tablet_tool_get_rotation (tablet_event); + g_array_append_val (axes, value); + } + + if (libinput_tablet_tool_has_slider (libinput_tool)) + { + value = libinput_event_tablet_tool_get_slider_position (tablet_event); + g_array_append_val (axes, value); + } + + if (libinput_tablet_tool_has_wheel (libinput_tool)) + { + value = libinput_event_tablet_tool_get_wheel_delta (tablet_event); + g_array_append_val (axes, value); + } + + if (axes->len == 0) + { + g_array_free (axes, TRUE); + return NULL; + } + else + return (double *) g_array_free (axes, FALSE); +} + +static void +notify_continuous_axis (MetaSeatImpl *seat_impl, + ClutterInputDevice *device, + uint64_t time_us, + ClutterScrollSource scroll_source, + struct libinput_event_pointer *axis_event) +{ + double dx = 0.0, dy = 0.0; + ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE; + + if (libinput_event_pointer_has_axis (axis_event, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) + { + dx = libinput_event_pointer_get_axis_value ( + axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + + if (fabs (dx) < DBL_EPSILON) + finish_flags |= CLUTTER_SCROLL_FINISHED_HORIZONTAL; + } + if (libinput_event_pointer_has_axis (axis_event, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) + { + dy = libinput_event_pointer_get_axis_value ( + axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + + if (fabs (dy) < DBL_EPSILON) + finish_flags |= CLUTTER_SCROLL_FINISHED_VERTICAL; + } + + meta_seat_impl_notify_scroll_continuous (seat_impl, device, time_us, + dx, dy, + scroll_source, finish_flags); +} + +static void +notify_discrete_axis (MetaSeatImpl *seat_impl, + ClutterInputDevice *device, + uint64_t time_us, + ClutterScrollSource scroll_source, + struct libinput_event_pointer *axis_event) +{ + double discrete_dx = 0.0, discrete_dy = 0.0; + + if (libinput_event_pointer_has_axis (axis_event, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) + { + discrete_dx = libinput_event_pointer_get_axis_value_discrete ( + axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + } + if (libinput_event_pointer_has_axis (axis_event, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) + { + discrete_dy = libinput_event_pointer_get_axis_value_discrete ( + axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + } + + meta_seat_impl_notify_discrete_scroll (seat_impl, device, + time_us, + discrete_dx, discrete_dy, + scroll_source); +} + +static void +process_tablet_axis (MetaSeatImpl *seat_impl, + struct libinput_event *event) +{ + struct libinput_device *libinput_device = libinput_event_get_device (event); + uint64_t time; + double x, y, dx, dy, *axes; + float stage_width, stage_height; + ClutterInputDevice *device; + struct libinput_event_tablet_tool *tablet_event = + libinput_event_get_tablet_tool_event (event); + MetaInputDeviceNative *evdev_device; + + device = libinput_device_get_user_data (libinput_device); + evdev_device = META_INPUT_DEVICE_NATIVE (device); + + axes = translate_tablet_axes (tablet_event, + evdev_device->last_tool); + if (!axes) + return; + + meta_viewport_info_get_extents (seat_impl->viewports, + &stage_width, &stage_height); + + time = libinput_event_tablet_tool_get_time_usec (tablet_event); + + if (meta_input_device_native_get_mapping_mode (device) == META_INPUT_DEVICE_MAPPING_RELATIVE || + clutter_input_device_tool_get_tool_type (evdev_device->last_tool) == CLUTTER_INPUT_DEVICE_TOOL_MOUSE || + clutter_input_device_tool_get_tool_type (evdev_device->last_tool) == CLUTTER_INPUT_DEVICE_TOOL_LENS) + { + dx = libinput_event_tablet_tool_get_dx (tablet_event); + dy = libinput_event_tablet_tool_get_dy (tablet_event); + notify_relative_tool_motion (device, time, dx, dy, axes); + } + else + { + x = libinput_event_tablet_tool_get_x_transformed (tablet_event, stage_width); + y = libinput_event_tablet_tool_get_y_transformed (tablet_event, stage_height); + notify_absolute_motion (device, time, x, y, axes); + } +} + +static gboolean +process_device_event (MetaSeatImpl *seat_impl, + struct libinput_event *event) +{ + gboolean handled = TRUE; + struct libinput_device *libinput_device = libinput_event_get_device(event); + ClutterInputDevice *device; + MetaInputDeviceNative *device_native; + + switch (libinput_event_get_type (event)) + { + case LIBINPUT_EVENT_KEYBOARD_KEY: + { + uint32_t key, key_state, seat_key_count; + uint64_t time_us; + struct libinput_event_keyboard *key_event = + libinput_event_get_keyboard_event (event); + + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_keyboard_get_time_usec (key_event); + key = libinput_event_keyboard_get_key (key_event); + key_state = libinput_event_keyboard_get_key_state (key_event) == + LIBINPUT_KEY_STATE_PRESSED; + seat_key_count = + libinput_event_keyboard_get_seat_key_count (key_event); + + /* Ignore key events that are not seat wide state changes. */ + if ((key_state == LIBINPUT_KEY_STATE_PRESSED && + seat_key_count != 1) || + (key_state == LIBINPUT_KEY_STATE_RELEASED && + seat_key_count != 0)) + { + meta_topic (META_DEBUG_INPUT, + "Dropping key-%s of key 0x%x because seat-wide " + "key count is %d", + key_state == LIBINPUT_KEY_STATE_PRESSED ? "press" : "release", + key, seat_key_count); + break; + } + + meta_seat_impl_notify_key (seat_impl, + device, + time_us, key, key_state, TRUE); + + break; + } + + case LIBINPUT_EVENT_POINTER_MOTION: + { + struct libinput_event_pointer *pointer_event = + libinput_event_get_pointer_event (event); + uint64_t time_us; + double dx; + double dy; + double dx_unaccel; + double dy_unaccel; + + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_pointer_get_time_usec (pointer_event); + dx = libinput_event_pointer_get_dx (pointer_event); + dy = libinput_event_pointer_get_dy (pointer_event); + dx_unaccel = libinput_event_pointer_get_dx_unaccelerated (pointer_event); + dy_unaccel = libinput_event_pointer_get_dy_unaccelerated (pointer_event); + + meta_seat_impl_notify_relative_motion (seat_impl, + device, + time_us, + dx, dy, + dx_unaccel, dy_unaccel); + + break; + } + + case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: + { + uint64_t time_us; + double x, y; + float stage_width, stage_height; + struct libinput_event_pointer *motion_event = + libinput_event_get_pointer_event (event); + device = libinput_device_get_user_data (libinput_device); + + meta_viewport_info_get_extents (seat_impl->viewports, + &stage_width, &stage_height); + + time_us = libinput_event_pointer_get_time_usec (motion_event); + x = libinput_event_pointer_get_absolute_x_transformed (motion_event, + stage_width); + y = libinput_event_pointer_get_absolute_y_transformed (motion_event, + stage_height); + + meta_seat_impl_notify_absolute_motion (seat_impl, + device, + time_us, + x, y, + NULL); + + break; + } + + case LIBINPUT_EVENT_POINTER_BUTTON: + { + uint32_t button, button_state, seat_button_count; + uint64_t time_us; + struct libinput_event_pointer *button_event = + libinput_event_get_pointer_event (event); + device = libinput_device_get_user_data (libinput_device); + + time_us = libinput_event_pointer_get_time_usec (button_event); + button = libinput_event_pointer_get_button (button_event); + button_state = libinput_event_pointer_get_button_state (button_event) == + LIBINPUT_BUTTON_STATE_PRESSED; + seat_button_count = + libinput_event_pointer_get_seat_button_count (button_event); + + /* Ignore button events that are not seat wide state changes. */ + if ((button_state == LIBINPUT_BUTTON_STATE_PRESSED && + seat_button_count != 1) || + (button_state == LIBINPUT_BUTTON_STATE_RELEASED && + seat_button_count != 0)) + { + meta_topic (META_DEBUG_INPUT, + "Dropping button-%s of button 0x%x because seat-wide " + "button count is %d", + button_state == LIBINPUT_BUTTON_STATE_PRESSED ? "press" : "release", + button, seat_button_count); + break; + } + + meta_seat_impl_notify_button (seat_impl, device, + time_us, button, button_state); + break; + } + + case LIBINPUT_EVENT_POINTER_AXIS: + { + uint64_t time_us; + enum libinput_pointer_axis_source source; + struct libinput_event_pointer *axis_event = + libinput_event_get_pointer_event (event); + ClutterScrollSource scroll_source; + + device = libinput_device_get_user_data (libinput_device); + + time_us = libinput_event_pointer_get_time_usec (axis_event); + source = libinput_event_pointer_get_axis_source (axis_event); + scroll_source = translate_scroll_source (source); + + /* libinput < 0.8 sent wheel click events with value 10. Since 0.8 + the value is the angle of the click in degrees. To keep + backwards-compat with existing clients, we just send multiples of + the click count. */ + + switch (scroll_source) + { + case CLUTTER_SCROLL_SOURCE_WHEEL: + notify_discrete_axis (seat_impl, device, time_us, scroll_source, + axis_event); + break; + case CLUTTER_SCROLL_SOURCE_FINGER: + case CLUTTER_SCROLL_SOURCE_CONTINUOUS: + case CLUTTER_SCROLL_SOURCE_UNKNOWN: + notify_continuous_axis (seat_impl, device, time_us, scroll_source, + axis_event); + break; + } + break; + } + + case LIBINPUT_EVENT_TOUCH_DOWN: + { + int seat_slot; + uint64_t time_us; + double x, y; + float stage_width, stage_height; + MetaTouchState *touch_state; + struct libinput_event_touch *touch_event = + libinput_event_get_touch_event (event); + + device = libinput_device_get_user_data (libinput_device); + device_native = META_INPUT_DEVICE_NATIVE (device); + + meta_viewport_info_get_extents (seat_impl->viewports, + &stage_width, &stage_height); + + seat_slot = libinput_event_touch_get_seat_slot (touch_event); + time_us = libinput_event_touch_get_time_usec (touch_event); + x = libinput_event_touch_get_x_transformed (touch_event, + stage_width); + y = libinput_event_touch_get_y_transformed (touch_event, + stage_height); + + touch_state = meta_seat_impl_acquire_touch_state (seat_impl, seat_slot); + touch_state->coords.x = x; + touch_state->coords.y = y; + + meta_seat_impl_notify_touch_event (seat_impl, device, + CLUTTER_TOUCH_BEGIN, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); + break; + } + + case LIBINPUT_EVENT_TOUCH_UP: + { + int seat_slot; + uint64_t time_us; + MetaTouchState *touch_state; + struct libinput_event_touch *touch_event = + libinput_event_get_touch_event (event); + + device = libinput_device_get_user_data (libinput_device); + device_native = META_INPUT_DEVICE_NATIVE (device); + + seat_slot = libinput_event_touch_get_seat_slot (touch_event); + time_us = libinput_event_touch_get_time_usec (touch_event); + touch_state = meta_seat_impl_lookup_touch_state (seat_impl, seat_slot); + if (!touch_state) + break; + + meta_seat_impl_notify_touch_event (seat_impl, device, + CLUTTER_TOUCH_END, time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); + meta_seat_impl_release_touch_state (seat_impl, seat_slot); + break; + } + + case LIBINPUT_EVENT_TOUCH_MOTION: + { + int seat_slot; + uint64_t time_us; + double x, y; + float stage_width, stage_height; + MetaTouchState *touch_state; + struct libinput_event_touch *touch_event = + libinput_event_get_touch_event (event); + + device = libinput_device_get_user_data (libinput_device); + device_native = META_INPUT_DEVICE_NATIVE (device); + + meta_viewport_info_get_extents (seat_impl->viewports, + &stage_width, &stage_height); + + seat_slot = libinput_event_touch_get_seat_slot (touch_event); + time_us = libinput_event_touch_get_time_usec (touch_event); + x = libinput_event_touch_get_x_transformed (touch_event, + stage_width); + y = libinput_event_touch_get_y_transformed (touch_event, + stage_height); + + touch_state = meta_seat_impl_lookup_touch_state (seat_impl, seat_slot); + if (!touch_state) + break; + + touch_state->coords.x = x; + touch_state->coords.y = y; + + meta_seat_impl_notify_touch_event (seat_impl, device, + CLUTTER_TOUCH_UPDATE, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); + break; + } + case LIBINPUT_EVENT_TOUCH_CANCEL: + { + int seat_slot; + MetaTouchState *touch_state; + uint64_t time_us; + struct libinput_event_touch *touch_event = + libinput_event_get_touch_event (event); + + device = libinput_device_get_user_data (libinput_device); + device_native = META_INPUT_DEVICE_NATIVE (device); + time_us = libinput_event_touch_get_time_usec (touch_event); + + seat_slot = libinput_event_touch_get_seat_slot (touch_event); + touch_state = meta_seat_impl_lookup_touch_state (seat_impl, seat_slot); + if (!touch_state) + break; + + meta_seat_impl_notify_touch_event (touch_state->seat_impl, + CLUTTER_INPUT_DEVICE (device_native), + CLUTTER_TOUCH_CANCEL, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); + + meta_seat_impl_release_touch_state (seat_impl, seat_slot); + break; + } + case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: + case LIBINPUT_EVENT_GESTURE_PINCH_END: + { + struct libinput_event_gesture *gesture_event = + libinput_event_get_gesture_event (event); + ClutterTouchpadGesturePhase phase; + uint32_t n_fingers; + uint64_t time_us; + + if (libinput_event_get_type (event) == LIBINPUT_EVENT_GESTURE_PINCH_BEGIN) + phase = CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN; + else + phase = libinput_event_gesture_get_cancelled (gesture_event) ? + CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL : CLUTTER_TOUCHPAD_GESTURE_PHASE_END; + + n_fingers = libinput_event_gesture_get_finger_count (gesture_event); + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_gesture_get_time_usec (gesture_event); + notify_pinch_gesture_event (device, phase, time_us, 0, 0, 0, 0, n_fingers); + break; + } + case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: + { + struct libinput_event_gesture *gesture_event = + libinput_event_get_gesture_event (event); + double angle_delta, scale, dx, dy; + uint32_t n_fingers; + uint64_t time_us; + + n_fingers = libinput_event_gesture_get_finger_count (gesture_event); + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_gesture_get_time_usec (gesture_event); + angle_delta = libinput_event_gesture_get_angle_delta (gesture_event); + scale = libinput_event_gesture_get_scale (gesture_event); + dx = libinput_event_gesture_get_dx (gesture_event); + dy = libinput_event_gesture_get_dy (gesture_event); + + notify_pinch_gesture_event (device, + CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE, + time_us, dx, dy, angle_delta, scale, n_fingers); + break; + } + case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN: + case LIBINPUT_EVENT_GESTURE_SWIPE_END: + { + struct libinput_event_gesture *gesture_event = + libinput_event_get_gesture_event (event); + ClutterTouchpadGesturePhase phase; + uint32_t n_fingers; + uint64_t time_us; + + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_gesture_get_time_usec (gesture_event); + n_fingers = libinput_event_gesture_get_finger_count (gesture_event); + + if (libinput_event_get_type (event) == LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN) + phase = CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN; + else + phase = libinput_event_gesture_get_cancelled (gesture_event) ? + CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL : CLUTTER_TOUCHPAD_GESTURE_PHASE_END; + + notify_swipe_gesture_event (device, phase, time_us, n_fingers, 0, 0); + break; + } + case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE: + { + struct libinput_event_gesture *gesture_event = + libinput_event_get_gesture_event (event); + uint32_t n_fingers; + uint64_t time_us; + double dx, dy; + + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_gesture_get_time_usec (gesture_event); + n_fingers = libinput_event_gesture_get_finger_count (gesture_event); + dx = libinput_event_gesture_get_dx (gesture_event); + dy = libinput_event_gesture_get_dy (gesture_event); + + notify_swipe_gesture_event (device, + CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE, + time_us, n_fingers, dx, dy); + break; + } + case LIBINPUT_EVENT_TABLET_TOOL_AXIS: + { + process_tablet_axis (seat_impl, event); + break; + } + case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: + { + uint64_t time; + struct libinput_event_tablet_tool *tablet_event = + libinput_event_get_tablet_tool_event (event); + struct libinput_tablet_tool *libinput_tool = NULL; + enum libinput_tablet_tool_proximity_state state; + gboolean in; + + state = libinput_event_tablet_tool_get_proximity_state (tablet_event); + time = libinput_event_tablet_tool_get_time_usec (tablet_event); + device = libinput_device_get_user_data (libinput_device); + in = state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN; + + libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event); + + if (in) + input_device_update_tool (device, libinput_tool); + notify_proximity (device, time, in); + if (!in) + input_device_update_tool (device, NULL); + + break; + } + case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: + { + uint64_t time_us; + uint32_t button_state; + struct libinput_event_tablet_tool *tablet_event = + libinput_event_get_tablet_tool_event (event); + uint32_t tablet_button; + + process_tablet_axis (seat_impl, event); + + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_tablet_tool_get_time_usec (tablet_event); + tablet_button = libinput_event_tablet_tool_get_button (tablet_event); + + button_state = libinput_event_tablet_tool_get_button_state (tablet_event) == + LIBINPUT_BUTTON_STATE_PRESSED; + + meta_seat_impl_notify_button (seat_impl, device, + time_us, tablet_button, button_state); + break; + } + case LIBINPUT_EVENT_TABLET_TOOL_TIP: + { + uint64_t time_us; + uint32_t button_state; + struct libinput_event_tablet_tool *tablet_event = + libinput_event_get_tablet_tool_event (event); + + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_tablet_tool_get_time_usec (tablet_event); + + button_state = libinput_event_tablet_tool_get_tip_state (tablet_event) == + LIBINPUT_TABLET_TOOL_TIP_DOWN; + + /* To avoid jumps on tip, notify axes before the tip down event + but after the tip up event */ + if (button_state) + process_tablet_axis (seat_impl, event); + + meta_seat_impl_notify_button (seat_impl, device, + time_us, BTN_TOUCH, button_state); + if (!button_state) + process_tablet_axis (seat_impl, event); + break; + } + case LIBINPUT_EVENT_TABLET_PAD_BUTTON: + { + uint64_t time; + uint32_t button_state, button, group, mode; + struct libinput_tablet_pad_mode_group *mode_group; + struct libinput_event_tablet_pad *pad_event = + libinput_event_get_tablet_pad_event (event); + + device = libinput_device_get_user_data (libinput_device); + time = libinput_event_tablet_pad_get_time_usec (pad_event); + + mode_group = libinput_event_tablet_pad_get_mode_group (pad_event); + group = libinput_tablet_pad_mode_group_get_index (mode_group); + mode = libinput_event_tablet_pad_get_mode (pad_event); + + button = libinput_event_tablet_pad_get_button_number (pad_event); + button_state = libinput_event_tablet_pad_get_button_state (pad_event) == + LIBINPUT_BUTTON_STATE_PRESSED; + notify_pad_button (device, time, button, group, mode, button_state); + break; + } + case LIBINPUT_EVENT_TABLET_PAD_STRIP: + { + uint64_t time; + uint32_t number, source, group, mode; + struct libinput_tablet_pad_mode_group *mode_group; + struct libinput_event_tablet_pad *pad_event = + libinput_event_get_tablet_pad_event (event); + double value; + + device = libinput_device_get_user_data (libinput_device); + time = libinput_event_tablet_pad_get_time_usec (pad_event); + number = libinput_event_tablet_pad_get_strip_number (pad_event); + value = libinput_event_tablet_pad_get_strip_position (pad_event); + source = libinput_event_tablet_pad_get_strip_source (pad_event); + + mode_group = libinput_event_tablet_pad_get_mode_group (pad_event); + group = libinput_tablet_pad_mode_group_get_index (mode_group); + mode = libinput_event_tablet_pad_get_mode (pad_event); + + notify_pad_strip (device, time, number, source, group, mode, value); + break; + } + case LIBINPUT_EVENT_TABLET_PAD_RING: + { + uint64_t time; + uint32_t number, source, group, mode; + struct libinput_tablet_pad_mode_group *mode_group; + struct libinput_event_tablet_pad *pad_event = + libinput_event_get_tablet_pad_event (event); + double angle; + + device = libinput_device_get_user_data (libinput_device); + time = libinput_event_tablet_pad_get_time_usec (pad_event); + number = libinput_event_tablet_pad_get_ring_number (pad_event); + angle = libinput_event_tablet_pad_get_ring_position (pad_event); + source = libinput_event_tablet_pad_get_ring_source (pad_event); + + mode_group = libinput_event_tablet_pad_get_mode_group (pad_event); + group = libinput_tablet_pad_mode_group_get_index (mode_group); + mode = libinput_event_tablet_pad_get_mode (pad_event); + + notify_pad_ring (device, time, number, source, group, mode, angle); + break; + } + case LIBINPUT_EVENT_SWITCH_TOGGLE: + { + struct libinput_event_switch *switch_event = + libinput_event_get_switch_event (event); + enum libinput_switch sw = + libinput_event_switch_get_switch (switch_event); + enum libinput_switch_state state = + libinput_event_switch_get_switch_state (switch_event); + + if (sw == LIBINPUT_SWITCH_TABLET_MODE) + { + seat_impl->tablet_mode_switch_state = (state == LIBINPUT_SWITCH_STATE_ON); + update_touch_mode (seat_impl); + } + break; + } + default: + handled = FALSE; + } + + return handled; +} + +static void +process_event (MetaSeatImpl *seat_impl, + struct libinput_event *event) +{ + if (process_base_event (seat_impl, event)) + return; + if (process_device_event (seat_impl, event)) + return; +} + +static void +process_events (MetaSeatImpl *seat_impl) +{ + struct libinput_event *event; + + while ((event = libinput_get_event (seat_impl->libinput))) + { + process_event(seat_impl, event); + libinput_event_destroy(event); + } +} + +static int +open_restricted (const char *path, + int flags, + void *user_data) +{ + int fd; + + if (device_open_callback) + { + GError *error = NULL; + + fd = device_open_callback (path, flags, device_callback_data, &error); + + if (fd < 0) + { + g_warning ("Could not open device %s: %s", path, error->message); + g_error_free (error); + } + } + else + { + fd = open (path, O_RDWR | O_NONBLOCK); + if (fd < 0) + { + g_warning ("Could not open device %s: %s", path, strerror (errno)); + } + } + + return fd; +} + +static void +close_restricted (int fd, + void *user_data) +{ + if (device_close_callback) + device_close_callback (fd, device_callback_data); + else + close (fd); +} + +static const struct libinput_interface libinput_interface = { + open_restricted, + close_restricted +}; + +static void +meta_seat_impl_constructed (GObject *object) +{ + MetaSeatImpl *seat_impl = META_SEAT_IMPL (object); + ClutterInputDevice *device; + MetaEventSource *source; + struct udev *udev; + struct xkb_keymap *xkb_keymap; + + device = meta_input_device_native_new_virtual ( + seat_impl, CLUTTER_POINTER_DEVICE, + CLUTTER_INPUT_MODE_LOGICAL); + seat_impl->pointer_x = INITIAL_POINTER_X; + seat_impl->pointer_y = INITIAL_POINTER_Y; + meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (device), + seat_impl->pointer_x, + seat_impl->pointer_y); + seat_impl->core_pointer = device; + + device = meta_input_device_native_new_virtual ( + seat_impl, CLUTTER_KEYBOARD_DEVICE, + CLUTTER_INPUT_MODE_LOGICAL); + seat_impl->core_keyboard = device; + + udev = udev_new (); + if (G_UNLIKELY (udev == NULL)) + { + g_warning ("Failed to create udev object"); + return; + } + + seat_impl->libinput = libinput_udev_create_context (&libinput_interface, + seat_impl, udev); + if (seat_impl->libinput == NULL) + { + g_critical ("Failed to create the libinput object."); + return; + } + + if (libinput_udev_assign_seat (seat_impl->libinput, seat_impl->seat_id) == -1) + { + g_critical ("Failed to assign a seat to the libinput object."); + libinput_unref (seat_impl->libinput); + seat_impl->libinput = NULL; + return; + } + + udev_unref (udev); + + seat_impl->udev_client = g_udev_client_new ((const char *[]) { "input", NULL }); + + source = meta_event_source_new (seat_impl); + seat_impl->event_source = source; + + seat_impl->keymap = g_object_new (META_TYPE_KEYMAP_NATIVE, NULL); + xkb_keymap = meta_keymap_native_get_keyboard_map (seat_impl->keymap); + + if (xkb_keymap) + { + seat_impl->xkb = xkb_state_new (xkb_keymap); + + seat_impl->caps_lock_led = + xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_CAPS); + seat_impl->num_lock_led = + xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_NUM); + seat_impl->scroll_lock_led = + xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL); + } + + seat_impl->has_touchscreen = has_touchscreen (seat_impl); + seat_impl->has_tablet_switch = has_tablet_switch (seat_impl); + update_touch_mode (seat_impl); + + if (G_OBJECT_CLASS (meta_seat_impl_parent_class)->constructed) + G_OBJECT_CLASS (meta_seat_impl_parent_class)->constructed (object); +} + +static void +meta_seat_impl_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaSeatImpl *seat_impl = META_SEAT_IMPL (object); + + switch (prop_id) + { + case PROP_SEAT: + seat_impl->seat_native = g_value_get_object (value); + break; + case PROP_SEAT_ID: + seat_impl->seat_id = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_seat_impl_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaSeatImpl *seat_impl = META_SEAT_IMPL (object); + + switch (prop_id) + { + case PROP_SEAT: + g_value_set_object (value, seat_impl->seat_native); + break; + case PROP_SEAT_ID: + g_value_set_string (value, seat_impl->seat_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_seat_impl_dispose (GObject *object) +{ + MetaSeatImpl *seat_impl = META_SEAT_IMPL (object); + + if (seat_impl->libinput) + { + libinput_unref (seat_impl->libinput); + seat_impl->libinput = NULL; + } + + G_OBJECT_CLASS (meta_seat_impl_parent_class)->dispose (object); +} + +static void +meta_seat_impl_finalize (GObject *object) +{ + MetaSeatImpl *seat_impl = META_SEAT_IMPL (object); + GSList *iter; + + for (iter = seat_impl->devices; iter; iter = g_slist_next (iter)) + { + ClutterInputDevice *device = iter->data; + + g_object_unref (device); + } + g_slist_free (seat_impl->devices); + + if (seat_impl->touch_states) + g_hash_table_destroy (seat_impl->touch_states); + + g_object_unref (seat_impl->udev_client); + + meta_event_source_free (seat_impl->event_source); + + xkb_state_unref (seat_impl->xkb); + + meta_seat_impl_clear_repeat_timer (seat_impl); + + g_free (seat_impl->seat_id); + + G_OBJECT_CLASS (meta_seat_impl_parent_class)->finalize (object); +} + +ClutterInputDevice * +meta_seat_impl_get_pointer (MetaSeatImpl *seat_impl) +{ + return seat_impl->core_pointer; +} + +ClutterInputDevice * +meta_seat_impl_get_keyboard (MetaSeatImpl *seat_impl) +{ + return seat_impl->core_keyboard; +} + +GSList * +meta_seat_impl_get_devices (MetaSeatImpl *seat_impl) +{ + return g_slist_copy_deep (seat_impl->devices, + (GCopyFunc) g_object_ref, + NULL); +} + +MetaKeymapNative * +meta_seat_impl_get_keymap (MetaSeatImpl *seat_impl) +{ + return g_object_ref (seat_impl->keymap); +} + +void +meta_seat_impl_warp_pointer (MetaSeatImpl *seat_impl, + int x, + int y) +{ + notify_absolute_motion (seat_impl->core_pointer, 0, x, y, NULL); +} + +gboolean +meta_seat_impl_query_state (MetaSeatImpl *seat_impl, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + graphene_point_t *coords, + ClutterModifierType *modifiers) +{ + MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); + + if (sequence) + { + MetaTouchState *touch_state; + int slot; + + slot = meta_event_native_sequence_get_slot (sequence); + touch_state = meta_seat_impl_lookup_touch_state (seat_impl, slot); + if (!touch_state) + return FALSE; + + if (coords) + { + coords->x = touch_state->coords.x; + coords->y = touch_state->coords.y; + } + + if (modifiers) + *modifiers = meta_xkb_translate_modifiers (seat_impl->xkb, 0); + + return TRUE; + } + else + { + if (coords) + { + coords->x = device_native->pointer_x; + coords->y = device_native->pointer_y; + } + + if (modifiers) + { + *modifiers = meta_xkb_translate_modifiers (seat_impl->xkb, + seat_impl->button_state); + } + + return TRUE; + } +} + +static void +meta_seat_impl_class_init (MetaSeatImplClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = meta_seat_impl_constructed; + object_class->set_property = meta_seat_impl_set_property; + object_class->get_property = meta_seat_impl_get_property; + object_class->dispose = meta_seat_impl_dispose; + object_class->finalize = meta_seat_impl_finalize; + + props[PROP_SEAT] = + g_param_spec_object ("seat", + "Seat", + "Seat", + META_TYPE_SEAT_NATIVE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + props[PROP_SEAT_ID] = + g_param_spec_string ("seat-id", + "Seat ID", + "Seat ID", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, N_PROPS, props); +} + +static void +meta_seat_impl_init (MetaSeatImpl *seat_impl) +{ + seat_impl->repeat = TRUE; + seat_impl->repeat_delay = 250; /* ms */ + seat_impl->repeat_interval = 33; /* ms */ + + seat_impl->barrier_manager = meta_barrier_manager_native_new (); +} + +/** + * meta_seat_impl_set_device_callbacks: (skip) + * @open_callback: the user replacement for open() + * @close_callback: the user replacement for close() + * @user_data: user data for @callback + * + * Through this function, the application can set a custom callback + * to be invoked when Clutter is about to open an evdev device. It can do + * so if special handling is needed, for example to circumvent permission + * problems. + * + * Setting @callback to %NULL will reset the default behavior. + * + * For reliable effects, this function must be called before clutter_init(). + */ +void +meta_seat_impl_set_device_callbacks (MetaOpenDeviceCallback open_callback, + MetaCloseDeviceCallback close_callback, + gpointer user_data) +{ + device_open_callback = open_callback; + device_close_callback = close_callback; + device_callback_data = user_data; +} + +void +meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl) +{ + xkb_mod_mask_t latched_mods; + xkb_mod_mask_t locked_mods; + struct xkb_keymap *xkb_keymap; + + xkb_keymap = meta_keymap_native_get_keyboard_map (seat_impl->keymap); + + latched_mods = xkb_state_serialize_mods (seat_impl->xkb, + XKB_STATE_MODS_LATCHED); + locked_mods = xkb_state_serialize_mods (seat_impl->xkb, + XKB_STATE_MODS_LOCKED); + xkb_state_unref (seat_impl->xkb); + seat_impl->xkb = xkb_state_new (xkb_keymap); + + xkb_state_update_mask (seat_impl->xkb, + 0, /* depressed */ + latched_mods, + locked_mods, + 0, 0, seat_impl->layout_idx); + + seat_impl->caps_lock_led = + xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_CAPS); + seat_impl->num_lock_led = + xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_NUM); + seat_impl->scroll_lock_led = + xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL); + + meta_seat_impl_sync_leds (seat_impl); +} + +/** + * meta_seat_impl_release_devices: + * + * Releases all the evdev devices that Clutter is currently managing. This api + * is typically used when switching away from the Clutter application when + * switching tty. The devices can be reclaimed later with a call to + * meta_seat_impl_reclaim_devices(). + * + * This function should only be called after clutter has been initialized. + */ +void +meta_seat_impl_release_devices (MetaSeatImpl *seat_impl) +{ + if (seat_impl->released) + { + g_warning ("meta_seat_impl_release_devices() shouldn't be called " + "multiple times without a corresponding call to " + "meta_seat_impl_reclaim_devices() first"); + return; + } + + libinput_suspend (seat_impl->libinput); + process_events (seat_impl); + + seat_impl->released = TRUE; +} + +/** + * meta_seat_impl_reclaim_devices: + * + * This causes Clutter to re-probe for evdev devices. This is must only be + * called after a corresponding call to meta_seat_impl_release_devices() + * was previously used to release all evdev devices. This API is typically + * used when a clutter application using evdev has regained focus due to + * switching ttys. + * + * This function should only be called after clutter has been initialized. + */ +void +meta_seat_impl_reclaim_devices (MetaSeatImpl *seat_impl) +{ + if (!seat_impl->released) + { + g_warning ("Spurious call to meta_seat_impl_reclaim_devices() without " + "previous call to meta_seat_impl_release_devices"); + return; + } + + libinput_resume (seat_impl->libinput); + meta_seat_impl_update_xkb_state (seat_impl); + process_events (seat_impl); + + seat_impl->released = FALSE; +} + +/** + * meta_seat_impl_set_keyboard_map: (skip) + * @seat: the #ClutterSeat created by the evdev backend + * @keymap: the new keymap + * + * Instructs @evdev to use the speficied keyboard map. This will cause + * the backend to drop the state and create a new one with the new + * map. To avoid state being lost, callers should ensure that no key + * is pressed when calling this function. + */ +void +meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat_impl, + struct xkb_keymap *xkb_keymap) +{ + MetaKeymapNative *keymap; + + g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); + + keymap = seat_impl->keymap; + meta_keymap_native_set_keyboard_map (keymap, xkb_keymap); + + meta_seat_impl_update_xkb_state (seat_impl); +} + +/** + * meta_seat_impl_get_keyboard_map: (skip) + * @seat: the #ClutterSeat created by the evdev backend + * + * Retrieves the #xkb_keymap in use by the evdev backend. + * + * Return value: the #xkb_keymap. + */ +struct xkb_keymap * +meta_seat_impl_get_keyboard_map (MetaSeatImpl *seat_impl) +{ + g_return_val_if_fail (META_IS_SEAT_IMPL (seat_impl), NULL); + + return xkb_state_get_keymap (seat_impl->xkb); +} + +/** + * meta_seat_impl_set_keyboard_layout_index: (skip) + * @seat: the #ClutterSeat created by the evdev backend + * @idx: the xkb layout index to set + * + * Sets the xkb layout index on the backend's #xkb_state . + */ +void +meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, + xkb_layout_index_t idx) +{ + xkb_mod_mask_t depressed_mods; + xkb_mod_mask_t latched_mods; + xkb_mod_mask_t locked_mods; + struct xkb_state *state; + + g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); + + state = seat_impl->xkb; + + depressed_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED); + latched_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED); + locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED); + + xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx); + + seat_impl->layout_idx = idx; +} + +/** + * meta_seat_impl_get_keyboard_layout_index: (skip) + */ +xkb_layout_index_t +meta_seat_impl_get_keyboard_layout_index (MetaSeatImpl *seat_impl) +{ + return seat_impl->layout_idx; +} + +/** + * meta_seat_impl_set_keyboard_numlock: (skip) + * @seat: the #ClutterSeat created by the evdev backend + * @numlock_set: TRUE to set NumLock ON, FALSE otherwise. + * + * Sets the NumLock state on the backend's #xkb_state . + */ +void +meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, + gboolean numlock_state) +{ + xkb_mod_mask_t depressed_mods; + xkb_mod_mask_t latched_mods; + xkb_mod_mask_t locked_mods; + xkb_mod_mask_t group_mods; + xkb_mod_mask_t numlock; + struct xkb_keymap *xkb_keymap; + MetaKeymapNative *keymap; + + g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); + + keymap = seat_impl->keymap; + xkb_keymap = meta_keymap_native_get_keyboard_map (keymap); + + numlock = (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod2")); + + depressed_mods = + xkb_state_serialize_mods (seat_impl->xkb, XKB_STATE_MODS_DEPRESSED); + latched_mods = + xkb_state_serialize_mods (seat_impl->xkb, XKB_STATE_MODS_LATCHED); + locked_mods = + xkb_state_serialize_mods (seat_impl->xkb, XKB_STATE_MODS_LOCKED); + group_mods = + xkb_state_serialize_layout (seat_impl->xkb, XKB_STATE_LAYOUT_EFFECTIVE); + + if (numlock_state) + locked_mods |= numlock; + else + locked_mods &= ~numlock; + + xkb_state_update_mask (seat_impl->xkb, + depressed_mods, + latched_mods, + locked_mods, + 0, 0, + group_mods); + + meta_seat_impl_sync_leds (seat_impl); +} + +/** + * meta_seat_impl_set_keyboard_repeat: + * @seat: the #ClutterSeat created by the evdev backend + * @repeat: whether to enable or disable keyboard repeat events + * @delay: the delay in ms between the hardware key press event and + * the first synthetic event + * @interval: the period in ms between consecutive synthetic key + * press events + * + * Enables or disables sythetic key press events, allowing for initial + * delay and interval period to be specified. + */ +void +meta_seat_impl_set_keyboard_repeat (MetaSeatImpl *seat_impl, + gboolean repeat, + uint32_t delay, + uint32_t interval) +{ + g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); + + seat_impl->repeat = repeat; + seat_impl->repeat_delay = delay; + seat_impl->repeat_interval = interval; +} + +struct xkb_state * +meta_seat_impl_get_xkb_state (MetaSeatImpl *seat_impl) +{ + return seat_impl->xkb; +} + +MetaBarrierManagerNative * +meta_seat_impl_get_barrier_manager (MetaSeatImpl *seat_impl) +{ + return seat_impl->barrier_manager; +} + +void +meta_seat_impl_set_pointer_constraint (MetaSeatImpl *seat_impl, + MetaPointerConstraintImpl *constraint_impl) +{ + if (!g_set_object (&seat_impl->pointer_constraint, constraint_impl)) + return; + + if (constraint_impl) + { + meta_pointer_constraint_impl_ensure_constrained (constraint_impl, + seat_impl->core_pointer); + } +} + +void +meta_seat_impl_set_viewports (MetaSeatImpl *seat_impl, + MetaViewportInfo *viewports) +{ + g_set_object (&seat_impl->viewports, viewports); +} + +MetaSeatImpl * +meta_seat_impl_new (MetaSeatNative *seat_native, + const char *seat_id) +{ + return g_object_new (META_TYPE_SEAT_IMPL, + "seat", seat_native, + "seat-id", seat_id, + NULL); +} diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h new file mode 100644 index 00000000000..71241cbc736 --- /dev/null +++ b/src/backends/native/meta-seat-impl.h @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2010 Intel Corp. + * Copyright (C) 2014 Jonas Ã…dahl + * Copyright (C) 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Damien Lespiau + * Author: Jonas Ã…dahl + */ + +#ifndef META_SEAT_IMPL_H +#define META_SEAT_IMPL_H + +#include +#include +#include + +#include "backends/meta-viewport-info.h" +#include "backends/native/meta-backend-native-types.h" +#include "backends/native/meta-barrier-native.h" +#include "backends/native/meta-cursor-renderer-native.h" +#include "backends/native/meta-keymap-native.h" +#include "backends/native/meta-pointer-constraint-native.h" +#include "backends/native/meta-xkb-utils.h" +#include "clutter/clutter.h" + +typedef struct _MetaTouchState MetaTouchState; +typedef struct _MetaSeatImpl MetaSeatImpl; +typedef struct _MetaEventSource MetaEventSource; + +struct _MetaTouchState +{ + MetaSeatImpl *seat_impl; + + int device_slot; + int seat_slot; + graphene_point_t coords; +}; + +struct _MetaSeatImpl +{ + GObject parent_instance; + + MetaSeatNative *seat_native; + char *seat_id; + MetaEventSource *event_source; + struct libinput *libinput; + + GSList *devices; + + ClutterInputDevice *core_pointer; + ClutterInputDevice *core_keyboard; + + GHashTable *touch_states; + GHashTable *cursor_renderers; + + struct xkb_state *xkb; + xkb_led_index_t caps_lock_led; + xkb_led_index_t num_lock_led; + xkb_led_index_t scroll_lock_led; + xkb_layout_index_t layout_idx; + uint32_t button_state; + int button_count[KEY_CNT]; + + MetaBarrierManagerNative *barrier_manager; + MetaPointerConstraintImpl *pointer_constraint; + + MetaKeymapNative *keymap; + + MetaViewportInfo *viewports; + + GUdevClient *udev_client; + gboolean tablet_mode_switch_state; + gboolean has_touchscreen; + gboolean has_tablet_switch; + gboolean touch_mode; + + /* keyboard repeat */ + gboolean repeat; + uint32_t repeat_delay; + uint32_t repeat_interval; + uint32_t repeat_key; + uint32_t repeat_count; + uint32_t repeat_timer; + ClutterInputDevice *repeat_device; + + float pointer_x; + float pointer_y; + + /* Emulation of discrete scroll events out of smooth ones */ + float accum_scroll_dx; + float accum_scroll_dy; + + gboolean released; +}; + +#define META_TYPE_SEAT_IMPL meta_seat_impl_get_type () +G_DECLARE_FINAL_TYPE (MetaSeatImpl, meta_seat_impl, + META, SEAT_IMPL, GObject) + +MetaSeatImpl * meta_seat_impl_new (MetaSeatNative *seat_native, + const char *seat_id); + +void meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, + ClutterInputDevice *device, + uint64_t time_us, + uint32_t key, + uint32_t state, + gboolean update_keys); + +void meta_seat_impl_notify_relative_motion (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + float dx, + float dy, + float dx_unaccel, + float dy_unaccel); + +void meta_seat_impl_notify_absolute_motion (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + float x, + float y, + double *axes); + +void meta_seat_impl_notify_button (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + uint32_t button, + uint32_t state); + +void meta_seat_impl_notify_scroll_continuous (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + double dx, + double dy, + ClutterScrollSource source, + ClutterScrollFinishFlags flags); + +void meta_seat_impl_notify_discrete_scroll (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + double discrete_dx, + double discrete_dy, + ClutterScrollSource source); + +void meta_seat_impl_notify_touch_event (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + ClutterEventType evtype, + uint64_t time_us, + int slot, + double x, + double y); + +void meta_seat_impl_sync_leds (MetaSeatImpl *seat_impl); + +MetaTouchState * meta_seat_impl_acquire_touch_state (MetaSeatImpl *seat_impl, + int seat_slot); +MetaTouchState * meta_seat_impl_lookup_touch_state (MetaSeatImpl *seat_impl, + int seat_slot); +void meta_seat_impl_release_touch_state (MetaSeatImpl *seat_impl, + int seat_slot); + +void meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl); + +/** + * MetaOpenDeviceCallback: + * @path: the device path + * @flags: flags to be passed to open + * + * This callback will be called when Clutter needs to access an input + * device. It should return an open file descriptor for the file at @path, + * or -1 if opening failed. + */ +typedef int (* MetaOpenDeviceCallback) (const char *path, + int flags, + gpointer user_data, + GError **error); +typedef void (* MetaCloseDeviceCallback) (int fd, + gpointer user_data); + +void meta_seat_impl_set_device_callbacks (MetaOpenDeviceCallback open_callback, + MetaCloseDeviceCallback close_callback, + gpointer user_data); + +void meta_seat_impl_release_devices (MetaSeatImpl *seat_impl); +void meta_seat_impl_reclaim_devices (MetaSeatImpl *seat_impl); + +struct xkb_state * meta_seat_impl_get_xkb_state (MetaSeatImpl *seat_impl); + +void meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat_impl, + struct xkb_keymap *keymap); + +struct xkb_keymap * meta_seat_impl_get_keyboard_map (MetaSeatImpl *seat_impl); + +void meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, + xkb_layout_index_t idx); + +xkb_layout_index_t meta_seat_impl_get_keyboard_layout_index (MetaSeatImpl *seat_impl); + +void meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, + gboolean numlock_state); + +void meta_seat_impl_set_keyboard_repeat (MetaSeatImpl *seat_impl, + gboolean repeat, + uint32_t delay, + uint32_t interval); + +MetaBarrierManagerNative * meta_seat_impl_get_barrier_manager (MetaSeatImpl *seat_impl); + +void meta_seat_impl_set_pointer_constraint (MetaSeatImpl *seat_impl, + MetaPointerConstraintImpl *constraint_impl); +void meta_seat_impl_set_viewports (MetaSeatImpl *seat_impl, + MetaViewportInfo *viewports); + +void meta_seat_impl_warp_pointer (MetaSeatImpl *seat_impl, + int x, + int y); +gboolean meta_seat_impl_query_state (MetaSeatImpl *seat_impl, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + graphene_point_t *coords, + ClutterModifierType *modifiers); +ClutterInputDevice * meta_seat_impl_get_pointer (MetaSeatImpl *seat_impl); +ClutterInputDevice * meta_seat_impl_get_keyboard (MetaSeatImpl *seat_impl); +GSList * meta_seat_impl_get_devices (MetaSeatImpl *seat_impl); + +MetaKeymapNative * meta_seat_impl_get_keymap (MetaSeatImpl *seat_impl); + +#endif /* META_SEAT_IMPL_H */ diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 13aa4b58857..e9c83927eea 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -28,1809 +28,39 @@ #include "backends/native/meta-seat-native.h" -#include -#include -#include -#include -#include - -#include "backends/meta-cursor-tracker-private.h" -#include "backends/native/meta-barrier-native.h" -#include "backends/native/meta-event-native.h" -#include "backends/native/meta-input-device-native.h" -#include "backends/native/meta-input-device-tool-native.h" -#include "backends/native/meta-keymap-native.h" -#include "backends/native/meta-virtual-input-device-native.h" -#include "clutter/clutter-mutter.h" -#include "core/bell.h" - -/* - * Clutter makes the assumption that two core devices have ID's 2 and 3 (core - * pointer and core keyboard). - * - * Since the two first devices that will ever be created will be the virtual - * pointer and virtual keyboard of the first seat, we fulfill the made - * assumptions by having the first device having ID 2 and following 3. - */ -#define INITIAL_DEVICE_ID 2 - -/* Try to keep the pointer inside the stage. Hopefully no one is using - * this backend with stages smaller than this. */ -#define INITIAL_POINTER_X 16 -#define INITIAL_POINTER_Y 16 - -#define AUTOREPEAT_VALUE 2 - -#define DISCRETE_SCROLL_STEP 10.0 - -#ifndef BTN_STYLUS3 -#define BTN_STYLUS3 0x149 /* Linux 4.15 */ -#endif - -struct _MetaEventSource -{ - GSource source; - - MetaSeatNative *seat; - GPollFD event_poll_fd; -}; - -static MetaOpenDeviceCallback device_open_callback; -static MetaCloseDeviceCallback device_close_callback; -static gpointer device_callback_data; - -#ifdef CLUTTER_ENABLE_DEBUG -static const char *device_type_str[] = { - "pointer", /* CLUTTER_POINTER_DEVICE */ - "keyboard", /* CLUTTER_KEYBOARD_DEVICE */ - "extension", /* CLUTTER_EXTENSION_DEVICE */ - "joystick", /* CLUTTER_JOYSTICK_DEVICE */ - "tablet", /* CLUTTER_TABLET_DEVICE */ - "touchpad", /* CLUTTER_TOUCHPAD_DEVICE */ - "touchscreen", /* CLUTTER_TOUCHSCREEN_DEVICE */ - "pen", /* CLUTTER_PEN_DEVICE */ - "eraser", /* CLUTTER_ERASER_DEVICE */ - "cursor", /* CLUTTER_CURSOR_DEVICE */ - "pad", /* CLUTTER_PAD_DEVICE */ -}; -#endif /* CLUTTER_ENABLE_DEBUG */ - -enum -{ - PROP_0, - PROP_SEAT_ID, - N_PROPS, - - /* This property is overridden */ - PROP_TOUCH_MODE, -}; - -GParamSpec *props[N_PROPS] = { NULL }; - -G_DEFINE_TYPE (MetaSeatNative, meta_seat_native, CLUTTER_TYPE_SEAT) - -static void process_events (MetaSeatNative *seat); - -void -meta_seat_native_set_libinput_seat (MetaSeatNative *seat, - struct libinput_seat *libinput_seat) -{ - g_assert (seat->libinput_seat == NULL); - - libinput_seat_ref (libinput_seat); - libinput_seat_set_user_data (libinput_seat, seat); - seat->libinput_seat = libinput_seat; -} - -void -meta_seat_native_sync_leds (MetaSeatNative *seat) -{ - GSList *iter; - MetaInputDeviceNative *device_evdev; - int caps_lock, num_lock, scroll_lock; - enum libinput_led leds = 0; - - caps_lock = xkb_state_led_index_is_active (seat->xkb, seat->caps_lock_led); - num_lock = xkb_state_led_index_is_active (seat->xkb, seat->num_lock_led); - scroll_lock = xkb_state_led_index_is_active (seat->xkb, seat->scroll_lock_led); - - if (caps_lock) - leds |= LIBINPUT_LED_CAPS_LOCK; - if (num_lock) - leds |= LIBINPUT_LED_NUM_LOCK; - if (scroll_lock) - leds |= LIBINPUT_LED_SCROLL_LOCK; - - for (iter = seat->devices; iter; iter = iter->next) - { - device_evdev = iter->data; - meta_input_device_native_update_leds (device_evdev, leds); - } -} - -MetaTouchState * -meta_seat_native_lookup_touch_state (MetaSeatNative *seat, - int seat_slot) -{ - if (!seat->touch_states) - return NULL; - - return g_hash_table_lookup (seat->touch_states, GINT_TO_POINTER (seat_slot)); -} - -static void -meta_touch_state_free (MetaTouchState *state) -{ - g_slice_free (MetaTouchState, state); -} - -MetaTouchState * -meta_seat_native_acquire_touch_state (MetaSeatNative *seat, - int seat_slot) -{ - MetaTouchState *touch_state; - - if (!seat->touch_states) - { - seat->touch_states = - g_hash_table_new_full (NULL, NULL, NULL, - (GDestroyNotify) meta_touch_state_free); - } - - g_assert (!g_hash_table_contains (seat->touch_states, - GINT_TO_POINTER (seat_slot))); - - touch_state = g_slice_new0 (MetaTouchState); - *touch_state = (MetaTouchState) { - .seat = seat, - .seat_slot = seat_slot, - }; - - g_hash_table_insert (seat->touch_states, GINT_TO_POINTER (seat_slot), - touch_state); - - return touch_state; -} - -void -meta_seat_native_release_touch_state (MetaSeatNative *seat, - int seat_slot) -{ - if (!seat->touch_states) - return; - - g_hash_table_remove (seat->touch_states, GINT_TO_POINTER (seat_slot)); -} - -void -meta_seat_native_clear_repeat_timer (MetaSeatNative *seat) -{ - if (seat->repeat_timer) - { - g_clear_handle_id (&seat->repeat_timer, g_source_remove); - g_clear_object (&seat->repeat_device); - } -} - -static void -dispatch_libinput (MetaSeatNative *seat) -{ - libinput_dispatch (seat->libinput); - process_events (seat); -} - -static gboolean -keyboard_repeat (gpointer data) -{ - MetaSeatNative *seat = data; - GSource *source; - - /* There might be events queued in libinput that could cancel the - repeat timer. */ - dispatch_libinput (seat); - if (!seat->repeat_timer) - return G_SOURCE_REMOVE; - - g_return_val_if_fail (seat->repeat_device != NULL, G_SOURCE_REMOVE); - source = g_main_context_find_source_by_id (NULL, seat->repeat_timer); - - meta_seat_native_notify_key (seat, - seat->repeat_device, - g_source_get_time (source), - seat->repeat_key, - AUTOREPEAT_VALUE, - FALSE); - - return G_SOURCE_CONTINUE; -} - -static void -queue_event (MetaSeatNative *seat, - ClutterEvent *event) -{ - _clutter_event_push (event, FALSE); -} - -static int -update_button_count (MetaSeatNative *seat, - uint32_t button, - uint32_t state) -{ - if (state) - { - return ++seat->button_count[button]; - } - else - { - /* Handle cases where we newer saw the initial pressed event. */ - if (seat->button_count[button] == 0) - { - meta_topic (META_DEBUG_INPUT, - "Counting release of key 0x%x and count is already 0", - button); - return 0; - } - - return --seat->button_count[button]; - } -} - -void -meta_seat_native_notify_key (MetaSeatNative *seat, - ClutterInputDevice *device, - uint64_t time_us, - uint32_t key, - uint32_t state, - gboolean update_keys) -{ - ClutterEvent *event = NULL; - enum xkb_state_component changed_state; - - if (state != AUTOREPEAT_VALUE) - { - /* Drop any repeated button press (for example from virtual devices. */ - int count = update_button_count (seat, key, state); - if ((state && count > 1) || - (!state && count != 0)) - { - meta_topic (META_DEBUG_INPUT, - "Dropping repeated %s of key 0x%x, count %d, state %d", - state ? "press" : "release", key, count, state); - return; - } - } - - event = meta_key_event_new_from_evdev (device, - seat->core_keyboard, - seat->xkb, - seat->button_state, - us2ms (time_us), key, state); - meta_event_native_set_event_code (event, key); - - /* We must be careful and not pass multiple releases to xkb, otherwise it gets - confused and locks the modifiers */ - if (state != AUTOREPEAT_VALUE) - { - changed_state = xkb_state_update_key (seat->xkb, - event->key.hardware_keycode, - state ? XKB_KEY_DOWN : XKB_KEY_UP); - } - else - { - changed_state = 0; - clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_REPEATED); - } - - queue_event (seat, event); - - if (update_keys && (changed_state & XKB_STATE_LEDS)) - { - g_signal_emit_by_name (seat->keymap, "state-changed"); - meta_seat_native_sync_leds (seat); - meta_input_device_native_a11y_maybe_notify_toggle_keys (META_INPUT_DEVICE_NATIVE (seat->core_keyboard)); - } - - if (state == 0 || /* key release */ - !seat->repeat || - !xkb_keymap_key_repeats (xkb_state_get_keymap (seat->xkb), - event->key.hardware_keycode)) - { - meta_seat_native_clear_repeat_timer (seat); - return; - } - - if (state == 1) /* key press */ - seat->repeat_count = 0; - - seat->repeat_count += 1; - seat->repeat_key = key; - - switch (seat->repeat_count) - { - case 1: - case 2: - { - uint32_t interval; - - meta_seat_native_clear_repeat_timer (seat); - seat->repeat_device = g_object_ref (device); - - if (seat->repeat_count == 1) - interval = seat->repeat_delay; - else - interval = seat->repeat_interval; - - seat->repeat_timer = - clutter_threads_add_timeout_full (CLUTTER_PRIORITY_EVENTS, - interval, - keyboard_repeat, - seat, - NULL); - return; - } - default: - return; - } -} - -static ClutterEvent * -new_absolute_motion_event (MetaSeatNative *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - float x, - float y, - double *axes) -{ - ClutterEvent *event; - - event = clutter_event_new (CLUTTER_MOTION); - - if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE) - { - meta_seat_native_constrain_pointer (seat, - seat->core_pointer, - time_us, - seat->pointer_x, - seat->pointer_y, - &x, &y); - } - - meta_event_native_set_time_usec (event, time_us); - event->motion.time = us2ms (time_us); - meta_xkb_translate_state (event, seat->xkb, seat->button_state); - event->motion.x = x; - event->motion.y = y; - - /* This may happen early at startup */ - if (seat->viewports) - { - meta_input_device_native_translate_coordinates (input_device, - seat->viewports, - &event->motion.x, - &event->motion.y); - } - - event->motion.axes = axes; - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - - if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) - { - MetaInputDeviceNative *device_evdev = - META_INPUT_DEVICE_NATIVE (input_device); - - clutter_event_set_device_tool (event, device_evdev->last_tool); - clutter_event_set_device (event, input_device); - meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (input_device), - x, y); - } - else - { - clutter_event_set_device (event, seat->core_pointer); - meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (seat->core_pointer), - x, y); - } - - if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE) - { - seat->pointer_x = x; - seat->pointer_y = y; - } - - return event; -} - -void -meta_seat_native_notify_relative_motion (MetaSeatNative *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - float dx, - float dy, - float dx_unaccel, - float dy_unaccel) -{ - float new_x, new_y; - ClutterEvent *event; - - meta_seat_native_filter_relative_motion (seat, - input_device, - seat->pointer_x, - seat->pointer_y, - &dx, - &dy); - - new_x = seat->pointer_x + dx; - new_y = seat->pointer_y + dy; - event = new_absolute_motion_event (seat, input_device, - time_us, new_x, new_y, NULL); - - meta_event_native_set_relative_motion (event, - dx, dy, - dx_unaccel, dy_unaccel); - - queue_event (seat, event); -} - -void -meta_seat_native_notify_absolute_motion (MetaSeatNative *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - float x, - float y, - double *axes) -{ - ClutterEvent *event; - - event = new_absolute_motion_event (seat, input_device, time_us, x, y, axes); - - queue_event (seat, event); -} - -void -meta_seat_native_notify_button (MetaSeatNative *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - uint32_t button, - uint32_t state) -{ - MetaInputDeviceNative *device_evdev = (MetaInputDeviceNative *) input_device; - ClutterEvent *event = NULL; - int button_nr; - static int maskmap[8] = - { - CLUTTER_BUTTON1_MASK, CLUTTER_BUTTON3_MASK, CLUTTER_BUTTON2_MASK, - CLUTTER_BUTTON4_MASK, CLUTTER_BUTTON5_MASK, 0, 0, 0 - }; - int button_count; - - /* Drop any repeated button press (for example from virtual devices. */ - button_count = update_button_count (seat, button, state); - if ((state && button_count > 1) || - (!state && button_count != 0)) - { - meta_topic (META_DEBUG_INPUT, - "Dropping repeated %s of button 0x%x, count %d", - state ? "press" : "release", button, button_count); - return; - } - - /* The evdev button numbers don't map sequentially to clutter button - * numbers (the right and middle mouse buttons are in the opposite - * order) so we'll map them directly with a switch statement */ - switch (button) - { - case BTN_LEFT: - case BTN_TOUCH: - button_nr = CLUTTER_BUTTON_PRIMARY; - break; - - case BTN_RIGHT: - case BTN_STYLUS: - button_nr = CLUTTER_BUTTON_SECONDARY; - break; - - case BTN_MIDDLE: - case BTN_STYLUS2: - button_nr = CLUTTER_BUTTON_MIDDLE; - break; - - case 0x149: /* BTN_STYLUS3 */ - button_nr = 8; - break; - - default: - /* For compatibility reasons, all additional buttons go after the old 4-7 scroll ones */ - if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) - button_nr = button - BTN_TOOL_PEN + 4; - else - button_nr = button - (BTN_LEFT - 1) + 4; - break; - } - - if (button_nr < 1 || button_nr > 12) - { - g_warning ("Unhandled button event 0x%x", button); - return; - } - - if (state) - event = clutter_event_new (CLUTTER_BUTTON_PRESS); - else - event = clutter_event_new (CLUTTER_BUTTON_RELEASE); - - if (button_nr < G_N_ELEMENTS (maskmap)) - { - /* Update the modifiers */ - if (state) - seat->button_state |= maskmap[button_nr - 1]; - else - seat->button_state &= ~maskmap[button_nr - 1]; - } - - meta_event_native_set_time_usec (event, time_us); - event->button.time = us2ms (time_us); - meta_xkb_translate_state (event, seat->xkb, seat->button_state); - event->button.button = button_nr; - - if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) - { - meta_input_device_native_get_coords (device_evdev, - &event->button.x, - &event->button.y); - } - else - { - meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (seat->core_pointer), - &event->button.x, - &event->button.y); - } - - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - - if (device_evdev->last_tool) - { - /* Apply the button event code as per the tool mapping */ - uint32_t mapped_button; - - mapped_button = meta_input_device_tool_native_get_button_code (device_evdev->last_tool, - button_nr); - if (mapped_button != 0) - button = mapped_button; - } - - meta_event_native_set_event_code (event, button); - - if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) - { - clutter_event_set_device_tool (event, device_evdev->last_tool); - clutter_event_set_device (event, input_device); - } - else - { - clutter_event_set_device (event, seat->core_pointer); - } - - queue_event (seat, event); -} - -static void -notify_scroll (ClutterInputDevice *input_device, - uint64_t time_us, - double dx, - double dy, - ClutterScrollSource scroll_source, - ClutterScrollFinishFlags flags, - gboolean emulated) -{ - MetaInputDeviceNative *device_evdev; - MetaSeatNative *seat; - ClutterEvent *event = NULL; - double scroll_factor; - - device_evdev = META_INPUT_DEVICE_NATIVE (input_device); - seat = meta_input_device_native_get_seat (device_evdev); - - event = clutter_event_new (CLUTTER_SCROLL); - - meta_event_native_set_time_usec (event, time_us); - event->scroll.time = us2ms (time_us); - meta_xkb_translate_state (event, seat->xkb, seat->button_state); - - /* libinput pointer axis events are in pointer motion coordinate space. - * To convert to Xi2 discrete step coordinate space, multiply the factor - * 1/10. */ - event->scroll.direction = CLUTTER_SCROLL_SMOOTH; - scroll_factor = 1.0 / DISCRETE_SCROLL_STEP; - clutter_event_set_scroll_delta (event, - scroll_factor * dx, - scroll_factor * dy); - - event->scroll.x = seat->pointer_x; - event->scroll.y = seat->pointer_y; - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - event->scroll.scroll_source = scroll_source; - event->scroll.finish_flags = flags; - - _clutter_event_set_pointer_emulated (event, emulated); - - queue_event (seat, event); -} - -static void -notify_discrete_scroll (ClutterInputDevice *input_device, - uint64_t time_us, - ClutterScrollDirection direction, - ClutterScrollSource scroll_source, - gboolean emulated) -{ - MetaInputDeviceNative *device_evdev; - MetaSeatNative *seat; - ClutterEvent *event = NULL; - - if (direction == CLUTTER_SCROLL_SMOOTH) - return; - - device_evdev = META_INPUT_DEVICE_NATIVE (input_device); - seat = meta_input_device_native_get_seat (device_evdev); - - event = clutter_event_new (CLUTTER_SCROLL); - - meta_event_native_set_time_usec (event, time_us); - event->scroll.time = us2ms (time_us); - meta_xkb_translate_state (event, seat->xkb, seat->button_state); - - event->scroll.direction = direction; - - event->scroll.x = seat->pointer_x; - event->scroll.y = seat->pointer_y; - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - event->scroll.scroll_source = scroll_source; - - _clutter_event_set_pointer_emulated (event, emulated); - - queue_event (seat, event); -} - -static void -check_notify_discrete_scroll (MetaSeatNative *seat, - ClutterInputDevice *device, - uint64_t time_us, - ClutterScrollSource scroll_source) -{ - int i, n_xscrolls, n_yscrolls; - - n_xscrolls = floor (fabs (seat->accum_scroll_dx) / DISCRETE_SCROLL_STEP); - n_yscrolls = floor (fabs (seat->accum_scroll_dy) / DISCRETE_SCROLL_STEP); - - for (i = 0; i < n_xscrolls; i++) - { - notify_discrete_scroll (device, time_us, - seat->accum_scroll_dx > 0 ? - CLUTTER_SCROLL_RIGHT : CLUTTER_SCROLL_LEFT, - scroll_source, TRUE); - } - - for (i = 0; i < n_yscrolls; i++) - { - notify_discrete_scroll (device, time_us, - seat->accum_scroll_dy > 0 ? - CLUTTER_SCROLL_DOWN : CLUTTER_SCROLL_UP, - scroll_source, TRUE); - } - - seat->accum_scroll_dx = fmodf (seat->accum_scroll_dx, DISCRETE_SCROLL_STEP); - seat->accum_scroll_dy = fmodf (seat->accum_scroll_dy, DISCRETE_SCROLL_STEP); -} - -void -meta_seat_native_notify_scroll_continuous (MetaSeatNative *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - double dx, - double dy, - ClutterScrollSource scroll_source, - ClutterScrollFinishFlags finish_flags) -{ - if (finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL) - seat->accum_scroll_dx = 0; - else - seat->accum_scroll_dx += dx; - - if (finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL) - seat->accum_scroll_dy = 0; - else - seat->accum_scroll_dy += dy; - - notify_scroll (input_device, time_us, dx, dy, scroll_source, - finish_flags, FALSE); - check_notify_discrete_scroll (seat, input_device, time_us, scroll_source); -} - -static ClutterScrollDirection -discrete_to_direction (double discrete_dx, - double discrete_dy) -{ - if (discrete_dx > 0) - return CLUTTER_SCROLL_RIGHT; - else if (discrete_dx < 0) - return CLUTTER_SCROLL_LEFT; - else if (discrete_dy > 0) - return CLUTTER_SCROLL_DOWN; - else if (discrete_dy < 0) - return CLUTTER_SCROLL_UP; - else - g_assert_not_reached (); - return 0; -} - -void -meta_seat_native_notify_discrete_scroll (MetaSeatNative *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - double discrete_dx, - double discrete_dy, - ClutterScrollSource scroll_source) -{ - notify_scroll (input_device, time_us, - discrete_dx * DISCRETE_SCROLL_STEP, - discrete_dy * DISCRETE_SCROLL_STEP, - scroll_source, CLUTTER_SCROLL_FINISHED_NONE, - TRUE); - notify_discrete_scroll (input_device, time_us, - discrete_to_direction (discrete_dx, discrete_dy), - scroll_source, FALSE); - -} - -void -meta_seat_native_notify_touch_event (MetaSeatNative *seat, - ClutterInputDevice *input_device, - ClutterEventType evtype, - uint64_t time_us, - int slot, - double x, - double y) -{ - ClutterEvent *event = NULL; - - event = clutter_event_new (evtype); - - meta_event_native_set_time_usec (event, time_us); - event->touch.time = us2ms (time_us); - event->touch.x = x; - event->touch.y = y; - meta_input_device_native_translate_coordinates (input_device, - seat->viewports, - &event->touch.x, - &event->touch.y); - - /* "NULL" sequences are special cased in clutter */ - event->touch.sequence = GINT_TO_POINTER (MAX (1, slot + 1)); - meta_xkb_translate_state (event, seat->xkb, seat->button_state); - - if (evtype == CLUTTER_TOUCH_BEGIN || - evtype == CLUTTER_TOUCH_UPDATE) - event->touch.modifier_state |= CLUTTER_BUTTON1_MASK; - - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - - queue_event (seat, event); -} - - -/* - * MetaEventSource for reading input devices - */ -static gboolean -meta_event_prepare (GSource *source, - gint *timeout) -{ - gboolean retval; - - *timeout = -1; - retval = clutter_events_pending (); - - return retval; -} - -static gboolean -meta_event_check (GSource *source) -{ - MetaEventSource *event_source = (MetaEventSource *) source; - gboolean retval; - - retval = ((event_source->event_poll_fd.revents & G_IO_IN) || - clutter_events_pending ()); - - return retval; -} - -static void -constrain_to_barriers (MetaSeatNative *seat, - ClutterInputDevice *device, - uint32_t time, - float *new_x, - float *new_y) -{ - meta_barrier_manager_native_process (seat->barrier_manager, - device, - time, - new_x, new_y); -} - -/* - * The pointer constrain code is mostly a rip-off of the XRandR code from Xorg. - * (from xserver/randr/rrcrtc.c, RRConstrainCursorHarder) - * - * Copyright © 2006 Keith Packard - * Copyright 2010 Red Hat, Inc - * - */ - -static void -constrain_all_screen_monitors (ClutterInputDevice *device, - MetaViewportInfo *viewports, - float *x, - float *y) -{ - float cx, cy; - int i, n_views; - - meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (device), - &cx, &cy); - - /* if we're trying to escape, clamp to the CRTC we're coming from */ - - n_views = meta_viewport_info_get_num_views (viewports); - - for (i = 0; i < n_views; i++) - { - int left, right, top, bottom; - cairo_rectangle_int_t rect; - - meta_viewport_info_get_view_info (viewports, i, &rect, NULL); - - left = rect.x; - right = left + rect.width; - top = rect.y; - bottom = top + rect.height; - - if ((cx >= left) && (cx < right) && (cy >= top) && (cy < bottom)) - { - if (*x < left) - *x = left; - if (*x >= right) - *x = right - 1; - if (*y < top) - *y = top; - if (*y >= bottom) - *y = bottom - 1; - - return; - } - } -} - -void -meta_seat_native_constrain_pointer (MetaSeatNative *seat, - ClutterInputDevice *core_pointer, - uint64_t time_us, - float x, - float y, - float *new_x, - float *new_y) -{ - constrain_to_barriers (seat, core_pointer, - us2ms (time_us), - new_x, new_y); - - /* Bar to constraints */ - if (seat->pointer_constraint) - { - meta_pointer_constraint_impl_constrain (seat->pointer_constraint, - core_pointer, - us2ms (time_us), - x, y, - new_x, new_y); - } - - if (seat->viewports) - { - /* if we're moving inside a monitor, we're fine */ - if (meta_viewport_info_get_view_at (seat->viewports, *new_x, *new_y) >= 0) - return; - - /* if we're trying to escape, clamp to the CRTC we're coming from */ - constrain_all_screen_monitors (core_pointer, seat->viewports, new_x, new_y); - } -} - -static void -relative_motion_across_outputs (MetaViewportInfo *viewports, - int view, - float cur_x, - float cur_y, - float *dx_inout, - float *dy_inout) -{ - int cur_view = view; - float x = cur_x, y = cur_y; - float target_x = cur_x, target_y = cur_y; - float dx = *dx_inout, dy = *dy_inout; - MetaDisplayDirection direction = -1; - - while (cur_view >= 0) - { - MetaLine2 left, right, top, bottom, motion; - MetaVector2 intersection; - cairo_rectangle_int_t rect; - float scale; - - meta_viewport_info_get_view_info (viewports, cur_view, &rect, &scale); - - motion = (MetaLine2) { - .a = { x, y }, - .b = { x + (dx * scale), y + (dy * scale) } - }; - left = (MetaLine2) { - { rect.x, rect.y }, - { rect.x, rect.y + rect.height } - }; - right = (MetaLine2) { - { rect.x + rect.width, rect.y }, - { rect.x + rect.width, rect.y + rect.height } - }; - top = (MetaLine2) { - { rect.x, rect.y }, - { rect.x + rect.width, rect.y } - }; - bottom = (MetaLine2) { - { rect.x, rect.y + rect.height }, - { rect.x + rect.width, rect.y + rect.height } - }; - - target_x = motion.b.x; - target_y = motion.b.y; - - if (direction != META_DISPLAY_RIGHT && - meta_line2_intersects_with (&motion, &left, &intersection)) - direction = META_DISPLAY_LEFT; - else if (direction != META_DISPLAY_LEFT && - meta_line2_intersects_with (&motion, &right, &intersection)) - direction = META_DISPLAY_RIGHT; - else if (direction != META_DISPLAY_DOWN && - meta_line2_intersects_with (&motion, &top, &intersection)) - direction = META_DISPLAY_UP; - else if (direction != META_DISPLAY_UP && - meta_line2_intersects_with (&motion, &bottom, &intersection)) - direction = META_DISPLAY_DOWN; - else - /* We reached the dest logical monitor */ - break; - - x = intersection.x; - y = intersection.y; - dx -= intersection.x - motion.a.x; - dy -= intersection.y - motion.a.y; - - cur_view = meta_viewport_info_get_neighbor (viewports, cur_view, - direction); - } - - *dx_inout = target_x - cur_x; - *dy_inout = target_y - cur_y; -} - -void -meta_seat_native_filter_relative_motion (MetaSeatNative *seat, - ClutterInputDevice *device, - float x, - float y, - float *dx, - float *dy) -{ - int view = -1, dest_view; - float new_dx, new_dy, scale; - - if (meta_is_stage_views_scaled ()) - return; - - if (seat->viewports) - view = meta_viewport_info_get_view_at (seat->viewports, x, y); - if (view < 0) - return; - - meta_viewport_info_get_view_info (seat->viewports, view, NULL, &scale); - new_dx = (*dx) * scale; - new_dy = (*dy) * scale; - - dest_view = meta_viewport_info_get_view_at (seat->viewports, - x + new_dx, - y + new_dy); - if (dest_view >= 0 && dest_view != view) - { - /* If we are crossing monitors, attempt to bisect the distance on each - * axis and apply the relative scale for each of them. - */ - new_dx = *dx; - new_dy = *dy; - relative_motion_across_outputs (seat->viewports, view, - x, y, &new_dx, &new_dy); - } - - *dx = new_dx; - *dy = new_dy; -} - -static void -notify_absolute_motion (ClutterInputDevice *input_device, - uint64_t time_us, - float x, - float y, - double *axes) -{ - MetaSeatNative *seat; - ClutterEvent *event; - - seat = meta_input_device_native_get_seat (META_INPUT_DEVICE_NATIVE (input_device)); - event = new_absolute_motion_event (seat, input_device, time_us, x, y, axes); - - queue_event (seat, event); -} - -static void -notify_relative_tool_motion (ClutterInputDevice *input_device, - uint64_t time_us, - float dx, - float dy, - double *axes) -{ - MetaInputDeviceNative *device_evdev; - ClutterEvent *event; - MetaSeatNative *seat; - gfloat x, y; - - device_evdev = META_INPUT_DEVICE_NATIVE (input_device); - seat = meta_input_device_native_get_seat (device_evdev); - x = device_evdev->pointer_x + dx; - y = device_evdev->pointer_y + dy; - - meta_seat_native_filter_relative_motion (seat, - input_device, - seat->pointer_x, - seat->pointer_y, - &dx, - &dy); - - event = new_absolute_motion_event (seat, input_device, time_us, x, y, axes); - meta_event_native_set_relative_motion (event, dx, dy, 0, 0); - - queue_event (seat, event); -} - -static void -notify_pinch_gesture_event (ClutterInputDevice *input_device, - ClutterTouchpadGesturePhase phase, - uint64_t time_us, - double dx, - double dy, - double angle_delta, - double scale, - uint32_t n_fingers) -{ - MetaInputDeviceNative *device_evdev; - MetaSeatNative *seat; - ClutterEvent *event = NULL; - - device_evdev = META_INPUT_DEVICE_NATIVE (input_device); - seat = meta_input_device_native_get_seat (device_evdev); - - event = clutter_event_new (CLUTTER_TOUCHPAD_PINCH); - - meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (seat->core_pointer), - &event->touchpad_pinch.x, - &event->touchpad_pinch.y); - - meta_event_native_set_time_usec (event, time_us); - event->touchpad_pinch.phase = phase; - event->touchpad_pinch.time = us2ms (time_us); - event->touchpad_pinch.dx = dx; - event->touchpad_pinch.dy = dy; - event->touchpad_pinch.angle_delta = angle_delta; - event->touchpad_pinch.scale = scale; - event->touchpad_pinch.n_fingers = n_fingers; - - meta_xkb_translate_state (event, seat->xkb, seat->button_state); - - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - - queue_event (seat, event); -} - -static void -notify_swipe_gesture_event (ClutterInputDevice *input_device, - ClutterTouchpadGesturePhase phase, - uint64_t time_us, - uint32_t n_fingers, - double dx, - double dy) -{ - MetaInputDeviceNative *device_evdev; - MetaSeatNative *seat; - ClutterEvent *event = NULL; - - device_evdev = META_INPUT_DEVICE_NATIVE (input_device); - seat = meta_input_device_native_get_seat (device_evdev); - - event = clutter_event_new (CLUTTER_TOUCHPAD_SWIPE); - - meta_event_native_set_time_usec (event, time_us); - event->touchpad_swipe.phase = phase; - event->touchpad_swipe.time = us2ms (time_us); - - meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (seat->core_pointer), - &event->touchpad_swipe.x, - &event->touchpad_swipe.y); - event->touchpad_swipe.dx = dx; - event->touchpad_swipe.dy = dy; - event->touchpad_swipe.n_fingers = n_fingers; - - meta_xkb_translate_state (event, seat->xkb, seat->button_state); - - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - - queue_event (seat, event); -} - -static void -notify_proximity (ClutterInputDevice *input_device, - uint64_t time_us, - gboolean in) -{ - MetaInputDeviceNative *device_evdev; - MetaSeatNative *seat; - ClutterEvent *event = NULL; - - device_evdev = META_INPUT_DEVICE_NATIVE (input_device); - seat = meta_input_device_native_get_seat (device_evdev); - - if (in) - event = clutter_event_new (CLUTTER_PROXIMITY_IN); - else - event = clutter_event_new (CLUTTER_PROXIMITY_OUT); - - meta_event_native_set_time_usec (event, time_us); - - event->proximity.time = us2ms (time_us); - clutter_event_set_device_tool (event, device_evdev->last_tool); - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - - queue_event (seat, event); -} - -static void -notify_pad_button (ClutterInputDevice *input_device, - uint64_t time_us, - uint32_t button, - uint32_t mode_group, - uint32_t mode, - uint32_t pressed) -{ - MetaInputDeviceNative *device_evdev; - MetaSeatNative *seat; - ClutterEvent *event; - - device_evdev = META_INPUT_DEVICE_NATIVE (input_device); - seat = meta_input_device_native_get_seat (device_evdev); - - if (pressed) - event = clutter_event_new (CLUTTER_PAD_BUTTON_PRESS); - else - event = clutter_event_new (CLUTTER_PAD_BUTTON_RELEASE); - - meta_event_native_set_time_usec (event, time_us); - event->pad_button.button = button; - event->pad_button.group = mode_group; - event->pad_button.mode = mode; - clutter_event_set_device (event, input_device); - clutter_event_set_source_device (event, input_device); - clutter_event_set_time (event, us2ms (time_us)); - - queue_event (seat, event); -} - -static void -notify_pad_strip (ClutterInputDevice *input_device, - uint64_t time_us, - uint32_t strip_number, - uint32_t strip_source, - uint32_t mode_group, - uint32_t mode, - double value) -{ - ClutterInputDevicePadSource source; - MetaInputDeviceNative *device_evdev; - MetaSeatNative *seat; - ClutterEvent *event; - - device_evdev = META_INPUT_DEVICE_NATIVE (input_device); - seat = meta_input_device_native_get_seat (device_evdev); - - if (strip_source == LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER) - source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER; - else - source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN; - - event = clutter_event_new (CLUTTER_PAD_STRIP); - meta_event_native_set_time_usec (event, time_us); - event->pad_strip.strip_source = source; - event->pad_strip.strip_number = strip_number; - event->pad_strip.value = value; - event->pad_strip.group = mode_group; - event->pad_strip.mode = mode; - clutter_event_set_device (event, input_device); - clutter_event_set_source_device (event, input_device); - clutter_event_set_time (event, us2ms (time_us)); - - queue_event (seat, event); -} - -static void -notify_pad_ring (ClutterInputDevice *input_device, - uint64_t time_us, - uint32_t ring_number, - uint32_t ring_source, - uint32_t mode_group, - uint32_t mode, - double angle) -{ - ClutterInputDevicePadSource source; - MetaInputDeviceNative *device_evdev; - MetaSeatNative *seat; - ClutterEvent *event; - - device_evdev = META_INPUT_DEVICE_NATIVE (input_device); - seat = meta_input_device_native_get_seat (device_evdev); - - if (ring_source == LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER) - source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER; - else - source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN; - - event = clutter_event_new (CLUTTER_PAD_RING); - meta_event_native_set_time_usec (event, time_us); - event->pad_ring.ring_source = source; - event->pad_ring.ring_number = ring_number; - event->pad_ring.angle = angle; - event->pad_ring.group = mode_group; - event->pad_ring.mode = mode; - clutter_event_set_device (event, input_device); - clutter_event_set_source_device (event, input_device); - clutter_event_set_time (event, us2ms (time_us)); - - queue_event (seat, event); -} - -static gboolean -meta_event_dispatch (GSource *g_source, - GSourceFunc callback, - gpointer user_data) -{ - MetaEventSource *source = (MetaEventSource *) g_source; - MetaSeatNative *seat; - - seat = source->seat; - - /* Don't queue more events if we haven't finished handling the previous batch - */ - if (clutter_events_pending ()) - goto queue_event; - - dispatch_libinput (seat); - - queue_event: - - return TRUE; -} -static GSourceFuncs event_funcs = { - meta_event_prepare, - meta_event_check, - meta_event_dispatch, - NULL -}; - -static MetaEventSource * -meta_event_source_new (MetaSeatNative *seat) -{ - GSource *source; - MetaEventSource *event_source; - gint fd; - - source = g_source_new (&event_funcs, sizeof (MetaEventSource)); - event_source = (MetaEventSource *) source; - - /* setup the source */ - event_source->seat = seat; - - fd = libinput_get_fd (seat->libinput); - event_source->event_poll_fd.fd = fd; - event_source->event_poll_fd.events = G_IO_IN; - - /* and finally configure and attach the GSource */ - g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS); - g_source_add_poll (source, &event_source->event_poll_fd); - g_source_set_can_recurse (source, TRUE); - g_source_attach (source, NULL); - - return event_source; -} - -static void -meta_event_source_free (MetaEventSource *source) -{ - GSource *g_source = (GSource *) source; - - /* ignore the return value of close, it's not like we can do something - * about it */ - close (source->event_poll_fd.fd); - - g_source_destroy (g_source); - g_source_unref (g_source); -} - -static gboolean -has_touchscreen (MetaSeatNative *seat) -{ - GSList *l; - - for (l = seat->devices; l; l = l->next) - { - ClutterInputDeviceType device_type; - - device_type = clutter_input_device_get_device_type (l->data); - - if (device_type == CLUTTER_TOUCHSCREEN_DEVICE) - return TRUE; - } - - return FALSE; -} - -static gboolean -has_tablet_switch (MetaSeatNative *seat) -{ - GSList *l; - - for (l = seat->devices; l; l = l->next) - { - MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (l->data); - - if (libinput_device_has_capability (device_native->libinput_device, - LIBINPUT_DEVICE_CAP_SWITCH) && - libinput_device_switch_has_switch (device_native->libinput_device, - LIBINPUT_SWITCH_TABLET_MODE)) - return TRUE; - } - - return FALSE; -} - -static void -update_touch_mode (MetaSeatNative *seat) -{ - gboolean touch_mode; - - /* No touch mode if we don't have a touchscreen, easy */ - if (!seat->has_touchscreen) - touch_mode = FALSE; - /* If we have a tablet mode switch, honor it being unset */ - else if (seat->has_tablet_switch && !seat->tablet_mode_switch_state) - touch_mode = FALSE; - /* If tablet mode is enabled, or if there is no tablet mode switch - * (eg. kiosk machines), assume touch-mode. - */ - else - touch_mode = TRUE; - - if (seat->touch_mode != touch_mode) - { - seat->touch_mode = touch_mode; - g_object_notify (G_OBJECT (seat), "touch-mode"); - } -} - -static ClutterInputDevice * -evdev_add_device (MetaSeatNative *seat, - struct libinput_device *libinput_device) -{ - ClutterInputDeviceType type; - ClutterInputDevice *device, *logical = NULL; - - device = meta_input_device_native_new (seat, libinput_device); - - seat->devices = g_slist_prepend (seat->devices, device); - - /* Clutter assumes that device types are exclusive in the - * ClutterInputDevice API */ - type = meta_input_device_native_determine_type (libinput_device); - - if (type == CLUTTER_KEYBOARD_DEVICE) - logical = seat->core_keyboard; - else if (type == CLUTTER_POINTER_DEVICE) - logical = seat->core_pointer; - - if (logical) - { - _clutter_input_device_set_associated_device (device, logical); - _clutter_input_device_add_physical_device (logical, device); - } - - return device; -} - -static void -evdev_remove_device (MetaSeatNative *seat, - MetaInputDeviceNative *device_evdev) -{ - ClutterInputDevice *device; - - device = CLUTTER_INPUT_DEVICE (device_evdev); - seat->devices = g_slist_remove (seat->devices, device); - - g_object_unref (device); -} - -static gboolean -meta_seat_native_handle_event_post (ClutterSeat *seat, - const ClutterEvent *event) -{ - MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); - ClutterInputDevice *device = event->device.device; - MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); - gboolean is_touchscreen, is_tablet_switch; - - is_touchscreen = - clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE; - is_tablet_switch = - libinput_device_has_capability (device_native->libinput_device, - LIBINPUT_DEVICE_CAP_SWITCH) && - libinput_device_switch_has_switch (device_native->libinput_device, - LIBINPUT_SWITCH_TABLET_MODE); - - switch (event->type) - { - case CLUTTER_DEVICE_ADDED: - if (is_touchscreen) - seat_native->has_touchscreen = TRUE; - - if (is_tablet_switch) - seat_native->has_tablet_switch = TRUE; - break; - - case CLUTTER_DEVICE_REMOVED: - if (is_touchscreen) - seat_native->has_touchscreen = has_touchscreen (seat_native); - - if (is_tablet_switch) - seat_native->has_tablet_switch = has_tablet_switch (seat_native); - - if (seat_native->repeat_timer && seat_native->repeat_device == device) - meta_seat_native_clear_repeat_timer (seat_native); - break; - - default: - break; - } - - if (is_touchscreen || is_tablet_switch) - update_touch_mode (seat_native); - - return TRUE; -} - -static gboolean -process_base_event (MetaSeatNative *seat, - struct libinput_event *event) -{ - ClutterInputDevice *device = NULL; - ClutterEvent *device_event = NULL; - struct libinput_device *libinput_device; - - switch (libinput_event_get_type (event)) - { - case LIBINPUT_EVENT_DEVICE_ADDED: - libinput_device = libinput_event_get_device (event); - device = evdev_add_device (seat, libinput_device); - device_event = clutter_event_new (CLUTTER_DEVICE_ADDED); - clutter_event_set_device (device_event, device); - break; - - case LIBINPUT_EVENT_DEVICE_REMOVED: - libinput_device = libinput_event_get_device (event); - - device = libinput_device_get_user_data (libinput_device); - device_event = clutter_event_new (CLUTTER_DEVICE_REMOVED); - clutter_event_set_device (device_event, device); - evdev_remove_device (seat, - META_INPUT_DEVICE_NATIVE (device)); - break; - - default: - break; - } - - if (device_event) - { - queue_event (seat, device_event); - return TRUE; - } - - return FALSE; -} - -static ClutterScrollSource -translate_scroll_source (enum libinput_pointer_axis_source source) -{ - switch (source) - { - case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: - return CLUTTER_SCROLL_SOURCE_WHEEL; - case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: - return CLUTTER_SCROLL_SOURCE_FINGER; - case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: - return CLUTTER_SCROLL_SOURCE_CONTINUOUS; - default: - return CLUTTER_SCROLL_SOURCE_UNKNOWN; - } -} - -static ClutterInputDeviceToolType -translate_tool_type (struct libinput_tablet_tool *libinput_tool) -{ - enum libinput_tablet_tool_type tool; - - tool = libinput_tablet_tool_get_type (libinput_tool); - - switch (tool) - { - case LIBINPUT_TABLET_TOOL_TYPE_PEN: - return CLUTTER_INPUT_DEVICE_TOOL_PEN; - case LIBINPUT_TABLET_TOOL_TYPE_ERASER: - return CLUTTER_INPUT_DEVICE_TOOL_ERASER; - case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: - return CLUTTER_INPUT_DEVICE_TOOL_BRUSH; - case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: - return CLUTTER_INPUT_DEVICE_TOOL_PENCIL; - case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: - return CLUTTER_INPUT_DEVICE_TOOL_AIRBRUSH; - case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: - return CLUTTER_INPUT_DEVICE_TOOL_MOUSE; - case LIBINPUT_TABLET_TOOL_TYPE_LENS: - return CLUTTER_INPUT_DEVICE_TOOL_LENS; - default: - return CLUTTER_INPUT_DEVICE_TOOL_NONE; - } -} - -static void -input_device_update_tool (ClutterInputDevice *input_device, - struct libinput_tablet_tool *libinput_tool) -{ - MetaInputDeviceNative *evdev_device = META_INPUT_DEVICE_NATIVE (input_device); - MetaSeatNative *seat = meta_input_device_native_get_seat (evdev_device); - ClutterInputDeviceTool *tool = NULL; - ClutterInputDeviceToolType tool_type; - uint64_t tool_serial; - - if (libinput_tool) - { - tool_serial = libinput_tablet_tool_get_serial (libinput_tool); - tool_type = translate_tool_type (libinput_tool); - tool = clutter_input_device_lookup_tool (input_device, - tool_serial, tool_type); - - if (!tool) - { - tool = meta_input_device_tool_native_new (libinput_tool, - tool_serial, tool_type); - clutter_input_device_add_tool (input_device, tool); - } - } - - if (evdev_device->last_tool != tool) - { - evdev_device->last_tool = tool; - g_signal_emit_by_name (seat, "tool-changed", input_device, tool); - } -} - -static gdouble * -translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event, - ClutterInputDeviceTool *tool) -{ - GArray *axes = g_array_new (FALSE, FALSE, sizeof (gdouble)); - struct libinput_tablet_tool *libinput_tool; - gdouble value; - - libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event); - - value = libinput_event_tablet_tool_get_x (tablet_event); - g_array_append_val (axes, value); - value = libinput_event_tablet_tool_get_y (tablet_event); - g_array_append_val (axes, value); - - if (libinput_tablet_tool_has_distance (libinput_tool)) - { - value = libinput_event_tablet_tool_get_distance (tablet_event); - g_array_append_val (axes, value); - } - - if (libinput_tablet_tool_has_pressure (libinput_tool)) - { - value = libinput_event_tablet_tool_get_pressure (tablet_event); - value = meta_input_device_tool_native_translate_pressure (tool, value); - g_array_append_val (axes, value); - } - - if (libinput_tablet_tool_has_tilt (libinput_tool)) - { - value = libinput_event_tablet_tool_get_tilt_x (tablet_event); - g_array_append_val (axes, value); - value = libinput_event_tablet_tool_get_tilt_y (tablet_event); - g_array_append_val (axes, value); - } - - if (libinput_tablet_tool_has_rotation (libinput_tool)) - { - value = libinput_event_tablet_tool_get_rotation (tablet_event); - g_array_append_val (axes, value); - } - - if (libinput_tablet_tool_has_slider (libinput_tool)) - { - value = libinput_event_tablet_tool_get_slider_position (tablet_event); - g_array_append_val (axes, value); - } - - if (libinput_tablet_tool_has_wheel (libinput_tool)) - { - value = libinput_event_tablet_tool_get_wheel_delta (tablet_event); - g_array_append_val (axes, value); - } - - if (axes->len == 0) - { - g_array_free (axes, TRUE); - return NULL; - } - else - return (gdouble *) g_array_free (axes, FALSE); -} - -static MetaSeatNative * -seat_from_device (ClutterInputDevice *device) -{ - MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device); - - return meta_input_device_native_get_seat (device_evdev); -} +#include "backends/meta-cursor-tracker-private.h" +#include "backends/native/meta-barrier-native.h" +#include "backends/native/meta-event-native.h" +#include "backends/native/meta-input-device-native.h" +#include "backends/native/meta-input-device-tool-native.h" +#include "backends/native/meta-keymap-native.h" +#include "backends/native/meta-virtual-input-device-native.h" +#include "clutter/clutter-mutter.h" +#include "core/bell.h" -static void -notify_continuous_axis (MetaSeatNative *seat, - ClutterInputDevice *device, - uint64_t time_us, - ClutterScrollSource scroll_source, - struct libinput_event_pointer *axis_event) +enum { - gdouble dx = 0.0, dy = 0.0; - ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE; - - if (libinput_event_pointer_has_axis (axis_event, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) - { - dx = libinput_event_pointer_get_axis_value ( - axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); - - if (fabs (dx) < DBL_EPSILON) - finish_flags |= CLUTTER_SCROLL_FINISHED_HORIZONTAL; - } - if (libinput_event_pointer_has_axis (axis_event, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) - { - dy = libinput_event_pointer_get_axis_value ( - axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - - if (fabs (dy) < DBL_EPSILON) - finish_flags |= CLUTTER_SCROLL_FINISHED_VERTICAL; - } - - meta_seat_native_notify_scroll_continuous (seat, device, time_us, - dx, dy, - scroll_source, finish_flags); -} + PROP_0, + PROP_SEAT_ID, + N_PROPS, -static void -notify_discrete_axis (MetaSeatNative *seat, - ClutterInputDevice *device, - uint64_t time_us, - ClutterScrollSource scroll_source, - struct libinput_event_pointer *axis_event) -{ - gdouble discrete_dx = 0.0, discrete_dy = 0.0; + /* This property is overridden */ + PROP_TOUCH_MODE, +}; - if (libinput_event_pointer_has_axis (axis_event, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) - { - discrete_dx = libinput_event_pointer_get_axis_value_discrete ( - axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); - } - if (libinput_event_pointer_has_axis (axis_event, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) - { - discrete_dy = libinput_event_pointer_get_axis_value_discrete ( - axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - } +static GParamSpec *props[N_PROPS] = { NULL }; - meta_seat_native_notify_discrete_scroll (seat, device, - time_us, - discrete_dx, discrete_dy, - scroll_source); -} +G_DEFINE_TYPE (MetaSeatNative, meta_seat_native, CLUTTER_TYPE_SEAT) -static void -process_tablet_axis (MetaSeatNative *seat, - struct libinput_event *event) +static gboolean +meta_seat_native_handle_event_post (ClutterSeat *seat, + const ClutterEvent *event) { - struct libinput_device *libinput_device = libinput_event_get_device (event); - uint64_t time; - double x, y, dx, dy, *axes; - float stage_width, stage_height; - ClutterInputDevice *device; - struct libinput_event_tablet_tool *tablet_event = - libinput_event_get_tablet_tool_event (event); - MetaInputDeviceNative *evdev_device; - - device = libinput_device_get_user_data (libinput_device); - evdev_device = META_INPUT_DEVICE_NATIVE (device); - - axes = translate_tablet_axes (tablet_event, - evdev_device->last_tool); - if (!axes) - return; - - meta_viewport_info_get_extents (seat->viewports, &stage_width, &stage_height); - - time = libinput_event_tablet_tool_get_time_usec (tablet_event); - - if (meta_input_device_native_get_mapping_mode (device) == META_INPUT_DEVICE_MAPPING_RELATIVE || - clutter_input_device_tool_get_tool_type (evdev_device->last_tool) == CLUTTER_INPUT_DEVICE_TOOL_MOUSE || - clutter_input_device_tool_get_tool_type (evdev_device->last_tool) == CLUTTER_INPUT_DEVICE_TOOL_LENS) - { - dx = libinput_event_tablet_tool_get_dx (tablet_event); - dy = libinput_event_tablet_tool_get_dy (tablet_event); - notify_relative_tool_motion (device, time, dx, dy, axes); - } - else - { - x = libinput_event_tablet_tool_get_x_transformed (tablet_event, stage_width); - y = libinput_event_tablet_tool_get_y_transformed (tablet_event, stage_height); - notify_absolute_motion (device, time, x, y, axes); - } -} + MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); + ClutterInputDevice *device = clutter_event_get_source_device (event); + ClutterEventType event_type = event->type; -static void -update_tablet_cursor_state (MetaSeatNative *seat_native, - ClutterInputDevice *device, - gboolean in) -{ - if (in) + if (event_type == CLUTTER_PROXIMITY_IN) { MetaCursorRendererNative *cursor_renderer_native; @@ -1844,706 +74,42 @@ update_tablet_cursor_state (MetaSeatNative *seat_native, meta_cursor_renderer_native_new (meta_get_backend (), device); g_hash_table_insert (seat_native->tablet_cursors, device, cursor_renderer_native); + return TRUE; } - else + else if (event_type == CLUTTER_PROXIMITY_OUT) { if (seat_native->tablet_cursors) g_hash_table_remove (seat_native->tablet_cursors, device); + return TRUE; } -} - -static gboolean -process_device_event (MetaSeatNative *seat, - struct libinput_event *event) -{ - gboolean handled = TRUE; - struct libinput_device *libinput_device = libinput_event_get_device(event); - ClutterInputDevice *device; - MetaInputDeviceNative *device_evdev; - - switch (libinput_event_get_type (event)) - { - case LIBINPUT_EVENT_KEYBOARD_KEY: - { - uint32_t key, key_state, seat_key_count; - uint64_t time_us; - struct libinput_event_keyboard *key_event = - libinput_event_get_keyboard_event (event); - - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_keyboard_get_time_usec (key_event); - key = libinput_event_keyboard_get_key (key_event); - key_state = libinput_event_keyboard_get_key_state (key_event) == - LIBINPUT_KEY_STATE_PRESSED; - seat_key_count = - libinput_event_keyboard_get_seat_key_count (key_event); - - /* Ignore key events that are not seat wide state changes. */ - if ((key_state == LIBINPUT_KEY_STATE_PRESSED && - seat_key_count != 1) || - (key_state == LIBINPUT_KEY_STATE_RELEASED && - seat_key_count != 0)) - { - meta_topic (META_DEBUG_INPUT, - "Dropping key-%s of key 0x%x because seat-wide " - "key count is %d", - key_state == LIBINPUT_KEY_STATE_PRESSED ? "press" : "release", - key, seat_key_count); - break; - } - - meta_seat_native_notify_key (seat_from_device (device), - device, - time_us, key, key_state, TRUE); - - break; - } - - case LIBINPUT_EVENT_POINTER_MOTION: - { - struct libinput_event_pointer *pointer_event = - libinput_event_get_pointer_event (event); - uint64_t time_us; - double dx; - double dy; - double dx_unaccel; - double dy_unaccel; - - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_pointer_get_time_usec (pointer_event); - dx = libinput_event_pointer_get_dx (pointer_event); - dy = libinput_event_pointer_get_dy (pointer_event); - dx_unaccel = libinput_event_pointer_get_dx_unaccelerated (pointer_event); - dy_unaccel = libinput_event_pointer_get_dy_unaccelerated (pointer_event); - - meta_seat_native_notify_relative_motion (seat_from_device (device), - device, - time_us, - dx, dy, - dx_unaccel, dy_unaccel); - - break; - } - - case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: - { - uint64_t time_us; - double x, y; - float stage_width, stage_height; - struct libinput_event_pointer *motion_event = - libinput_event_get_pointer_event (event); - device = libinput_device_get_user_data (libinput_device); - - meta_viewport_info_get_extents (seat->viewports, - &stage_width, &stage_height); - - time_us = libinput_event_pointer_get_time_usec (motion_event); - x = libinput_event_pointer_get_absolute_x_transformed (motion_event, - stage_width); - y = libinput_event_pointer_get_absolute_y_transformed (motion_event, - stage_height); - - meta_seat_native_notify_absolute_motion (seat_from_device (device), - device, - time_us, - x, y, - NULL); - - break; - } - - case LIBINPUT_EVENT_POINTER_BUTTON: - { - uint32_t button, button_state, seat_button_count; - uint64_t time_us; - struct libinput_event_pointer *button_event = - libinput_event_get_pointer_event (event); - device = libinput_device_get_user_data (libinput_device); - - time_us = libinput_event_pointer_get_time_usec (button_event); - button = libinput_event_pointer_get_button (button_event); - button_state = libinput_event_pointer_get_button_state (button_event) == - LIBINPUT_BUTTON_STATE_PRESSED; - seat_button_count = - libinput_event_pointer_get_seat_button_count (button_event); - - /* Ignore button events that are not seat wide state changes. */ - if ((button_state == LIBINPUT_BUTTON_STATE_PRESSED && - seat_button_count != 1) || - (button_state == LIBINPUT_BUTTON_STATE_RELEASED && - seat_button_count != 0)) - { - meta_topic (META_DEBUG_INPUT, - "Dropping button-%s of button 0x%x because seat-wide " - "button count is %d", - button_state == LIBINPUT_BUTTON_STATE_PRESSED ? "press" : "release", - button, seat_button_count); - break; - } - - meta_seat_native_notify_button (seat_from_device (device), device, - time_us, button, button_state); - break; - } - - case LIBINPUT_EVENT_POINTER_AXIS: - { - uint64_t time_us; - enum libinput_pointer_axis_source source; - struct libinput_event_pointer *axis_event = - libinput_event_get_pointer_event (event); - MetaSeatNative *seat; - ClutterScrollSource scroll_source; - - device = libinput_device_get_user_data (libinput_device); - seat = meta_input_device_native_get_seat (META_INPUT_DEVICE_NATIVE (device)); - - time_us = libinput_event_pointer_get_time_usec (axis_event); - source = libinput_event_pointer_get_axis_source (axis_event); - scroll_source = translate_scroll_source (source); - - /* libinput < 0.8 sent wheel click events with value 10. Since 0.8 - the value is the angle of the click in degrees. To keep - backwards-compat with existing clients, we just send multiples of - the click count. */ - - switch (scroll_source) - { - case CLUTTER_SCROLL_SOURCE_WHEEL: - notify_discrete_axis (seat, device, time_us, scroll_source, - axis_event); - break; - case CLUTTER_SCROLL_SOURCE_FINGER: - case CLUTTER_SCROLL_SOURCE_CONTINUOUS: - case CLUTTER_SCROLL_SOURCE_UNKNOWN: - notify_continuous_axis (seat, device, time_us, scroll_source, - axis_event); - break; - } - break; - } - - case LIBINPUT_EVENT_TOUCH_DOWN: - { - int seat_slot; - uint64_t time_us; - double x, y; - float stage_width, stage_height; - MetaSeatNative *seat; - MetaTouchState *touch_state; - struct libinput_event_touch *touch_event = - libinput_event_get_touch_event (event); - - device = libinput_device_get_user_data (libinput_device); - device_evdev = META_INPUT_DEVICE_NATIVE (device); - seat = meta_input_device_native_get_seat (device_evdev); - - meta_viewport_info_get_extents (seat->viewports, - &stage_width, &stage_height); - - seat_slot = libinput_event_touch_get_seat_slot (touch_event); - time_us = libinput_event_touch_get_time_usec (touch_event); - x = libinput_event_touch_get_x_transformed (touch_event, - stage_width); - y = libinput_event_touch_get_y_transformed (touch_event, - stage_height); - - touch_state = meta_seat_native_acquire_touch_state (seat, seat_slot); - touch_state->coords.x = x; - touch_state->coords.y = y; - - meta_seat_native_notify_touch_event (seat, device, - CLUTTER_TOUCH_BEGIN, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); - break; - } - - case LIBINPUT_EVENT_TOUCH_UP: - { - int seat_slot; - uint64_t time_us; - MetaSeatNative *seat; - MetaTouchState *touch_state; - struct libinput_event_touch *touch_event = - libinput_event_get_touch_event (event); - - device = libinput_device_get_user_data (libinput_device); - device_evdev = META_INPUT_DEVICE_NATIVE (device); - seat = meta_input_device_native_get_seat (device_evdev); - - seat_slot = libinput_event_touch_get_seat_slot (touch_event); - time_us = libinput_event_touch_get_time_usec (touch_event); - touch_state = meta_seat_native_lookup_touch_state (seat, seat_slot); - if (!touch_state) - break; - - meta_seat_native_notify_touch_event (seat, device, - CLUTTER_TOUCH_END, time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); - meta_seat_native_release_touch_state (seat, seat_slot); - break; - } - - case LIBINPUT_EVENT_TOUCH_MOTION: - { - int seat_slot; - uint64_t time_us; - double x, y; - float stage_width, stage_height; - MetaSeatNative *seat; - MetaTouchState *touch_state; - struct libinput_event_touch *touch_event = - libinput_event_get_touch_event (event); - - device = libinput_device_get_user_data (libinput_device); - device_evdev = META_INPUT_DEVICE_NATIVE (device); - seat = meta_input_device_native_get_seat (device_evdev); - - meta_viewport_info_get_extents (seat->viewports, - &stage_width, &stage_height); - - seat_slot = libinput_event_touch_get_seat_slot (touch_event); - time_us = libinput_event_touch_get_time_usec (touch_event); - x = libinput_event_touch_get_x_transformed (touch_event, - stage_width); - y = libinput_event_touch_get_y_transformed (touch_event, - stage_height); - - touch_state = meta_seat_native_lookup_touch_state (seat, seat_slot); - if (!touch_state) - break; - - touch_state->coords.x = x; - touch_state->coords.y = y; - - meta_seat_native_notify_touch_event (seat, device, - CLUTTER_TOUCH_UPDATE, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); - break; - } - case LIBINPUT_EVENT_TOUCH_CANCEL: - { - int seat_slot; - MetaTouchState *touch_state; - uint64_t time_us; - MetaSeatNative *seat; - struct libinput_event_touch *touch_event = - libinput_event_get_touch_event (event); - - device = libinput_device_get_user_data (libinput_device); - device_evdev = META_INPUT_DEVICE_NATIVE (device); - seat = meta_input_device_native_get_seat (device_evdev); - time_us = libinput_event_touch_get_time_usec (touch_event); - - seat_slot = libinput_event_touch_get_seat_slot (touch_event); - touch_state = meta_seat_native_lookup_touch_state (seat, seat_slot); - if (!touch_state) - break; - - meta_seat_native_notify_touch_event (touch_state->seat, - device, - CLUTTER_TOUCH_CANCEL, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); - - meta_seat_native_release_touch_state (seat, seat_slot); - break; - } - case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: - case LIBINPUT_EVENT_GESTURE_PINCH_END: - { - struct libinput_event_gesture *gesture_event = - libinput_event_get_gesture_event (event); - ClutterTouchpadGesturePhase phase; - uint32_t n_fingers; - uint64_t time_us; - - if (libinput_event_get_type (event) == LIBINPUT_EVENT_GESTURE_PINCH_BEGIN) - phase = CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN; - else - phase = libinput_event_gesture_get_cancelled (gesture_event) ? - CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL : CLUTTER_TOUCHPAD_GESTURE_PHASE_END; - - n_fingers = libinput_event_gesture_get_finger_count (gesture_event); - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_gesture_get_time_usec (gesture_event); - notify_pinch_gesture_event (device, phase, time_us, 0, 0, 0, 0, n_fingers); - break; - } - case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: - { - struct libinput_event_gesture *gesture_event = - libinput_event_get_gesture_event (event); - gdouble angle_delta, scale, dx, dy; - uint32_t n_fingers; - uint64_t time_us; - - n_fingers = libinput_event_gesture_get_finger_count (gesture_event); - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_gesture_get_time_usec (gesture_event); - angle_delta = libinput_event_gesture_get_angle_delta (gesture_event); - scale = libinput_event_gesture_get_scale (gesture_event); - dx = libinput_event_gesture_get_dx (gesture_event); - dy = libinput_event_gesture_get_dy (gesture_event); - - notify_pinch_gesture_event (device, - CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE, - time_us, dx, dy, angle_delta, scale, n_fingers); - break; - } - case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN: - case LIBINPUT_EVENT_GESTURE_SWIPE_END: - { - struct libinput_event_gesture *gesture_event = - libinput_event_get_gesture_event (event); - ClutterTouchpadGesturePhase phase; - uint32_t n_fingers; - uint64_t time_us; - - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_gesture_get_time_usec (gesture_event); - n_fingers = libinput_event_gesture_get_finger_count (gesture_event); - - if (libinput_event_get_type (event) == LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN) - phase = CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN; - else - phase = libinput_event_gesture_get_cancelled (gesture_event) ? - CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL : CLUTTER_TOUCHPAD_GESTURE_PHASE_END; - - notify_swipe_gesture_event (device, phase, time_us, n_fingers, 0, 0); - break; - } - case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE: - { - struct libinput_event_gesture *gesture_event = - libinput_event_get_gesture_event (event); - uint32_t n_fingers; - uint64_t time_us; - double dx, dy; - - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_gesture_get_time_usec (gesture_event); - n_fingers = libinput_event_gesture_get_finger_count (gesture_event); - dx = libinput_event_gesture_get_dx (gesture_event); - dy = libinput_event_gesture_get_dy (gesture_event); - - notify_swipe_gesture_event (device, - CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE, - time_us, n_fingers, dx, dy); - break; - } - case LIBINPUT_EVENT_TABLET_TOOL_AXIS: - { - process_tablet_axis (seat, event); - break; - } - case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: - { - uint64_t time; - struct libinput_event_tablet_tool *tablet_event = - libinput_event_get_tablet_tool_event (event); - struct libinput_tablet_tool *libinput_tool = NULL; - enum libinput_tablet_tool_proximity_state state; - gboolean in; - - state = libinput_event_tablet_tool_get_proximity_state (tablet_event); - time = libinput_event_tablet_tool_get_time_usec (tablet_event); - device = libinput_device_get_user_data (libinput_device); - in = state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN; - - libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event); - - if (in) - input_device_update_tool (device, libinput_tool); - notify_proximity (device, time, in); - if (!in) - input_device_update_tool (device, NULL); - - update_tablet_cursor_state (seat, device, in); - break; - } - case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: - { - uint64_t time_us; - uint32_t button_state; - struct libinput_event_tablet_tool *tablet_event = - libinput_event_get_tablet_tool_event (event); - uint32_t tablet_button; - - process_tablet_axis (seat, event); - - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_tablet_tool_get_time_usec (tablet_event); - tablet_button = libinput_event_tablet_tool_get_button (tablet_event); - - button_state = libinput_event_tablet_tool_get_button_state (tablet_event) == - LIBINPUT_BUTTON_STATE_PRESSED; - - meta_seat_native_notify_button (seat_from_device (device), device, - time_us, tablet_button, button_state); - break; - } - case LIBINPUT_EVENT_TABLET_TOOL_TIP: - { - uint64_t time_us; - uint32_t button_state; - struct libinput_event_tablet_tool *tablet_event = - libinput_event_get_tablet_tool_event (event); - - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_tablet_tool_get_time_usec (tablet_event); - - button_state = libinput_event_tablet_tool_get_tip_state (tablet_event) == - LIBINPUT_TABLET_TOOL_TIP_DOWN; - - /* To avoid jumps on tip, notify axes before the tip down event - but after the tip up event */ - if (button_state) - process_tablet_axis (seat, event); - - meta_seat_native_notify_button (seat_from_device (device), device, - time_us, BTN_TOUCH, button_state); - if (!button_state) - process_tablet_axis (seat, event); - break; - } - case LIBINPUT_EVENT_TABLET_PAD_BUTTON: - { - uint64_t time; - uint32_t button_state, button, group, mode; - struct libinput_tablet_pad_mode_group *mode_group; - struct libinput_event_tablet_pad *pad_event = - libinput_event_get_tablet_pad_event (event); - - device = libinput_device_get_user_data (libinput_device); - time = libinput_event_tablet_pad_get_time_usec (pad_event); - - mode_group = libinput_event_tablet_pad_get_mode_group (pad_event); - group = libinput_tablet_pad_mode_group_get_index (mode_group); - mode = libinput_event_tablet_pad_get_mode (pad_event); - - button = libinput_event_tablet_pad_get_button_number (pad_event); - button_state = libinput_event_tablet_pad_get_button_state (pad_event) == - LIBINPUT_BUTTON_STATE_PRESSED; - notify_pad_button (device, time, button, group, mode, button_state); - break; - } - case LIBINPUT_EVENT_TABLET_PAD_STRIP: - { - uint64_t time; - uint32_t number, source, group, mode; - struct libinput_tablet_pad_mode_group *mode_group; - struct libinput_event_tablet_pad *pad_event = - libinput_event_get_tablet_pad_event (event); - double value; - - device = libinput_device_get_user_data (libinput_device); - time = libinput_event_tablet_pad_get_time_usec (pad_event); - number = libinput_event_tablet_pad_get_strip_number (pad_event); - value = libinput_event_tablet_pad_get_strip_position (pad_event); - source = libinput_event_tablet_pad_get_strip_source (pad_event); - - mode_group = libinput_event_tablet_pad_get_mode_group (pad_event); - group = libinput_tablet_pad_mode_group_get_index (mode_group); - mode = libinput_event_tablet_pad_get_mode (pad_event); - - notify_pad_strip (device, time, number, source, group, mode, value); - break; - } - case LIBINPUT_EVENT_TABLET_PAD_RING: - { - uint64_t time; - uint32_t number, source, group, mode; - struct libinput_tablet_pad_mode_group *mode_group; - struct libinput_event_tablet_pad *pad_event = - libinput_event_get_tablet_pad_event (event); - double angle; - - device = libinput_device_get_user_data (libinput_device); - time = libinput_event_tablet_pad_get_time_usec (pad_event); - number = libinput_event_tablet_pad_get_ring_number (pad_event); - angle = libinput_event_tablet_pad_get_ring_position (pad_event); - source = libinput_event_tablet_pad_get_ring_source (pad_event); - - mode_group = libinput_event_tablet_pad_get_mode_group (pad_event); - group = libinput_tablet_pad_mode_group_get_index (mode_group); - mode = libinput_event_tablet_pad_get_mode (pad_event); - - notify_pad_ring (device, time, number, source, group, mode, angle); - break; - } - case LIBINPUT_EVENT_SWITCH_TOGGLE: - { - struct libinput_event_switch *switch_event = - libinput_event_get_switch_event (event); - enum libinput_switch sw = - libinput_event_switch_get_switch (switch_event); - enum libinput_switch_state state = - libinput_event_switch_get_switch_state (switch_event); - - if (sw == LIBINPUT_SWITCH_TABLET_MODE) - { - seat->tablet_mode_switch_state = (state == LIBINPUT_SWITCH_STATE_ON); - update_touch_mode (seat); - } - break; - } - default: - handled = FALSE; - } - - return handled; -} - -static void -process_event (MetaSeatNative *seat, - struct libinput_event *event) -{ - if (process_base_event (seat, event)) - return; - if (process_device_event (seat, event)) - return; -} - -static void -process_events (MetaSeatNative *seat) -{ - struct libinput_event *event; - - while ((event = libinput_get_event (seat->libinput))) + else if (event_type == CLUTTER_DEVICE_ADDED) { - process_event(seat, event); - libinput_event_destroy(event); + if (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_LOGICAL) + seat_native->devices = g_list_prepend (seat_native->devices, g_object_ref (device)); } -} - -static int -open_restricted (const char *path, - int flags, - void *user_data) -{ - gint fd; - - if (device_open_callback) + else if (event_type == CLUTTER_DEVICE_REMOVED) { - GError *error = NULL; + GList *l = g_list_find (seat_native->devices, device); - fd = device_open_callback (path, flags, device_callback_data, &error); - - if (fd < 0) - { - g_warning ("Could not open device %s: %s", path, error->message); - g_error_free (error); - } - } - else - { - fd = open (path, O_RDWR | O_NONBLOCK); - if (fd < 0) + if (l) { - g_warning ("Could not open device %s: %s", path, strerror (errno)); + seat_native->devices = g_list_delete_link (seat_native->devices, l); + g_object_unref (device); } } - return fd; -} - -static void -close_restricted (int fd, - void *user_data) -{ - if (device_close_callback) - device_close_callback (fd, device_callback_data); - else - close (fd); + return FALSE; } -static const struct libinput_interface libinput_interface = { - open_restricted, - close_restricted -}; - static void meta_seat_native_constructed (GObject *object) { MetaSeatNative *seat = META_SEAT_NATIVE (object); - ClutterInputDevice *device; - MetaEventSource *source; - struct udev *udev; - struct xkb_keymap *xkb_keymap; - - device = meta_input_device_native_new_virtual ( - seat, CLUTTER_POINTER_DEVICE, - CLUTTER_INPUT_MODE_LOGICAL); - seat->pointer_x = INITIAL_POINTER_X; - seat->pointer_y = INITIAL_POINTER_Y; - meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (device), - seat->pointer_x, seat->pointer_y); - seat->core_pointer = device; - - device = meta_input_device_native_new_virtual ( - seat, CLUTTER_KEYBOARD_DEVICE, - CLUTTER_INPUT_MODE_LOGICAL); - seat->core_keyboard = device; - - udev = udev_new (); - if (G_UNLIKELY (udev == NULL)) - { - g_warning ("Failed to create udev object"); - return; - } - - seat->libinput = libinput_udev_create_context (&libinput_interface, - seat, udev); - if (seat->libinput == NULL) - { - g_critical ("Failed to create the libinput object."); - return; - } - - if (libinput_udev_assign_seat (seat->libinput, seat->seat_id) == -1) - { - g_critical ("Failed to assign a seat to the libinput object."); - libinput_unref (seat->libinput); - seat->libinput = NULL; - return; - } - - udev_unref (udev); - - seat->udev_client = g_udev_client_new ((const gchar *[]) { "input", NULL }); - - source = meta_event_source_new (seat); - seat->event_source = source; - seat->keymap = g_object_new (META_TYPE_KEYMAP_NATIVE, NULL); - xkb_keymap = meta_keymap_native_get_keyboard_map (seat->keymap); + seat->impl = meta_seat_impl_new (seat, seat->seat_id); - if (xkb_keymap) - { - seat->xkb = xkb_state_new (xkb_keymap); - - seat->caps_lock_led = - xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_CAPS); - seat->num_lock_led = - xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_NUM); - seat->scroll_lock_led = - xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL); - } - - seat->has_touchscreen = has_touchscreen (seat); - seat->has_tablet_switch = has_tablet_switch (seat); - update_touch_mode (seat); + seat->core_pointer = meta_seat_impl_get_pointer (seat->impl); + seat->core_keyboard = meta_seat_impl_get_keyboard (seat->impl); if (G_OBJECT_CLASS (meta_seat_native_parent_class)->constructed) G_OBJECT_CLASS (meta_seat_native_parent_class)->constructed (object); @@ -2582,60 +148,35 @@ meta_seat_native_get_property (GObject *object, g_value_set_string (value, seat_native->seat_id); break; case PROP_TOUCH_MODE: - g_value_set_boolean (value, seat_native->touch_mode); + g_value_set_boolean (value, seat_native->impl->touch_mode); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } -static void -meta_seat_native_dispose (GObject *object) -{ - MetaSeatNative *seat = META_SEAT_NATIVE (object); - - if (seat->libinput) - { - libinput_unref (seat->libinput); - seat->libinput = NULL; - } - - G_OBJECT_CLASS (meta_seat_native_parent_class)->dispose (object); -} - static void meta_seat_native_finalize (GObject *object) { MetaSeatNative *seat = META_SEAT_NATIVE (object); - GSList *iter; + GList *iter; - for (iter = seat->devices; iter; iter = g_slist_next (iter)) + g_clear_object (&seat->core_pointer); + g_clear_object (&seat->core_keyboard); + g_clear_object (&seat->impl); + + for (iter = seat->devices; iter; iter = g_list_next (iter)) { ClutterInputDevice *device = iter->data; g_object_unref (device); } - g_slist_free (seat->devices); - - if (seat->touch_states) - g_hash_table_destroy (seat->touch_states); + g_list_free (seat->devices); g_hash_table_destroy (seat->reserved_virtual_slots); g_clear_pointer (&seat->tablet_cursors, g_hash_table_unref); g_object_unref (seat->cursor_renderer); - g_object_unref (seat->udev_client); - - meta_event_source_free (seat->event_source); - - xkb_state_unref (seat->xkb); - - meta_seat_native_clear_repeat_timer (seat); - - if (seat->libinput_seat) - libinput_seat_unref (seat->libinput_seat); - - g_list_free (seat->free_device_ids); g_free (seat->seat_id); @@ -2679,6 +220,9 @@ meta_seat_native_get_keymap (ClutterSeat *seat) { MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); + if (!seat_native->keymap) + seat_native->keymap = meta_seat_impl_get_keymap (seat_native->impl); + return CLUTTER_KEYMAP (seat_native->keymap); } @@ -2794,8 +338,7 @@ meta_seat_native_warp_pointer (ClutterSeat *seat, meta_backend_get_cursor_renderer (backend); MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); - notify_absolute_motion (seat_native->core_pointer, 0, x, y, NULL); - + meta_seat_impl_warp_pointer (seat_native->impl, x, y); meta_cursor_renderer_update_position (cursor_renderer); meta_cursor_tracker_invalidate_position (cursor_tracker); } @@ -2807,46 +350,10 @@ meta_seat_native_query_state (ClutterSeat *seat, graphene_point_t *coords, ClutterModifierType *modifiers) { - MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); - if (sequence) - { - MetaTouchState *touch_state; - int slot; - - slot = meta_event_native_sequence_get_slot (sequence); - touch_state = meta_seat_native_lookup_touch_state (seat_native, slot); - if (!touch_state) - return FALSE; - - if (coords) - { - coords->x = touch_state->coords.x; - coords->y = touch_state->coords.y; - } - - if (modifiers) - *modifiers = meta_xkb_translate_modifiers (seat_native->xkb, 0); - - return TRUE; - } - else - { - if (coords) - { - coords->x = device_native->pointer_x; - coords->y = device_native->pointer_y; - } - - if (modifiers) - { - *modifiers = meta_xkb_translate_modifiers (seat_native->xkb, - seat_native->button_state); - } - - return TRUE; - } + return meta_seat_impl_query_state (seat_native->impl, device, sequence, + coords, modifiers); } static void @@ -2858,7 +365,6 @@ meta_seat_native_class_init (MetaSeatNativeClass *klass) object_class->constructed = meta_seat_native_constructed; object_class->set_property = meta_seat_native_set_property; object_class->get_property = meta_seat_native_get_property; - object_class->dispose = meta_seat_native_dispose; object_class->finalize = meta_seat_native_finalize; seat_class->get_pointer = meta_seat_native_get_pointer; @@ -2892,71 +398,9 @@ meta_seat_native_class_init (MetaSeatNativeClass *klass) static void meta_seat_native_init (MetaSeatNative *seat) { - seat->device_id_next = INITIAL_DEVICE_ID; - - seat->repeat = TRUE; - seat->repeat_delay = 250; /* ms */ - seat->repeat_interval = 33; /* ms */ - - seat->barrier_manager = meta_barrier_manager_native_new (); - seat->reserved_virtual_slots = g_hash_table_new (NULL, NULL); } -/** - * meta_seat_native_set_device_callbacks: (skip) - * @open_callback: the user replacement for open() - * @close_callback: the user replacement for close() - * @user_data: user data for @callback - * - * Through this function, the application can set a custom callback - * to be invoked when Clutter is about to open an evdev device. It can do - * so if special handling is needed, for example to circumvent permission - * problems. - * - * Setting @callback to %NULL will reset the default behavior. - * - * For reliable effects, this function must be called before clutter_init(). - */ -void -meta_seat_native_set_device_callbacks (MetaOpenDeviceCallback open_callback, - MetaCloseDeviceCallback close_callback, - gpointer user_data) -{ - device_open_callback = open_callback; - device_close_callback = close_callback; - device_callback_data = user_data; -} - -void -meta_seat_native_update_xkb_state (MetaSeatNative *seat) -{ - xkb_mod_mask_t latched_mods; - xkb_mod_mask_t locked_mods; - struct xkb_keymap *xkb_keymap; - - xkb_keymap = meta_keymap_native_get_keyboard_map (seat->keymap); - - latched_mods = xkb_state_serialize_mods (seat->xkb, - XKB_STATE_MODS_LATCHED); - locked_mods = xkb_state_serialize_mods (seat->xkb, - XKB_STATE_MODS_LOCKED); - xkb_state_unref (seat->xkb); - seat->xkb = xkb_state_new (xkb_keymap); - - xkb_state_update_mask (seat->xkb, - 0, /* depressed */ - latched_mods, - locked_mods, - 0, 0, seat->layout_idx); - - seat->caps_lock_led = xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_CAPS); - seat->num_lock_led = xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_NUM); - seat->scroll_lock_led = xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL); - - meta_seat_native_sync_leds (seat); -} - /** * meta_seat_native_release_devices: * @@ -2980,9 +424,7 @@ meta_seat_native_release_devices (MetaSeatNative *seat) return; } - libinput_suspend (seat->libinput); - process_events (seat); - + meta_seat_impl_release_devices (seat->impl); seat->released = TRUE; } @@ -3007,10 +449,7 @@ meta_seat_native_reclaim_devices (MetaSeatNative *seat) return; } - libinput_resume (seat->libinput); - meta_seat_native_update_xkb_state (seat); - process_events (seat); - + meta_seat_impl_reclaim_devices (seat->impl); seat->released = FALSE; } @@ -3028,16 +467,10 @@ void meta_seat_native_set_keyboard_map (MetaSeatNative *seat, struct xkb_keymap *xkb_keymap) { - ClutterKeymap *keymap; - g_return_if_fail (META_IS_SEAT_NATIVE (seat)); g_return_if_fail (xkb_keymap != NULL); - keymap = clutter_seat_get_keymap (CLUTTER_SEAT (seat)); - meta_keymap_native_set_keyboard_map (META_KEYMAP_NATIVE (keymap), - xkb_keymap); - - meta_seat_native_update_xkb_state (seat); + meta_seat_impl_set_keyboard_map (seat->impl, xkb_keymap); } /** @@ -3053,7 +486,7 @@ meta_seat_native_get_keyboard_map (MetaSeatNative *seat) { g_return_val_if_fail (META_IS_SEAT_NATIVE (seat), NULL); - return xkb_state_get_keymap (seat->xkb); + return meta_seat_impl_get_keyboard_map (seat->impl); } /** @@ -3067,22 +500,9 @@ void meta_seat_native_set_keyboard_layout_index (MetaSeatNative *seat, xkb_layout_index_t idx) { - xkb_mod_mask_t depressed_mods; - xkb_mod_mask_t latched_mods; - xkb_mod_mask_t locked_mods; - struct xkb_state *state; - g_return_if_fail (META_IS_SEAT_NATIVE (seat)); - state = seat->xkb; - - depressed_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED); - latched_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED); - locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED); - - xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx); - - seat->layout_idx = idx; + meta_seat_impl_set_keyboard_layout_index (seat->impl, idx); } /** @@ -3091,7 +511,7 @@ meta_seat_native_set_keyboard_layout_index (MetaSeatNative *seat, xkb_layout_index_t meta_seat_native_get_keyboard_layout_index (MetaSeatNative *seat) { - return seat->layout_idx; + return meta_seat_impl_get_keyboard_layout_index (seat->impl); } /** @@ -3105,90 +525,20 @@ void meta_seat_native_set_keyboard_numlock (MetaSeatNative *seat, gboolean numlock_state) { - xkb_mod_mask_t depressed_mods; - xkb_mod_mask_t latched_mods; - xkb_mod_mask_t locked_mods; - xkb_mod_mask_t group_mods; - xkb_mod_mask_t numlock; - struct xkb_keymap *xkb_keymap; - ClutterKeymap *keymap; - - g_return_if_fail (META_IS_SEAT_NATIVE (seat)); - - keymap = clutter_seat_get_keymap (CLUTTER_SEAT (seat)); - xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap)); - - numlock = (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod2")); - - depressed_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED); - latched_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LATCHED); - locked_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LOCKED); - group_mods = xkb_state_serialize_layout (seat->xkb, XKB_STATE_LAYOUT_EFFECTIVE); - - if (numlock_state) - locked_mods |= numlock; - else - locked_mods &= ~numlock; - - xkb_state_update_mask (seat->xkb, - depressed_mods, - latched_mods, - locked_mods, - 0, 0, - group_mods); - - meta_seat_native_sync_leds (seat); -} - -/** - * meta_seat_native_set_keyboard_repeat: - * @seat: the #ClutterSeat created by the evdev backend - * @repeat: whether to enable or disable keyboard repeat events - * @delay: the delay in ms between the hardware key press event and - * the first synthetic event - * @interval: the period in ms between consecutive synthetic key - * press events - * - * Enables or disables sythetic key press events, allowing for initial - * delay and interval period to be specified. - */ -void -meta_seat_native_set_keyboard_repeat (MetaSeatNative *seat, - gboolean repeat, - uint32_t delay, - uint32_t interval) -{ - g_return_if_fail (META_IS_SEAT_NATIVE (seat)); - - seat->repeat = repeat; - seat->repeat_delay = delay; - seat->repeat_interval = interval; -} - -struct xkb_state * -meta_seat_native_get_xkb_state (MetaSeatNative *seat) -{ - return seat->xkb; + meta_seat_impl_set_keyboard_numlock (seat->impl, numlock_state); } MetaBarrierManagerNative * meta_seat_native_get_barrier_manager (MetaSeatNative *seat) { - return seat->barrier_manager; + return meta_seat_impl_get_barrier_manager (seat->impl); } void meta_seat_native_set_pointer_constraint (MetaSeatNative *seat, MetaPointerConstraintImpl *constraint_impl) { - if (!g_set_object (&seat->pointer_constraint, constraint_impl)) - return; - - if (constraint_impl) - { - meta_pointer_constraint_impl_ensure_constrained (constraint_impl, - seat->core_pointer); - } + meta_seat_impl_set_pointer_constraint (seat->impl, constraint_impl); } MetaCursorRenderer * @@ -3222,5 +572,5 @@ void meta_seat_native_set_viewports (MetaSeatNative *seat, MetaViewportInfo *viewports) { - g_set_object (&seat->viewports, viewports); + meta_seat_impl_set_viewports (seat->impl, viewports); } diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h index 1f64b60a813..7a409e98e3b 100644 --- a/src/backends/native/meta-seat-native.h +++ b/src/backends/native/meta-seat-native.h @@ -32,83 +32,31 @@ #include "backends/native/meta-cursor-renderer-native.h" #include "backends/native/meta-keymap-native.h" #include "backends/native/meta-pointer-constraint-native.h" +#include "backends/native/meta-seat-impl.h" #include "backends/native/meta-xkb-utils.h" #include "clutter/clutter.h" -typedef struct _MetaTouchState MetaTouchState; typedef struct _MetaSeatNative MetaSeatNative; -typedef struct _MetaEventSource MetaEventSource; - -struct _MetaTouchState -{ - MetaSeatNative *seat; - - int device_slot; - int seat_slot; - graphene_point_t coords; -}; struct _MetaSeatNative { ClutterSeat parent_instance; + MetaSeatImpl *impl; char *seat_id; - MetaEventSource *event_source; - struct libinput *libinput; - struct libinput_seat *libinput_seat; - GSList *devices; + GList *devices; ClutterInputDevice *core_pointer; ClutterInputDevice *core_keyboard; - GHashTable *touch_states; guint virtual_touch_slot_base; GHashTable *reserved_virtual_slots; - GHashTable *cursor_renderers; - - struct xkb_state *xkb; - xkb_led_index_t caps_lock_led; - xkb_led_index_t num_lock_led; - xkb_led_index_t scroll_lock_led; - xkb_layout_index_t layout_idx; - uint32_t button_state; - int button_count[KEY_CNT]; - - int device_id_next; - GList *free_device_ids; - - MetaBarrierManagerNative *barrier_manager; - MetaPointerConstraintImpl *pointer_constraint; MetaKeymapNative *keymap; MetaCursorRenderer *cursor_renderer; GHashTable *tablet_cursors; - MetaViewportInfo *viewports; - - GUdevClient *udev_client; - guint tablet_mode_switch_state : 1; - guint has_touchscreen : 1; - guint has_tablet_switch : 1; - guint touch_mode : 1; - - /* keyboard repeat */ - gboolean repeat; - uint32_t repeat_delay; - uint32_t repeat_interval; - uint32_t repeat_key; - uint32_t repeat_count; - uint32_t repeat_timer; - ClutterInputDevice *repeat_device; - - float pointer_x; - float pointer_y; - - /* Emulation of discrete scroll events out of smooth ones */ - float accum_scroll_dx; - float accum_scroll_dy; - gboolean released; }; @@ -116,95 +64,11 @@ struct _MetaSeatNative G_DECLARE_FINAL_TYPE (MetaSeatNative, meta_seat_native, META, SEAT_NATIVE, ClutterSeat) -void meta_seat_native_notify_key (MetaSeatNative *seat, - ClutterInputDevice *device, - uint64_t time_us, - uint32_t key, - uint32_t state, - gboolean update_keys); - -void meta_seat_native_notify_relative_motion (MetaSeatNative *seat_evdev, - ClutterInputDevice *input_device, - uint64_t time_us, - float dx, - float dy, - float dx_unaccel, - float dy_unaccel); - -void meta_seat_native_notify_absolute_motion (MetaSeatNative *seat_evdev, - ClutterInputDevice *input_device, - uint64_t time_us, - float x, - float y, - double *axes); - -void meta_seat_native_notify_button (MetaSeatNative *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - uint32_t button, - uint32_t state); - -void meta_seat_native_notify_scroll_continuous (MetaSeatNative *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - double dx, - double dy, - ClutterScrollSource source, - ClutterScrollFinishFlags flags); - -void meta_seat_native_notify_discrete_scroll (MetaSeatNative *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - double discrete_dx, - double discrete_dy, - ClutterScrollSource source); - -void meta_seat_native_notify_touch_event (MetaSeatNative *seat, - ClutterInputDevice *input_device, - ClutterEventType evtype, - uint64_t time_us, - int slot, - double x, - double y); - void meta_seat_native_set_libinput_seat (MetaSeatNative *seat, struct libinput_seat *libinput_seat); void meta_seat_native_sync_leds (MetaSeatNative *seat); -MetaTouchState * meta_seat_native_acquire_touch_state (MetaSeatNative *seat, - int seat_slot); -MetaTouchState * meta_seat_native_lookup_touch_state (MetaSeatNative *seat, - int seat_slot); - -void meta_seat_native_release_touch_state (MetaSeatNative *seat, - int seat_slot); - -void meta_seat_native_clear_repeat_timer (MetaSeatNative *seat); - -gint meta_seat_native_acquire_device_id (MetaSeatNative *seat); -void meta_seat_native_release_device_id (MetaSeatNative *seat, - ClutterInputDevice *device); - -void meta_seat_native_update_xkb_state (MetaSeatNative *seat); - -void meta_seat_native_constrain_pointer (MetaSeatNative *seat, - ClutterInputDevice *core_pointer, - uint64_t time_us, - float x, - float y, - float *new_x, - float *new_y); - -void meta_seat_native_filter_relative_motion (MetaSeatNative *seat, - ClutterInputDevice *device, - float x, - float y, - float *dx, - float *dy); - -void meta_seat_native_dispatch (MetaSeatNative *seat); - /** * MetaOpenDeviceCallback: * @path: the device path @@ -228,8 +92,6 @@ void meta_seat_native_set_device_callbacks (MetaOpenDeviceCallback open_callba void meta_seat_native_release_devices (MetaSeatNative *seat); void meta_seat_native_reclaim_devices (MetaSeatNative *seat); -struct xkb_state * meta_seat_native_get_xkb_state (MetaSeatNative *seat); - void meta_seat_native_set_keyboard_map (MetaSeatNative *seat, struct xkb_keymap *keymap); diff --git a/src/backends/native/meta-virtual-input-device-native.c b/src/backends/native/meta-virtual-input-device-native.c index 42fba7dbe66..2082c11ab8e 100644 --- a/src/backends/native/meta-virtual-input-device-native.c +++ b/src/backends/native/meta-virtual-input-device-native.c @@ -131,19 +131,19 @@ release_pressed_buttons (ClutterVirtualInputDevice *virtual_device) switch (get_button_type (code)) { case EVDEV_BUTTON_TYPE_KEY: - meta_seat_native_notify_key (virtual_evdev->seat, - virtual_evdev->device, - time_us, - code, - CLUTTER_KEY_STATE_RELEASED, - TRUE); + meta_seat_impl_notify_key (virtual_evdev->seat->impl, + virtual_evdev->device, + time_us, + code, + CLUTTER_KEY_STATE_RELEASED, + TRUE); break; case EVDEV_BUTTON_TYPE_BUTTON: - meta_seat_native_notify_button (virtual_evdev->seat, - virtual_evdev->device, - time_us, - code, - CLUTTER_BUTTON_STATE_RELEASED); + meta_seat_impl_notify_button (virtual_evdev->seat->impl, + virtual_evdev->device, + time_us, + code, + CLUTTER_BUTTON_STATE_RELEASED); break; case EVDEV_BUTTON_TYPE_NONE: g_assert_not_reached (); @@ -167,11 +167,11 @@ meta_virtual_input_device_native_notify_relative_motion (ClutterVirtualInputDevi if (time_us == CLUTTER_CURRENT_TIME) time_us = g_get_monotonic_time (); - meta_seat_native_notify_relative_motion (virtual_evdev->seat, - virtual_evdev->device, - time_us, - dx, dy, - dx, dy); + meta_seat_impl_notify_relative_motion (virtual_evdev->seat->impl, + virtual_evdev->device, + time_us, + dx, dy, + dx, dy); } static void @@ -188,11 +188,11 @@ meta_virtual_input_device_native_notify_absolute_motion (ClutterVirtualInputDevi if (time_us == CLUTTER_CURRENT_TIME) time_us = g_get_monotonic_time (); - meta_seat_native_notify_absolute_motion (virtual_evdev->seat, - virtual_evdev->device, - time_us, - x, y, - NULL); + meta_seat_impl_notify_absolute_motion (virtual_evdev->seat->impl, + virtual_evdev->device, + time_us, + x, y, + NULL); } static int @@ -254,11 +254,11 @@ meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtu button_state == CLUTTER_BUTTON_STATE_PRESSED ? "press" : "release", evdev_button, virtual_device); - meta_seat_native_notify_button (virtual_evdev->seat, - virtual_evdev->device, - time_us, - evdev_button, - button_state); + meta_seat_impl_notify_button (virtual_evdev->seat->impl, + virtual_evdev->device, + time_us, + evdev_button, + button_state); } static void @@ -296,12 +296,12 @@ meta_virtual_input_device_native_notify_key (ClutterVirtualInputDevice *virtual_ key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release", key, virtual_device); - meta_seat_native_notify_key (virtual_evdev->seat, - virtual_evdev->device, - time_us, - key, - key_state, - TRUE); + meta_seat_impl_notify_key (virtual_evdev->seat->impl, + virtual_evdev->device, + time_us, + key, + key_state, + TRUE); } static gboolean @@ -322,7 +322,7 @@ pick_keycode_for_keyval_in_current_group (ClutterVirtualInputDevice *virtual_dev backend = clutter_get_default_backend (); keymap = clutter_seat_get_keymap (clutter_backend_get_default_seat (backend)); xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap)); - state = virtual_evdev->seat->xkb; + state = meta_seat_impl_get_xkb_state (virtual_evdev->seat->impl); layout = xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE); min_keycode = xkb_keymap_min_keycode (xkb_keymap); @@ -391,12 +391,12 @@ apply_level_modifiers (ClutterVirtualInputDevice *virtual_device, key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release", evcode, virtual_device); - meta_seat_native_notify_key (virtual_evdev->seat, - virtual_evdev->device, - time_us, - evcode, - key_state, - TRUE); + meta_seat_impl_notify_key (virtual_evdev->seat->impl, + virtual_evdev->device, + time_us, + evcode, + key_state, + TRUE); } static void @@ -449,12 +449,12 @@ meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtu if (key_state) apply_level_modifiers (virtual_device, time_us, level, key_state); - meta_seat_native_notify_key (virtual_evdev->seat, - virtual_evdev->device, - time_us, - evcode, - key_state, - TRUE); + meta_seat_impl_notify_key (virtual_evdev->seat->impl, + virtual_evdev->device, + time_us, + evcode, + key_state, + TRUE); if (!key_state) apply_level_modifiers (virtual_device, time_us, level, key_state); @@ -506,11 +506,11 @@ meta_virtual_input_device_native_notify_discrete_scroll (ClutterVirtualInputDevi direction_to_discrete (direction, &discrete_dx, &discrete_dy); - meta_seat_native_notify_discrete_scroll (virtual_evdev->seat, - virtual_evdev->device, - time_us, - discrete_dx, discrete_dy, - scroll_source); + meta_seat_impl_notify_discrete_scroll (virtual_evdev->seat->impl, + virtual_evdev->device, + time_us, + discrete_dx, discrete_dy, + scroll_source); } static void @@ -529,12 +529,12 @@ meta_virtual_input_device_native_notify_scroll_continuous (ClutterVirtualInputDe if (time_us == CLUTTER_CURRENT_TIME) time_us = g_get_monotonic_time (); - meta_seat_native_notify_scroll_continuous (virtual_evdev->seat, - virtual_evdev->device, - time_us, - dx, dy, - scroll_source, - CLUTTER_SCROLL_FINISHED_NONE); + meta_seat_impl_notify_scroll_continuous (virtual_evdev->seat->impl, + virtual_evdev->device, + time_us, + dx, dy, + scroll_source, + CLUTTER_SCROLL_FINISHED_NONE); } static void @@ -555,21 +555,21 @@ meta_virtual_input_device_native_notify_touch_down (ClutterVirtualInputDevice *v time_us = g_get_monotonic_time (); seat_slot = virtual_evdev->slot_base + (guint) device_slot; - touch_state = meta_seat_native_acquire_touch_state (virtual_evdev->seat, - seat_slot); + touch_state = meta_seat_impl_acquire_touch_state (virtual_evdev->seat->impl, + seat_slot); if (!touch_state) return; touch_state->coords.x = x; touch_state->coords.y = y; - meta_seat_native_notify_touch_event (virtual_evdev->seat, - virtual_evdev->device, - CLUTTER_TOUCH_BEGIN, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); + meta_seat_impl_notify_touch_event (virtual_evdev->seat->impl, + virtual_evdev->device, + CLUTTER_TOUCH_BEGIN, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); } static void @@ -590,21 +590,21 @@ meta_virtual_input_device_native_notify_touch_motion (ClutterVirtualInputDevice time_us = g_get_monotonic_time (); seat_slot = virtual_evdev->slot_base + (guint) device_slot; - touch_state = meta_seat_native_lookup_touch_state (virtual_evdev->seat, - seat_slot); + touch_state = meta_seat_impl_lookup_touch_state (virtual_evdev->seat->impl, + seat_slot); if (!touch_state) return; touch_state->coords.x = x; touch_state->coords.y = y; - meta_seat_native_notify_touch_event (virtual_evdev->seat, - virtual_evdev->device, - CLUTTER_TOUCH_BEGIN, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); + meta_seat_impl_notify_touch_event (virtual_evdev->seat->impl, + virtual_evdev->device, + CLUTTER_TOUCH_BEGIN, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); } static void @@ -623,21 +623,21 @@ meta_virtual_input_device_native_notify_touch_up (ClutterVirtualInputDevice *vir time_us = g_get_monotonic_time (); seat_slot = virtual_evdev->slot_base + (guint) device_slot; - touch_state = meta_seat_native_lookup_touch_state (virtual_evdev->seat, - seat_slot); + touch_state = meta_seat_impl_lookup_touch_state (virtual_evdev->seat->impl, + seat_slot); if (!touch_state) return; - meta_seat_native_notify_touch_event (virtual_evdev->seat, - virtual_evdev->device, - CLUTTER_TOUCH_BEGIN, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); + meta_seat_impl_notify_touch_event (virtual_evdev->seat->impl, + virtual_evdev->device, + CLUTTER_TOUCH_BEGIN, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); - meta_seat_native_release_touch_state (virtual_evdev->seat, - touch_state->seat_slot); + meta_seat_impl_release_touch_state (virtual_evdev->seat->impl, + touch_state->seat_slot); } static void @@ -702,7 +702,7 @@ meta_virtual_input_device_native_constructed (GObject *object) device_type, virtual_device); virtual_evdev->device = - meta_input_device_native_new_virtual (virtual_evdev->seat, + meta_input_device_native_new_virtual (virtual_evdev->seat->impl, device_type, CLUTTER_INPUT_MODE_PHYSICAL); diff --git a/src/meson.build b/src/meson.build index dd0167cb876..6db0462fe77 100644 --- a/src/meson.build +++ b/src/meson.build @@ -705,6 +705,8 @@ if have_native_backend 'backends/native/meta-renderer-native-gles3.c', 'backends/native/meta-renderer-native-gles3.h', 'backends/native/meta-renderer-native.h', + 'backends/native/meta-seat-impl.c', + 'backends/native/meta-seat-impl.h', 'backends/native/meta-seat-native.c', 'backends/native/meta-seat-native.h', 'backends/native/meta-stage-native.c', -- GitLab From 39f4acac3de765bf560da54fc98db06c0bdabcca Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 21 Nov 2020 18:03:27 +0100 Subject: [PATCH 44/85] backend/native: Let cursor renderer/tracker be updated by events after warp We will generate a motion event, which will end up with the same result, at a time we can ensure it did happen. Part-of: --- src/backends/native/meta-seat-native.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index e9c83927eea..fa86b775b55 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -333,14 +333,8 @@ meta_seat_native_warp_pointer (ClutterSeat *seat, int y) { MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); - MetaBackend *backend = meta_get_backend (); - MetaCursorRenderer *cursor_renderer = - meta_backend_get_cursor_renderer (backend); - MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); meta_seat_impl_warp_pointer (seat_native->impl, x, y); - meta_cursor_renderer_update_position (cursor_renderer); - meta_cursor_tracker_invalidate_position (cursor_tracker); } static gboolean -- GitLab From 31439d78410f5a0def3b5a778df4066add60c224 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 11 Aug 2020 17:11:51 +0200 Subject: [PATCH 45/85] backends/native: Forward keyboard a11y changes via the MetaSeatImpl These changes will happen in the input event management code, so let them be emitted via the MetaSeatImpl, as that's what we'll have neat access to. The ClutterSeat signals are now emitted from there. Part-of: --- .../native/meta-input-device-native.c | 30 ++++++------- src/backends/native/meta-seat-impl.c | 42 +++++++++++++++++++ src/backends/native/meta-seat-impl.h | 8 ++++ src/backends/native/meta-seat-native.c | 27 ++++++++++++ 4 files changed, 90 insertions(+), 17 deletions(-) diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index ec41afc08c4..b9f3d36feee 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -27,7 +27,7 @@ #include "backends/meta-backend-private.h" #include "backends/native/meta-input-device-tool-native.h" #include "backends/native/meta-input-device-native.h" -#include "backends/native/meta-seat-native.h" +#include "backends/native/meta-seat-impl.h" #include "clutter/clutter-mutter.h" G_DEFINE_TYPE (MetaInputDeviceNative, @@ -416,10 +416,9 @@ key_event_is_modifier (ClutterEvent *event) static void notify_stickykeys_mask (MetaInputDeviceNative *device) { - g_signal_emit_by_name (device->seat_impl->seat_native, - "kbd-a11y-mods-state-changed", - device->stickykeys_latched_mask, - device->stickykeys_locked_mask); + meta_seat_impl_notify_kbd_a11y_mods_state_changed (device->seat_impl, + device->stickykeys_latched_mask, + device->stickykeys_locked_mask); } static void @@ -492,10 +491,9 @@ notify_stickykeys_change (MetaInputDeviceNative *device) device->stickykeys_depressed_mask = 0; update_internal_xkb_state (device, 0, 0); - g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->seat, - "kbd-a11y-flags-changed", - device->a11y_flags, - META_A11Y_STICKY_KEYS_ENABLED); + meta_seat_impl_notify_kbd_a11y_flags_changed (device->seat_impl, + device->a11y_flags, + META_A11Y_STICKY_KEYS_ENABLED); } static void @@ -525,10 +523,9 @@ set_slowkeys_off (MetaInputDeviceNative *device) { device->a11y_flags &= ~META_A11Y_SLOW_KEYS_ENABLED; - g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->seat, - "kbd-a11y-flags-changed", - device->a11y_flags, - META_A11Y_SLOW_KEYS_ENABLED); + meta_seat_impl_notify_kbd_a11y_flags_changed (device->seat_impl, + device->a11y_flags, + META_A11Y_SLOW_KEYS_ENABLED); } static void @@ -536,10 +533,9 @@ set_slowkeys_on (MetaInputDeviceNative *device) { device->a11y_flags |= META_A11Y_SLOW_KEYS_ENABLED; - g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->seat, - "kbd-a11y-flags-changed", - device->a11y_flags, - META_A11Y_SLOW_KEYS_ENABLED); + meta_seat_impl_notify_kbd_a11y_flags_changed (device->seat_impl, + device->a11y_flags, + META_A11Y_SLOW_KEYS_ENABLED); } static void diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index f3eb6efe114..a8ee3fc2a6a 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -106,6 +106,15 @@ enum static GParamSpec *props[N_PROPS] = { NULL }; +enum +{ + KBD_A11Y_FLAGS_CHANGED, + KBD_A11Y_MODS_STATE_CHANGED, + N_SIGNALS +}; + +static guint signals[N_SIGNALS] = { 0 }; + G_DEFINE_TYPE (MetaSeatImpl, meta_seat_impl, G_TYPE_OBJECT) static void process_events (MetaSeatImpl *seat_impl); @@ -2700,6 +2709,21 @@ meta_seat_impl_class_init (MetaSeatImplClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + signals[KBD_A11Y_FLAGS_CHANGED] = + g_signal_new ("kbd-a11y-flags-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 2, + G_TYPE_UINT, G_TYPE_UINT); + signals[KBD_A11Y_MODS_STATE_CHANGED] = + g_signal_new ("kbd-a11y-mods-state-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 2, + G_TYPE_UINT, G_TYPE_UINT); + g_object_class_install_properties (object_class, N_PROPS, props); } @@ -3020,3 +3044,21 @@ meta_seat_impl_new (MetaSeatNative *seat_native, "seat-id", seat_id, NULL); } + +void +meta_seat_impl_notify_kbd_a11y_flags_changed (MetaSeatImpl *seat_impl, + MetaKeyboardA11yFlags new_flags, + MetaKeyboardA11yFlags what_changed) +{ + g_signal_emit (seat_impl, signals[KBD_A11Y_FLAGS_CHANGED], 0, + new_flags, what_changed); +} + +void +meta_seat_impl_notify_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_impl, + xkb_mod_mask_t new_latched_mods, + xkb_mod_mask_t new_locked_mods) +{ + g_signal_emit (seat_impl, signals[KBD_A11Y_MODS_STATE_CHANGED], 0, + new_latched_mods, new_locked_mods); +} diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index 71241cbc736..8d643992110 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -27,6 +27,7 @@ #include #include +#include "backends/meta-input-settings-private.h" #include "backends/meta-viewport-info.h" #include "backends/native/meta-backend-native-types.h" #include "backends/native/meta-barrier-native.h" @@ -239,4 +240,11 @@ GSList * meta_seat_impl_get_devices (MetaSeatImpl *seat_impl); MetaKeymapNative * meta_seat_impl_get_keymap (MetaSeatImpl *seat_impl); +void meta_seat_impl_notify_kbd_a11y_flags_changed (MetaSeatImpl *seat_impl, + MetaKeyboardA11yFlags new_flags, + MetaKeyboardA11yFlags what_changed); +void meta_seat_impl_notify_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_impl, + xkb_mod_mask_t new_latched_mods, + xkb_mod_mask_t new_locked_mods); + #endif /* META_SEAT_IMPL_H */ diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index fa86b775b55..f8f155a8b98 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -101,12 +101,39 @@ meta_seat_native_handle_event_post (ClutterSeat *seat, return FALSE; } +static void +proxy_kbd_a11y_flags_changed (MetaSeatImpl *seat_impl, + MetaKeyboardA11yFlags new_flags, + MetaKeyboardA11yFlags what_changed, + MetaSeatNative *seat_native) +{ + g_signal_emit_by_name (seat_native, + "kbd-a11y-flags-changed", + new_flags, what_changed); +} + +static void +proxy_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_impl, + xkb_mod_mask_t new_latched_mods, + xkb_mod_mask_t new_locked_mods, + MetaSeatNative *seat_native) +{ + g_signal_emit_by_name (seat_native, + "kbd-a11y-mods-state-changed", + new_latched_mods, + new_locked_mods); +} + static void meta_seat_native_constructed (GObject *object) { MetaSeatNative *seat = META_SEAT_NATIVE (object); seat->impl = meta_seat_impl_new (seat, seat->seat_id); + g_signal_connect (seat->impl, "kbd-a11y-flags-changed", + G_CALLBACK (proxy_kbd_a11y_flags_changed), seat); + g_signal_connect (seat->impl, "kbd-a11y-mods-state-changed", + G_CALLBACK (proxy_kbd_a11y_mods_state_changed), seat); seat->core_pointer = meta_seat_impl_get_pointer (seat->impl); seat->core_keyboard = meta_seat_impl_get_keyboard (seat->impl); -- GitLab From facc9632139de3b7f87e21e72f1dca4cd12f4928 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 11 Aug 2020 17:19:21 +0200 Subject: [PATCH 46/85] backends/native: Proxy touch-mode via MetaSeatImpl Handle this via a MetaSeatImpl signal, as the heuristics that apply here are based on libinput events. The MetaSeatNative just forwards the touch-mode changes now. Part-of: --- src/backends/native/meta-seat-impl.c | 10 +++++++++- src/backends/native/meta-seat-native.c | 13 ++++++++++++- src/backends/native/meta-seat-native.h | 4 ++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index a8ee3fc2a6a..43d5052df81 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -110,6 +110,7 @@ enum { KBD_A11Y_FLAGS_CHANGED, KBD_A11Y_MODS_STATE_CHANGED, + TOUCH_MODE, N_SIGNALS }; @@ -1467,7 +1468,7 @@ update_touch_mode (MetaSeatImpl *seat_impl) if (seat_impl->touch_mode != touch_mode) { seat_impl->touch_mode = touch_mode; - g_object_notify (G_OBJECT (seat_impl->seat_native), "touch-mode"); + g_signal_emit (seat_impl, signals[TOUCH_MODE], 0, touch_mode); } } @@ -2723,6 +2724,13 @@ meta_seat_impl_class_init (MetaSeatImplClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); + signals[TOUCH_MODE] = + g_signal_new ("touch-mode", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); g_object_class_install_properties (object_class, N_PROPS, props); } diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index f8f155a8b98..2995247352c 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -124,6 +124,15 @@ proxy_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_impl, new_locked_mods); } +static void +proxy_touch_mode_changed (MetaSeatImpl *seat_impl, + gboolean enabled, + MetaSeatNative *seat_native) +{ + seat_native->touch_mode = enabled; + g_object_notify (G_OBJECT (seat_native), "touch-mode"); +} + static void meta_seat_native_constructed (GObject *object) { @@ -134,6 +143,8 @@ meta_seat_native_constructed (GObject *object) G_CALLBACK (proxy_kbd_a11y_flags_changed), seat); g_signal_connect (seat->impl, "kbd-a11y-mods-state-changed", G_CALLBACK (proxy_kbd_a11y_mods_state_changed), seat); + g_signal_connect (seat->impl, "touch-mode", + G_CALLBACK (proxy_touch_mode_changed), seat); seat->core_pointer = meta_seat_impl_get_pointer (seat->impl); seat->core_keyboard = meta_seat_impl_get_keyboard (seat->impl); @@ -175,7 +186,7 @@ meta_seat_native_get_property (GObject *object, g_value_set_string (value, seat_native->seat_id); break; case PROP_TOUCH_MODE: - g_value_set_boolean (value, seat_native->impl->touch_mode); + g_value_set_boolean (value, seat_native->touch_mode); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h index 7a409e98e3b..84eb8bb7e64 100644 --- a/src/backends/native/meta-seat-native.h +++ b/src/backends/native/meta-seat-native.h @@ -58,6 +58,7 @@ struct _MetaSeatNative GHashTable *tablet_cursors; gboolean released; + gboolean touch_mode; }; #define META_TYPE_SEAT_NATIVE meta_seat_native_get_type () @@ -122,5 +123,8 @@ MetaCursorRenderer * meta_seat_native_maybe_ensure_cursor_renderer (MetaSeatNati void meta_seat_native_set_viewports (MetaSeatNative *seat, MetaViewportInfo *viewports); +void meta_seat_native_notify_kbd_a11y_change (MetaSeatNative *seat, + MetaKeyboardA11yFlags new_flags, + MetaKeyboardA11yFlags what_changed); #endif /* META_SEAT_NATIVE_H */ -- GitLab From be1ffc86ca03f9df4d88fb53dc0747f64c1a4e66 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 11 Aug 2020 17:32:48 +0200 Subject: [PATCH 47/85] backends/native: Proxy bell notifications from within the MetaSeatImpl As with other changes from within the MetaSeatImpl realm, proxy that through a MetaSeatImpl signal, instead of poking directly on the ClutterSeat. Part-of: --- src/backends/native/meta-input-device-native.c | 2 +- src/backends/native/meta-seat-impl.c | 13 +++++++++++++ src/backends/native/meta-seat-impl.h | 1 + src/backends/native/meta-seat-native.c | 9 +++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index b9f3d36feee..fde23231eb6 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -215,7 +215,7 @@ meta_input_device_native_is_grouped (ClutterInputDevice *device, static void meta_input_device_native_bell_notify (MetaInputDeviceNative *device) { - clutter_seat_bell_notify (CLUTTER_SEAT (device->seat_impl->seat_native)); + meta_seat_impl_notify_bell (device->seat_impl); } static void diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 43d5052df81..4aeb0d0c082 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -111,6 +111,7 @@ enum KBD_A11Y_FLAGS_CHANGED, KBD_A11Y_MODS_STATE_CHANGED, TOUCH_MODE, + BELL, N_SIGNALS }; @@ -2731,6 +2732,12 @@ meta_seat_impl_class_init (MetaSeatImplClass *klass) 0, NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + signals[BELL] = + g_signal_new ("bell", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); g_object_class_install_properties (object_class, N_PROPS, props); } @@ -3070,3 +3077,9 @@ meta_seat_impl_notify_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_impl, g_signal_emit (seat_impl, signals[KBD_A11Y_MODS_STATE_CHANGED], 0, new_latched_mods, new_locked_mods); } + +void +meta_seat_impl_notify_bell (MetaSeatImpl *seat_impl) +{ + g_signal_emit (seat_impl, signals[BELL], 0); +} diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index 8d643992110..49a77298bc7 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -246,5 +246,6 @@ void meta_seat_impl_notify_kbd_a11y_flags_changed (MetaSeatImpl *seat_i void meta_seat_impl_notify_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_impl, xkb_mod_mask_t new_latched_mods, xkb_mod_mask_t new_locked_mods); +void meta_seat_impl_notify_bell (MetaSeatImpl *seat_impl); #endif /* META_SEAT_IMPL_H */ diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 2995247352c..bad7c656f8e 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -133,6 +133,13 @@ proxy_touch_mode_changed (MetaSeatImpl *seat_impl, g_object_notify (G_OBJECT (seat_native), "touch-mode"); } +static void +proxy_bell (MetaSeatImpl *seat_impl, + MetaSeatNative *seat_native) +{ + clutter_seat_bell_notify (CLUTTER_SEAT (seat_native)); +} + static void meta_seat_native_constructed (GObject *object) { @@ -145,6 +152,8 @@ meta_seat_native_constructed (GObject *object) G_CALLBACK (proxy_kbd_a11y_mods_state_changed), seat); g_signal_connect (seat->impl, "touch-mode", G_CALLBACK (proxy_touch_mode_changed), seat); + g_signal_connect (seat->impl, "bell", + G_CALLBACK (proxy_bell), seat); seat->core_pointer = meta_seat_impl_get_pointer (seat->impl); seat->core_keyboard = meta_seat_impl_get_keyboard (seat->impl); -- GitLab From 89a140d6187c8d90bff76841cd8949f25fdcd95c Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 11 Aug 2020 17:38:32 +0200 Subject: [PATCH 48/85] backends/native: Proxy modifier state changes via MetaSeatImpl This changes within the MetaSeatImpl realm, so use a signal to forward this to the MetaSeatNative/MetaKeymapNative one. Part-of: --- src/backends/native/meta-seat-impl.c | 9 ++++++++- src/backends/native/meta-seat-native.c | 12 ++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 4aeb0d0c082..32773a47817 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -112,6 +112,7 @@ enum KBD_A11Y_MODS_STATE_CHANGED, TOUCH_MODE, BELL, + MODS_STATE_CHANGED, N_SIGNALS }; @@ -343,7 +344,7 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, { MetaInputDeviceNative *keyboard_native; - g_signal_emit_by_name (seat_impl->keymap, "state-changed"); + g_signal_emit (seat_impl, signals[MODS_STATE_CHANGED], 0); meta_seat_impl_sync_leds (seat_impl); keyboard_native = META_INPUT_DEVICE_NATIVE (seat_impl->core_keyboard); meta_input_device_native_a11y_maybe_notify_toggle_keys (keyboard_native); @@ -2738,6 +2739,12 @@ meta_seat_impl_class_init (MetaSeatImplClass *klass) G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + signals[MODS_STATE_CHANGED] = + g_signal_new ("mods-state-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); g_object_class_install_properties (object_class, N_PROPS, props); } diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index bad7c656f8e..00b3c36ba66 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -140,6 +140,16 @@ proxy_bell (MetaSeatImpl *seat_impl, clutter_seat_bell_notify (CLUTTER_SEAT (seat_native)); } +static void +proxy_mods_state_changed (MetaSeatImpl *seat_impl, + ClutterSeat *seat) +{ + ClutterKeymap *keymap; + + keymap = clutter_seat_get_keymap (seat); + g_signal_emit_by_name (keymap, "state-changed"); +} + static void meta_seat_native_constructed (GObject *object) { @@ -154,6 +164,8 @@ meta_seat_native_constructed (GObject *object) G_CALLBACK (proxy_touch_mode_changed), seat); g_signal_connect (seat->impl, "bell", G_CALLBACK (proxy_bell), seat); + g_signal_connect (seat->impl, "mods-state-changed", + G_CALLBACK (proxy_mods_state_changed), seat); seat->core_pointer = meta_seat_impl_get_pointer (seat->impl); seat->core_keyboard = meta_seat_impl_get_keyboard (seat->impl); -- GitLab From c601a824e94d2903e126760c35775332afe6085c Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 23 Oct 2020 23:51:42 +0200 Subject: [PATCH 49/85] clutter: Update device for the current tool in backends This should happen deeper in backends, not here in clutter-main. Part-of: --- clutter/clutter/clutter-main.c | 3 --- src/backends/native/meta-seat-impl.c | 3 +++ src/backends/x11/meta-seat-x11.c | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index 9ac6d53bff4..706fb430ac3 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -1912,9 +1912,6 @@ _clutter_process_event_details (ClutterActor *stage, case CLUTTER_PROXIMITY_IN: case CLUTTER_PROXIMITY_OUT: - clutter_input_device_update_from_tool (clutter_event_get_source_device (event), - clutter_event_get_device_tool (event)); - if (_clutter_event_process_filters (event)) break; diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 32773a47817..7329568f953 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -1656,6 +1656,9 @@ input_device_update_tool (ClutterInputDevice *input_device, if (evdev_device->last_tool != tool) { + if (tool) + clutter_input_device_update_from_tool (input_device, tool); + evdev_device->last_tool = tool; g_signal_emit_by_name (seat_impl->seat_native, "tool-changed", input_device, tool); diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index f437ef16d5c..4437a247a87 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -960,6 +960,9 @@ translate_property_event (MetaSeatX11 *seat_x11, meta_input_device_x11_update_tool (device, tool); g_signal_emit_by_name (seat_x11, "tool-changed", device, tool); + + if (tool) + clutter_input_device_update_from_tool (device, tool); } } -- GitLab From fe9092da1972e520bd56dfa88a1080e7b72283b8 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 11 Aug 2020 17:40:52 +0200 Subject: [PATCH 50/85] backends: Simplify function arguments We just pass a device in order to check it with the seat pointer, we can do without this. Part-of: --- src/backends/meta-input-settings.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 6feb5469043..36998868c56 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -1274,19 +1274,13 @@ pointer_a11y_dwell_direction_from_setting (MetaInputSettings *input_settings, } static void -load_pointer_a11y_settings (MetaInputSettings *input_settings, - ClutterInputDevice *device) +load_pointer_a11y_settings (MetaInputSettings *input_settings) { MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings); ClutterPointerA11ySettings pointer_a11y_settings; - ClutterInputDevice *core_pointer; GDesktopMouseDwellMode dwell_mode; guint i; - core_pointer = clutter_seat_get_pointer (priv->seat); - if (device && device != core_pointer) - return; - clutter_seat_get_pointer_a11y_settings (CLUTTER_SEAT (priv->seat), &pointer_a11y_settings); pointer_a11y_settings.controls = 0; @@ -1331,7 +1325,7 @@ meta_input_mouse_a11y_settings_changed (GSettings *settings, { MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data); - load_pointer_a11y_settings (input_settings, NULL); + load_pointer_a11y_settings (input_settings); } static GSettings * @@ -1496,7 +1490,6 @@ apply_device_settings (MetaInputSettings *input_settings, update_pointer_accel_profile (input_settings, priv->trackball_settings, device); - load_pointer_a11y_settings (input_settings, device); update_middle_click_emulation (input_settings, priv->mouse_settings, device); update_middle_click_emulation (input_settings, priv->touchpad_settings, device); @@ -1721,6 +1714,7 @@ meta_input_settings_constructed (GObject *object) check_mappable_devices (input_settings); load_keyboard_a11y_settings (input_settings); + load_pointer_a11y_settings (input_settings); } static void -- GitLab From 2c1558ddbd04a9eaee97d717ca81d2957e045f15 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 11 Aug 2020 16:27:35 +0200 Subject: [PATCH 51/85] backends: Make device tracking at MetaInputSettings ad-hoc API Depending on the backend, we want to integrate this object at different levels. It will sit close to the MetaBackendX11/MetaSeatX11 in X11, but it will be put deep down with MetaSeatImpl in the native backend, in a separate thread. Since we can't depend on a single object type, nor are able to track ClutterSeat signals neatly, make this API something to be called explicitly by backends. Part-of: --- clutter/clutter/clutter-seat.c | 13 ------- src/backends/meta-input-settings-private.h | 11 ++++++ src/backends/meta-input-settings.c | 40 ++++++++-------------- src/backends/native/meta-seat-impl.c | 16 +++++++-- src/backends/x11/meta-seat-x11.c | 9 ++++- src/backends/x11/meta-xkb-a11y-x11.c | 13 ++++--- 6 files changed, 55 insertions(+), 47 deletions(-) diff --git a/clutter/clutter/clutter-seat.c b/clutter/clutter/clutter-seat.c index ed78f43a598..f4309787c56 100644 --- a/clutter/clutter/clutter-seat.c +++ b/clutter/clutter/clutter-seat.c @@ -36,7 +36,6 @@ enum { DEVICE_ADDED, DEVICE_REMOVED, - TOOL_CHANGED, KBD_A11Y_MASK_CHANGED, KBD_A11Y_FLAGS_CHANGED, PTR_A11Y_DWELL_CLICK_TYPE_CHANGED, @@ -149,18 +148,6 @@ clutter_seat_class_init (ClutterSeatClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_INPUT_DEVICE); - signals[TOOL_CHANGED] = - g_signal_new (I_("tool-changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - _clutter_marshal_VOID__OBJECT_OBJECT, - G_TYPE_NONE, 2, - CLUTTER_TYPE_INPUT_DEVICE, - CLUTTER_TYPE_INPUT_DEVICE_TOOL); - g_signal_set_va_marshaller (signals[TOOL_CHANGED], - G_TYPE_FROM_CLASS (object_class), - _clutter_marshal_VOID__OBJECT_OBJECTv); /** * ClutterSeat::kbd-a11y-mods-state-changed: diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h index f6e928dc450..639bede2265 100644 --- a/src/backends/meta-input-settings-private.h +++ b/src/backends/meta-input-settings-private.h @@ -189,4 +189,15 @@ void meta_input_settings_set_device_aspect_ratio (MetaInputSettings *input_sett void meta_input_settings_get_kbd_a11y_settings (MetaInputSettings *input_settings, MetaKbdA11ySettings *a11y_settings); +void meta_input_settings_add_device (MetaInputSettings *input_settings, + ClutterInputDevice *device); +void meta_input_settings_remove_device (MetaInputSettings *input_settings, + ClutterInputDevice *device); +void meta_input_settings_notify_tool_change (MetaInputSettings *input_settings, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool); +void meta_input_settings_notify_kbd_a11y_change (MetaInputSettings *input_settings, + MetaKeyboardA11yFlags new_flags, + MetaKeyboardA11yFlags what_changed); + #endif /* META_INPUT_SETTINGS_PRIVATE_H */ diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 36998868c56..35d46483b30 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -1209,11 +1209,10 @@ load_keyboard_a11y_settings (MetaInputSettings *input_settings) g_signal_emit (input_settings, signals[KBD_A11Y_CHANGED], 0, &priv->kbd_a11y_settings); } -static void -on_keyboard_a11y_settings_changed (ClutterSeat *seat, - MetaKeyboardA11yFlags new_flags, - MetaKeyboardA11yFlags what_changed, - MetaInputSettings *input_settings) +void +meta_input_settings_notify_kbd_a11y_change (MetaInputSettings *input_settings, + MetaKeyboardA11yFlags new_flags, + MetaKeyboardA11yFlags what_changed) { MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings); guint i; @@ -1585,10 +1584,9 @@ evaluate_two_finger_scrolling (MetaInputSettings *input_settings, g_hash_table_add (priv->two_finger_devices, device); } -static void -meta_input_settings_device_added (ClutterSeat *seat, - ClutterInputDevice *device, - MetaInputSettings *input_settings) +void +meta_input_settings_add_device (MetaInputSettings *input_settings, + ClutterInputDevice *device) { if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_LOGICAL) return; @@ -1599,10 +1597,9 @@ meta_input_settings_device_added (ClutterSeat *seat, check_add_mappable_device (input_settings, device); } -static void -meta_input_settings_device_removed (ClutterSeat *seat, - ClutterInputDevice *device, - MetaInputSettings *input_settings) +void +meta_input_settings_remove_device (MetaInputSettings *input_settings, + ClutterInputDevice *device) { MetaInputSettingsPrivate *priv; @@ -1651,11 +1648,10 @@ current_tool_info_free (CurrentToolInfo *info) g_free (info); } -static void -meta_input_settings_tool_changed (ClutterSeat *seat, - ClutterInputDevice *device, - ClutterInputDeviceTool *tool, - MetaInputSettings *input_settings) +void +meta_input_settings_notify_tool_change (MetaInputSettings *input_settings, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool) { MetaInputSettingsPrivate *priv; @@ -1744,12 +1740,6 @@ meta_input_settings_init (MetaInputSettings *settings) priv = meta_input_settings_get_instance_private (settings); priv->seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); - g_signal_connect (priv->seat, "device-added", - G_CALLBACK (meta_input_settings_device_added), settings); - g_signal_connect (priv->seat, "device-removed", - G_CALLBACK (meta_input_settings_device_removed), settings); - g_signal_connect (priv->seat, "tool-changed", - G_CALLBACK (meta_input_settings_tool_changed), settings); priv->mouse_settings = g_settings_new ("org.gnome.desktop.peripherals.mouse"); g_signal_connect (priv->mouse_settings, "changed", @@ -1776,8 +1766,6 @@ meta_input_settings_init (MetaInputSettings *settings) priv->keyboard_a11y_settings = g_settings_new ("org.gnome.desktop.a11y.keyboard"); g_signal_connect (priv->keyboard_a11y_settings, "changed", G_CALLBACK (meta_input_keyboard_a11y_settings_changed), settings); - g_signal_connect (priv->seat, "kbd-a11y-flags-changed", - G_CALLBACK (on_keyboard_a11y_settings_changed), settings); priv->mouse_a11y_settings = g_settings_new ("org.gnome.desktop.a11y.mouse"); g_signal_connect (priv->mouse_a11y_settings, "changed", diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 7329568f953..53e2fb50db4 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -1551,6 +1551,9 @@ process_base_event (MetaSeatImpl *seat_impl, ClutterInputDevice *device; ClutterEvent *device_event = NULL; struct libinput_device *libinput_device; + MetaInputSettings *input_settings; + + input_settings = meta_backend_get_input_settings (meta_get_backend ()); switch (libinput_event_get_type (event)) { @@ -1560,6 +1563,7 @@ process_base_event (MetaSeatImpl *seat_impl, device = evdev_add_device (seat_impl, libinput_device); device_event = clutter_event_new (CLUTTER_DEVICE_ADDED); clutter_event_set_device (device_event, device); + meta_input_settings_add_device (input_settings, device); break; case LIBINPUT_EVENT_DEVICE_REMOVED: @@ -1570,6 +1574,7 @@ process_base_event (MetaSeatImpl *seat_impl, clutter_event_set_device (device_event, device); evdev_remove_device (seat_impl, META_INPUT_DEVICE_NATIVE (device)); + meta_input_settings_remove_device (input_settings, device); break; default: @@ -1634,9 +1639,9 @@ input_device_update_tool (ClutterInputDevice *input_device, struct libinput_tablet_tool *libinput_tool) { MetaInputDeviceNative *evdev_device = META_INPUT_DEVICE_NATIVE (input_device); - MetaSeatImpl *seat_impl = seat_impl_from_device (input_device); ClutterInputDeviceTool *tool = NULL; ClutterInputDeviceToolType tool_type; + MetaInputSettings *input_settings; uint64_t tool_serial; if (libinput_tool) @@ -1660,8 +1665,8 @@ input_device_update_tool (ClutterInputDevice *input_device, clutter_input_device_update_from_tool (input_device, tool); evdev_device->last_tool = tool; - g_signal_emit_by_name (seat_impl->seat_native, "tool-changed", - input_device, tool); + input_settings = meta_backend_get_input_settings (meta_get_backend ()); + meta_input_settings_notify_tool_change (input_settings, input_device, tool); } } @@ -3075,6 +3080,11 @@ meta_seat_impl_notify_kbd_a11y_flags_changed (MetaSeatImpl *seat_impl, MetaKeyboardA11yFlags new_flags, MetaKeyboardA11yFlags what_changed) { + MetaInputSettings *input_settings; + + input_settings = meta_backend_get_input_settings (meta_get_backend ()); + meta_input_settings_notify_kbd_a11y_change (input_settings, + new_flags, what_changed); g_signal_emit (seat_impl, signals[KBD_A11Y_FLAGS_CHANGED], 0, new_flags, what_changed); } diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index 4437a247a87..24d6369b880 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -21,6 +21,7 @@ #include #include +#include "backends/meta-input-settings-private.h" #include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-event-x11.h" #include "backends/x11/meta-input-device-tool-x11.h" @@ -725,6 +726,7 @@ meta_seat_x11_handle_event_post (ClutterSeat *seat, { MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); ClutterInputDevice *device; + MetaInputSettings *input_settings; gboolean is_touch; if (event->type != CLUTTER_DEVICE_ADDED && @@ -734,15 +736,18 @@ meta_seat_x11_handle_event_post (ClutterSeat *seat, device = clutter_event_get_device (event); is_touch = clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE; + input_settings = meta_backend_get_input_settings (meta_get_backend ()); switch (event->type) { case CLUTTER_DEVICE_ADDED: + meta_input_settings_add_device (input_settings, device); seat_x11->has_touchscreens |= is_touch; break; case CLUTTER_DEVICE_REMOVED: if (is_touch) seat_x11->has_touchscreens = has_touchscreens (seat_x11); + meta_input_settings_remove_device (input_settings, device); break; default: break; @@ -939,6 +944,7 @@ translate_property_event (MetaSeatX11 *seat_x11, { ClutterInputDeviceTool *tool = NULL; ClutterInputDeviceToolType type; + MetaInputSettings *input_settings; int serial_id; serial_id = device_get_tool_serial (device); @@ -959,7 +965,8 @@ translate_property_event (MetaSeatX11 *seat_x11, } meta_input_device_x11_update_tool (device, tool); - g_signal_emit_by_name (seat_x11, "tool-changed", device, tool); + input_settings = meta_backend_get_input_settings (meta_get_backend ()); + meta_input_settings_notify_tool_change (input_settings, device, tool); if (tool) clutter_input_device_update_from_tool (device, tool); diff --git a/src/backends/x11/meta-xkb-a11y-x11.c b/src/backends/x11/meta-xkb-a11y-x11.c index 024618be6bd..d2e76b3f75b 100644 --- a/src/backends/x11/meta-xkb-a11y-x11.c +++ b/src/backends/x11/meta-xkb-a11y-x11.c @@ -118,10 +118,15 @@ check_settings_changed (ClutterSeat *seat) } if (what_changed) - g_signal_emit_by_name (seat, - "kbd-a11y-flags-changed", - kbd_a11y_settings.controls, - what_changed); + { + meta_input_settings_notify_kbd_a11y_change (input_settings, + kbd_a11y_settings.controls, + what_changed); + g_signal_emit_by_name (seat, + "kbd-a11y-flags-changed", + kbd_a11y_settings.controls, + what_changed); + } XkbFreeKeyboard (desc, XkbAllComponentsMask, TRUE); } -- GitLab From 4e56352bcc12a093320e052f4661ee8bcd560706 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 11 Aug 2020 18:10:28 +0200 Subject: [PATCH 52/85] backends: Do not use clutter_seat_list_devices() in MetaInputSettings Make it keep its own list of devices, it's not that far off. Part-of: --- src/backends/meta-input-settings.c | 36 +++++++++++++----------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 35d46483b30..6b878240a10 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -77,6 +77,7 @@ struct _MetaInputSettingsPrivate GSettings *keyboard_a11y_settings; GSettings *mouse_a11y_settings; + GList *devices; GHashTable *mappable_devices; GHashTable *current_tools; @@ -115,13 +116,12 @@ meta_input_settings_get_devices (MetaInputSettings *settings, ClutterInputDeviceType type) { MetaInputSettingsPrivate *priv; - GList *l, *devices; + GList *l; GSList *list = NULL; priv = meta_input_settings_get_instance_private (settings); - devices = clutter_seat_list_devices (priv->seat); - for (l = devices; l; l = l->next) + for (l = priv->devices; l; l = l->next) { ClutterInputDevice *device = l->data; @@ -130,8 +130,6 @@ meta_input_settings_get_devices (MetaInputSettings *settings, list = g_slist_prepend (list, device); } - g_list_free (devices); - return list; } @@ -364,10 +362,9 @@ update_pointer_accel_profile (MetaInputSettings *input_settings, { MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings); - GList *l, *devices; + GList *l; - devices = clutter_seat_list_devices (priv->seat); - for (l = devices; l; l = l->next) + for (l = priv->devices; l; l = l->next) { device = l->data; @@ -378,8 +375,6 @@ update_pointer_accel_profile (MetaInputSettings *input_settings, do_update_pointer_accel_profile (input_settings, settings, device, profile); } - - g_list_free (devices); } } @@ -857,19 +852,15 @@ update_trackball_scroll_button (MetaInputSettings *input_settings, } else if (!device) { - GList *l, *devices; + GList *l; - devices = clutter_seat_list_devices (priv->seat); - - for (l = devices; l; l = l->next) + for (l = priv->devices; l; l = l->next) { device = l->data; if (input_settings_class->is_trackball_device (input_settings, device)) input_settings_class->set_scroll_button (input_settings, device, button, button_lock); } - - g_list_free (devices); } } @@ -1588,9 +1579,13 @@ void meta_input_settings_add_device (MetaInputSettings *input_settings, ClutterInputDevice *device) { + MetaInputSettingsPrivate *priv = + meta_input_settings_get_instance_private (input_settings); + if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_LOGICAL) return; + priv->devices = g_list_prepend (priv->devices, device); evaluate_two_finger_scrolling (input_settings, device); apply_device_settings (input_settings, device); @@ -1610,6 +1605,8 @@ meta_input_settings_remove_device (MetaInputSettings *input_settings, if (g_hash_table_remove (priv->two_finger_devices, device) && g_hash_table_size (priv->two_finger_devices) == 0) apply_device_settings (input_settings, NULL); + + priv->devices = g_list_remove (priv->devices, device); } static void @@ -1675,12 +1672,11 @@ static void check_mappable_devices (MetaInputSettings *input_settings) { MetaInputSettingsPrivate *priv; - GList *l, *devices; + GList *l; priv = meta_input_settings_get_instance_private (input_settings); - devices = clutter_seat_list_devices (priv->seat); - for (l = devices; l; l = l->next) + for (l = priv->devices; l; l = l->next) { ClutterInputDevice *device = l->data; @@ -1689,8 +1685,6 @@ check_mappable_devices (MetaInputSettings *input_settings) check_add_mappable_device (input_settings, device); } - - g_list_free (devices); } static void -- GitLab From 1609d1459ef9a6cf43714621e8307a14d9d05072 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 11 Aug 2020 18:33:07 +0200 Subject: [PATCH 53/85] backends/native: Move MetaInputSettings ownership to MetaSeatImpl Together with keymaps and devices, MetaInputSettings will live in the ninth circle of hell with MetaSeatImpl, forever tied to it. Part-of: --- src/backends/meta-input-settings.c | 65 +++++++++++++++- src/backends/native/meta-backend-native.c | 46 +++++------ .../native/meta-input-device-native.c | 6 +- .../native/meta-input-settings-native.c | 78 ++++++++++++++++++- .../native/meta-input-settings-native.h | 3 + src/backends/native/meta-seat-impl.c | 22 ++++-- src/backends/native/meta-seat-impl.h | 3 + 7 files changed, 188 insertions(+), 35 deletions(-) diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 6b878240a10..0b70681aef8 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -111,6 +111,15 @@ enum static guint signals[N_SIGNALS] = { 0 }; +enum +{ + PROP_0, + PROP_SEAT, + N_PROPS, +}; + +static GParamSpec *props[N_PROPS] = { 0 }; + static GSList * meta_input_settings_get_devices (MetaInputSettings *settings, ClutterInputDeviceType type) @@ -152,10 +161,53 @@ meta_input_settings_dispose (GObject *object) g_clear_pointer (&priv->current_tools, g_hash_table_unref); g_clear_pointer (&priv->two_finger_devices, g_hash_table_destroy); + g_clear_object (&priv->seat); G_OBJECT_CLASS (meta_input_settings_parent_class)->dispose (object); } +static void +meta_input_settings_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaInputSettings *input_settings = META_INPUT_SETTINGS (object); + MetaInputSettingsPrivate *priv = + meta_input_settings_get_instance_private (input_settings); + + switch (prop_id) + { + case PROP_SEAT: + priv->seat = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_input_settings_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaInputSettings *input_settings = META_INPUT_SETTINGS (object); + MetaInputSettingsPrivate *priv = + meta_input_settings_get_instance_private (input_settings); + + switch (prop_id) + { + case PROP_SEAT: + g_value_set_object (value, priv->seat); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void settings_device_set_bool_setting (MetaInputSettings *input_settings, ClutterInputDevice *device, @@ -1714,6 +1766,8 @@ meta_input_settings_class_init (MetaInputSettingsClass *klass) object_class->dispose = meta_input_settings_dispose; object_class->constructed = meta_input_settings_constructed; + object_class->set_property = meta_input_settings_set_property; + object_class->get_property = meta_input_settings_get_property; quark_tool_settings = g_quark_from_static_string ("meta-input-settings-tool-settings"); @@ -1725,6 +1779,16 @@ meta_input_settings_class_init (MetaInputSettingsClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_POINTER); + + props[PROP_SEAT] = + g_param_spec_object ("seat", + "Seat", + "Seat", + CLUTTER_TYPE_SEAT, + CLUTTER_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, N_PROPS, props); } static void @@ -1733,7 +1797,6 @@ meta_input_settings_init (MetaInputSettings *settings) MetaInputSettingsPrivate *priv; priv = meta_input_settings_get_instance_private (settings); - priv->seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); priv->mouse_settings = g_settings_new ("org.gnome.desktop.peripherals.mouse"); g_signal_connect (priv->mouse_settings, "changed", diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index 17fb6f67875..bcc9a55ab32 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -163,13 +163,36 @@ update_viewports (MetaBackend *backend) g_object_unref (viewports); } +static void +kbd_a11y_changed_cb (MetaInputSettings *input_settings, + MetaKbdA11ySettings *a11y_settings, + MetaBackend *backend) +{ + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); + ClutterInputDevice *device; + + device = clutter_seat_get_keyboard (seat); + if (device) + meta_input_device_native_apply_kbd_a11y_settings (META_INPUT_DEVICE_NATIVE (device), + a11y_settings); +} + static void meta_backend_native_post_init (MetaBackend *backend) { + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); MetaSettings *settings = meta_backend_get_settings (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + MetaSeatNative *seat = + META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend)); META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend); + backend_native->input_settings = meta_seat_impl_get_input_settings (seat->impl); + g_signal_connect_object (backend_native->input_settings, "kbd-a11y-changed", + G_CALLBACK (kbd_a11y_changed_cb), backend, 0); + if (meta_settings_is_experimental_feature_enabled (settings, META_EXPERIMENTAL_FEATURE_RT_SCHEDULER)) { @@ -235,34 +258,11 @@ meta_backend_native_create_renderer (MetaBackend *backend, return META_RENDERER (renderer_native); } -static void -kbd_a11y_changed_cb (MetaInputSettings *input_settings, - MetaKbdA11ySettings *a11y_settings, - MetaBackend *backend) -{ - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); - ClutterInputDevice *device; - - device = clutter_seat_get_keyboard (seat); - if (device) - meta_input_device_native_apply_kbd_a11y_settings (META_INPUT_DEVICE_NATIVE (device), - a11y_settings); -} - static MetaInputSettings * meta_backend_native_create_input_settings (MetaBackend *backend) { MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); - if (!backend_native->input_settings) - { - backend_native->input_settings = - g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL); - g_signal_connect_object (backend_native->input_settings, "kbd-a11y-changed", - G_CALLBACK (kbd_a11y_changed_cb), backend, 0); - } - return backend_native->input_settings; } diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index fde23231eb6..ff1faedeba2 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -239,10 +239,11 @@ clear_slow_keys (MetaInputDeviceNative *device) static guint get_slow_keys_delay (ClutterInputDevice *device) { + MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); MetaKbdA11ySettings a11y_settings; MetaInputSettings *input_settings; - input_settings = meta_backend_get_input_settings (meta_get_backend ()); + input_settings = meta_seat_impl_get_input_settings (device_native->seat_impl); meta_input_settings_get_kbd_a11y_settings (input_settings, &a11y_settings); /* Settings use int, we use uint, make sure we dont go negative */ return MAX (0, a11y_settings.slowkeys_delay); @@ -335,10 +336,11 @@ stop_slow_keys (ClutterEvent *event, static guint get_debounce_delay (ClutterInputDevice *device) { + MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); MetaKbdA11ySettings a11y_settings; MetaInputSettings *input_settings; - input_settings = meta_backend_get_input_settings (meta_get_backend ()); + input_settings = meta_seat_impl_get_input_settings (device_native->seat_impl); meta_input_settings_get_kbd_a11y_settings (input_settings, &a11y_settings); /* Settings use int, we use uint, make sure we dont go negative */ return MAX (0, a11y_settings.debounce_delay); diff --git a/src/backends/native/meta-input-settings-native.c b/src/backends/native/meta-input-settings-native.c index f16fbd9c10a..c0550f8d16a 100644 --- a/src/backends/native/meta-input-settings-native.c +++ b/src/backends/native/meta-input-settings-native.c @@ -33,6 +33,55 @@ G_DEFINE_TYPE (MetaInputSettingsNative, meta_input_settings_native, META_TYPE_INPUT_SETTINGS) +enum +{ + PROP_0, + PROP_SEAT_IMPL, + N_PROPS, +}; + +static GParamSpec *props[N_PROPS] = { 0 }; + +static void +meta_input_settings_native_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaInputSettingsNative *input_settings_native = + META_INPUT_SETTINGS_NATIVE (object); + + switch (prop_id) + { + case PROP_SEAT_IMPL: + input_settings_native->seat_impl = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_input_settings_native_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaInputSettingsNative *input_settings_native = + META_INPUT_SETTINGS_NATIVE (object); + + switch (prop_id) + { + case PROP_SEAT_IMPL: + g_value_set_object (value, input_settings_native->seat_impl); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void meta_input_settings_native_set_send_events (MetaInputSettings *settings, ClutterInputDevice *device, @@ -409,10 +458,10 @@ meta_input_settings_native_set_keyboard_repeat (MetaInputSettings *settings, guint delay, guint interval) { - ClutterSeat *seat; + MetaInputSettingsNative *input_settings_native; - seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); - meta_seat_impl_set_keyboard_repeat (META_SEAT_NATIVE (seat)->impl, + input_settings_native = META_INPUT_SETTINGS_NATIVE (settings); + meta_seat_impl_set_keyboard_repeat (input_settings_native->seat_impl, enabled, delay, interval); } @@ -698,6 +747,10 @@ static void meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass) { MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = meta_input_settings_native_set_property; + object_class->get_property = meta_input_settings_native_get_property; input_settings_class->set_send_events = meta_input_settings_native_set_send_events; input_settings_class->set_matrix = meta_input_settings_native_set_matrix; @@ -732,9 +785,28 @@ meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass) input_settings_class->has_two_finger_scroll = meta_input_settings_native_has_two_finger_scroll; input_settings_class->is_trackball_device = meta_input_settings_native_is_trackball_device; + + props[PROP_SEAT_IMPL] = + g_param_spec_object ("seat-impl", + "Seat Impl", + "Seat Impl", + META_TYPE_SEAT_IMPL, + CLUTTER_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, N_PROPS, props); } static void meta_input_settings_native_init (MetaInputSettingsNative *settings) { } + +MetaInputSettings * +meta_input_settings_native_new (MetaSeatImpl *seat_impl) +{ + return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, + "seat-impl", seat_impl, + "seat", seat_impl->seat_native, + NULL); +} diff --git a/src/backends/native/meta-input-settings-native.h b/src/backends/native/meta-input-settings-native.h index ee600d5d839..dece62aaa00 100644 --- a/src/backends/native/meta-input-settings-native.h +++ b/src/backends/native/meta-input-settings-native.h @@ -37,6 +37,7 @@ typedef struct _MetaInputSettingsNativeClass MetaInputSettingsNativeClass; struct _MetaInputSettingsNative { MetaInputSettings parent_instance; + MetaSeatImpl *seat_impl; }; struct _MetaInputSettingsNativeClass @@ -46,4 +47,6 @@ struct _MetaInputSettingsNativeClass GType meta_input_settings_native_get_type (void) G_GNUC_CONST; +MetaInputSettings * meta_input_settings_native_new (MetaSeatImpl *seat_impl); + #endif /* META_INPUT_SETTINGS_NATIVE_H */ diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 53e2fb50db4..19092c01d58 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -40,6 +40,7 @@ #include "backends/native/meta-event-native.h" #include "backends/native/meta-input-device-native.h" #include "backends/native/meta-input-device-tool-native.h" +#include "backends/native/meta-input-settings-native.h" #include "backends/native/meta-keymap-native.h" #include "backends/native/meta-virtual-input-device-native.h" #include "clutter/clutter-mutter.h" @@ -1553,7 +1554,7 @@ process_base_event (MetaSeatImpl *seat_impl, struct libinput_device *libinput_device; MetaInputSettings *input_settings; - input_settings = meta_backend_get_input_settings (meta_get_backend ()); + input_settings = seat_impl->input_settings; switch (libinput_event_get_type (event)) { @@ -1635,7 +1636,8 @@ translate_tool_type (struct libinput_tablet_tool *libinput_tool) } static void -input_device_update_tool (ClutterInputDevice *input_device, +input_device_update_tool (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, struct libinput_tablet_tool *libinput_tool) { MetaInputDeviceNative *evdev_device = META_INPUT_DEVICE_NATIVE (input_device); @@ -1665,7 +1667,7 @@ input_device_update_tool (ClutterInputDevice *input_device, clutter_input_device_update_from_tool (input_device, tool); evdev_device->last_tool = tool; - input_settings = meta_backend_get_input_settings (meta_get_backend ()); + input_settings = seat_impl->input_settings; meta_input_settings_notify_tool_change (input_settings, input_device, tool); } } @@ -2239,10 +2241,10 @@ process_device_event (MetaSeatImpl *seat_impl, libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event); if (in) - input_device_update_tool (device, libinput_tool); + input_device_update_tool (seat_impl, device, libinput_tool); notify_proximity (device, time, in); if (!in) - input_device_update_tool (device, NULL); + input_device_update_tool (seat_impl, device, NULL); break; } @@ -2496,6 +2498,8 @@ meta_seat_impl_constructed (GObject *object) udev_unref (udev); + seat_impl->input_settings = meta_input_settings_native_new (seat_impl); + seat_impl->udev_client = g_udev_client_new ((const char *[]) { "input", NULL }); source = meta_event_source_new (seat_impl); @@ -3082,7 +3086,7 @@ meta_seat_impl_notify_kbd_a11y_flags_changed (MetaSeatImpl *seat_impl, { MetaInputSettings *input_settings; - input_settings = meta_backend_get_input_settings (meta_get_backend ()); + input_settings = seat_impl->input_settings; meta_input_settings_notify_kbd_a11y_change (input_settings, new_flags, what_changed); g_signal_emit (seat_impl, signals[KBD_A11Y_FLAGS_CHANGED], 0, @@ -3103,3 +3107,9 @@ meta_seat_impl_notify_bell (MetaSeatImpl *seat_impl) { g_signal_emit (seat_impl, signals[BELL], 0); } + +MetaInputSettings * +meta_seat_impl_get_input_settings (MetaSeatImpl *seat_impl) +{ + return seat_impl->input_settings; +} diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index 49a77298bc7..d04b1ae7f30 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -79,6 +79,7 @@ struct _MetaSeatImpl MetaPointerConstraintImpl *pointer_constraint; MetaKeymapNative *keymap; + MetaInputSettings *input_settings; MetaViewportInfo *viewports; @@ -248,4 +249,6 @@ void meta_seat_impl_notify_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_imp xkb_mod_mask_t new_locked_mods); void meta_seat_impl_notify_bell (MetaSeatImpl *seat_impl); +MetaInputSettings * meta_seat_impl_get_input_settings (MetaSeatImpl *seat_impl); + #endif /* META_SEAT_IMPL_H */ -- GitLab From b789d38f680ec4b547143c66cbe18994b1d06796 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 11 Aug 2020 19:01:12 +0200 Subject: [PATCH 54/85] clutter: Switch to GAsyncQueue for ClutterMainContext event queue We will be moving to having events produced in one thread and consumed in another. Make this an async event queue in preparation for that. Part-of: --- clutter/clutter/clutter-event.c | 20 ++++++-------------- clutter/clutter/clutter-main.c | 25 +++++++++++++++++-------- clutter/clutter/clutter-private.h | 2 +- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/clutter/clutter/clutter-event.c b/clutter/clutter/clutter-event.c index ac1d2cfd349..cc8741221b0 100644 --- a/clutter/clutter/clutter-event.c +++ b/clutter/clutter/clutter-event.c @@ -1445,14 +1445,11 @@ ClutterEvent * clutter_event_get (void) { ClutterMainContext *context = _clutter_context_get_default (); + ClutterEvent *event; - if (context->events_queue == NULL) - return NULL; + event = g_async_queue_try_pop (context->events_queue); - if (g_queue_is_empty (context->events_queue)) - return NULL; - - return g_queue_pop_tail (context->events_queue); + return event; } void @@ -1463,9 +1460,6 @@ _clutter_event_push (const ClutterEvent *event, g_assert (context != NULL); - if (context->events_queue == NULL) - context->events_queue = g_queue_new (); - if (do_copy) { ClutterEvent *copy; @@ -1474,7 +1468,8 @@ _clutter_event_push (const ClutterEvent *event, event = copy; } - g_queue_push_head (context->events_queue, (gpointer) event); + g_async_queue_push (context->events_queue, (gpointer) event); + g_main_context_wakeup (NULL); } /** @@ -1511,10 +1506,7 @@ clutter_events_pending (void) g_return_val_if_fail (context != NULL, FALSE); - if (context->events_queue == NULL) - return FALSE; - - return g_queue_is_empty (context->events_queue) == FALSE; + return g_async_queue_length (context->events_queue) > 0; } /** diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index 706fb430ac3..035ed944413 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -697,6 +697,8 @@ _clutter_context_get_default (void) ctx->settings = clutter_settings_get_default (); _clutter_settings_set_backend (ctx->settings, ctx->backend); + ctx->events_queue = g_async_queue_new (); + ctx->last_repaint_id = 1; } @@ -2286,15 +2288,22 @@ void _clutter_clear_events_queue (void) { ClutterMainContext *context = _clutter_context_get_default (); + ClutterEvent *event; + GAsyncQueue *events_queue; - if (context->events_queue != NULL) - { - g_queue_foreach (context->events_queue, - (GFunc) clutter_event_free, - NULL); - g_queue_free (context->events_queue); - context->events_queue = NULL; - } + if (!context->events_queue) + return; + + g_async_queue_lock (context->events_queue); + + while ((event = g_async_queue_try_pop_unlocked (context->events_queue))) + clutter_event_free (event); + + events_queue = context->events_queue; + context->events_queue = NULL; + + g_async_queue_unlock (events_queue); + g_async_queue_unref (events_queue); } /** diff --git a/clutter/clutter/clutter-private.h b/clutter/clutter/clutter-private.h index 08a8c3f8c27..4c6f32282b9 100644 --- a/clutter/clutter/clutter-private.h +++ b/clutter/clutter/clutter-private.h @@ -121,7 +121,7 @@ struct _ClutterMainContext ClutterStageManager *stage_manager; /* the main event queue */ - GQueue *events_queue; + GAsyncQueue *events_queue; /* the event filters added via clutter_event_add_filter. these are * ordered from least recently added to most recently added */ -- GitLab From e76a7f43e02d360b624425816181a28144b61faf Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 11 Aug 2020 20:21:08 +0200 Subject: [PATCH 55/85] backends/native: Protect MetaBarrierManagerNative While barriers will be added from the main thread, the native barrier manager will sit close to the MetaSeatImpl in its own thread. Add the necessary locking so that we can pass MetaBarrierImplNative from the UI thread to the input thread, and ensure the MetaBarrier signals are still emitted in the UI thread. Part-of: --- src/backends/native/meta-barrier-native.c | 64 ++++++++++++++++++++--- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/src/backends/native/meta-barrier-native.c b/src/backends/native/meta-barrier-native.c index bdb006fb139..8db73ee0689 100644 --- a/src/backends/native/meta-barrier-native.c +++ b/src/backends/native/meta-barrier-native.c @@ -43,6 +43,7 @@ struct _MetaBarrierManagerNative { GHashTable *barriers; + GMutex mutex; }; typedef enum @@ -77,6 +78,7 @@ struct _MetaBarrierImplNative int trigger_serial; guint32 last_event_time; MetaBarrierDirection blocked_dir; + GMainContext *main_context; }; G_DEFINE_TYPE (MetaBarrierImplNative, @@ -340,6 +342,49 @@ typedef struct _MetaBarrierEventData float dy; } MetaBarrierEventData; +typedef struct +{ + MetaBarrierEvent *event; + MetaBarrier *barrier; + MetaBarrierState state; +} MetaBarrierIdleData; + +static gboolean +emit_event_idle (MetaBarrierIdleData *idle_data) +{ + if (idle_data->state == META_BARRIER_STATE_HELD) + _meta_barrier_emit_hit_signal (idle_data->barrier, idle_data->event); + else + _meta_barrier_emit_left_signal (idle_data->barrier, idle_data->event); + + meta_barrier_event_unref (idle_data->event); + + return G_SOURCE_REMOVE; +} + +static void +queue_event (MetaBarrierImplNative *self, + MetaBarrierEvent *event) +{ + MetaBarrierIdleData *idle_data; + GSource *source; + + idle_data = g_new0 (MetaBarrierIdleData, 1); + idle_data->state = self->state; + idle_data->barrier = self->barrier; + idle_data->event = event; + + source = g_idle_source_new (); + g_source_set_priority (source, G_PRIORITY_HIGH); + g_source_set_callback (source, + (GSourceFunc) emit_event_idle, + idle_data, + g_free); + + g_source_attach (source, self->main_context); + g_source_unref (source); +} + static void emit_barrier_event (MetaBarrierImplNative *self, guint32 time, @@ -350,7 +395,6 @@ emit_barrier_event (MetaBarrierImplNative *self, float dx, float dy) { - MetaBarrier *barrier = self->barrier; MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent); MetaBarrierState old_state = self->state; @@ -389,12 +433,7 @@ emit_barrier_event (MetaBarrierImplNative *self, self->last_event_time = time; - if (self->state == META_BARRIER_STATE_HELD) - _meta_barrier_emit_hit_signal (barrier, event); - else - _meta_barrier_emit_left_signal (barrier, event); - - meta_barrier_event_unref (event); + queue_event (self, event); } static void @@ -479,6 +518,8 @@ meta_barrier_manager_native_process (MetaBarrierManagerNative *manager, if (!clutter_input_device_get_coords (device, NULL, &prev_pos)) return; + g_mutex_lock (&manager->mutex); + prev_x = prev_pos.x; prev_y = prev_pos.y; @@ -523,6 +564,8 @@ meta_barrier_manager_native_process (MetaBarrierManagerNative *manager, g_hash_table_foreach (manager->barriers, maybe_emit_barrier_event, &barrier_event_data); + + g_mutex_unlock (&manager->mutex); } static gboolean @@ -549,7 +592,10 @@ _meta_barrier_impl_native_destroy (MetaBarrierImpl *impl) { MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl); + g_mutex_lock (&self->manager->mutex); g_hash_table_remove (self->manager->barriers, self); + g_mutex_unlock (&self->manager->mutex); + g_main_context_unref (self->main_context); self->is_active = FALSE; } @@ -565,10 +611,13 @@ meta_barrier_impl_native_new (MetaBarrier *barrier) self->barrier = barrier; self->is_active = TRUE; + self->main_context = g_main_context_ref_thread_default (); manager = meta_seat_native_get_barrier_manager (META_SEAT_NATIVE (seat)); self->manager = manager; + g_mutex_lock (&manager->mutex); g_hash_table_add (manager->barriers, self); + g_mutex_unlock (&manager->mutex); return META_BARRIER_IMPL (self); } @@ -596,6 +645,7 @@ meta_barrier_manager_native_new (void) manager = g_new0 (MetaBarrierManagerNative, 1); manager->barriers = g_hash_table_new (NULL, NULL); + g_mutex_init (&manager->mutex); return manager; } -- GitLab From cf45050cba4c8387e2ad4cf1edb853612e25c2ee Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 12 Aug 2020 10:43:48 +0200 Subject: [PATCH 56/85] backends/native: Surround device state queries/updates with RW lock Wrap all keyboard state updates, and all pointer/stylus/touch cursor position with a write lock, and ::query_state() (The only entrypoint to this state from other threads) with a read lock. The principle is that query_state may be called from different threads (UI so far, but maybe KMS too in the future), while the input thread may (or may not) be updating it. This state is fetched "atomically" (eg. x/y will be consistently old or new, if the input thread were updating it at the same time). There's other places deep in backends/native that read this state, they all will run in the input thread, so they count as "other readers" to the other thread. Those changes are already mutually exclusive with updates, so they don't explicitly need the RW lock. Part-of: --- .../native/meta-input-device-native.c | 4 ++ src/backends/native/meta-seat-impl.c | 51 ++++++++++++++++--- src/backends/native/meta-seat-impl.h | 1 + 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index ff1faedeba2..240392b86f1 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -435,6 +435,8 @@ update_internal_xkb_state (MetaInputDeviceNative *device, xkb_mod_mask_t group_mods; struct xkb_state *xkb_state; + g_rw_lock_writer_lock (&seat_impl->state_lock); + xkb_state = meta_seat_impl_get_xkb_state (seat_impl); depressed_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED); latched_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LATCHED); @@ -457,6 +459,8 @@ update_internal_xkb_state (MetaInputDeviceNative *device, locked_mods, 0, 0, group_mods); notify_stickykeys_mask (device); + + g_rw_lock_writer_unlock (&seat_impl->state_lock); } static void diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 19092c01d58..32322231213 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -435,6 +435,8 @@ new_absolute_motion_event (MetaSeatImpl *seat_impl, clutter_event_set_device (event, seat_impl->core_pointer); clutter_event_set_source_device (event, input_device); + g_rw_lock_writer_lock (&seat_impl->state_lock); + if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) { MetaInputDeviceNative *device_native = @@ -458,6 +460,8 @@ new_absolute_motion_event (MetaSeatImpl *seat_impl, seat_impl->pointer_y = y; } + g_rw_lock_writer_unlock (&seat_impl->state_lock); + return event; } @@ -2031,10 +2035,14 @@ process_device_event (MetaSeatImpl *seat_impl, y = libinput_event_touch_get_y_transformed (touch_event, stage_height); + g_rw_lock_writer_lock (&seat_impl->state_lock); + touch_state = meta_seat_impl_acquire_touch_state (seat_impl, seat_slot); touch_state->coords.x = x; touch_state->coords.y = y; + g_rw_lock_writer_unlock (&seat_impl->state_lock); + meta_seat_impl_notify_touch_event (seat_impl, device, CLUTTER_TOUCH_BEGIN, time_us, @@ -2066,7 +2074,10 @@ process_device_event (MetaSeatImpl *seat_impl, touch_state->seat_slot, touch_state->coords.x, touch_state->coords.y); + + g_rw_lock_writer_lock (&seat_impl->state_lock); meta_seat_impl_release_touch_state (seat_impl, seat_slot); + g_rw_lock_writer_unlock (&seat_impl->state_lock); break; } @@ -2093,13 +2104,18 @@ process_device_event (MetaSeatImpl *seat_impl, y = libinput_event_touch_get_y_transformed (touch_event, stage_height); + g_rw_lock_writer_lock (&seat_impl->state_lock); touch_state = meta_seat_impl_lookup_touch_state (seat_impl, seat_slot); + if (touch_state) + { + touch_state->coords.x = x; + touch_state->coords.y = y; + } + g_rw_lock_writer_unlock (&seat_impl->state_lock); + if (!touch_state) break; - touch_state->coords.x = x; - touch_state->coords.y = y; - meta_seat_impl_notify_touch_event (seat_impl, device, CLUTTER_TOUCH_UPDATE, time_us, @@ -2611,6 +2627,8 @@ meta_seat_impl_finalize (GObject *object) g_free (seat_impl->seat_id); + g_rw_lock_clear (&seat_impl->state_lock); + G_OBJECT_CLASS (meta_seat_impl_parent_class)->finalize (object); } @@ -2656,6 +2674,9 @@ meta_seat_impl_query_state (MetaSeatImpl *seat_impl, ClutterModifierType *modifiers) { MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); + gboolean retval = FALSE; + + g_rw_lock_reader_lock (&seat_impl->state_lock); if (sequence) { @@ -2665,7 +2686,7 @@ meta_seat_impl_query_state (MetaSeatImpl *seat_impl, slot = meta_event_native_sequence_get_slot (sequence); touch_state = meta_seat_impl_lookup_touch_state (seat_impl, slot); if (!touch_state) - return FALSE; + goto out; if (coords) { @@ -2676,7 +2697,7 @@ meta_seat_impl_query_state (MetaSeatImpl *seat_impl, if (modifiers) *modifiers = meta_xkb_translate_modifiers (seat_impl->xkb, 0); - return TRUE; + retval = TRUE; } else { @@ -2692,8 +2713,12 @@ meta_seat_impl_query_state (MetaSeatImpl *seat_impl, seat_impl->button_state); } - return TRUE; + retval = TRUE; } + + out: + g_rw_lock_reader_unlock (&seat_impl->state_lock); + return retval; } static void @@ -2764,6 +2789,8 @@ meta_seat_impl_class_init (MetaSeatImplClass *klass) static void meta_seat_impl_init (MetaSeatImpl *seat_impl) { + g_rw_lock_init (&seat_impl->state_lock); + seat_impl->repeat = TRUE; seat_impl->repeat_delay = 250; /* ms */ seat_impl->repeat_interval = 33; /* ms */ @@ -2803,6 +2830,8 @@ meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl) xkb_mod_mask_t locked_mods; struct xkb_keymap *xkb_keymap; + g_rw_lock_writer_lock (&seat_impl->state_lock); + xkb_keymap = meta_keymap_native_get_keyboard_map (seat_impl->keymap); latched_mods = xkb_state_serialize_mods (seat_impl->xkb, @@ -2826,6 +2855,8 @@ meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl) xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL); meta_seat_impl_sync_leds (seat_impl); + + g_rw_lock_writer_unlock (&seat_impl->state_lock); } /** @@ -2941,6 +2972,8 @@ meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); + g_rw_lock_writer_lock (&seat_impl->state_lock); + state = seat_impl->xkb; depressed_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED); @@ -2950,6 +2983,8 @@ meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx); seat_impl->layout_idx = idx; + + g_rw_lock_writer_unlock (&seat_impl->state_lock); } /** @@ -2982,6 +3017,8 @@ meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); + g_rw_lock_writer_lock (&seat_impl->state_lock); + keymap = seat_impl->keymap; xkb_keymap = meta_keymap_native_get_keyboard_map (keymap); @@ -3009,6 +3046,8 @@ meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, group_mods); meta_seat_impl_sync_leds (seat_impl); + + g_rw_lock_writer_unlock (&seat_impl->state_lock); } /** diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index d04b1ae7f30..027fd624bf2 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -58,6 +58,7 @@ struct _MetaSeatImpl char *seat_id; MetaEventSource *event_source; struct libinput *libinput; + GRWLock state_lock; GSList *devices; -- GitLab From 40665b0fb168e28292c26aeed4619abd62e0c35f Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 12 Aug 2020 11:16:39 +0200 Subject: [PATCH 57/85] backends/native: Seal MetaKeymapNative xkb usage Don't let the vfuncs (meant to be called from the UI thread) deal with xkb state itself. Instead store the current state in struct fields, which is then fetched in vfuncs. This makes the keymap able to be used from the UI thread, while being maintained by the input thread. Same caveats apply than clutter_seat_query_state(), you are asking for the most up-to-date state, but it still may be changing under your feet. Part-of: --- src/backends/native/meta-keymap-native.c | 45 ++++++++++++++---------- src/backends/native/meta-keymap-native.h | 1 + src/backends/native/meta-seat-impl.c | 3 ++ 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c index d1990353229..ee56443b584 100644 --- a/src/backends/native/meta-keymap-native.c +++ b/src/backends/native/meta-keymap-native.c @@ -36,6 +36,8 @@ struct _MetaKeymapNative ClutterKeymap parent_instance; struct xkb_keymap *keymap; + gboolean num_lock; + gboolean caps_lock; }; G_DEFINE_TYPE (MetaKeymapNative, meta_keymap_native, @@ -54,31 +56,17 @@ meta_keymap_native_finalize (GObject *object) static gboolean meta_keymap_native_get_num_lock_state (ClutterKeymap *keymap) { - struct xkb_state *xkb_state; - ClutterSeat *seat; - - seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); - xkb_state = meta_seat_impl_get_xkb_state (META_SEAT_NATIVE (seat)->impl); + MetaKeymapNative *keymap_native = META_KEYMAP_NATIVE (keymap); - return xkb_state_mod_name_is_active (xkb_state, - XKB_MOD_NAME_NUM, - XKB_STATE_MODS_LATCHED | - XKB_STATE_MODS_LOCKED); + return keymap_native->num_lock; } static gboolean meta_keymap_native_get_caps_lock_state (ClutterKeymap *keymap) { - struct xkb_state *xkb_state; - ClutterSeat *seat; - - seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); - xkb_state = meta_seat_impl_get_xkb_state (META_SEAT_NATIVE (seat)->impl); + MetaKeymapNative *keymap_native = META_KEYMAP_NATIVE (keymap); - return xkb_state_mod_name_is_active (xkb_state, - XKB_MOD_NAME_CAPS, - XKB_STATE_MODS_LATCHED | - XKB_STATE_MODS_LOCKED); + return keymap_native->caps_lock; } static PangoDirection @@ -134,3 +122,24 @@ meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap) { return keymap->keymap; } + +void +meta_keymap_native_update (MetaKeymapNative *keymap) +{ + struct xkb_state *xkb_state; + ClutterSeat *seat; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + xkb_state = meta_seat_impl_get_xkb_state (META_SEAT_NATIVE (seat)->impl); + + keymap->num_lock = + xkb_state_mod_name_is_active (xkb_state, + XKB_MOD_NAME_NUM, + XKB_STATE_MODS_LATCHED | + XKB_STATE_MODS_LOCKED); + keymap->caps_lock = + xkb_state_mod_name_is_active (xkb_state, + XKB_MOD_NAME_CAPS, + XKB_STATE_MODS_LATCHED | + XKB_STATE_MODS_LOCKED); +} diff --git a/src/backends/native/meta-keymap-native.h b/src/backends/native/meta-keymap-native.h index 27364984ce3..8b276df5d6f 100644 --- a/src/backends/native/meta-keymap-native.h +++ b/src/backends/native/meta-keymap-native.h @@ -32,5 +32,6 @@ G_DECLARE_FINAL_TYPE (MetaKeymapNative, meta_keymap_native, void meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap, struct xkb_keymap *xkb_keymap); struct xkb_keymap * meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap); +void meta_keymap_native_update (MetaKeymapNative *keymap); #endif /* META_KEYMAP_NATIVE_H */ diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 32322231213..d7cdd8243c7 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -2855,6 +2855,7 @@ meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl) xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL); meta_seat_impl_sync_leds (seat_impl); + meta_keymap_native_update (seat_impl->keymap); g_rw_lock_writer_unlock (&seat_impl->state_lock); } @@ -2981,6 +2982,7 @@ meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED); xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx); + meta_keymap_native_update (seat_impl->keymap); seat_impl->layout_idx = idx; @@ -3046,6 +3048,7 @@ meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, group_mods); meta_seat_impl_sync_leds (seat_impl); + meta_keymap_native_update (seat_impl->keymap); g_rw_lock_writer_unlock (&seat_impl->state_lock); } -- GitLab From 23f95348fd73f2c19a0e9aa6c28712dfc9538a2a Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 12 Aug 2020 12:47:07 +0200 Subject: [PATCH 58/85] backends/native: Shuffle xkb_keymap creation Push it a little bit down to the MetaSeatNative. As both the UI thread and the input thread are interested in dealing with the xkb_keymap and it is not meant to be used in different threads, keep 2 separate copies around. The keyboard map will always be set from the UI thread, so the xkb_keymap owned by the MetaSeatNative (owned by the UI thread) can be considered canonical. Part-of: --- src/backends/native/meta-backend-native.c | 30 ++---------- src/backends/native/meta-seat-impl.c | 44 +++++------------ src/backends/native/meta-seat-impl.h | 4 -- src/backends/native/meta-seat-native.c | 59 ++++++++++++++++++++--- src/backends/native/meta-seat-native.h | 8 ++- 5 files changed, 74 insertions(+), 71 deletions(-) diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index bcc9a55ab32..c7809a8b583 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -187,12 +187,12 @@ meta_backend_native_post_init (MetaBackend *backend) MetaSeatNative *seat = META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend)); - META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend); - backend_native->input_settings = meta_seat_impl_get_input_settings (seat->impl); g_signal_connect_object (backend_native->input_settings, "kbd-a11y-changed", G_CALLBACK (kbd_a11y_changed_cb), backend, 0); + META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend); + if (meta_settings_is_experimental_feature_enabled (settings, META_EXPERIMENTAL_FEATURE_RT_SCHEDULER)) { @@ -286,35 +286,13 @@ meta_backend_native_set_keymap (MetaBackend *backend, const char *options) { ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - struct xkb_rule_names names; - struct xkb_keymap *keymap; - struct xkb_context *context; ClutterSeat *seat; - names.rules = DEFAULT_XKB_RULES_FILE; - names.model = DEFAULT_XKB_MODEL; - names.layout = layouts; - names.variant = variants; - names.options = options; - - context = meta_create_xkb_context (); - keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS); - xkb_context_unref (context); - - if (keymap == NULL) - { - g_warning ("Unable to load configured keymap: rules=%s, model=%s, layout=%s, variant=%s, options=%s", - DEFAULT_XKB_RULES_FILE, DEFAULT_XKB_MODEL, layouts, - variants, options); - return; - } - seat = clutter_backend_get_default_seat (clutter_backend); - meta_seat_native_set_keyboard_map (META_SEAT_NATIVE (seat), keymap); + meta_seat_native_set_keyboard_map (META_SEAT_NATIVE (seat), + layouts, variants, options); meta_backend_notify_keymap_changed (backend); - - xkb_keymap_unref (keymap); } static struct xkb_keymap * diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index d7cdd8243c7..df53e55f5a4 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -2826,19 +2826,23 @@ meta_seat_impl_set_device_callbacks (MetaOpenDeviceCallback open_callback, void meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl) { - xkb_mod_mask_t latched_mods; - xkb_mod_mask_t locked_mods; + xkb_mod_mask_t latched_mods = 0; + xkb_mod_mask_t locked_mods = 0; struct xkb_keymap *xkb_keymap; g_rw_lock_writer_lock (&seat_impl->state_lock); xkb_keymap = meta_keymap_native_get_keyboard_map (seat_impl->keymap); - latched_mods = xkb_state_serialize_mods (seat_impl->xkb, - XKB_STATE_MODS_LATCHED); - locked_mods = xkb_state_serialize_mods (seat_impl->xkb, - XKB_STATE_MODS_LOCKED); - xkb_state_unref (seat_impl->xkb); + if (seat_impl->xkb) + { + latched_mods = xkb_state_serialize_mods (seat_impl->xkb, + XKB_STATE_MODS_LATCHED); + locked_mods = xkb_state_serialize_mods (seat_impl->xkb, + XKB_STATE_MODS_LOCKED); + xkb_state_unref (seat_impl->xkb); + } + seat_impl->xkb = xkb_state_new (xkb_keymap); xkb_state_update_mask (seat_impl->xkb, @@ -2932,6 +2936,7 @@ meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat_impl, MetaKeymapNative *keymap; g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); + g_return_if_fail (xkb_keymap != NULL); keymap = seat_impl->keymap; meta_keymap_native_set_keyboard_map (keymap, xkb_keymap); @@ -2939,22 +2944,6 @@ meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat_impl, meta_seat_impl_update_xkb_state (seat_impl); } -/** - * meta_seat_impl_get_keyboard_map: (skip) - * @seat: the #ClutterSeat created by the evdev backend - * - * Retrieves the #xkb_keymap in use by the evdev backend. - * - * Return value: the #xkb_keymap. - */ -struct xkb_keymap * -meta_seat_impl_get_keyboard_map (MetaSeatImpl *seat_impl) -{ - g_return_val_if_fail (META_IS_SEAT_IMPL (seat_impl), NULL); - - return xkb_state_get_keymap (seat_impl->xkb); -} - /** * meta_seat_impl_set_keyboard_layout_index: (skip) * @seat: the #ClutterSeat created by the evdev backend @@ -2989,15 +2978,6 @@ meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, g_rw_lock_writer_unlock (&seat_impl->state_lock); } -/** - * meta_seat_impl_get_keyboard_layout_index: (skip) - */ -xkb_layout_index_t -meta_seat_impl_get_keyboard_layout_index (MetaSeatImpl *seat_impl) -{ - return seat_impl->layout_idx; -} - /** * meta_seat_impl_set_keyboard_numlock: (skip) * @seat: the #ClutterSeat created by the evdev backend diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index 027fd624bf2..a62af83f5df 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -206,13 +206,9 @@ struct xkb_state * meta_seat_impl_get_xkb_state (MetaSeatImpl *seat_impl); void meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat_impl, struct xkb_keymap *keymap); -struct xkb_keymap * meta_seat_impl_get_keyboard_map (MetaSeatImpl *seat_impl); - void meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, xkb_layout_index_t idx); -xkb_layout_index_t meta_seat_impl_get_keyboard_layout_index (MetaSeatImpl *seat_impl); - void meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, gboolean numlock_state); diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 00b3c36ba66..88654f7b5a0 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -29,6 +29,7 @@ #include "backends/native/meta-seat-native.h" #include "backends/meta-cursor-tracker-private.h" +#include "backends/meta-keymap-utils.h" #include "backends/native/meta-barrier-native.h" #include "backends/native/meta-event-native.h" #include "backends/native/meta-input-device-native.h" @@ -170,6 +171,8 @@ meta_seat_native_constructed (GObject *object) seat->core_pointer = meta_seat_impl_get_pointer (seat->impl); seat->core_keyboard = meta_seat_impl_get_keyboard (seat->impl); + meta_seat_native_set_keyboard_map (seat, "us", "", ""); + if (G_OBJECT_CLASS (meta_seat_native_parent_class)->constructed) G_OBJECT_CLASS (meta_seat_native_parent_class)->constructed (object); } @@ -220,6 +223,8 @@ meta_seat_native_finalize (GObject *object) MetaSeatNative *seat = META_SEAT_NATIVE (object); GList *iter; + if (seat->xkb_keymap) + xkb_keymap_unref (seat->xkb_keymap); g_clear_object (&seat->core_pointer); g_clear_object (&seat->core_keyboard); g_clear_object (&seat->impl); @@ -506,6 +511,28 @@ meta_seat_native_reclaim_devices (MetaSeatNative *seat) seat->released = FALSE; } +static struct xkb_keymap * +create_keymap (const char *layouts, + const char *variants, + const char *options) +{ + struct xkb_rule_names names; + struct xkb_keymap *keymap; + struct xkb_context *context; + + names.rules = DEFAULT_XKB_RULES_FILE; + names.model = DEFAULT_XKB_MODEL; + names.layout = layouts; + names.variant = variants; + names.options = options; + + context = meta_create_xkb_context (); + keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS); + xkb_context_unref (context); + + return keymap; +} + /** * meta_seat_native_set_keyboard_map: (skip) * @seat: the #ClutterSeat created by the evdev backend @@ -517,13 +544,30 @@ meta_seat_native_reclaim_devices (MetaSeatNative *seat) * is pressed when calling this function. */ void -meta_seat_native_set_keyboard_map (MetaSeatNative *seat, - struct xkb_keymap *xkb_keymap) +meta_seat_native_set_keyboard_map (MetaSeatNative *seat, + const char *layouts, + const char *variants, + const char *options) { - g_return_if_fail (META_IS_SEAT_NATIVE (seat)); - g_return_if_fail (xkb_keymap != NULL); + struct xkb_keymap *keymap, *impl_keymap; + + keymap = create_keymap (layouts, variants, options); + impl_keymap = create_keymap (layouts, variants, options); + + if (keymap == NULL) + { + g_warning ("Unable to load configured keymap: rules=%s, model=%s, layout=%s, variant=%s, options=%s", + DEFAULT_XKB_RULES_FILE, DEFAULT_XKB_MODEL, layouts, + variants, options); + return; + } + + if (seat->xkb_keymap) + xkb_keymap_unref (seat->xkb_keymap); + seat->xkb_keymap = keymap; - meta_seat_impl_set_keyboard_map (seat->impl, xkb_keymap); + meta_seat_impl_set_keyboard_map (seat->impl, impl_keymap); + xkb_keymap_unref (impl_keymap); } /** @@ -539,7 +583,7 @@ meta_seat_native_get_keyboard_map (MetaSeatNative *seat) { g_return_val_if_fail (META_IS_SEAT_NATIVE (seat), NULL); - return meta_seat_impl_get_keyboard_map (seat->impl); + return seat->xkb_keymap; } /** @@ -555,6 +599,7 @@ meta_seat_native_set_keyboard_layout_index (MetaSeatNative *seat, { g_return_if_fail (META_IS_SEAT_NATIVE (seat)); + seat->xkb_layout_index = idx; meta_seat_impl_set_keyboard_layout_index (seat->impl, idx); } @@ -564,7 +609,7 @@ meta_seat_native_set_keyboard_layout_index (MetaSeatNative *seat, xkb_layout_index_t meta_seat_native_get_keyboard_layout_index (MetaSeatNative *seat) { - return meta_seat_impl_get_keyboard_layout_index (seat->impl); + return seat->xkb_layout_index; } /** diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h index 84eb8bb7e64..787b2cc2b67 100644 --- a/src/backends/native/meta-seat-native.h +++ b/src/backends/native/meta-seat-native.h @@ -46,6 +46,8 @@ struct _MetaSeatNative char *seat_id; GList *devices; + struct xkb_keymap *xkb_keymap; + xkb_layout_index_t xkb_layout_index; ClutterInputDevice *core_pointer; ClutterInputDevice *core_keyboard; @@ -93,8 +95,10 @@ void meta_seat_native_set_device_callbacks (MetaOpenDeviceCallback open_callba void meta_seat_native_release_devices (MetaSeatNative *seat); void meta_seat_native_reclaim_devices (MetaSeatNative *seat); -void meta_seat_native_set_keyboard_map (MetaSeatNative *seat, - struct xkb_keymap *keymap); +void meta_seat_native_set_keyboard_map (MetaSeatNative *seat, + const char *layouts, + const char *variants, + const char *options); struct xkb_keymap * meta_seat_native_get_keyboard_map (MetaSeatNative *seat); -- GitLab From f7fbd6ea6f8b6486cd3738d869f45d18f0f585b9 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 26 Nov 2020 23:10:25 +0100 Subject: [PATCH 59/85] backends: Handle numlock saving/restoring directly in backends Simplify the handling of numlock state, so it can be entirely handled within the input thread. Since the saving/restoring is triggered inside each backend code, there's no need anymore for meta_backend_set_numlock(). Part-of: --- src/backends/meta-backend-private.h | 3 - src/backends/meta-backend.c | 29 ----- src/backends/meta-input-settings-private.h | 5 +- src/backends/meta-input-settings.c | 23 ++-- src/backends/native/meta-backend-native.c | 13 --- src/backends/native/meta-seat-impl.c | 117 +++++++++++---------- src/backends/native/meta-seat-impl.h | 3 - src/backends/native/meta-seat-native.c | 14 --- src/backends/native/meta-seat-native.h | 3 - src/backends/x11/meta-backend-x11.c | 36 ++++--- src/backends/x11/meta-keymap-x11.c | 17 +++ 11 files changed, 111 insertions(+), 152 deletions(-) diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index 3d32f05a397..b4dc5de10c1 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -100,9 +100,6 @@ struct _MetaBackendClass void (* update_screen_size) (MetaBackend *backend, int width, int height); void (* select_stage_events) (MetaBackend *backend); - void (* set_numlock) (MetaBackend *backend, - gboolean numlock_state); - void (* set_pointer_constraint) (MetaBackend *backend, MetaPointerConstraint *constraint); }; diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index ba964c58b76..fb05e078c77 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -157,7 +157,6 @@ struct _MetaBackendPrivate gboolean is_pointer_position_initialized; guint device_update_idle_id; - gulong keymap_state_changed_id; GHashTable *device_monitors; @@ -198,16 +197,6 @@ meta_backend_finalize (GObject *object) MetaBackend *backend = META_BACKEND (object); MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); - if (priv->keymap_state_changed_id) - { - ClutterSeat *seat; - ClutterKeymap *keymap; - - seat = clutter_backend_get_default_seat (priv->clutter_backend); - keymap = clutter_seat_get_keymap (seat); - g_clear_signal_handler (&priv->keymap_state_changed_id, keymap); - } - g_list_free_full (priv->gpus, g_object_unref); g_clear_object (&priv->current_device); @@ -579,7 +568,6 @@ meta_backend_real_post_init (MetaBackend *backend) { MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); ClutterSeat *seat = clutter_backend_get_default_seat (priv->clutter_backend); - ClutterKeymap *keymap = clutter_seat_get_keymap (seat); priv->stage = meta_stage_new (backend); clutter_actor_realize (priv->stage); @@ -602,15 +590,6 @@ meta_backend_real_post_init (MetaBackend *backend) priv->input_settings = meta_backend_create_input_settings (backend); - if (priv->input_settings) - { - priv->keymap_state_changed_id = - g_signal_connect_swapped (keymap, "state-changed", - G_CALLBACK (meta_input_settings_maybe_save_numlock_state), - priv->input_settings); - meta_input_settings_maybe_restore_numlock_state (priv->input_settings); - } - priv->input_mapper = meta_input_mapper_new (); g_signal_connect (priv->input_mapper, "device-mapped", G_CALLBACK (input_mapper_device_mapped_cb), backend); @@ -1357,14 +1336,6 @@ meta_backend_lock_layout_group (MetaBackend *backend, META_BACKEND_GET_CLASS (backend)->lock_layout_group (backend, idx); } -void -meta_backend_set_numlock (MetaBackend *backend, - gboolean numlock_state) -{ - META_BACKEND_GET_CLASS (backend)->set_numlock (backend, numlock_state); -} - - /** * meta_backend_get_stage: * @backend: A #MetaBackend diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h index 639bede2265..10de61d7832 100644 --- a/src/backends/meta-input-settings-private.h +++ b/src/backends/meta-input-settings-private.h @@ -173,8 +173,9 @@ struct _MetaInputSettingsClass ClutterInputDevice *device); }; -void meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings); -void meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings); +void meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings, + gboolean numlock_state); +gboolean meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings); void meta_input_settings_set_device_matrix (MetaInputSettings *input_settings, ClutterInputDevice *device, diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 0b70681aef8..5780fb9dee4 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -1161,8 +1161,6 @@ meta_input_settings_changed_cb (GSettings *settings, strcmp (key, "repeat-interval") == 0 || strcmp (key, "delay") == 0) update_keyboard_repeat (input_settings); - else if (strcmp (key, "remember-numlock-state") == 0) - meta_input_settings_maybe_save_numlock_state (input_settings); } } @@ -1838,41 +1836,34 @@ meta_input_settings_init (MetaInputSettings *settings) } void -meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings) +meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings, + gboolean numlock_state) { MetaInputSettingsPrivate *priv; - ClutterSeat *seat; - ClutterKeymap *keymap; - gboolean numlock_state; priv = meta_input_settings_get_instance_private (input_settings); if (!g_settings_get_boolean (priv->keyboard_settings, "remember-numlock-state")) return; - seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); - keymap = clutter_seat_get_keymap (seat); - numlock_state = clutter_keymap_get_num_lock_state (keymap); - if (numlock_state == g_settings_get_boolean (priv->keyboard_settings, "numlock-state")) return; g_settings_set_boolean (priv->keyboard_settings, "numlock-state", numlock_state); } -void +gboolean meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings) { MetaInputSettingsPrivate *priv; - gboolean numlock_state; + gboolean numlock_state = FALSE; priv = meta_input_settings_get_instance_private (input_settings); - if (!g_settings_get_boolean (priv->keyboard_settings, "remember-numlock-state")) - return; + if (g_settings_get_boolean (priv->keyboard_settings, "remember-numlock-state")) + numlock_state = g_settings_get_boolean (priv->keyboard_settings, "numlock-state"); - numlock_state = g_settings_get_boolean (priv->keyboard_settings, "numlock-state"); - meta_backend_set_numlock (meta_get_backend (), numlock_state); + return numlock_state; } void diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index c7809a8b583..a78c0866f6e 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -332,18 +332,6 @@ meta_backend_native_lock_layout_group (MetaBackend *backend, meta_backend_notify_keymap_layout_group_changed (backend, idx); } -static void -meta_backend_native_set_numlock (MetaBackend *backend, - gboolean numlock_state) -{ - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - ClutterSeat *seat; - - seat = clutter_backend_get_default_seat (clutter_backend); - meta_seat_native_set_keyboard_numlock (META_SEAT_NATIVE (seat), - numlock_state); -} - static void meta_backend_native_set_pointer_constraint (MetaBackend *backend, MetaPointerConstraint *constraint) @@ -576,7 +564,6 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass) backend_class->get_keymap_layout_group = meta_backend_native_get_keymap_layout_group; backend_class->lock_layout_group = meta_backend_native_lock_layout_group; backend_class->update_screen_size = meta_backend_native_update_screen_size; - backend_class->set_numlock = meta_backend_native_set_numlock; backend_class->set_pointer_constraint = meta_backend_native_set_pointer_constraint; } diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index df53e55f5a4..a3cfef9d12f 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -344,9 +344,18 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, if (update_keys && (changed_state & XKB_STATE_LEDS)) { MetaInputDeviceNative *keyboard_native; + gboolean numlock_active; g_signal_emit (seat_impl, signals[MODS_STATE_CHANGED], 0); meta_seat_impl_sync_leds (seat_impl); + + numlock_active = + xkb_state_mod_name_is_active (seat_impl->xkb, XKB_MOD_NAME_NUM, + XKB_STATE_MODS_LATCHED | + XKB_STATE_MODS_LOCKED); + meta_input_settings_maybe_save_numlock_state (seat_impl->input_settings, + numlock_active); + keyboard_native = META_INPUT_DEVICE_NATIVE (seat_impl->core_keyboard); meta_input_device_native_a11y_maybe_notify_toggle_keys (keyboard_native); } @@ -2465,6 +2474,48 @@ static const struct libinput_interface libinput_interface = { close_restricted }; +static void +meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, + gboolean numlock_state) +{ + xkb_mod_mask_t depressed_mods; + xkb_mod_mask_t latched_mods; + xkb_mod_mask_t locked_mods; + xkb_mod_mask_t group_mods; + xkb_mod_mask_t numlock; + struct xkb_keymap *xkb_keymap; + MetaKeymapNative *keymap; + + keymap = seat_impl->keymap; + xkb_keymap = meta_keymap_native_get_keyboard_map (keymap); + + numlock = (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod2")); + + depressed_mods = + xkb_state_serialize_mods (seat_impl->xkb, XKB_STATE_MODS_DEPRESSED); + latched_mods = + xkb_state_serialize_mods (seat_impl->xkb, XKB_STATE_MODS_LATCHED); + locked_mods = + xkb_state_serialize_mods (seat_impl->xkb, XKB_STATE_MODS_LOCKED); + group_mods = + xkb_state_serialize_layout (seat_impl->xkb, XKB_STATE_LAYOUT_EFFECTIVE); + + if (numlock_state) + locked_mods |= numlock; + else + locked_mods &= ~numlock; + + xkb_state_update_mask (seat_impl->xkb, + depressed_mods, + latched_mods, + locked_mods, + 0, 0, + group_mods); + + meta_seat_impl_sync_leds (seat_impl); + meta_keymap_native_update (seat_impl->keymap); +} + static void meta_seat_impl_constructed (GObject *object) { @@ -2536,6 +2587,9 @@ meta_seat_impl_constructed (GObject *object) xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL); } + if (meta_input_settings_maybe_restore_numlock_state (seat_impl->input_settings)) + meta_seat_impl_set_keyboard_numlock (seat_impl, TRUE); + seat_impl->has_touchscreen = has_touchscreen (seat_impl); seat_impl->has_tablet_switch = has_tablet_switch (seat_impl); update_touch_mode (seat_impl); @@ -2604,6 +2658,7 @@ static void meta_seat_impl_finalize (GObject *object) { MetaSeatImpl *seat_impl = META_SEAT_IMPL (object); + gboolean numlock_active; GSList *iter; for (iter = seat_impl->devices; iter; iter = g_slist_next (iter)) @@ -2621,6 +2676,13 @@ meta_seat_impl_finalize (GObject *object) meta_event_source_free (seat_impl->event_source); + numlock_active = + xkb_state_mod_name_is_active (seat_impl->xkb, XKB_MOD_NAME_NUM, + XKB_STATE_MODS_LATCHED | + XKB_STATE_MODS_LOCKED); + meta_input_settings_maybe_save_numlock_state (seat_impl->input_settings, + numlock_active); + xkb_state_unref (seat_impl->xkb); meta_seat_impl_clear_repeat_timer (seat_impl); @@ -2978,61 +3040,6 @@ meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, g_rw_lock_writer_unlock (&seat_impl->state_lock); } -/** - * meta_seat_impl_set_keyboard_numlock: (skip) - * @seat: the #ClutterSeat created by the evdev backend - * @numlock_set: TRUE to set NumLock ON, FALSE otherwise. - * - * Sets the NumLock state on the backend's #xkb_state . - */ -void -meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, - gboolean numlock_state) -{ - xkb_mod_mask_t depressed_mods; - xkb_mod_mask_t latched_mods; - xkb_mod_mask_t locked_mods; - xkb_mod_mask_t group_mods; - xkb_mod_mask_t numlock; - struct xkb_keymap *xkb_keymap; - MetaKeymapNative *keymap; - - g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); - - g_rw_lock_writer_lock (&seat_impl->state_lock); - - keymap = seat_impl->keymap; - xkb_keymap = meta_keymap_native_get_keyboard_map (keymap); - - numlock = (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod2")); - - depressed_mods = - xkb_state_serialize_mods (seat_impl->xkb, XKB_STATE_MODS_DEPRESSED); - latched_mods = - xkb_state_serialize_mods (seat_impl->xkb, XKB_STATE_MODS_LATCHED); - locked_mods = - xkb_state_serialize_mods (seat_impl->xkb, XKB_STATE_MODS_LOCKED); - group_mods = - xkb_state_serialize_layout (seat_impl->xkb, XKB_STATE_LAYOUT_EFFECTIVE); - - if (numlock_state) - locked_mods |= numlock; - else - locked_mods &= ~numlock; - - xkb_state_update_mask (seat_impl->xkb, - depressed_mods, - latched_mods, - locked_mods, - 0, 0, - group_mods); - - meta_seat_impl_sync_leds (seat_impl); - meta_keymap_native_update (seat_impl->keymap); - - g_rw_lock_writer_unlock (&seat_impl->state_lock); -} - /** * meta_seat_impl_set_keyboard_repeat: * @seat: the #ClutterSeat created by the evdev backend diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index a62af83f5df..92d97b7328e 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -209,9 +209,6 @@ void meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat_im void meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, xkb_layout_index_t idx); -void meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, - gboolean numlock_state); - void meta_seat_impl_set_keyboard_repeat (MetaSeatImpl *seat_impl, gboolean repeat, uint32_t delay, diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 88654f7b5a0..432b0fc0070 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -612,20 +612,6 @@ meta_seat_native_get_keyboard_layout_index (MetaSeatNative *seat) return seat->xkb_layout_index; } -/** - * meta_seat_native_set_keyboard_numlock: (skip) - * @seat: the #ClutterSeat created by the evdev backend - * @numlock_set: TRUE to set NumLock ON, FALSE otherwise. - * - * Sets the NumLock state on the backend's #xkb_state . - */ -void -meta_seat_native_set_keyboard_numlock (MetaSeatNative *seat, - gboolean numlock_state) -{ - meta_seat_impl_set_keyboard_numlock (seat->impl, numlock_state); -} - MetaBarrierManagerNative * meta_seat_native_get_barrier_manager (MetaSeatNative *seat) { diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h index 787b2cc2b67..4f7c30e460c 100644 --- a/src/backends/native/meta-seat-native.h +++ b/src/backends/native/meta-seat-native.h @@ -107,9 +107,6 @@ void meta_seat_native_set_keyboard_layout_index (MetaSeatNative *seat, xkb_layout_index_t meta_seat_native_get_keyboard_layout_index (MetaSeatNative *seat); -void meta_seat_native_set_keyboard_numlock (MetaSeatNative *seat, - gboolean numlock_state); - void meta_seat_native_set_keyboard_repeat (MetaSeatNative *seat, gboolean repeat, uint32_t delay, diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c index 068f138c659..94a13e7cdb6 100644 --- a/src/backends/x11/meta-backend-x11.c +++ b/src/backends/x11/meta-backend-x11.c @@ -82,6 +82,8 @@ struct _MetaBackendX11Private uint8_t xkb_event_base; uint8_t xkb_error_base; + gulong keymap_state_changed_id; + struct xkb_keymap *keymap; xkb_layout_index_t keymap_layout_group; @@ -605,6 +607,14 @@ meta_backend_x11_post_init (MetaBackend *backend) g_signal_connect_object (meta_backend_get_input_settings (backend), "kbd-a11y-changed", G_CALLBACK (on_kbd_a11y_changed), backend, 0); + + if (meta_input_settings_maybe_restore_numlock_state (input_settings)) + { + unsigned int num_mask; + + num_mask = XkbKeysymToModifiers (priv->xdisplay, XK_Num_Lock); + XkbLockModifiers (priv->xdisplay, XkbUseCoreKbd, num_mask, num_mask); + } } } @@ -758,19 +768,6 @@ meta_backend_x11_get_keymap_layout_group (MetaBackend *backend) return priv->keymap_layout_group; } -static void -meta_backend_x11_set_numlock (MetaBackend *backend, - gboolean numlock_state) -{ - MetaBackendX11 *x11 = META_BACKEND_X11 (backend); - MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); - unsigned int num_mask; - - num_mask = XkbKeysymToModifiers (priv->xdisplay, XK_Num_Lock); - XkbLockModifiers (priv->xdisplay, XkbUseCoreKbd, num_mask, - numlock_state ? num_mask : 0); -} - void meta_backend_x11_handle_event (MetaBackendX11 *x11, XEvent *xevent) @@ -853,9 +850,21 @@ initable_iface_init (GInitableIface *initable_iface) static void meta_backend_x11_finalize (GObject *object) { + MetaBackend *backend = META_BACKEND (object); MetaBackendX11 *x11 = META_BACKEND_X11 (object); MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + if (priv->keymap_state_changed_id) + { + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); + ClutterKeymap *keymap; + + seat = clutter_backend_get_default_seat (clutter_backend); + keymap = clutter_seat_get_keymap (seat); + g_clear_signal_handler (&priv->keymap_state_changed_id, keymap); + } + if (priv->user_active_alarm != None) { XSyncDestroyAlarm (priv->xdisplay, priv->user_active_alarm); @@ -880,7 +889,6 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass) backend_class->get_current_logical_monitor = meta_backend_x11_get_current_logical_monitor; backend_class->get_keymap = meta_backend_x11_get_keymap; backend_class->get_keymap_layout_group = meta_backend_x11_get_keymap_layout_group; - backend_class->set_numlock = meta_backend_x11_set_numlock; } static void diff --git a/src/backends/x11/meta-keymap-x11.c b/src/backends/x11/meta-keymap-x11.c index ac2b1d7878f..d30b46e985b 100644 --- a/src/backends/x11/meta-keymap-x11.c +++ b/src/backends/x11/meta-keymap-x11.c @@ -26,6 +26,8 @@ #include #include +#include "backends/meta-backend-private.h" +#include "backends/meta-input-settings-private.h" #include "backends/x11/meta-keymap-x11.h" #include "clutter/clutter.h" #include "clutter/clutter-mutter.h" @@ -218,6 +220,21 @@ update_locked_mods (MetaKeymapX11 *keymap_x11, if ((keymap_x11->caps_lock_state != old_caps_lock_state) || (keymap_x11->num_lock_state != old_num_lock_state)) g_signal_emit_by_name (keymap_x11, "state-changed"); + + if (keymap_x11->num_lock_state != old_num_lock_state) + { + MetaBackend *backend; + MetaInputSettings *input_settings; + + backend = meta_get_backend (); + input_settings = meta_backend_get_input_settings (backend); + + if (input_settings) + { + meta_input_settings_maybe_save_numlock_state (input_settings, + keymap_x11->num_lock_state); + } + } } /* the code to retrieve the keymap direction and cache it -- GitLab From fd90e41e128962b653511768763fb003f1cb8f1a Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 12 Aug 2020 15:37:43 +0200 Subject: [PATCH 60/85] backends/native: Make some MetaSeatImpl API "async" This API is the one accessed from different bits of the UI thread, make it "async" (it's basically one-way setters, so API stays the same in the surface) and able to run in the MetaSeatImpl main context. Part-of: --- src/backends/native/meta-seat-impl.c | 250 ++++++++++++++++++++++----- src/backends/native/meta-seat-impl.h | 5 + 2 files changed, 211 insertions(+), 44 deletions(-) diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index a3cfef9d12f..69be7c97622 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -137,6 +137,23 @@ void meta_seat_impl_filter_relative_motion (MetaSeatImpl *seat_impl, float *dy); void meta_seat_impl_clear_repeat_timer (MetaSeatImpl *seat_impl); +void +meta_seat_impl_run_input_task (MetaSeatImpl *seat_impl, + GTask *task, + GSourceFunc dispatch_func) +{ + GSource *source; + + source = g_idle_source_new (); + g_source_set_priority (source, G_PRIORITY_HIGH); + g_source_set_callback (source, + dispatch_func, + g_object_ref (task), + g_object_unref); + g_source_attach (source, seat_impl->input_context); + g_source_unref (source); +} + void meta_seat_impl_sync_leds (MetaSeatImpl *seat_impl) { @@ -2720,12 +2737,36 @@ meta_seat_impl_get_keymap (MetaSeatImpl *seat_impl) return g_object_ref (seat_impl->keymap); } +static gboolean +warp_pointer (GTask *task) +{ + MetaSeatImpl *seat = g_task_get_source_object (task); + graphene_point_t *point; + + point = g_task_get_task_data (task); + notify_absolute_motion (seat->core_pointer, 0, + point->x, point->y, NULL); + g_task_return_boolean (task, TRUE); + + return G_SOURCE_REMOVE; +} + void meta_seat_impl_warp_pointer (MetaSeatImpl *seat_impl, int x, int y) { - notify_absolute_motion (seat_impl->core_pointer, 0, x, y, NULL); + graphene_point_t *point; + GTask *task; + + point = graphene_point_alloc (); + point->x = x; + point->y = y; + + task = g_task_new (seat_impl, NULL, NULL, NULL); + g_task_set_task_data (task, point, (GDestroyNotify) graphene_point_free); + meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) warp_pointer); + g_object_unref (task); } gboolean @@ -2737,6 +2778,7 @@ meta_seat_impl_query_state (MetaSeatImpl *seat_impl, { MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); gboolean retval = FALSE; + ClutterModifierType mods = 0; g_rw_lock_reader_lock (&seat_impl->state_lock); @@ -2756,8 +2798,8 @@ meta_seat_impl_query_state (MetaSeatImpl *seat_impl, coords->y = touch_state->coords.y; } - if (modifiers) - *modifiers = meta_xkb_translate_modifiers (seat_impl->xkb, 0); + if (seat_impl->xkb) + mods = meta_xkb_translate_modifiers (seat_impl->xkb, 0); retval = TRUE; } @@ -2769,15 +2811,18 @@ meta_seat_impl_query_state (MetaSeatImpl *seat_impl, coords->y = device_native->pointer_y; } - if (modifiers) + if (seat_impl->xkb) { - *modifiers = meta_xkb_translate_modifiers (seat_impl->xkb, - seat_impl->button_state); + mods = meta_xkb_translate_modifiers (seat_impl->xkb, + seat_impl->button_state); } retval = TRUE; } + if (modifiers) + *modifiers = mods; + out: g_rw_lock_reader_unlock (&seat_impl->state_lock); return retval; @@ -2926,6 +2971,30 @@ meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl) g_rw_lock_writer_unlock (&seat_impl->state_lock); } +static gboolean +release_devices (GTask *task) +{ + MetaSeatImpl *seat_impl = g_task_get_source_object (task); + + if (seat_impl->released) + { + g_warning ("meta_seat_impl_release_devices() shouldn't be called " + "multiple times without a corresponding call to " + "meta_seat_impl_reclaim_devices() first"); + } + else + { + libinput_suspend (seat_impl->libinput); + process_events (seat_impl); + + seat_impl->released = TRUE; + } + + g_task_return_boolean (task, TRUE); + + return G_SOURCE_REMOVE; +} + /** * meta_seat_impl_release_devices: * @@ -2939,18 +3008,38 @@ meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl) void meta_seat_impl_release_devices (MetaSeatImpl *seat_impl) { + GTask *task; + + g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); + + task = g_task_new (seat_impl, NULL, NULL, NULL); + meta_seat_impl_run_input_task (seat_impl, task, + (GSourceFunc) release_devices); + g_object_unref (task); +} + +static gboolean +reclaim_devices (GTask *task) +{ + MetaSeatImpl *seat_impl = g_task_get_source_object (task); + if (seat_impl->released) { - g_warning ("meta_seat_impl_release_devices() shouldn't be called " - "multiple times without a corresponding call to " - "meta_seat_impl_reclaim_devices() first"); - return; + libinput_resume (seat_impl->libinput); + meta_seat_impl_update_xkb_state (seat_impl); + process_events (seat_impl); + + seat_impl->released = FALSE; + } + else + { + g_warning ("Spurious call to meta_seat_impl_reclaim_devices() without " + "previous call to meta_seat_impl_release_devices"); } - libinput_suspend (seat_impl->libinput); - process_events (seat_impl); + g_task_return_boolean (task, TRUE); - seat_impl->released = TRUE; + return G_SOURCE_REMOVE; } /** @@ -2967,18 +3056,29 @@ meta_seat_impl_release_devices (MetaSeatImpl *seat_impl) void meta_seat_impl_reclaim_devices (MetaSeatImpl *seat_impl) { - if (!seat_impl->released) - { - g_warning ("Spurious call to meta_seat_impl_reclaim_devices() without " - "previous call to meta_seat_impl_release_devices"); - return; - } + GTask *task; + + g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); + + task = g_task_new (seat_impl, NULL, NULL, NULL); + meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) reclaim_devices); + g_object_unref (task); +} + +static gboolean +set_keyboard_map (GTask *task) +{ + MetaSeatImpl *seat_impl = g_task_get_source_object (task); + struct xkb_keymap *xkb_keymap = g_task_get_task_data (task); + MetaKeymapNative *keymap; + + keymap = seat_impl->keymap; + meta_keymap_native_set_keyboard_map (keymap, xkb_keymap); - libinput_resume (seat_impl->libinput); meta_seat_impl_update_xkb_state (seat_impl); - process_events (seat_impl); + g_task_return_boolean (task, TRUE); - seat_impl->released = FALSE; + return G_SOURCE_REMOVE; } /** @@ -2995,35 +3095,29 @@ void meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat_impl, struct xkb_keymap *xkb_keymap) { - MetaKeymapNative *keymap; + GTask *task; g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); g_return_if_fail (xkb_keymap != NULL); - keymap = seat_impl->keymap; - meta_keymap_native_set_keyboard_map (keymap, xkb_keymap); - - meta_seat_impl_update_xkb_state (seat_impl); + task = g_task_new (seat_impl, NULL, NULL, NULL); + g_task_set_task_data (task, + xkb_keymap_ref (xkb_keymap), + (GDestroyNotify) xkb_keymap_unref); + meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) set_keyboard_map); + g_object_unref (task); } -/** - * meta_seat_impl_set_keyboard_layout_index: (skip) - * @seat: the #ClutterSeat created by the evdev backend - * @idx: the xkb layout index to set - * - * Sets the xkb layout index on the backend's #xkb_state . - */ -void -meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, - xkb_layout_index_t idx) +static gboolean +set_keyboard_layout_index (GTask *task) { + MetaSeatImpl *seat_impl = g_task_get_source_object (task); + xkb_layout_index_t idx = GPOINTER_TO_UINT (g_task_get_task_data (task)); xkb_mod_mask_t depressed_mods; xkb_mod_mask_t latched_mods; xkb_mod_mask_t locked_mods; struct xkb_state *state; - g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); - g_rw_lock_writer_lock (&seat_impl->state_lock); state = seat_impl->xkb; @@ -3038,8 +3132,35 @@ meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, seat_impl->layout_idx = idx; g_rw_lock_writer_unlock (&seat_impl->state_lock); + + g_task_return_boolean (task, TRUE); + + return G_SOURCE_REMOVE; +} + +/** + * meta_seat_impl_set_keyboard_layout_index: (skip) + * @seat: the #ClutterSeat created by the evdev backend + * @idx: the xkb layout index to set + * + * Sets the xkb layout index on the backend's #xkb_state . + */ +void +meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, + xkb_layout_index_t idx) +{ + GTask *task; + + g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); + + task = g_task_new (seat_impl, NULL, NULL, NULL); + g_task_set_task_data (task, GUINT_TO_POINTER (idx), NULL); + meta_seat_impl_run_input_task (seat_impl, task, + (GSourceFunc) set_keyboard_layout_index); + g_object_unref (task); } + /** * meta_seat_impl_set_keyboard_repeat: * @seat: the #ClutterSeat created by the evdev backend @@ -3077,25 +3198,66 @@ meta_seat_impl_get_barrier_manager (MetaSeatImpl *seat_impl) return seat_impl->barrier_manager; } -void -meta_seat_impl_set_pointer_constraint (MetaSeatImpl *seat_impl, - MetaPointerConstraintImpl *constraint_impl) +static gboolean +set_pointer_constraint (GTask *task) { + MetaSeatImpl *seat_impl = g_task_get_source_object (task); + MetaPointerConstraintImpl *constraint_impl = g_task_get_task_data (task); + if (!g_set_object (&seat_impl->pointer_constraint, constraint_impl)) - return; + return G_SOURCE_REMOVE; if (constraint_impl) { meta_pointer_constraint_impl_ensure_constrained (constraint_impl, seat_impl->core_pointer); } + + g_task_return_boolean (task, TRUE); + + return G_SOURCE_REMOVE; +} + +void +meta_seat_impl_set_pointer_constraint (MetaSeatImpl *seat, + MetaPointerConstraintImpl *constraint_impl) +{ + GTask *task; + + g_return_if_fail (META_IS_SEAT_IMPL (seat)); + + task = g_task_new (seat, NULL, NULL, NULL); + g_task_set_task_data (task, g_object_ref (constraint_impl), g_object_unref); + meta_seat_impl_run_input_task (seat, task, + (GSourceFunc) set_pointer_constraint); + g_object_unref (task); +} + +static gboolean +set_viewports (GTask *task) +{ + MetaSeatImpl *seat = g_task_get_source_object (task); + MetaViewportInfo *viewports = g_task_get_task_data (task); + + g_set_object (&seat->viewports, viewports); + g_task_return_boolean (task, TRUE); + + return G_SOURCE_REMOVE; } void meta_seat_impl_set_viewports (MetaSeatImpl *seat_impl, MetaViewportInfo *viewports) { - g_set_object (&seat_impl->viewports, viewports); + GTask *task; + + g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); + + task = g_task_new (seat_impl, NULL, NULL, NULL); + g_task_set_task_data (task, g_object_ref (viewports), g_object_unref); + meta_seat_impl_run_input_task (seat_impl, task, + (GSourceFunc) set_viewports); + g_object_unref (task); } MetaSeatImpl * diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index 92d97b7328e..30b52ffb0a8 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -54,6 +54,7 @@ struct _MetaSeatImpl { GObject parent_instance; + GMainContext *input_context; MetaSeatNative *seat_native; char *seat_id; MetaEventSource *event_source; @@ -116,6 +117,10 @@ G_DECLARE_FINAL_TYPE (MetaSeatImpl, meta_seat_impl, MetaSeatImpl * meta_seat_impl_new (MetaSeatNative *seat_native, const char *seat_id); +void meta_seat_impl_run_input_task (MetaSeatImpl *seat_impl, + GTask *task, + GSourceFunc dispatch_func); + void meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, ClutterInputDevice *device, uint64_t time_us, -- GitLab From fb2440a1cf50c005071b6f901066a8c93ce2763e Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 12 Aug 2020 17:01:02 +0200 Subject: [PATCH 61/85] backends/native: Make MetaVirtualInputDevice vmethods "async" These are one-way API calls, that now should get executed in the MetaSeatImpl context. Use the MetaSeatImpl async task plumbing so that's the case. Part-of: --- .../native/meta-virtual-input-device-native.c | 698 +++++++++++++----- 1 file changed, 507 insertions(+), 191 deletions(-) diff --git a/src/backends/native/meta-virtual-input-device-native.c b/src/backends/native/meta-virtual-input-device-native.c index 2082c11ab8e..28542dc94e8 100644 --- a/src/backends/native/meta-virtual-input-device-native.c +++ b/src/backends/native/meta-virtual-input-device-native.c @@ -41,16 +41,62 @@ enum static GParamSpec *obj_props[PROP_LAST]; +typedef struct _ImplState ImplState; + +struct _ImplState +{ + ClutterInputDevice *device; + int button_count[KEY_CNT]; +}; + struct _MetaVirtualInputDeviceNative { ClutterVirtualInputDevice parent; - ClutterInputDevice *device; MetaSeatNative *seat; guint slot_base; - int button_count[KEY_CNT]; + ImplState *impl_state; }; +typedef struct +{ + uint64_t time_us; + double x; + double y; +} MetaVirtualEventMotion; + +typedef struct +{ + uint64_t time_us; + uint32_t button; + ClutterButtonState button_state; +} MetaVirtualEventButton; + +typedef struct +{ + uint64_t time_us; + double dx; + double dy; + ClutterScrollDirection direction; + ClutterScrollSource scroll_source; + ClutterScrollFinishFlags finish_flags; +} MetaVirtualEventScroll; + +typedef struct +{ + uint64_t time_us; + uint32_t key; + ClutterKeyState key_state; +} MetaVirtualEventKey; + +typedef struct +{ + uint64_t time_us; + int device_slot; + double x; + double y; +} MetaVirtualEventTouch; + G_DEFINE_TYPE (MetaVirtualInputDeviceNative, meta_virtual_input_device_native, CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE) @@ -68,9 +114,9 @@ update_button_count (MetaVirtualInputDeviceNative *virtual_evdev, uint32_t state) { if (state) - return ++virtual_evdev->button_count[button]; + return ++virtual_evdev->impl_state->button_count[button]; else - return --virtual_evdev->button_count[button]; + return --virtual_evdev->impl_state->button_count[button]; } static EvdevButtonType @@ -109,38 +155,41 @@ get_button_type (uint16_t code) return EVDEV_BUTTON_TYPE_NONE; } -static void -release_pressed_buttons (ClutterVirtualInputDevice *virtual_device) +static gboolean +release_device (GTask *task) { - MetaVirtualInputDeviceNative *virtual_evdev = - META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + ImplState *impl_state = g_task_get_task_data (task); + MetaInputDeviceNative *device_native; + MetaSeatImpl *seat_impl; int code; uint64_t time_us; + device_native = META_INPUT_DEVICE_NATIVE (impl_state->device); + seat_impl = meta_input_device_native_get_seat_impl (device_native); time_us = g_get_monotonic_time (); meta_topic (META_DEBUG_INPUT, "Releasing pressed buttons while destroying virtual input device " - "(device %p)", virtual_device); + "(device %p)", device_native); - for (code = 0; code < G_N_ELEMENTS (virtual_evdev->button_count); code++) + for (code = 0; code < G_N_ELEMENTS (impl_state->button_count); code++) { - if (virtual_evdev->button_count[code] == 0) + if (impl_state->button_count[code] == 0) continue; switch (get_button_type (code)) { case EVDEV_BUTTON_TYPE_KEY: - meta_seat_impl_notify_key (virtual_evdev->seat->impl, - virtual_evdev->device, + meta_seat_impl_notify_key (seat_impl, + impl_state->device, time_us, code, CLUTTER_KEY_STATE_RELEASED, TRUE); break; case EVDEV_BUTTON_TYPE_BUTTON: - meta_seat_impl_notify_button (virtual_evdev->seat->impl, - virtual_evdev->device, + meta_seat_impl_notify_button (seat_impl, + impl_state->device, time_us, code, CLUTTER_BUTTON_STATE_RELEASED); @@ -148,9 +197,32 @@ release_pressed_buttons (ClutterVirtualInputDevice *virtual_device) case EVDEV_BUTTON_TYPE_NONE: g_assert_not_reached (); } - - update_button_count (virtual_evdev, code, 0); } + + g_clear_object (&impl_state->device); + g_task_return_boolean (task, TRUE); + + return G_SOURCE_REMOVE; +} + +static gboolean +notify_relative_motion (GTask *task) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + g_task_get_source_object (task); + MetaSeatImpl *seat = virtual_evdev->seat->impl; + MetaVirtualEventMotion *event = g_task_get_task_data (task); + + if (event->time_us == CLUTTER_CURRENT_TIME) + event->time_us = g_get_monotonic_time (); + + meta_seat_impl_notify_relative_motion (seat, + virtual_evdev->impl_state->device, + event->time_us, + event->x, event->y, + event->x, event->y); + g_task_return_boolean (task, TRUE); + return G_SOURCE_REMOVE; } static void @@ -159,19 +231,43 @@ meta_virtual_input_device_native_notify_relative_motion (ClutterVirtualInputDevi double dx, double dy) { + MetaVirtualEventMotion *event; MetaVirtualInputDeviceNative *virtual_evdev = META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + GTask *task; - g_return_if_fail (virtual_evdev->device != NULL); + g_return_if_fail (virtual_evdev->impl_state->device != NULL); - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); + event = g_new0 (MetaVirtualEventMotion, 1); + event->time_us = time_us; + event->x = dx; + event->y = dy; - meta_seat_impl_notify_relative_motion (virtual_evdev->seat->impl, - virtual_evdev->device, - time_us, - dx, dy, - dx, dy); + task = g_task_new (virtual_device, NULL, NULL, NULL); + g_task_set_task_data (task, event, g_free); + meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, + (GSourceFunc) notify_relative_motion); + g_object_unref (task); +} + +static gboolean +notify_absolute_motion (GTask *task) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + g_task_get_source_object (task); + MetaSeatImpl *seat = virtual_evdev->seat->impl; + MetaVirtualEventMotion *event = g_task_get_task_data (task); + + if (event->time_us == CLUTTER_CURRENT_TIME) + event->time_us = g_get_monotonic_time (); + + meta_seat_impl_notify_absolute_motion (seat, + virtual_evdev->impl_state->device, + event->time_us, + event->x, event->y, + NULL); + g_task_return_boolean (task, TRUE); + return G_SOURCE_REMOVE; } static void @@ -180,19 +276,23 @@ meta_virtual_input_device_native_notify_absolute_motion (ClutterVirtualInputDevi double x, double y) { + MetaVirtualEventMotion *event; MetaVirtualInputDeviceNative *virtual_evdev = META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + GTask *task; - g_return_if_fail (virtual_evdev->device != NULL); + g_return_if_fail (virtual_evdev->impl_state->device != NULL); - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); + event = g_new0 (MetaVirtualEventMotion, 1); + event->time_us = time_us; + event->x = x; + event->y = y; - meta_seat_impl_notify_absolute_motion (virtual_evdev->seat->impl, - virtual_evdev->device, - time_us, - x, y, - NULL); + task = g_task_new (virtual_device, NULL, NULL, NULL); + g_task_set_task_data (task, event, g_free); + meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, + (GSourceFunc) notify_absolute_motion); + g_object_unref (task); } static int @@ -215,93 +315,148 @@ translate_to_evdev_button (int clutter_button) } } -static void -meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t button, - ClutterButtonState button_state) +static gboolean +notify_button (GTask *task) { MetaVirtualInputDeviceNative *virtual_evdev = - META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + g_task_get_source_object (task); + MetaSeatImpl *seat = virtual_evdev->seat->impl; + MetaVirtualEventButton *event = g_task_get_task_data (task); int button_count; int evdev_button; - g_return_if_fail (virtual_evdev->device != NULL); + if (event->time_us == CLUTTER_CURRENT_TIME) + event->time_us = g_get_monotonic_time (); - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); - - evdev_button = translate_to_evdev_button (button); + evdev_button = translate_to_evdev_button (event->button); if (get_button_type (evdev_button) != EVDEV_BUTTON_TYPE_BUTTON) { g_warning ("Unknown/invalid virtual device button 0x%x pressed", evdev_button); - return; + goto out; } - button_count = update_button_count (virtual_evdev, evdev_button, button_state); + button_count = update_button_count (virtual_evdev, evdev_button, + event->button_state); if (button_count < 0 || button_count > 1) { g_warning ("Received multiple virtual 0x%x button %s (ignoring)", evdev_button, - button_state == CLUTTER_BUTTON_STATE_PRESSED ? "presses" : "releases"); - update_button_count (virtual_evdev, evdev_button, 1 - button_state); - return; + event->button_state == CLUTTER_BUTTON_STATE_PRESSED ? + "presses" : "releases"); + update_button_count (virtual_evdev, evdev_button, 1 - event->button_state); + goto out; } meta_topic (META_DEBUG_INPUT, "Emitting virtual button-%s of button 0x%x (device %p)", - button_state == CLUTTER_BUTTON_STATE_PRESSED ? "press" : "release", - evdev_button, virtual_device); + event->button_state == CLUTTER_BUTTON_STATE_PRESSED ? + "press" : "release", + evdev_button, virtual_evdev); - meta_seat_impl_notify_button (virtual_evdev->seat->impl, - virtual_evdev->device, - time_us, + meta_seat_impl_notify_button (seat, + virtual_evdev->impl_state->device, + event->time_us, evdev_button, - button_state); + event->button_state); + out: + g_task_return_boolean (task, TRUE); + return G_SOURCE_REMOVE; } static void -meta_virtual_input_device_native_notify_key (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t key, - ClutterKeyState key_state) +meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t button, + ClutterButtonState button_state) { + MetaVirtualEventButton *event; MetaVirtualInputDeviceNative *virtual_evdev = META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); - int key_count; + GTask *task; - g_return_if_fail (virtual_evdev->device != NULL); + g_return_if_fail (virtual_evdev->impl_state->device != NULL); - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); + event = g_new0 (MetaVirtualEventButton, 1); + event->time_us = time_us; + event->button = button; + event->button_state = button_state; - if (get_button_type (key) != EVDEV_BUTTON_TYPE_KEY) + task = g_task_new (virtual_device, NULL, NULL, NULL); + g_task_set_task_data (task, event, g_free); + meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, + (GSourceFunc) notify_button); + g_object_unref (task); +} + +static gboolean +notify_key (GTask *task) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + g_task_get_source_object (task); + MetaSeatImpl *seat = virtual_evdev->seat->impl; + MetaVirtualEventKey *event = g_task_get_task_data (task); + int key_count; + + if (event->time_us == CLUTTER_CURRENT_TIME) + event->time_us = g_get_monotonic_time (); + + if (get_button_type (event->key) != EVDEV_BUTTON_TYPE_KEY) { - g_warning ("Unknown/invalid virtual device key 0x%x pressed", key); - return; + g_warning ("Unknown/invalid virtual device key 0x%x pressed", event->key); + goto out; } - key_count = update_button_count (virtual_evdev, key, key_state); + key_count = update_button_count (virtual_evdev, event->key, event->key_state); if (key_count < 0 || key_count > 1) { - g_warning ("Received multiple virtual 0x%x key %s (ignoring)", key, - key_state == CLUTTER_KEY_STATE_PRESSED ? "presses" : "releases"); - update_button_count (virtual_evdev, key, 1 - key_state); - return; + g_warning ("Received multiple virtual 0x%x key %s (ignoring)", event->key, + event->key_state == CLUTTER_KEY_STATE_PRESSED ? + "presses" : "releases"); + update_button_count (virtual_evdev, event->key, 1 - event->key_state); + goto out; } meta_topic (META_DEBUG_INPUT, "Emitting virtual key-%s of key 0x%x (device %p)", - key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release", - key, virtual_device); - - meta_seat_impl_notify_key (virtual_evdev->seat->impl, - virtual_evdev->device, - time_us, - key, - key_state, + event->key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release", + event->key, virtual_evdev); + + meta_seat_impl_notify_key (seat, + virtual_evdev->impl_state->device, + event->time_us, + event->key, + event->key_state, TRUE); + + out: + g_task_return_boolean (task, TRUE); + return G_SOURCE_REMOVE; +} + +static void +meta_virtual_input_device_native_notify_key (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t key, + ClutterKeyState key_state) +{ + MetaVirtualEventKey *event; + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + GTask *task; + + g_return_if_fail (virtual_evdev->impl_state->device != NULL); + + event = g_new0 (MetaVirtualEventKey, 1); + event->time_us = time_us; + event->key = key; + event->key_state = key_state; + + task = g_task_new (virtual_device, NULL, NULL, NULL); + g_task_set_task_data (task, event, g_free); + meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, + (GSourceFunc) notify_key); + g_object_unref (task); } static gboolean @@ -383,7 +538,7 @@ apply_level_modifiers (ClutterVirtualInputDevice *virtual_device, &keycode, NULL)) return; - clutter_input_device_keycode_to_evdev (virtual_evdev->device, + clutter_input_device_keycode_to_evdev (virtual_evdev->impl_state->device, keycode, &evcode); meta_topic (META_DEBUG_INPUT, @@ -392,72 +547,101 @@ apply_level_modifiers (ClutterVirtualInputDevice *virtual_device, evcode, virtual_device); meta_seat_impl_notify_key (virtual_evdev->seat->impl, - virtual_evdev->device, + virtual_evdev->impl_state->device, time_us, evcode, key_state, TRUE); } -static void -meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t keyval, - ClutterKeyState key_state) +static gboolean +notify_keyval (GTask *task) { MetaVirtualInputDeviceNative *virtual_evdev = - META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + g_task_get_source_object (task); + ClutterVirtualInputDevice *virtual_device = + CLUTTER_VIRTUAL_INPUT_DEVICE (virtual_evdev); + MetaSeatImpl *seat = virtual_evdev->seat->impl; + MetaVirtualEventKey *event = g_task_get_task_data (task); int key_count; guint keycode = 0, level = 0, evcode = 0; - g_return_if_fail (virtual_evdev->device != NULL); - - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); + if (event->time_us == CLUTTER_CURRENT_TIME) + event->time_us = g_get_monotonic_time (); if (!pick_keycode_for_keyval_in_current_group (virtual_device, - keyval, &keycode, &level)) + event->key, &keycode, &level)) { - g_warning ("No keycode found for keyval %x in current group", keyval); - return; + g_warning ("No keycode found for keyval %x in current group", event->key); + goto out; } - clutter_input_device_keycode_to_evdev (virtual_evdev->device, + clutter_input_device_keycode_to_evdev (virtual_evdev->impl_state->device, keycode, &evcode); if (get_button_type (evcode) != EVDEV_BUTTON_TYPE_KEY) { g_warning ("Unknown/invalid virtual device key 0x%x pressed", evcode); - return; + goto out; } - key_count = update_button_count (virtual_evdev, evcode, key_state); + key_count = update_button_count (virtual_evdev, evcode, event->key_state); if (key_count < 0 || key_count > 1) { g_warning ("Received multiple virtual 0x%x key %s (ignoring)", evcode, - key_state == CLUTTER_KEY_STATE_PRESSED ? "presses" : "releases"); - update_button_count (virtual_evdev, evcode, 1 - key_state); - return; + event->key_state == CLUTTER_KEY_STATE_PRESSED ? + "presses" : "releases"); + update_button_count (virtual_evdev, evcode, 1 - event->key_state); + goto out; } meta_topic (META_DEBUG_INPUT, "Emitting virtual key-%s of key 0x%x with modifier level %d, " "press count %d (device %p)", - key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release", - evcode, level, key_count, virtual_device); + event->key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release", + evcode, level, key_count, virtual_evdev); - if (key_state) - apply_level_modifiers (virtual_device, time_us, level, key_state); + if (event->key_state) + apply_level_modifiers (virtual_device, event->time_us, level, event->key_state); - meta_seat_impl_notify_key (virtual_evdev->seat->impl, - virtual_evdev->device, - time_us, + meta_seat_impl_notify_key (seat, + virtual_evdev->impl_state->device, + event->time_us, evcode, - key_state, + event->key_state, TRUE); - if (!key_state) - apply_level_modifiers (virtual_device, time_us, level, key_state); + if (!event->key_state) + apply_level_modifiers (virtual_device, event->time_us, level, event->key_state); + + out: + g_task_return_boolean (task, TRUE); + return G_SOURCE_REMOVE; +} + +static void +meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t keyval, + ClutterKeyState key_state) +{ + MetaVirtualEventKey *event; + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + GTask *task; + + g_return_if_fail (virtual_evdev->impl_state->device != NULL); + + event = g_new0 (MetaVirtualEventKey, 1); + event->time_us = time_us; + event->key = keyval; + event->key_state = key_state; + + task = g_task_new (virtual_device, NULL, NULL, NULL); + g_task_set_task_data (task, event, g_free); + meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, + (GSourceFunc) notify_keyval); + g_object_unref (task); } static void @@ -489,28 +673,74 @@ direction_to_discrete (ClutterScrollDirection direction, } } +static gboolean +notify_discrete_scroll (GTask *task) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + g_task_get_source_object (task); + MetaSeatImpl *seat = virtual_evdev->seat->impl; + MetaVirtualEventScroll *event = g_task_get_task_data (task); + double discrete_dx = 0.0, discrete_dy = 0.0; + + if (event->time_us == CLUTTER_CURRENT_TIME) + event->time_us = g_get_monotonic_time (); + + direction_to_discrete (event->direction, &discrete_dx, &discrete_dy); + + meta_seat_impl_notify_discrete_scroll (seat, + virtual_evdev->impl_state->device, + event->time_us, + discrete_dx, discrete_dy, + event->scroll_source); + + g_task_return_boolean (task, TRUE); + return G_SOURCE_REMOVE; +} + static void meta_virtual_input_device_native_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device, uint64_t time_us, ClutterScrollDirection direction, ClutterScrollSource scroll_source) { + MetaVirtualEventScroll *event; MetaVirtualInputDeviceNative *virtual_evdev = META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); - double discrete_dx = 0.0, discrete_dy = 0.0; + GTask *task; - g_return_if_fail (virtual_evdev->device != NULL); + g_return_if_fail (virtual_evdev->impl_state->device != NULL); - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); + event = g_new0 (MetaVirtualEventScroll, 1); + event->time_us = time_us; + event->direction = direction; + event->scroll_source = scroll_source; - direction_to_discrete (direction, &discrete_dx, &discrete_dy); + task = g_task_new (virtual_device, NULL, NULL, NULL); + g_task_set_task_data (task, event, g_free); + meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, + (GSourceFunc) notify_discrete_scroll); + g_object_unref (task); +} - meta_seat_impl_notify_discrete_scroll (virtual_evdev->seat->impl, - virtual_evdev->device, - time_us, - discrete_dx, discrete_dy, - scroll_source); +static gboolean +notify_scroll_continuous (GTask *task) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + g_task_get_source_object (task); + MetaSeatImpl *seat = virtual_evdev->seat->impl; + MetaVirtualEventScroll *event = g_task_get_task_data (task); + + if (event->time_us == CLUTTER_CURRENT_TIME) + event->time_us = g_get_monotonic_time (); + + meta_seat_impl_notify_scroll_continuous (seat, + virtual_evdev->impl_state->device, + event->time_us, + event->dx, event->dy, + event->scroll_source, + CLUTTER_SCROLL_FINISHED_NONE); + g_task_return_boolean (task, TRUE); + return G_SOURCE_REMOVE; } static void @@ -521,20 +751,58 @@ meta_virtual_input_device_native_notify_scroll_continuous (ClutterVirtualInputDe ClutterScrollSource scroll_source, ClutterScrollFinishFlags finish_flags) { + MetaVirtualEventScroll *event; MetaVirtualInputDeviceNative *virtual_evdev = META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + GTask *task; + + g_return_if_fail (virtual_evdev->impl_state->device != NULL); + + event = g_new0 (MetaVirtualEventScroll, 1); + event->time_us = time_us; + event->dx = dx; + event->dy = dy; + event->scroll_source = scroll_source; + event->finish_flags = finish_flags; + + task = g_task_new (virtual_device, NULL, NULL, NULL); + g_task_set_task_data (task, event, g_free); + meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, + (GSourceFunc) notify_scroll_continuous); + g_object_unref (task); +} + +static gboolean +notify_touch_down (GTask *task) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + g_task_get_source_object (task); + MetaSeatImpl *seat = virtual_evdev->seat->impl; + MetaVirtualEventTouch *event = g_task_get_task_data (task); + MetaTouchState *touch_state; - g_return_if_fail (virtual_evdev->device != NULL); + if (event->time_us == CLUTTER_CURRENT_TIME) + event->time_us = g_get_monotonic_time (); - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); + touch_state = meta_seat_impl_acquire_touch_state (seat, + event->device_slot); + if (!touch_state) + goto out; - meta_seat_impl_notify_scroll_continuous (virtual_evdev->seat->impl, - virtual_evdev->device, - time_us, - dx, dy, - scroll_source, - CLUTTER_SCROLL_FINISHED_NONE); + touch_state->coords.x = event->x; + touch_state->coords.y = event->y; + + meta_seat_impl_notify_touch_event (seat, + virtual_evdev->impl_state->device, + CLUTTER_TOUCH_BEGIN, + event->time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); + + out: + g_task_return_boolean (task, TRUE); + return G_SOURCE_REMOVE; } static void @@ -544,32 +812,57 @@ meta_virtual_input_device_native_notify_touch_down (ClutterVirtualInputDevice *v double x, double y) { + MetaVirtualEventTouch *event; MetaVirtualInputDeviceNative *virtual_evdev = META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); - MetaTouchState *touch_state; - guint seat_slot; + GTask *task; - g_return_if_fail (virtual_evdev->device != NULL); + g_return_if_fail (virtual_evdev->impl_state->device != NULL); - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); + event = g_new0 (MetaVirtualEventTouch, 1); + event->time_us = time_us; + event->device_slot = virtual_evdev->slot_base + (guint) device_slot; + event->x = x; + event->y = y; - seat_slot = virtual_evdev->slot_base + (guint) device_slot; - touch_state = meta_seat_impl_acquire_touch_state (virtual_evdev->seat->impl, - seat_slot); + task = g_task_new (virtual_device, NULL, NULL, NULL); + g_task_set_task_data (task, event, g_free); + meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, + (GSourceFunc) notify_touch_down); + g_object_unref (task); +} + +static gboolean +notify_touch_motion (GTask *task) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + g_task_get_source_object (task); + MetaSeatImpl *seat = virtual_evdev->seat->impl; + MetaVirtualEventTouch *event = g_task_get_task_data (task); + MetaTouchState *touch_state; + + if (event->time_us == CLUTTER_CURRENT_TIME) + event->time_us = g_get_monotonic_time (); + + touch_state = meta_seat_impl_lookup_touch_state (seat, + event->device_slot); if (!touch_state) - return; + goto out; - touch_state->coords.x = x; - touch_state->coords.y = y; + touch_state->coords.x = event->x; + touch_state->coords.y = event->y; - meta_seat_impl_notify_touch_event (virtual_evdev->seat->impl, - virtual_evdev->device, - CLUTTER_TOUCH_BEGIN, - time_us, + meta_seat_impl_notify_touch_event (seat, + virtual_evdev->impl_state->device, + CLUTTER_TOUCH_UPDATE, + event->time_us, touch_state->seat_slot, touch_state->coords.x, touch_state->coords.y); + + out: + g_task_return_boolean (task, TRUE); + return G_SOURCE_REMOVE; } static void @@ -579,32 +872,57 @@ meta_virtual_input_device_native_notify_touch_motion (ClutterVirtualInputDevice double x, double y) { + MetaVirtualEventTouch *event; MetaVirtualInputDeviceNative *virtual_evdev = META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); - MetaTouchState *touch_state; - guint seat_slot; + GTask *task; - g_return_if_fail (virtual_evdev->device != NULL); + g_return_if_fail (virtual_evdev->impl_state->device != NULL); - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); + event = g_new0 (MetaVirtualEventTouch, 1); + event->time_us = time_us; + event->device_slot = virtual_evdev->slot_base + (guint) device_slot; + event->x = x; + event->y = y; - seat_slot = virtual_evdev->slot_base + (guint) device_slot; - touch_state = meta_seat_impl_lookup_touch_state (virtual_evdev->seat->impl, - seat_slot); - if (!touch_state) - return; + task = g_task_new (virtual_device, NULL, NULL, NULL); + g_task_set_task_data (task, event, g_free); + meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, + (GSourceFunc) notify_touch_motion); + g_object_unref (task); +} - touch_state->coords.x = x; - touch_state->coords.y = y; +static gboolean +notify_touch_up (GTask *task) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + g_task_get_source_object (task); + MetaSeatImpl *seat = virtual_evdev->seat->impl; + MetaVirtualEventTouch *event = g_task_get_task_data (task); + MetaTouchState *touch_state; - meta_seat_impl_notify_touch_event (virtual_evdev->seat->impl, - virtual_evdev->device, - CLUTTER_TOUCH_BEGIN, - time_us, + if (event->time_us == CLUTTER_CURRENT_TIME) + event->time_us = g_get_monotonic_time (); + + touch_state = meta_seat_impl_lookup_touch_state (seat, + event->device_slot); + if (!touch_state) + goto out; + + meta_seat_impl_notify_touch_event (seat, + virtual_evdev->impl_state->device, + CLUTTER_TOUCH_END, + event->time_us, touch_state->seat_slot, touch_state->coords.x, touch_state->coords.y); + + meta_seat_impl_release_touch_state (virtual_evdev->seat->impl, + touch_state->seat_slot); + + out: + g_task_return_boolean (task, TRUE); + return G_SOURCE_REMOVE; } static void @@ -612,32 +930,22 @@ meta_virtual_input_device_native_notify_touch_up (ClutterVirtualInputDevice *vir uint64_t time_us, int device_slot) { + MetaVirtualEventTouch *event; MetaVirtualInputDeviceNative *virtual_evdev = META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); - MetaTouchState *touch_state; - guint seat_slot; + GTask *task; - g_return_if_fail (virtual_evdev->device != NULL); - - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); - - seat_slot = virtual_evdev->slot_base + (guint) device_slot; - touch_state = meta_seat_impl_lookup_touch_state (virtual_evdev->seat->impl, - seat_slot); - if (!touch_state) - return; + g_return_if_fail (virtual_evdev->impl_state->device != NULL); - meta_seat_impl_notify_touch_event (virtual_evdev->seat->impl, - virtual_evdev->device, - CLUTTER_TOUCH_BEGIN, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); + event = g_new0 (MetaVirtualEventTouch, 1); + event->time_us = time_us; + event->device_slot = virtual_evdev->slot_base + (guint) device_slot; - meta_seat_impl_release_touch_state (virtual_evdev->seat->impl, - touch_state->seat_slot); + task = g_task_new (virtual_device, NULL, NULL, NULL); + g_task_set_task_data (task, event, g_free); + meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, + (GSourceFunc) notify_touch_up); + g_object_unref (task); } static void @@ -701,14 +1009,18 @@ meta_virtual_input_device_native_constructed (GObject *object) "Creating new virtual input device of type %d (%p)", device_type, virtual_device); - virtual_evdev->device = + virtual_evdev->impl_state = g_new0 (ImplState, 1); + virtual_evdev->impl_state->device = meta_input_device_native_new_virtual (virtual_evdev->seat->impl, device_type, CLUTTER_INPUT_MODE_PHYSICAL); +} - g_signal_emit_by_name (virtual_evdev->seat, - "device-added", - virtual_evdev->device); +static void +impl_state_free (ImplState *impl_state) +{ + g_clear_object (&impl_state->device); + g_free (impl_state); } static void @@ -721,14 +1033,18 @@ meta_virtual_input_device_native_dispose (GObject *object) GObjectClass *object_class = G_OBJECT_CLASS (meta_virtual_input_device_native_parent_class); - if (virtual_evdev->device) + if (virtual_evdev->impl_state) { - release_pressed_buttons (virtual_device); - g_signal_emit_by_name (virtual_evdev->seat, - "device-removed", - virtual_evdev->device); + GTask *task; + + task = g_task_new (virtual_device, NULL, NULL, NULL); + g_task_set_task_data (task, virtual_evdev->impl_state, + (GDestroyNotify) impl_state_free); + meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, + (GSourceFunc) release_device); + g_object_unref (task); - g_clear_object (&virtual_evdev->device); + virtual_evdev->impl_state = NULL; } meta_seat_native_release_touch_slots (virtual_evdev->seat, -- GitLab From efc1592d4dba446635a002ef6bc525937d1434f7 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 28 Oct 2020 19:41:40 +0100 Subject: [PATCH 62/85] backends: Make pointer cursor invisible until the stage is shown We are able to show the cursor before that, it doesn't mean we should. Part-of: --- src/backends/meta-backend.c | 11 +++++++++++ src/backends/meta-cursor-tracker.c | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index fb05e078c77..4d213b416bd 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -563,6 +563,14 @@ input_mapper_device_aspect_ratio_cb (MetaInputMapper *mapper, meta_input_settings_set_device_aspect_ratio (input_settings, device, aspect_ratio); } +static void +on_stage_shown_cb (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + meta_cursor_tracker_set_pointer_visible (priv->cursor_tracker, TRUE); +} + static void meta_backend_real_post_init (MetaBackend *backend) { @@ -572,6 +580,9 @@ meta_backend_real_post_init (MetaBackend *backend) priv->stage = meta_stage_new (backend); clutter_actor_realize (priv->stage); META_BACKEND_GET_CLASS (backend)->select_stage_events (backend); + g_signal_connect_object (priv->stage, "show", + G_CALLBACK (on_stage_shown_cb), backend, + G_CONNECT_SWAPPED); meta_monitor_manager_setup (priv->monitor_manager); diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c index 6b3d2289ad6..d2bd22606af 100644 --- a/src/backends/meta-cursor-tracker.c +++ b/src/backends/meta-cursor-tracker.c @@ -196,7 +196,7 @@ meta_cursor_tracker_init (MetaCursorTracker *tracker) MetaCursorTrackerPrivate *priv = meta_cursor_tracker_get_instance_private (tracker); - priv->is_showing = TRUE; + priv->is_showing = FALSE; priv->x = -1.0; priv->y = -1.0; } -- GitLab From c6849a66e88fba6e660f7fdf7297d57de10c9de7 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 18 Nov 2020 15:49:02 +0100 Subject: [PATCH 63/85] clutter: Drop clutter_input_device_get_coords() method This is not device state anymore. It uses ClutterSeat API underneath, so let callers do that instead. Part-of: --- clutter/clutter/clutter-input-device.c | 34 ++----------------- clutter/clutter/clutter-input-device.h | 4 --- clutter/clutter/clutter-stage.c | 3 +- src/backends/meta-backend.c | 2 +- src/backends/meta-cursor-renderer.c | 3 +- src/backends/native/meta-barrier-native.c | 3 +- .../native/meta-pointer-constraint-native.c | 3 +- src/wayland/meta-pointer-lock-wayland.c | 2 +- src/wayland/meta-wayland-cursor-surface.c | 3 +- src/wayland/meta-wayland-data-device.c | 3 +- src/wayland/meta-wayland-pointer.c | 6 ++-- src/wayland/meta-xwayland-dnd.c | 6 ++-- 12 files changed, 24 insertions(+), 48 deletions(-) diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 9a69dd6246a..25dd06ded9e 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -682,37 +682,6 @@ clutter_input_device_get_device_type (ClutterInputDevice *device) return device->device_type; } -/** - * clutter_input_device_get_coords: - * @device: a #ClutterInputDevice - * @sequence: (allow-none): a #ClutterEventSequence, or %NULL if - * the device is not touch-based - * @point: (out caller-allocates): return location for the pointer - * or touch point - * - * Retrieves the latest coordinates of a pointer or touch point of - * @device. - * - * Return value: %FALSE if the device's sequence hasn't been found, - * and %TRUE otherwise. - * - * Since: 1.12 - */ -gboolean -clutter_input_device_get_coords (ClutterInputDevice *device, - ClutterEventSequence *sequence, - graphene_point_t *point) -{ - ClutterSeat *seat; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - g_return_val_if_fail (point != NULL, FALSE); - - seat = clutter_input_device_get_seat (device); - - return clutter_seat_query_state (seat, device, sequence, point, NULL); -} - /* * clutter_input_device_update: * @device: a #ClutterInputDevice @@ -750,7 +719,8 @@ clutter_input_device_update (ClutterInputDevice *device, } else { - clutter_input_device_get_coords (device, sequence, &point); + clutter_seat_query_state (clutter_input_device_get_seat (device), + device, NULL, &point, NULL); time_ms = CLUTTER_CURRENT_TIME; } diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index e95909b5758..5952745ee83 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -83,10 +83,6 @@ GType clutter_input_device_get_type (void) G_GNUC_CONST; CLUTTER_EXPORT ClutterInputDeviceType clutter_input_device_get_device_type (ClutterInputDevice *device); -CLUTTER_EXPORT -gboolean clutter_input_device_get_coords (ClutterInputDevice *device, - ClutterEventSequence *sequence, - graphene_point_t *point); CLUTTER_EXPORT ClutterModifierType clutter_input_device_get_modifier_state (ClutterInputDevice *device); CLUTTER_EXPORT diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index dbfdfecebdf..a7261d36dd0 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -909,7 +909,8 @@ clutter_stage_find_updated_devices (ClutterStage *stage) case CLUTTER_PEN_DEVICE: case CLUTTER_ERASER_DEVICE: case CLUTTER_CURSOR_DEVICE: - if (!clutter_input_device_get_coords (dev, NULL, &point)) + if (!clutter_seat_query_state (seat, dev, NULL, + &point, NULL)) continue; view = clutter_stage_get_view_at (stage, point.x, point.y); diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 4d213b416bd..ddedfdd60e2 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -324,7 +324,7 @@ meta_backend_monitors_changed (MetaBackend *backend) meta_backend_sync_screen_size (backend); - if (clutter_input_device_get_coords (device, NULL, &point)) + if (clutter_seat_query_state (seat, device, NULL, &point, NULL)) { /* If we're outside all monitors, warp the pointer back inside */ if ((!meta_monitor_manager_get_logical_monitor_at (monitor_manager, diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c index a0b09c77884..46f561fe33d 100644 --- a/src/backends/meta-cursor-renderer.c +++ b/src/backends/meta-cursor-renderer.c @@ -448,7 +448,8 @@ meta_cursor_renderer_update_position (MetaCursorRenderer *renderer) MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); graphene_point_t pos; - clutter_input_device_get_coords (priv->device, NULL, &pos); + clutter_seat_query_state (clutter_input_device_get_seat (priv->device), + priv->device, NULL, &pos, NULL); priv->current_x = pos.x; priv->current_y = pos.y; diff --git a/src/backends/native/meta-barrier-native.c b/src/backends/native/meta-barrier-native.c index 8db73ee0689..d6267ceacd2 100644 --- a/src/backends/native/meta-barrier-native.c +++ b/src/backends/native/meta-barrier-native.c @@ -515,7 +515,8 @@ meta_barrier_manager_native_process (MetaBarrierManagerNative *manager, MetaBarrierEventData barrier_event_data; MetaBarrierImplNative *barrier_impl; - if (!clutter_input_device_get_coords (device, NULL, &prev_pos)) + if (!clutter_seat_query_state (clutter_input_device_get_seat (device), + device, NULL, &prev_pos, NULL)) return; g_mutex_lock (&manager->mutex); diff --git a/src/backends/native/meta-pointer-constraint-native.c b/src/backends/native/meta-pointer-constraint-native.c index 8ce678ae4a4..6a1c066ade3 100644 --- a/src/backends/native/meta-pointer-constraint-native.c +++ b/src/backends/native/meta-pointer-constraint-native.c @@ -609,7 +609,8 @@ meta_pointer_constraint_impl_native_ensure_constrained (MetaPointerConstraintImp constraint_impl_native = META_POINTER_CONSTRAINT_IMPL_NATIVE (constraint_impl); region = cairo_region_reference (constraint_impl_native->region); - clutter_input_device_get_coords (device, NULL, &point); + clutter_seat_query_state (clutter_input_device_get_seat (device), + device, NULL, &point, NULL); x = point.x; y = point.y; diff --git a/src/wayland/meta-pointer-lock-wayland.c b/src/wayland/meta-pointer-lock-wayland.c index e8722473232..9e0e8bcb8c0 100644 --- a/src/wayland/meta-pointer-lock-wayland.c +++ b/src/wayland/meta-pointer-lock-wayland.c @@ -63,7 +63,7 @@ meta_pointer_lock_wayland_create_constraint (MetaPointerConfinementWayland *conf cairo_region_t *region; float sx, sy, x, y; - clutter_input_device_get_coords (pointer, NULL, &point); + clutter_seat_query_state (seat, pointer, NULL, &point, NULL); wayland_constraint = meta_pointer_confinement_wayland_get_wayland_pointer_constraint (confinement); surface = meta_wayland_pointer_constraint_get_surface (wayland_constraint); diff --git a/src/wayland/meta-wayland-cursor-surface.c b/src/wayland/meta-wayland-cursor-surface.c index 7281be8541d..60c5d6c3dbc 100644 --- a/src/wayland/meta-wayland-cursor-surface.c +++ b/src/wayland/meta-wayland-cursor-surface.c @@ -198,7 +198,8 @@ meta_wayland_cursor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *role, meta_rectangle_to_graphene_rect (&logical_monitor->rect); device = meta_cursor_renderer_get_input_device (priv->cursor_renderer); - clutter_input_device_get_coords (device, NULL, &point); + clutter_seat_query_state (clutter_input_device_get_seat (device), + device, NULL, &point, NULL); return graphene_rect_contains_point (&logical_monitor_rect, &point); } diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index 9231ac59427..6e7a838a69f 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -641,7 +641,8 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data 0, 0); clutter_actor_add_child (drag_grab->feedback_actor, drag_surface_actor); - clutter_input_device_get_coords (seat->pointer->device, NULL, &pos); + clutter_seat_query_state (clutter_input_device_get_seat (seat->pointer->device), + seat->pointer->device, NULL, &pos, NULL); meta_feedback_actor_set_position (META_FEEDBACK_ACTOR (drag_grab->feedback_actor), pos.x, pos.y); } diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index c71a5eee18f..df7d6a442d7 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -949,7 +949,8 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, G_CALLBACK (focus_surface_destroyed), pointer); - clutter_input_device_get_coords (pointer->device, NULL, &pos); + clutter_seat_query_state (clutter_input_device_get_seat (pointer->device), + pointer->device, NULL, &pos, NULL); focus_window = meta_wayland_surface_get_window (pointer->focus_surface); if (focus_window) @@ -1061,7 +1062,8 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer, float xf = 0.0f, yf = 0.0f; graphene_point_t pos; - clutter_input_device_get_coords (pointer->device, NULL, &pos); + clutter_seat_query_state (clutter_input_device_get_seat (pointer->device), + pointer->device, NULL, &pos, NULL); meta_wayland_surface_get_relative_coordinates (surface, pos.x, pos.y, &xf, &yf); *sx = wl_fixed_from_double (xf); diff --git a/src/wayland/meta-xwayland-dnd.c b/src/wayland/meta-xwayland-dnd.c index 60f416821f0..7f19be24cf8 100644 --- a/src/wayland/meta-xwayland-dnd.c +++ b/src/wayland/meta-xwayland-dnd.c @@ -546,7 +546,8 @@ meta_x11_drag_dest_update (MetaWaylandDataDevice *data_device, MetaWaylandSeat *seat = compositor->seat; graphene_point_t pos; - clutter_input_device_get_coords (seat->pointer->device, NULL, &pos); + clutter_seat_query_state (clutter_input_device_get_seat (seat->pointer->device), + seat->pointer->device, NULL, &pos, NULL); xdnd_send_position (dnd, dnd->dnd_dest, clutter_get_current_event_time (), pos.x, pos.y); @@ -834,7 +835,8 @@ meta_xwayland_dnd_handle_client_message (MetaWaylandCompositor *compositor, dnd->client_message_timestamp = event->data.l[3]; motion = clutter_event_new (CLUTTER_MOTION); - clutter_input_device_get_coords (seat->pointer->device, NULL, &pos); + clutter_seat_query_state (clutter_input_device_get_seat (seat->pointer->device), + seat->pointer->device, NULL, &pos, NULL); clutter_event_set_coords (motion, pos.x, pos.y); clutter_event_set_device (motion, seat->pointer->device); clutter_event_set_source_device (motion, seat->pointer->device); -- GitLab From d58e082500a321b82db48e6a756d8be0b3d41226 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 18 Nov 2020 15:58:10 +0100 Subject: [PATCH 64/85] clutter: Drop clutter_input_device_get_modifier_state() API This is using ClutterSeat state queries underneath, let the only caller do that, and drop this call. Part-of: --- clutter/clutter/clutter-input-device.c | 27 -------------------------- clutter/clutter/clutter-input-device.h | 2 -- src/wayland/meta-wayland-data-device.c | 3 ++- 3 files changed, 2 insertions(+), 30 deletions(-) diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 25dd06ded9e..d3059c2c25c 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -465,33 +465,6 @@ clutter_input_device_init (ClutterInputDevice *self) self->inv_touch_sequence_actors = g_hash_table_new (NULL, NULL); } -/** - * clutter_input_device_get_modifier_state: - * @device: a #ClutterInputDevice - * - * Retrieves the current modifiers state of the device, as seen - * by the last event Clutter processed. - * - * Return value: the last known modifier state - * - * Since: 1.16 - */ -ClutterModifierType -clutter_input_device_get_modifier_state (ClutterInputDevice *device) -{ - uint32_t modifiers; - ClutterSeat *seat; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0); - - seat = clutter_input_device_get_seat (device); - - if (!clutter_seat_query_state (seat, device, NULL, NULL, &modifiers)) - return 0; - - return modifiers; -} - static void _clutter_input_device_associate_actor (ClutterInputDevice *device, ClutterEventSequence *sequence, diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index 5952745ee83..34206afb736 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -83,8 +83,6 @@ GType clutter_input_device_get_type (void) G_GNUC_CONST; CLUTTER_EXPORT ClutterInputDeviceType clutter_input_device_get_device_type (ClutterInputDevice *device); -CLUTTER_EXPORT -ClutterModifierType clutter_input_device_get_modifier_state (ClutterInputDevice *device); CLUTTER_EXPORT ClutterActor * clutter_input_device_get_actor (ClutterInputDevice *device, ClutterEventSequence *sequence); diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index 6e7a838a69f..b5f9a0c37f1 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -612,7 +612,8 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data drag_grab->need_initial_focus = TRUE; - modifiers = clutter_input_device_get_modifier_state (seat->pointer->device); + clutter_seat_query_state (clutter_input_device_get_seat (seat->pointer->device), + seat->pointer->device, NULL, NULL, &modifiers); drag_grab->buttons = modifiers & (CLUTTER_BUTTON1_MASK | CLUTTER_BUTTON2_MASK | CLUTTER_BUTTON3_MASK | CLUTTER_BUTTON4_MASK | CLUTTER_BUTTON5_MASK); -- GitLab From 699da157c70464725e0519223e5de2aeeb3a2556 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 18 Nov 2020 16:07:12 +0100 Subject: [PATCH 65/85] clutter: Drop clutter_input_device_get_key()/n_keys API And the corresponding setters. This is completely unused, and unrecommended. In xkb we trust. Part-of: --- .../clutter/clutter-input-device-private.h | 18 --- clutter/clutter/clutter-input-device.c | 115 ------------------ clutter/clutter/clutter-input-device.h | 8 -- src/backends/x11/meta-seat-x11.c | 17 --- 4 files changed, 158 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index 2b8dca60497..31be9dfef24 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -45,12 +45,6 @@ typedef struct _ClutterAxisInfo double resolution; } ClutterAxisInfo; -typedef struct _ClutterKeyInfo -{ - guint keyval; - ClutterModifierType modifiers; -} ClutterKeyInfo; - typedef struct _ClutterScrollInfo { guint axis_id; @@ -124,9 +118,6 @@ struct _ClutterInputDevice GArray *axes; - guint n_keys; - GArray *keys; - GArray *scroll_info; char *vendor_id; @@ -169,15 +160,6 @@ CLUTTER_EXPORT void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, ClutterEvent *event); CLUTTER_EXPORT -void _clutter_input_device_set_n_keys (ClutterInputDevice *device, - guint n_keys); -CLUTTER_EXPORT -void clutter_input_device_set_key (ClutterInputDevice *device, - guint index_, - guint keyval, - ClutterModifierType modifiers); - -CLUTTER_EXPORT gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device, guint index_, gdouble value, diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index d3059c2c25c..e6c6f6f79ce 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -108,7 +108,6 @@ clutter_input_device_dispose (GObject *gobject) g_clear_object (&device->accessibility_virtual_device); g_clear_pointer (&device->axes, g_array_unref); - g_clear_pointer (&device->keys, g_array_unref); g_clear_pointer (&device->scroll_info, g_array_unref); g_clear_pointer (&device->touch_sequence_actors, g_hash_table_unref); @@ -1041,120 +1040,6 @@ clutter_input_device_get_n_axes (ClutterInputDevice *device) return 0; } -/*< private > - * clutter_input_device_set_n_keys: - * @device: a #ClutterInputDevice - * @n_keys: the number of keys of the device - * - * Initializes the keys of @device. - * - * Call clutter_input_device_set_key() on each key to set the keyval - * and modifiers. - */ -void -_clutter_input_device_set_n_keys (ClutterInputDevice *device, - guint n_keys) -{ - if (device->keys != NULL) - g_array_free (device->keys, TRUE); - - device->n_keys = n_keys; - device->keys = g_array_sized_new (FALSE, TRUE, - sizeof (ClutterKeyInfo), - n_keys); -} - -/** - * clutter_input_device_get_n_keys: - * @device: a #ClutterInputDevice - * - * Retrieves the number of keys registered for @device. - * - * Return value: the number of registered keys - * - * Since: 1.6 - */ -guint -clutter_input_device_get_n_keys (ClutterInputDevice *device) -{ - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0); - - return device->n_keys; -} - -/** - * clutter_input_device_set_key: - * @device: a #ClutterInputDevice - * @index_: the index of the key - * @keyval: the keyval - * @modifiers: a bitmask of modifiers - * - * Sets the keyval and modifiers at the given @index_ for @device. - * - * Clutter will use the keyval and modifiers set when filling out - * an event coming from the same input device. - * - * Since: 1.6 - */ -void -clutter_input_device_set_key (ClutterInputDevice *device, - guint index_, - guint keyval, - ClutterModifierType modifiers) -{ - ClutterKeyInfo *key_info; - - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - g_return_if_fail (index_ < device->n_keys); - - key_info = &g_array_index (device->keys, ClutterKeyInfo, index_); - key_info->keyval = keyval; - key_info->modifiers = modifiers; -} - -/** - * clutter_input_device_get_key: - * @device: a #ClutterInputDevice - * @index_: the index of the key - * @keyval: (out): return location for the keyval at @index_ - * @modifiers: (out): return location for the modifiers at @index_ - * - * Retrieves the key set using clutter_input_device_set_key() - * - * Return value: %TRUE if a key was set at the given index - * - * Since: 1.6 - */ -gboolean -clutter_input_device_get_key (ClutterInputDevice *device, - guint index_, - guint *keyval, - ClutterModifierType *modifiers) -{ - ClutterKeyInfo *key_info; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - - if (device->keys == NULL) - return FALSE; - - if (index_ > device->keys->len) - return FALSE; - - key_info = &g_array_index (device->keys, ClutterKeyInfo, index_); - - if (!key_info->keyval && !key_info->modifiers) - return FALSE; - - if (keyval) - *keyval = key_info->keyval; - - if (modifiers) - *modifiers = key_info->modifiers; - - return TRUE; -} - /*< private > * clutter_input_device_add_physical_device: * @logical: a #ClutterInputDevice diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index 34206afb736..78b09ef2a9b 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -104,14 +104,6 @@ gboolean clutter_input_device_get_axis_value (ClutterInputDev ClutterInputAxis axis, gdouble *value); -CLUTTER_EXPORT -guint clutter_input_device_get_n_keys (ClutterInputDevice *device); -CLUTTER_EXPORT -gboolean clutter_input_device_get_key (ClutterInputDevice *device, - guint index_, - guint *keyval, - ClutterModifierType *modifiers); - CLUTTER_EXPORT ClutterInputDevice * clutter_input_device_get_associated_device (ClutterInputDevice *device); CLUTTER_EXPORT diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index 24d6369b880..26fe0680dec 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -175,23 +175,6 @@ translate_device_classes (Display *xdisplay, switch (class_info->type) { - case XIKeyClass: - { - XIKeyClassInfo *key_info = (XIKeyClassInfo *) class_info; - int j; - - _clutter_input_device_set_n_keys (device, - key_info->num_keycodes); - - for (j = 0; j < key_info->num_keycodes; j++) - { - clutter_input_device_set_key (device, j, - key_info->keycodes[i], - 0); - } - } - break; - case XIValuatorClass: translate_valuator_class (xdisplay, device, (XIValuatorClassInfo *) class_info); -- GitLab From c4fa5ef88a7a7062d3909f0dcc4b951b6149682b Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 18 Nov 2020 17:13:30 +0100 Subject: [PATCH 66/85] clutter: Drop clutter_input_device_get_physical_devices() API This is unused, we have the seat for this kind of stuff. Part-of: --- .../clutter/clutter-input-device-private.h | 8 --- clutter/clutter/clutter-input-device.c | 59 ------------------- clutter/clutter/clutter-input-device.h | 2 - src/backends/native/meta-seat-impl.c | 5 +- src/backends/x11/meta-seat-x11.c | 39 +----------- 5 files changed, 4 insertions(+), 109 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index 31be9dfef24..6fe519bdb21 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -88,8 +88,6 @@ struct _ClutterInputDevice /* the associated device */ ClutterInputDevice *associated; - GList *physical_devices; - /* the actor underneath the pointer */ ClutterActor *cursor_actor; GHashTable *inv_touch_sequence_actors; @@ -142,12 +140,6 @@ CLUTTER_EXPORT void _clutter_input_device_set_associated_device (ClutterInputDevice *device, ClutterInputDevice *associated); CLUTTER_EXPORT -void _clutter_input_device_add_physical_device (ClutterInputDevice *logical, - ClutterInputDevice *physical); -CLUTTER_EXPORT -void _clutter_input_device_remove_physical_device (ClutterInputDevice *logical, - ClutterInputDevice *physical); -CLUTTER_EXPORT void clutter_input_device_update_from_tool (ClutterInputDevice *device, ClutterInputDeviceTool *tool); CLUTTER_EXPORT diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index e6c6f6f79ce..41a941ad984 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -96,9 +96,6 @@ clutter_input_device_dispose (GObject *gobject) if (device->associated != NULL) { - if (device->device_mode == CLUTTER_INPUT_MODE_PHYSICAL) - _clutter_input_device_remove_physical_device (device->associated, device); - _clutter_input_device_set_associated_device (device->associated, NULL); g_object_unref (device->associated); device->associated = NULL; @@ -1040,42 +1037,6 @@ clutter_input_device_get_n_axes (ClutterInputDevice *device) return 0; } -/*< private > - * clutter_input_device_add_physical_device: - * @logical: a #ClutterInputDevice - * @physical: a #ClutterInputDevice - * - * Adds @physical to the list of physical devices of @logical - * - * This function does not increase the reference count of either @logical - * or @physical. - */ -void -_clutter_input_device_add_physical_device (ClutterInputDevice *logical, - ClutterInputDevice *physical) -{ - if (g_list_find (logical->physical_devices, physical) == NULL) - logical->physical_devices = g_list_prepend (logical->physical_devices, physical); -} - -/*< private > - * clutter_input_device_remove_physical_device: - * @logical: a #ClutterInputDevice - * @physical: a #ClutterInputDevice - * - * Removes @physical from the list of physical devices of @logical. - * - * This function does not decrease the reference count of either @logical - * or @physical. - */ -void -_clutter_input_device_remove_physical_device (ClutterInputDevice *logical, - ClutterInputDevice *physical) -{ - if (g_list_find (logical->physical_devices, physical) != NULL) - logical->physical_devices = g_list_remove (logical->physical_devices, physical); -} - /*< private > * clutter_input_device_remove_sequence: * @device: a #ClutterInputDevice @@ -1112,26 +1073,6 @@ _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, } } -/** - * clutter_input_device_get_physical_devices: - * @device: a #ClutterInputDevice - * - * Retrieves the physical devices attached to @device. - * - * Return value: (transfer container) (element-type Clutter.InputDevice): a - * list of #ClutterInputDevice, or %NULL. The contents of the list are - * owned by the device. Use g_list_free() when done - * - * Since: 1.6 - */ -GList * -clutter_input_device_get_physical_devices (ClutterInputDevice *device) -{ - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - - return g_list_copy (device->physical_devices); -} - /*< internal > * clutter_input_device_set_associated_device: * @device: a #ClutterInputDevice diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index 78b09ef2a9b..42948f59140 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -106,8 +106,6 @@ gboolean clutter_input_device_get_axis_value (ClutterInputDev CLUTTER_EXPORT ClutterInputDevice * clutter_input_device_get_associated_device (ClutterInputDevice *device); -CLUTTER_EXPORT -GList * clutter_input_device_get_physical_devices (ClutterInputDevice *device); CLUTTER_EXPORT void clutter_input_device_grab (ClutterInputDevice *device, diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 69be7c97622..386aee5cd2a 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -1527,10 +1527,7 @@ evdev_add_device (MetaSeatImpl *seat_impl, master = seat_impl->core_pointer; if (master) - { - _clutter_input_device_set_associated_device (device, master); - _clutter_input_device_add_physical_device (master, device); - } + _clutter_input_device_set_associated_device (device, master); is_touchscreen = type == CLUTTER_TOUCHSCREEN_DEVICE; is_tablet_switch = diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index 26fe0680dec..30fbf6b0415 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -664,7 +664,6 @@ add_device (MetaSeatX11 *seat_x11, logical = g_hash_table_lookup (seat_x11->devices_by_id, GINT_TO_POINTER (info->attachment)); _clutter_input_device_set_associated_device (device, logical); - _clutter_input_device_add_physical_device (logical, device); } } @@ -757,21 +756,6 @@ relate_logical_devices (gpointer key, _clutter_input_device_set_associated_device (relative, device); } -static void -relate_physical_devices (gpointer key, - gpointer value, - gpointer data) -{ - MetaSeatX11 *seat_x11 = data; - ClutterInputDevice *logical, *physical; - - physical = g_hash_table_lookup (seat_x11->devices_by_id, key); - logical = g_hash_table_lookup (seat_x11->devices_by_id, value); - - _clutter_input_device_set_associated_device (physical, logical); - _clutter_input_device_add_physical_device (logical, physical); -} - static uint device_get_tool_serial (ClutterInputDevice *device) { @@ -879,10 +863,7 @@ translate_hierarchy_event (ClutterBackend *backend, /* detach the physical device in both cases */ if (logical != NULL) - { - _clutter_input_device_remove_physical_device (logical, physical); - _clutter_input_device_set_associated_device (physical, NULL); - } + _clutter_input_device_set_associated_device (physical, NULL); /* and attach the physical device to the new logical device if needed */ if (ev->info[i].flags & XISlaveAttached) @@ -897,10 +878,7 @@ translate_hierarchy_event (ClutterBackend *backend, logical = g_hash_table_lookup (seat_x11->devices_by_id, GINT_TO_POINTER (info->attachment)); if (logical != NULL) - { - _clutter_input_device_set_associated_device (physical, logical); - _clutter_input_device_add_physical_device (logical, physical); - } + _clutter_input_device_set_associated_device (physical, logical); XIFreeDeviceInfo (info); } } @@ -1411,7 +1389,7 @@ meta_seat_x11_constructed (GObject *object) { MetaSeatX11 *seat_x11 = META_SEAT_X11 (object); ClutterBackend *backend = clutter_get_default_backend (); - GHashTable *logical_devices, *physical_devices; + GHashTable *logical_devices; XIDeviceInfo *info; XIEventMask event_mask; unsigned char mask[XIMaskLen(XI_LASTEVENT)] = { 0, }; @@ -1420,7 +1398,6 @@ meta_seat_x11_constructed (GObject *object) xdisplay = clutter_x11_get_default_display (); logical_devices = g_hash_table_new (NULL, NULL); - physical_devices = g_hash_table_new (NULL, NULL); info = XIQueryDevice (clutter_x11_get_default_display (), XIAllDevices, &n_devices); @@ -1441,13 +1418,6 @@ meta_seat_x11_constructed (GObject *object) GINT_TO_POINTER (xi_device->deviceid), GINT_TO_POINTER (xi_device->attachment)); } - else if (xi_device->use == XISlavePointer || - xi_device->use == XISlaveKeyboard) - { - g_hash_table_insert (physical_devices, - GINT_TO_POINTER (xi_device->deviceid), - GINT_TO_POINTER (xi_device->attachment)); - } } XIFreeDeviceInfo (info); @@ -1455,9 +1425,6 @@ meta_seat_x11_constructed (GObject *object) g_hash_table_foreach (logical_devices, relate_logical_devices, seat_x11); g_hash_table_destroy (logical_devices); - g_hash_table_foreach (physical_devices, relate_physical_devices, seat_x11); - g_hash_table_destroy (physical_devices); - XISetMask (mask, XI_HierarchyChanged); XISetMask (mask, XI_DeviceChanged); XISetMask (mask, XI_PropertyEvent); -- GitLab From be9c531ab94dfbbe66b691358d8fa62452363e18 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 18 Nov 2020 17:51:48 +0100 Subject: [PATCH 67/85] clutter: Drop clutter_input_device_get_associated_device() And the private setter. One may ask the seat for the pointer/keyboard instead of asking the device for its counterpart. Part-of: --- .../clutter/clutter-input-device-private.h | 6 -- clutter/clutter/clutter-input-device.c | 70 ---------------- clutter/clutter/clutter-input-device.h | 3 - src/backends/native/meta-seat-impl.c | 10 +-- src/backends/x11/meta-seat-x11.c | 80 +------------------ 5 files changed, 4 insertions(+), 165 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index 6fe519bdb21..3c541376424 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -85,9 +85,6 @@ struct _ClutterInputDevice ClutterBackend *backend; - /* the associated device */ - ClutterInputDevice *associated; - /* the actor underneath the pointer */ ClutterActor *cursor_actor; GHashTable *inv_touch_sequence_actors; @@ -136,9 +133,6 @@ struct _ClutterInputDevice ClutterPtrA11yData *ptr_a11y_data; }; -CLUTTER_EXPORT -void _clutter_input_device_set_associated_device (ClutterInputDevice *device, - ClutterInputDevice *associated); CLUTTER_EXPORT void clutter_input_device_update_from_tool (ClutterInputDevice *device, ClutterInputDeviceTool *tool); diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 41a941ad984..b8b10fd35ca 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -94,13 +94,6 @@ clutter_input_device_dispose (GObject *gobject) g_clear_pointer (&device->product_id, g_free); g_clear_pointer (&device->node_path, g_free); - if (device->associated != NULL) - { - _clutter_input_device_set_associated_device (device->associated, NULL); - g_object_unref (device->associated); - device->associated = NULL; - } - if (device->accessibility_virtual_device) g_clear_object (&device->accessibility_virtual_device); @@ -1073,69 +1066,6 @@ _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, } } -/*< internal > - * clutter_input_device_set_associated_device: - * @device: a #ClutterInputDevice - * @associated: (allow-none): a #ClutterInputDevice, or %NULL - * - * Sets the associated device for @device. - * - * This function keeps a reference on the associated device. - */ -void -_clutter_input_device_set_associated_device (ClutterInputDevice *device, - ClutterInputDevice *associated) -{ - if (device->associated == associated) - return; - - if (device->associated != NULL) - g_object_unref (device->associated); - - device->associated = associated; - if (device->associated != NULL) - g_object_ref (device->associated); - - CLUTTER_NOTE (MISC, "Associating device '%s' to device '%s'", - clutter_input_device_get_device_name (device), - device->associated != NULL - ? clutter_input_device_get_device_name (device->associated) - : "(none)"); - - if (device->device_mode != CLUTTER_INPUT_MODE_LOGICAL) - { - if (device->associated != NULL) - device->device_mode = CLUTTER_INPUT_MODE_PHYSICAL; - else - device->device_mode = CLUTTER_INPUT_MODE_FLOATING; - - g_object_notify_by_pspec (G_OBJECT (device), obj_props[PROP_DEVICE_MODE]); - } -} - -/** - * clutter_input_device_get_associated_device: - * @device: a #ClutterInputDevice - * - * Retrieves a pointer to the #ClutterInputDevice that has been - * associated to @device. - * - * If the #ClutterInputDevice:device-mode property of @device is - * set to %CLUTTER_INPUT_MODE_LOGICAL, this function will return - * %NULL. - * - * Return value: (transfer none): a #ClutterInputDevice, or %NULL - * - * Since: 1.6 - */ -ClutterInputDevice * -clutter_input_device_get_associated_device (ClutterInputDevice *device) -{ - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - - return device->associated; -} - /** * clutter_input_device_keycode_to_evdev: * @device: A #ClutterInputDevice diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index 42948f59140..8ae53f82d99 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -104,9 +104,6 @@ gboolean clutter_input_device_get_axis_value (ClutterInputDev ClutterInputAxis axis, gdouble *value); -CLUTTER_EXPORT -ClutterInputDevice * clutter_input_device_get_associated_device (ClutterInputDevice *device); - CLUTTER_EXPORT void clutter_input_device_grab (ClutterInputDevice *device, ClutterActor *actor); diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 386aee5cd2a..0eea3980645 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -1510,7 +1510,7 @@ evdev_add_device (MetaSeatImpl *seat_impl, struct libinput_device *libinput_device) { ClutterInputDeviceType type; - ClutterInputDevice *device, *master = NULL; + ClutterInputDevice *device; gboolean is_touchscreen, is_tablet_switch; device = meta_input_device_native_new (seat_impl, libinput_device); @@ -1521,14 +1521,6 @@ evdev_add_device (MetaSeatImpl *seat_impl, * ClutterInputDevice API */ type = meta_input_device_native_determine_type (libinput_device); - if (type == CLUTTER_KEYBOARD_DEVICE) - master = seat_impl->core_keyboard; - else if (type == CLUTTER_POINTER_DEVICE) - master = seat_impl->core_pointer; - - if (master) - _clutter_input_device_set_associated_device (device, master); - is_touchscreen = type == CLUTTER_TOUCHSCREEN_DEVICE; is_tablet_switch = device_is_tablet_switch (META_INPUT_DEVICE_NATIVE (device)); diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index 30fbf6b0415..a8f4f9fd11f 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -615,8 +615,7 @@ update_touch_mode (MetaSeatX11 *seat_x11) static ClutterInputDevice * add_device (MetaSeatX11 *seat_x11, ClutterBackend *backend, - XIDeviceInfo *info, - gboolean in_construction) + XIDeviceInfo *info) { ClutterInputDevice *device; @@ -652,21 +651,6 @@ add_device (MetaSeatX11 *seat_x11, if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE) pad_passive_button_grab (device); - /* relationships between devices and signal emissions are not - * necessary while we're constructing the device manager instance - */ - if (!in_construction) - { - if (info->use == XISlavePointer || info->use == XISlaveKeyboard) - { - ClutterInputDevice *logical; - - logical = g_hash_table_lookup (seat_x11->devices_by_id, - GINT_TO_POINTER (info->attachment)); - _clutter_input_device_set_associated_device (device, logical); - } - } - return device; } @@ -741,21 +725,6 @@ meta_seat_x11_handle_event_post (ClutterSeat *seat, return TRUE; } -static void -relate_logical_devices (gpointer key, - gpointer value, - gpointer data) -{ - MetaSeatX11 *seat_x11 = data; - ClutterInputDevice *device, *relative; - - device = g_hash_table_lookup (seat_x11->devices_by_id, key); - relative = g_hash_table_lookup (seat_x11->devices_by_id, value); - - _clutter_input_device_set_associated_device (device, relative); - _clutter_input_device_set_associated_device (relative, device); -} - static uint device_get_tool_serial (ClutterInputDevice *device) { @@ -814,7 +783,7 @@ translate_hierarchy_event (ClutterBackend *backend, { ClutterInputDevice *device; - device = add_device (seat_x11, backend, &info[0], FALSE); + device = add_device (seat_x11, backend, &info[0]); event->any.type = CLUTTER_DEVICE_ADDED; event->any.time = ev->time; @@ -848,40 +817,10 @@ translate_hierarchy_event (ClutterBackend *backend, else if ((ev->info[i].flags & XISlaveAttached) || (ev->info[i].flags & XISlaveDetached)) { - ClutterInputDevice *logical, *physical; - XIDeviceInfo *info; - int n_devices; - g_debug ("Hierarchy event: physical device %s", (ev->info[i].flags & XISlaveAttached) ? "attached" : "detached"); - - physical = g_hash_table_lookup (seat_x11->devices_by_id, - GINT_TO_POINTER (ev->info[i].deviceid)); - logical = clutter_input_device_get_associated_device (physical); - - /* detach the physical device in both cases */ - if (logical != NULL) - _clutter_input_device_set_associated_device (physical, NULL); - - /* and attach the physical device to the new logical device if needed */ - if (ev->info[i].flags & XISlaveAttached) - { - clutter_x11_trap_x_errors (); - info = XIQueryDevice (clutter_x11_get_default_display (), - ev->info[i].deviceid, - &n_devices); - clutter_x11_untrap_x_errors (); - if (info != NULL) - { - logical = g_hash_table_lookup (seat_x11->devices_by_id, - GINT_TO_POINTER (info->attachment)); - if (logical != NULL) - _clutter_input_device_set_associated_device (physical, logical); - XIFreeDeviceInfo (info); - } - } } } @@ -1389,7 +1328,6 @@ meta_seat_x11_constructed (GObject *object) { MetaSeatX11 *seat_x11 = META_SEAT_X11 (object); ClutterBackend *backend = clutter_get_default_backend (); - GHashTable *logical_devices; XIDeviceInfo *info; XIEventMask event_mask; unsigned char mask[XIMaskLen(XI_LASTEVENT)] = { 0, }; @@ -1397,7 +1335,6 @@ meta_seat_x11_constructed (GObject *object) Display *xdisplay; xdisplay = clutter_x11_get_default_display (); - logical_devices = g_hash_table_new (NULL, NULL); info = XIQueryDevice (clutter_x11_get_default_display (), XIAllDevices, &n_devices); @@ -1409,22 +1346,11 @@ meta_seat_x11_constructed (GObject *object) if (!xi_device->enabled) continue; - add_device (seat_x11, backend, xi_device, TRUE); - - if (xi_device->use == XIMasterPointer || - xi_device->use == XIMasterKeyboard) - { - g_hash_table_insert (logical_devices, - GINT_TO_POINTER (xi_device->deviceid), - GINT_TO_POINTER (xi_device->attachment)); - } + add_device (seat_x11, backend, xi_device); } XIFreeDeviceInfo (info); - g_hash_table_foreach (logical_devices, relate_logical_devices, seat_x11); - g_hash_table_destroy (logical_devices); - XISetMask (mask, XI_HierarchyChanged); XISetMask (mask, XI_DeviceChanged); XISetMask (mask, XI_PropertyEvent); -- GitLab From e772f62ea7d265cce1e7d5ad18dc82e6481ba418 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 19 Nov 2020 00:47:04 +0100 Subject: [PATCH 68/85] clutter: Make axes part of the device tool This info can be construct-only there, as opposed to devices. Move this info to tools, so we can drop it from devices. Part-of: --- clutter/clutter/clutter-enums.h | 14 ++++ clutter/clutter/clutter-input-device-tool.c | 27 +++++++ clutter/clutter/clutter-input-device-tool.h | 3 + .../native/meta-input-device-tool-native.c | 22 ++++++ src/backends/x11/meta-input-device-tool-x11.c | 11 +++ src/wayland/meta-wayland-tablet-tool.c | 76 ++++--------------- 6 files changed, 93 insertions(+), 60 deletions(-) diff --git a/clutter/clutter/clutter-enums.h b/clutter/clutter/clutter-enums.h index cd058b3e75d..bcc848b3834 100644 --- a/clutter/clutter/clutter-enums.h +++ b/clutter/clutter/clutter-enums.h @@ -1050,6 +1050,20 @@ typedef enum CLUTTER_INPUT_AXIS_LAST } ClutterInputAxis; +typedef enum +{ + CLUTTER_INPUT_AXIS_FLAG_NONE = 0, + CLUTTER_INPUT_AXIS_FLAG_X = 1 << CLUTTER_INPUT_AXIS_X, + CLUTTER_INPUT_AXIS_FLAG_Y = 1 << CLUTTER_INPUT_AXIS_Y, + CLUTTER_INPUT_AXIS_FLAG_PRESSURE = 1 << CLUTTER_INPUT_AXIS_PRESSURE, + CLUTTER_INPUT_AXIS_FLAG_XTILT = 1 << CLUTTER_INPUT_AXIS_XTILT, + CLUTTER_INPUT_AXIS_FLAG_YTILT = 1 << CLUTTER_INPUT_AXIS_YTILT, + CLUTTER_INPUT_AXIS_FLAG_WHEEL = 1 << CLUTTER_INPUT_AXIS_WHEEL, + CLUTTER_INPUT_AXIS_FLAG_DISTANCE = 1 << CLUTTER_INPUT_AXIS_DISTANCE, + CLUTTER_INPUT_AXIS_FLAG_ROTATION = 1 << CLUTTER_INPUT_AXIS_ROTATION, + CLUTTER_INPUT_AXIS_FLAG_SLIDER = 1 << CLUTTER_INPUT_AXIS_SLIDER, +} ClutterInputAxisFlags; + /** * ClutterSnapEdge: * @CLUTTER_SNAP_EDGE_TOP: the top edge diff --git a/clutter/clutter/clutter-input-device-tool.c b/clutter/clutter/clutter-input-device-tool.c index 982d94ce406..2582a695c34 100644 --- a/clutter/clutter/clutter-input-device-tool.c +++ b/clutter/clutter/clutter-input-device-tool.c @@ -33,6 +33,7 @@ struct _ClutterInputDeviceToolPrivate ClutterInputDeviceToolType type; guint64 serial; guint64 id; + ClutterInputAxisFlags axes; }; enum @@ -41,6 +42,7 @@ enum PROP_TYPE, PROP_SERIAL, PROP_ID, + PROP_AXES, PROP_LAST }; @@ -70,6 +72,9 @@ clutter_input_device_tool_set_property (GObject *object, case PROP_ID: priv->id = g_value_get_uint64 (value); break; + case PROP_AXES: + priv->axes = g_value_get_flags (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -97,6 +102,9 @@ clutter_input_device_tool_get_property (GObject *object, case PROP_ID: g_value_set_uint64 (value, priv->id); break; + case PROP_AXES: + g_value_set_flags (value, priv->axes); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -129,6 +137,13 @@ clutter_input_device_tool_class_init (ClutterInputDeviceToolClass *klass) P_("Tool ID"), 0, G_MAXUINT64, 0, CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + props[PROP_AXES] = + g_param_spec_flags ("axes", + P_("Axes"), + P_("Axes"), + CLUTTER_TYPE_INPUT_AXIS_FLAGS, + CLUTTER_INPUT_AXIS_FLAG_NONE, + CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_properties (gobject_class, PROP_LAST, props); } @@ -204,3 +219,15 @@ clutter_input_device_tool_get_id (ClutterInputDeviceTool *tool) return priv->id; } + +ClutterInputAxisFlags +clutter_input_device_tool_get_axes (ClutterInputDeviceTool *tool) +{ + ClutterInputDeviceToolPrivate *priv; + + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL (tool), 0); + + priv = clutter_input_device_tool_get_instance_private (tool); + + return priv->axes; +} diff --git a/clutter/clutter/clutter-input-device-tool.h b/clutter/clutter/clutter-input-device-tool.h index 36c8add8396..df5c8201d77 100644 --- a/clutter/clutter/clutter-input-device-tool.h +++ b/clutter/clutter/clutter-input-device-tool.h @@ -64,6 +64,9 @@ ClutterInputDeviceToolType clutter_input_device_tool_get_tool_type (ClutterInput CLUTTER_EXPORT guint64 clutter_input_device_tool_get_id (ClutterInputDeviceTool *tool); +CLUTTER_EXPORT +ClutterInputAxisFlags clutter_input_device_tool_get_axes (ClutterInputDeviceTool *tool); + G_END_DECLS #endif /* __CLUTTER_INPUT_DEVICE_TOOL_H__ */ diff --git a/src/backends/native/meta-input-device-tool-native.c b/src/backends/native/meta-input-device-tool-native.c index 8b540afbb5c..dc47b81a73c 100644 --- a/src/backends/native/meta-input-device-tool-native.c +++ b/src/backends/native/meta-input-device-tool-native.c @@ -49,6 +49,27 @@ meta_input_device_tool_native_init (MetaInputDeviceToolNative *tool) tool->button_map = g_hash_table_new (NULL, NULL); } +static ClutterInputAxisFlags +translate_axes (struct libinput_tablet_tool *tool) +{ + ClutterInputAxisFlags axes = 0; + + if (libinput_tablet_tool_has_pressure (tool)) + axes |= CLUTTER_INPUT_AXIS_FLAG_PRESSURE; + if (libinput_tablet_tool_has_distance (tool)) + axes |= CLUTTER_INPUT_AXIS_FLAG_DISTANCE; + if (libinput_tablet_tool_has_rotation (tool)) + axes |= CLUTTER_INPUT_AXIS_FLAG_ROTATION; + if (libinput_tablet_tool_has_slider (tool)) + axes |= CLUTTER_INPUT_AXIS_FLAG_SLIDER; + if (libinput_tablet_tool_has_wheel (tool)) + axes |= CLUTTER_INPUT_AXIS_FLAG_WHEEL; + if (libinput_tablet_tool_has_tilt (tool)) + axes |= CLUTTER_INPUT_AXIS_FLAG_XTILT | CLUTTER_INPUT_AXIS_FLAG_YTILT; + + return axes; +} + ClutterInputDeviceTool * meta_input_device_tool_native_new (struct libinput_tablet_tool *tool, uint64_t serial, @@ -60,6 +81,7 @@ meta_input_device_tool_native_new (struct libinput_tablet_tool *tool, "type", type, "serial", serial, "id", libinput_tablet_tool_get_tool_id (tool), + "axes", translate_axes (tool), NULL); evdev_tool->tool = libinput_tablet_tool_ref (tool); diff --git a/src/backends/x11/meta-input-device-tool-x11.c b/src/backends/x11/meta-input-device-tool-x11.c index 0632fea5a24..bec4d1fadf3 100644 --- a/src/backends/x11/meta-input-device-tool-x11.c +++ b/src/backends/x11/meta-input-device-tool-x11.c @@ -38,8 +38,19 @@ ClutterInputDeviceTool * meta_input_device_tool_x11_new (guint serial, ClutterInputDeviceToolType type) { + ClutterInputAxisFlags axes = + CLUTTER_INPUT_AXIS_FLAG_PRESSURE | + CLUTTER_INPUT_AXIS_FLAG_DISTANCE | + CLUTTER_INPUT_AXIS_FLAG_XTILT | + CLUTTER_INPUT_AXIS_FLAG_YTILT | + CLUTTER_INPUT_AXIS_FLAG_WHEEL | + CLUTTER_INPUT_AXIS_FLAG_DISTANCE | + CLUTTER_INPUT_AXIS_FLAG_ROTATION | + CLUTTER_INPUT_AXIS_FLAG_SLIDER; + return g_object_new (META_TYPE_INPUT_DEVICE_TOOL_X11, "type", type, "serial", serial, + "axes", axes, NULL); } diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c index 8ff2accb219..8c1984f622f 100644 --- a/src/wayland/meta-wayland-tablet-tool.c +++ b/src/wayland/meta-wayland-tablet-tool.c @@ -137,45 +137,6 @@ meta_wayland_tablet_tool_set_cursor_surface (MetaWaylandTabletTool *tool, meta_wayland_tablet_tool_update_cursor_surface (tool); } -static uint32_t -input_device_get_capabilities (ClutterInputDevice *device) -{ - ClutterInputAxis axis; - guint32 capabilities = 0, i; - - for (i = 0; i < clutter_input_device_get_n_axes (device); i++) - { - axis = clutter_input_device_get_axis (device, i); - - switch (axis) - { - case CLUTTER_INPUT_AXIS_PRESSURE: - capabilities |= 1 << ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE; - break; - case CLUTTER_INPUT_AXIS_DISTANCE: - capabilities |= 1 << ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE; - break; - case CLUTTER_INPUT_AXIS_XTILT: - case CLUTTER_INPUT_AXIS_YTILT: - capabilities |= 1 << ZWP_TABLET_TOOL_V2_CAPABILITY_TILT; - break; - case CLUTTER_INPUT_AXIS_ROTATION: - capabilities |= 1 << ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION; - break; - case CLUTTER_INPUT_AXIS_WHEEL: - capabilities |= 1 << ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL; - break; - case CLUTTER_INPUT_AXIS_SLIDER: - capabilities |= 1 << ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER; - break; - default: - break; - } - } - - return capabilities; -} - static enum zwp_tablet_tool_v2_type input_device_tool_get_type (ClutterInputDeviceTool *device_tool) { @@ -210,26 +171,26 @@ static void meta_wayland_tablet_tool_notify_capabilities (MetaWaylandTabletTool *tool, struct wl_resource *resource) { - uint32_t capabilities; + ClutterInputAxisFlags axes; - capabilities = input_device_get_capabilities (tool->device); + axes = clutter_input_device_tool_get_axes (tool->device_tool); - if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE)) + if (axes & CLUTTER_INPUT_AXIS_FLAG_PRESSURE) zwp_tablet_tool_v2_send_capability (resource, ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE); - if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE)) + if (axes & CLUTTER_INPUT_AXIS_FLAG_DISTANCE) zwp_tablet_tool_v2_send_capability (resource, ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE); - if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_TILT)) + if (axes & (CLUTTER_INPUT_AXIS_FLAG_XTILT | CLUTTER_INPUT_AXIS_FLAG_YTILT)) zwp_tablet_tool_v2_send_capability (resource, ZWP_TABLET_TOOL_V2_CAPABILITY_TILT); - if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION)) + if (axes & CLUTTER_INPUT_AXIS_FLAG_ROTATION) zwp_tablet_tool_v2_send_capability (resource, ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION); - if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER)) + if (axes & CLUTTER_INPUT_AXIS_FLAG_SLIDER) zwp_tablet_tool_v2_send_capability (resource, ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER); - if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL)) + if (axes & CLUTTER_INPUT_AXIS_FLAG_WHEEL) zwp_tablet_tool_v2_send_capability (resource, ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL); } @@ -842,26 +803,21 @@ static void broadcast_axes (MetaWaylandTabletTool *tool, const ClutterEvent *event) { - ClutterInputDevice *device; - guint32 capabilities; - - if (!event->motion.axes) - return; + ClutterInputAxisFlags axes; - device = clutter_event_get_source_device (event); - capabilities = input_device_get_capabilities (device); + axes = clutter_input_device_tool_get_axes (tool->device_tool); - if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE)) + if (axes & CLUTTER_INPUT_AXIS_FLAG_PRESSURE) broadcast_axis (tool, event, CLUTTER_INPUT_AXIS_PRESSURE); - if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE)) + if (axes & CLUTTER_INPUT_AXIS_FLAG_DISTANCE) broadcast_axis (tool, event, CLUTTER_INPUT_AXIS_DISTANCE); - if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_TILT)) + if (axes & (CLUTTER_INPUT_AXIS_FLAG_XTILT | CLUTTER_INPUT_AXIS_FLAG_YTILT)) broadcast_tilt (tool, event); - if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION)) + if (axes & CLUTTER_INPUT_AXIS_FLAG_ROTATION) broadcast_rotation (tool, event); - if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER)) + if (axes & CLUTTER_INPUT_AXIS_FLAG_SLIDER) broadcast_axis (tool, event, CLUTTER_INPUT_AXIS_SLIDER); - if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL)) + if (axes & CLUTTER_INPUT_AXIS_FLAG_WHEEL) broadcast_wheel (tool, event); } -- GitLab From 168ceb990553bf24a17886a63499b6252cffa8dc Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 19 Nov 2020 01:00:42 +0100 Subject: [PATCH 69/85] backends: Forward event axes as array of ClutterInputAxes elements Instead of encoding arrays in ways that we need the ClutterInputDevice to decode them, use ClutterInputAxes as the array index. Part-of: --- clutter/clutter/clutter-event.c | 28 ++++----------------- src/backends/native/meta-seat-impl.c | 30 ++++++++-------------- src/backends/x11/meta-seat-x11.c | 9 +++---- src/wayland/meta-wayland-tablet-tool.c | 35 +++++--------------------- 4 files changed, 26 insertions(+), 76 deletions(-) diff --git a/clutter/clutter/clutter-event.c b/clutter/clutter/clutter-event.c index cc8741221b0..dba5d2588de 100644 --- a/clutter/clutter/clutter-event.c +++ b/clutter/clutter/clutter-event.c @@ -1302,9 +1302,7 @@ clutter_event_copy (const ClutterEvent *event) { ClutterEvent *new_event; ClutterEventPrivate *new_real_event; - ClutterInputDevice *device; ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; - gint n_axes = 0; g_return_val_if_fail (event != NULL, NULL); @@ -1324,29 +1322,25 @@ clutter_event_copy (const ClutterEvent *event) new_real_event->locked_state = real_event->locked_state; new_real_event->tool = real_event->tool; - device = clutter_event_get_device (event); - if (device != NULL) - n_axes = clutter_input_device_get_n_axes (device); - switch (event->type) { case CLUTTER_BUTTON_PRESS: case CLUTTER_BUTTON_RELEASE: if (event->button.axes != NULL) new_event->button.axes = g_memdup (event->button.axes, - sizeof (gdouble) * n_axes); + sizeof (gdouble) * CLUTTER_INPUT_AXIS_LAST); break; case CLUTTER_SCROLL: if (event->scroll.axes != NULL) new_event->scroll.axes = g_memdup (event->scroll.axes, - sizeof (gdouble) * n_axes); + sizeof (gdouble) * CLUTTER_INPUT_AXIS_LAST); break; case CLUTTER_MOTION: if (event->motion.axes != NULL) new_event->motion.axes = g_memdup (event->motion.axes, - sizeof (gdouble) * n_axes); + sizeof (gdouble) * CLUTTER_INPUT_AXIS_LAST); break; case CLUTTER_TOUCH_BEGIN: @@ -1355,7 +1349,7 @@ clutter_event_copy (const ClutterEvent *event) case CLUTTER_TOUCH_CANCEL: if (event->touch.axes != NULL) new_event->touch.axes = g_memdup (event->touch.axes, - sizeof (gdouble) * n_axes); + sizeof (gdouble) * CLUTTER_INPUT_AXIS_LAST); break; case CLUTTER_DEVICE_ADDED: @@ -1624,7 +1618,6 @@ clutter_event_get_axes (const ClutterEvent *event, guint *n_axes) { gdouble *retval = NULL; - guint len = 0; switch (event->type) { @@ -1675,19 +1668,8 @@ clutter_event_get_axes (const ClutterEvent *event, break; } - if (retval != NULL) - { - ClutterInputDevice *device; - - device = clutter_event_get_device (event); - if (device != NULL) - len = clutter_input_device_get_n_axes (device); - else - retval = NULL; - } - if (n_axes) - *n_axes = len; + *n_axes = CLUTTER_INPUT_AXIS_LAST; return retval; } diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 0eea3980645..819e3b80bc4 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -1695,63 +1695,57 @@ static double * translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event, ClutterInputDeviceTool *tool) { - GArray *axes = g_array_new (FALSE, FALSE, sizeof (double)); + double *axes = g_new0 (double, CLUTTER_INPUT_AXIS_LAST); struct libinput_tablet_tool *libinput_tool; double value; libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event); value = libinput_event_tablet_tool_get_x (tablet_event); - g_array_append_val (axes, value); + axes[CLUTTER_INPUT_AXIS_X] = value; value = libinput_event_tablet_tool_get_y (tablet_event); - g_array_append_val (axes, value); + axes[CLUTTER_INPUT_AXIS_Y] = value; if (libinput_tablet_tool_has_distance (libinput_tool)) { value = libinput_event_tablet_tool_get_distance (tablet_event); - g_array_append_val (axes, value); + axes[CLUTTER_INPUT_AXIS_DISTANCE] = value; } if (libinput_tablet_tool_has_pressure (libinput_tool)) { value = libinput_event_tablet_tool_get_pressure (tablet_event); value = meta_input_device_tool_native_translate_pressure (tool, value); - g_array_append_val (axes, value); + axes[CLUTTER_INPUT_AXIS_PRESSURE] = value; } if (libinput_tablet_tool_has_tilt (libinput_tool)) { value = libinput_event_tablet_tool_get_tilt_x (tablet_event); - g_array_append_val (axes, value); + axes[CLUTTER_INPUT_AXIS_XTILT] = value; value = libinput_event_tablet_tool_get_tilt_y (tablet_event); - g_array_append_val (axes, value); + axes[CLUTTER_INPUT_AXIS_YTILT] = value; } if (libinput_tablet_tool_has_rotation (libinput_tool)) { value = libinput_event_tablet_tool_get_rotation (tablet_event); - g_array_append_val (axes, value); + axes[CLUTTER_INPUT_AXIS_ROTATION] = value; } if (libinput_tablet_tool_has_slider (libinput_tool)) { value = libinput_event_tablet_tool_get_slider_position (tablet_event); - g_array_append_val (axes, value); + axes[CLUTTER_INPUT_AXIS_SLIDER] = value; } if (libinput_tablet_tool_has_wheel (libinput_tool)) { value = libinput_event_tablet_tool_get_wheel_delta (tablet_event); - g_array_append_val (axes, value); + axes[CLUTTER_INPUT_AXIS_WHEEL] = value; } - if (axes->len == 0) - { - g_array_free (axes, TRUE); - return NULL; - } - else - return (double *) g_array_free (axes, FALSE); + return axes; } static void @@ -1834,8 +1828,6 @@ process_tablet_axis (MetaSeatImpl *seat_impl, axes = translate_tablet_axes (tablet_event, evdev_device->last_tool); - if (!axes) - return; meta_viewport_info_get_extents (seat_impl->viewports, &stage_width, &stage_height); diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index a8f4f9fd11f..a3f0bc59763 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -1135,12 +1135,11 @@ translate_axes (ClutterInputDevice *device, double y, XIValuatorState *valuators) { - uint32_t n_axes = clutter_input_device_get_n_axes (device); uint32_t i; double *retval; double *values; - retval = g_new0 (double, n_axes); + retval = g_new0 (double, CLUTTER_INPUT_AXIS_LAST); values = valuators->values; for (i = 0; i < valuators->mask_len * 8; i++) @@ -1157,15 +1156,15 @@ translate_axes (ClutterInputDevice *device, switch (axis) { case CLUTTER_INPUT_AXIS_X: - retval[i] = x; + retval[axis] = x; break; case CLUTTER_INPUT_AXIS_Y: - retval[i] = y; + retval[axis] = y; break; default: - _clutter_input_device_translate_axis (device, i, val, &retval[i]); + _clutter_input_device_translate_axis (device, i, val, &retval[axis]); break; } } diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c index 8c1984f622f..efcb53bca1c 100644 --- a/src/wayland/meta-wayland-tablet-tool.c +++ b/src/wayland/meta-wayland-tablet-tool.c @@ -691,15 +691,10 @@ broadcast_axis (MetaWaylandTabletTool *tool, ClutterInputAxis axis) { struct wl_resource *resource; - ClutterInputDevice *source; uint32_t value; - gdouble val; - - source = clutter_event_get_source_device (event); - - if (!clutter_input_device_get_axis_value (source, event->motion.axes, axis, &val)) - return; + double val; + val = event->motion.axes[axis]; value = val * TABLET_AXIS_MAX; wl_resource_for_each (resource, &tool->focus_resource_list) @@ -726,16 +721,10 @@ broadcast_tilt (MetaWaylandTabletTool *tool, const ClutterEvent *event) { struct wl_resource *resource; - ClutterInputDevice *source; gdouble xtilt, ytilt; - source = clutter_event_get_source_device (event); - - if (!clutter_input_device_get_axis_value (source, event->motion.axes, - CLUTTER_INPUT_AXIS_XTILT, &xtilt) || - !clutter_input_device_get_axis_value (source, event->motion.axes, - CLUTTER_INPUT_AXIS_YTILT, &ytilt)) - return; + xtilt = event->motion.axes[CLUTTER_INPUT_AXIS_FLAG_XTILT]; + ytilt = event->motion.axes[CLUTTER_INPUT_AXIS_FLAG_YTILT]; wl_resource_for_each (resource, &tool->focus_resource_list) { @@ -750,15 +739,9 @@ broadcast_rotation (MetaWaylandTabletTool *tool, const ClutterEvent *event) { struct wl_resource *resource; - ClutterInputDevice *source; gdouble rotation; - source = clutter_event_get_source_device (event); - - if (!clutter_input_device_get_axis_value (source, event->motion.axes, - CLUTTER_INPUT_AXIS_ROTATION, - &rotation)) - return; + rotation = event->motion.axes[CLUTTER_INPUT_AXIS_FLAG_ROTATION]; wl_resource_for_each (resource, &tool->focus_resource_list) { @@ -772,16 +755,10 @@ broadcast_wheel (MetaWaylandTabletTool *tool, const ClutterEvent *event) { struct wl_resource *resource; - ClutterInputDevice *source; gdouble angle; gint32 clicks = 0; - source = clutter_event_get_source_device (event); - - if (!clutter_input_device_get_axis_value (source, event->motion.axes, - CLUTTER_INPUT_AXIS_WHEEL, - &angle)) - return; + angle = event->motion.axes[CLUTTER_INPUT_AXIS_FLAG_WHEEL]; /* FIXME: Perform proper angle-to-clicks accumulation elsewhere */ if (angle > 0.01) -- GitLab From 5689a843c79ee9f3df496fe403959d9547abfb3c Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 19 Nov 2020 01:51:33 +0100 Subject: [PATCH 70/85] clutter: Drop internal update_from_tool() vmethod This is kinda pointless now, and will be made completely unneeded by dropping device axes. Part-of: --- .../clutter/clutter-input-device-private.h | 3 -- clutter/clutter/clutter-input-device.c | 14 ------- clutter/clutter/clutter-input-device.h | 2 - .../native/meta-input-device-native.c | 40 ------------------- src/backends/native/meta-seat-impl.c | 3 -- src/backends/x11/meta-seat-x11.c | 3 -- 6 files changed, 65 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index 3c541376424..baf02c069d1 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -133,9 +133,6 @@ struct _ClutterInputDevice ClutterPtrA11yData *ptr_a11y_data; }; -CLUTTER_EXPORT -void clutter_input_device_update_from_tool (ClutterInputDevice *device, - ClutterInputDeviceTool *tool); CLUTTER_EXPORT ClutterActor * clutter_input_device_update (ClutterInputDevice *device, ClutterEventSequence *sequence, diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index b8b10fd35ca..64c125e400e 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -1561,20 +1561,6 @@ clutter_input_device_lookup_tool (ClutterInputDevice *device, return NULL; } -void -clutter_input_device_update_from_tool (ClutterInputDevice *device, - ClutterInputDeviceTool *tool) -{ - ClutterInputDeviceClass *device_class; - - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - - device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device); - - if (device_class->update_from_tool) - device_class->update_from_tool (device, tool); -} - gint clutter_input_device_get_n_rings (ClutterInputDevice *device) { diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index 8ae53f82d99..72870c26044 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -44,8 +44,6 @@ struct _ClutterInputDeviceClass gboolean (* keycode_to_evdev) (ClutterInputDevice *device, guint hardware_keycode, guint *evdev_keycode); - void (* update_from_tool) (ClutterInputDevice *device, - ClutterInputDeviceTool *tool); gboolean (* is_mode_switch_button) (ClutterInputDevice *device, guint group, diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index 240392b86f1..7ab48e48064 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -133,45 +133,6 @@ meta_input_device_native_keycode_to_evdev (ClutterInputDevice *device, return TRUE; } -static void -meta_input_device_native_update_from_tool (ClutterInputDevice *device, - ClutterInputDeviceTool *tool) -{ - MetaInputDeviceToolNative *evdev_tool; - - evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool); - - g_object_freeze_notify (G_OBJECT (device)); - - _clutter_input_device_reset_axes (device); - - _clutter_input_device_add_axis (device, CLUTTER_INPUT_AXIS_X, 0, 0, 0); - _clutter_input_device_add_axis (device, CLUTTER_INPUT_AXIS_Y, 0, 0, 0); - - if (libinput_tablet_tool_has_distance (evdev_tool->tool)) - _clutter_input_device_add_axis (device, CLUTTER_INPUT_AXIS_DISTANCE, 0, 1, 0); - - if (libinput_tablet_tool_has_pressure (evdev_tool->tool)) - _clutter_input_device_add_axis (device, CLUTTER_INPUT_AXIS_PRESSURE, 0, 1, 0); - - if (libinput_tablet_tool_has_tilt (evdev_tool->tool)) - { - _clutter_input_device_add_axis (device, CLUTTER_INPUT_AXIS_XTILT, -90, 90, 0); - _clutter_input_device_add_axis (device, CLUTTER_INPUT_AXIS_YTILT, -90, 90, 0); - } - - if (libinput_tablet_tool_has_rotation (evdev_tool->tool)) - _clutter_input_device_add_axis (device, CLUTTER_INPUT_AXIS_ROTATION, 0, 360, 0); - - if (libinput_tablet_tool_has_slider (evdev_tool->tool)) - _clutter_input_device_add_axis (device, CLUTTER_INPUT_AXIS_SLIDER, -1, 1, 0); - - if (libinput_tablet_tool_has_wheel (evdev_tool->tool)) - _clutter_input_device_add_axis (device, CLUTTER_INPUT_AXIS_WHEEL, -180, 180, 0); - - g_object_thaw_notify (G_OBJECT (device)); -} - static gboolean meta_input_device_native_is_mode_switch_button (ClutterInputDevice *device, uint32_t group, @@ -1243,7 +1204,6 @@ meta_input_device_native_class_init (MetaInputDeviceNativeClass *klass) object_class->get_property = meta_input_device_native_get_property; device_manager_class->keycode_to_evdev = meta_input_device_native_keycode_to_evdev; - device_manager_class->update_from_tool = meta_input_device_native_update_from_tool; device_manager_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_manager_class->is_grouped = meta_input_device_native_is_grouped; diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 819e3b80bc4..56f4d3652cb 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -1682,9 +1682,6 @@ input_device_update_tool (MetaSeatImpl *seat_impl, if (evdev_device->last_tool != tool) { - if (tool) - clutter_input_device_update_from_tool (input_device, tool); - evdev_device->last_tool = tool; input_settings = seat_impl->input_settings; meta_input_settings_notify_tool_change (input_settings, input_device, tool); diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index a3f0bc59763..7f4c154026d 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -867,9 +867,6 @@ translate_property_event (MetaSeatX11 *seat_x11, meta_input_device_x11_update_tool (device, tool); input_settings = meta_backend_get_input_settings (meta_get_backend ()); meta_input_settings_notify_tool_change (input_settings, device, tool); - - if (tool) - clutter_input_device_update_from_tool (device, tool); } } -- GitLab From d7d92b0ddc4ec10189cdd61f55c32fa6fa434008 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 19 Nov 2020 01:15:42 +0100 Subject: [PATCH 71/85] clutter: Drop ClutterInputDevice axis API Most of this comes from X11 peculiarities that were open coded in the Clutter ABI. We don't need this except in X11, so move this axis handling there. Part-of: --- .../clutter/clutter-input-device-private.h | 29 -- clutter/clutter/clutter-input-device.c | 254 ------------------ src/backends/x11/meta-input-device-x11.c | 134 +++++++++ src/backends/x11/meta-input-device-x11.h | 15 ++ src/backends/x11/meta-seat-x11.c | 13 +- src/tests/clutter/interactive/test-devices.c | 50 +--- 6 files changed, 158 insertions(+), 337 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index baf02c069d1..caed7cbe7b5 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -32,19 +32,6 @@ G_BEGIN_DECLS -typedef struct _ClutterAxisInfo -{ - ClutterInputAxis axis; - - double min_axis; - double max_axis; - - double min_value; - double max_value; - - double resolution; -} ClutterAxisInfo; - typedef struct _ClutterScrollInfo { guint axis_id; @@ -111,8 +98,6 @@ struct _ClutterInputDevice uint32_t previous_time; int previous_button_number; - GArray *axes; - GArray *scroll_info; char *vendor_id; @@ -142,20 +127,6 @@ ClutterActor * clutter_input_device_update (ClutterInputDevice *device, CLUTTER_EXPORT void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, ClutterEvent *event); -CLUTTER_EXPORT -gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device, - guint index_, - gdouble value, - gdouble *axis_value); -CLUTTER_EXPORT -guint _clutter_input_device_add_axis (ClutterInputDevice *device, - ClutterInputAxis axis, - gdouble minimum, - gdouble maximum, - gdouble resolution); - -CLUTTER_EXPORT -void _clutter_input_device_reset_axes (ClutterInputDevice *device); CLUTTER_EXPORT void _clutter_input_device_add_scroll_info (ClutterInputDevice *device, diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 64c125e400e..4a7b4c85c11 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -61,8 +61,6 @@ enum PROP_HAS_CURSOR, - PROP_N_AXES, - PROP_VENDOR_ID, PROP_PRODUCT_ID, @@ -97,7 +95,6 @@ clutter_input_device_dispose (GObject *gobject) if (device->accessibility_virtual_device) g_clear_object (&device->accessibility_virtual_device); - g_clear_pointer (&device->axes, g_array_unref); g_clear_pointer (&device->scroll_info, g_array_unref); g_clear_pointer (&device->touch_sequence_actors, g_hash_table_unref); @@ -236,10 +233,6 @@ clutter_input_device_get_property (GObject *gobject, g_value_set_boolean (value, self->has_cursor); break; - case PROP_N_AXES: - g_value_set_uint (value, clutter_input_device_get_n_axes (self)); - break; - case PROP_VENDOR_ID: g_value_set_string (value, self->vendor_id); break; @@ -347,21 +340,6 @@ clutter_input_device_class_init (ClutterInputDeviceClass *klass) FALSE, CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); - /** - * ClutterInputDevice:n-axes: - * - * The number of axes of the device. - * - * Since: 1.6 - */ - obj_props[PROP_N_AXES] = - g_param_spec_uint ("n-axes", - P_("Number of Axes"), - P_("The number of axes on the device"), - 0, G_MAXUINT, - 0, - CLUTTER_PARAM_READABLE); - /** * ClutterInputDevice:backend: * @@ -800,236 +778,6 @@ clutter_input_device_get_device_mode (ClutterInputDevice *device) return device->device_mode; } -/*< private > - * clutter_input_device_reset_axes: - * @device: a #ClutterInputDevice - * - * Resets the axes on @device - */ -void -_clutter_input_device_reset_axes (ClutterInputDevice *device) -{ - if (device->axes != NULL) - { - g_array_free (device->axes, TRUE); - device->axes = NULL; - - g_object_notify_by_pspec (G_OBJECT (device), obj_props[PROP_N_AXES]); - } -} - -/*< private > - * clutter_input_device_add_axis: - * @device: a #ClutterInputDevice - * @axis: the axis type - * @minimum: the minimum axis value - * @maximum: the maximum axis value - * @resolution: the axis resolution - * - * Adds an axis of type @axis on @device. - */ -guint -_clutter_input_device_add_axis (ClutterInputDevice *device, - ClutterInputAxis axis, - gdouble minimum, - gdouble maximum, - gdouble resolution) -{ - ClutterAxisInfo info; - guint pos; - - if (device->axes == NULL) - device->axes = g_array_new (FALSE, TRUE, sizeof (ClutterAxisInfo)); - - info.axis = axis; - info.min_value = minimum; - info.max_value = maximum; - info.resolution = resolution; - - switch (axis) - { - case CLUTTER_INPUT_AXIS_X: - case CLUTTER_INPUT_AXIS_Y: - info.min_axis = 0; - info.max_axis = 0; - break; - - case CLUTTER_INPUT_AXIS_XTILT: - case CLUTTER_INPUT_AXIS_YTILT: - info.min_axis = -1; - info.max_axis = 1; - break; - - default: - info.min_axis = 0; - info.max_axis = 1; - break; - } - - device->axes = g_array_append_val (device->axes, info); - pos = device->axes->len - 1; - - g_object_notify_by_pspec (G_OBJECT (device), obj_props[PROP_N_AXES]); - - return pos; -} - -/*< private > - * clutter_input_translate_axis: - * @device: a #ClutterInputDevice - * @index_: the index of the axis - * @gint: the absolute value of the axis - * @axis_value: (out): the translated value of the axis - * - * Performs a conversion from the absolute value of the axis - * to a relative value. - * - * The axis at @index_ must not be %CLUTTER_INPUT_AXIS_X or - * %CLUTTER_INPUT_AXIS_Y. - * - * Return value: %TRUE if the conversion was successful - */ -gboolean -_clutter_input_device_translate_axis (ClutterInputDevice *device, - guint index_, - gdouble value, - gdouble *axis_value) -{ - ClutterAxisInfo *info; - gdouble width; - gdouble real_value; - - if (device->axes == NULL || index_ >= device->axes->len) - return FALSE; - - info = &g_array_index (device->axes, ClutterAxisInfo, index_); - - if (info->axis == CLUTTER_INPUT_AXIS_X || - info->axis == CLUTTER_INPUT_AXIS_Y) - return FALSE; - - if (fabs (info->max_value - info->min_value) < 0.0000001) - return FALSE; - - width = info->max_value - info->min_value; - real_value = (info->max_axis * (value - info->min_value) - + info->min_axis * (info->max_value - value)) - / width; - - if (axis_value) - *axis_value = real_value; - - return TRUE; -} - -/** - * clutter_input_device_get_axis: - * @device: a #ClutterInputDevice - * @index_: the index of the axis - * - * Retrieves the type of axis on @device at the given index. - * - * Return value: the axis type - * - * Since: 1.6 - */ -ClutterInputAxis -clutter_input_device_get_axis (ClutterInputDevice *device, - guint index_) -{ - ClutterAxisInfo *info; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), - CLUTTER_INPUT_AXIS_IGNORE); - - if (device->axes == NULL) - return CLUTTER_INPUT_AXIS_IGNORE; - - if (index_ >= device->axes->len) - return CLUTTER_INPUT_AXIS_IGNORE; - - info = &g_array_index (device->axes, ClutterAxisInfo, index_); - - return info->axis; -} - -/** - * clutter_input_device_get_axis_value: - * @device: a #ClutterInputDevice - * @axes: (array): an array of axes values, typically - * coming from clutter_event_get_axes() - * @axis: the axis to extract - * @value: (out): return location for the axis value - * - * Extracts the value of the given @axis of a #ClutterInputDevice from - * an array of axis values. - * - * An example of typical usage for this function is: - * - * |[ - * ClutterInputDevice *device = clutter_event_get_device (event); - * gdouble *axes = clutter_event_get_axes (event, NULL); - * gdouble pressure_value = 0; - * - * clutter_input_device_get_axis_value (device, axes, - * CLUTTER_INPUT_AXIS_PRESSURE, - * &pressure_value); - * ]| - * - * Return value: %TRUE if the value was set, and %FALSE otherwise - * - * Since: 1.6 - */ -gboolean -clutter_input_device_get_axis_value (ClutterInputDevice *device, - gdouble *axes, - ClutterInputAxis axis, - gdouble *value) -{ - gint i; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - g_return_val_if_fail (device->axes != NULL, FALSE); - - for (i = 0; i < device->axes->len; i++) - { - ClutterAxisInfo *info; - - info = &g_array_index (device->axes, ClutterAxisInfo, i); - - if (info->axis == axis) - { - if (value) - *value = axes[i]; - - return TRUE; - } - } - - return FALSE; -} - -/** - * clutter_input_device_get_n_axes: - * @device: a #ClutterInputDevice - * - * Retrieves the number of axes available on @device. - * - * Return value: the number of axes on the device - * - * Since: 1.6 - */ -guint -clutter_input_device_get_n_axes (ClutterInputDevice *device) -{ - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0); - - if (device->axes != NULL) - return device->axes->len; - - return 0; -} - /*< private > * clutter_input_device_remove_sequence: * @device: a #ClutterInputDevice @@ -1109,7 +857,6 @@ _clutter_input_device_add_scroll_info (ClutterInputDevice *device, ClutterScrollInfo info; g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - g_return_if_fail (index_ < clutter_input_device_get_n_axes (device)); info.axis_id = index_; info.direction = direction; @@ -1136,7 +883,6 @@ _clutter_input_device_get_scroll_delta (ClutterInputDevice *device, guint i; g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - g_return_val_if_fail (index_ < clutter_input_device_get_n_axes (device), FALSE); if (device->scroll_info == NULL) return FALSE; diff --git a/src/backends/x11/meta-input-device-x11.c b/src/backends/x11/meta-input-device-x11.c index 7d518076678..4fdd3b61b59 100644 --- a/src/backends/x11/meta-input-device-x11.c +++ b/src/backends/x11/meta-input-device-x11.c @@ -37,11 +37,26 @@ struct _MetaInputDeviceX11 float current_x; float current_y; + GArray *axes; + #ifdef HAVE_LIBWACOM GArray *group_modes; #endif }; +typedef struct _MetaX11AxisInfo +{ + ClutterInputAxis axis; + + double min_axis; + double max_axis; + + double min_value; + double max_value; + + double resolution; +} MetaX11AxisInfo; + struct _MetaInputDeviceX11Class { ClutterInputDeviceClass device_class; @@ -133,6 +148,8 @@ meta_input_device_x11_finalize (GObject *object) { MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (object); + g_clear_pointer (&device_xi2->axes, g_array_unref); + #ifdef HAVE_LIBWACOM if (device_xi2->group_modes) g_array_unref (device_xi2->group_modes); @@ -460,6 +477,123 @@ meta_input_device_x11_get_device_id (ClutterInputDevice *device) return device_xi2->device_id; } +void +meta_input_device_x11_reset_axes (ClutterInputDevice *device) +{ + MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device); + + g_clear_pointer (&device_x11->axes, g_array_unref); +} + +int +meta_input_device_x11_add_axis (ClutterInputDevice *device, + ClutterInputAxis axis, + double minimum, + double maximum, + double resolution) +{ + MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device); + MetaX11AxisInfo info; + guint pos; + + if (device_x11->axes == NULL) + device_x11->axes = g_array_new (FALSE, TRUE, sizeof (MetaX11AxisInfo)); + + info.axis = axis; + info.min_value = minimum; + info.max_value = maximum; + info.resolution = resolution; + + switch (axis) + { + case CLUTTER_INPUT_AXIS_X: + case CLUTTER_INPUT_AXIS_Y: + info.min_axis = 0; + info.max_axis = 0; + break; + + case CLUTTER_INPUT_AXIS_XTILT: + case CLUTTER_INPUT_AXIS_YTILT: + info.min_axis = -1; + info.max_axis = 1; + break; + + default: + info.min_axis = 0; + info.max_axis = 1; + break; + } + + g_array_append_val (device_x11->axes, info); + pos = device_x11->axes->len - 1; + + return pos; +} + +gboolean +meta_input_device_x11_get_axis (ClutterInputDevice *device, + int idx, + ClutterInputAxis *use) +{ + MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device); + MetaX11AxisInfo *info; + + if (device_x11->axes == NULL) + return FALSE; + + if (idx < 0 || idx >= device_x11->axes->len) + return FALSE; + + info = &g_array_index (device_x11->axes, MetaX11AxisInfo, idx); + + if (use) + *use = info->axis; + + return TRUE; +} + +gboolean +meta_input_device_x11_translate_axis (ClutterInputDevice *device, + int idx, + double value, + double *axis_value) +{ + MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device); + MetaX11AxisInfo *info; + double width; + double real_value; + + if (device_x11->axes == NULL || idx < 0 || idx >= device_x11->axes->len) + return FALSE; + + info = &g_array_index (device_x11->axes, MetaX11AxisInfo, idx); + + if (info->axis == CLUTTER_INPUT_AXIS_X || + info->axis == CLUTTER_INPUT_AXIS_Y) + return FALSE; + + if (fabs (info->max_value - info->min_value) < 0.0000001) + return FALSE; + + width = info->max_value - info->min_value; + real_value = (info->max_axis * (value - info->min_value) + + info->min_axis * (info->max_value - value)) + / width; + + if (axis_value) + *axis_value = real_value; + + return TRUE; +} + +int +meta_input_device_x11_get_n_axes (ClutterInputDevice *device) +{ + MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device); + + return device_x11->axes->len; +} + #ifdef HAVE_LIBWACOM uint32_t meta_input_device_x11_get_pad_group_mode (ClutterInputDevice *device, diff --git a/src/backends/x11/meta-input-device-x11.h b/src/backends/x11/meta-input-device-x11.h index f74c4a2a423..19f1efcdd27 100644 --- a/src/backends/x11/meta-input-device-x11.h +++ b/src/backends/x11/meta-input-device-x11.h @@ -71,6 +71,21 @@ gboolean meta_input_device_x11_get_pointer_location (ClutterInputDevice *device, float *y); int meta_input_device_x11_get_device_id (ClutterInputDevice *device); +int meta_input_device_x11_get_n_axes (ClutterInputDevice *device); +void meta_input_device_x11_reset_axes (ClutterInputDevice *device); +int meta_input_device_x11_add_axis (ClutterInputDevice *device, + ClutterInputAxis axis, + double minimum, + double maximum, + double resolution); +gboolean meta_input_device_x11_get_axis (ClutterInputDevice *device, + int idx, + ClutterInputAxis *use); +gboolean meta_input_device_x11_translate_axis (ClutterInputDevice *device, + int idx, + double value, + double *axis_value); + G_END_DECLS #endif /* META_INPUT_DEVICE_X11_H */ diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index 7f4c154026d..1983c93c43b 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -148,7 +148,7 @@ translate_valuator_class (Display *xdisplay, } } - _clutter_input_device_add_axis (device, axis, + meta_input_device_x11_add_axis (device, axis, class->min, class->max, class->resolution); @@ -947,7 +947,7 @@ translate_pad_axis (ClutterInputDevice *device, if (val <= 0) continue; - _clutter_input_device_translate_axis (device, i, val, value); + meta_input_device_x11_translate_axis (device, i, val, value); if (i == PAD_AXIS_RING1 || i == PAD_AXIS_RING2) { @@ -1146,8 +1146,9 @@ translate_axes (ClutterInputDevice *device, if (!XIMaskIsSet (valuators->mask, i)) continue; + if (!meta_input_device_x11_get_axis (device, i, &axis)) + continue; - axis = clutter_input_device_get_axis (device, i); val = *values++; switch (axis) @@ -1161,7 +1162,7 @@ translate_axes (ClutterInputDevice *device, break; default: - _clutter_input_device_translate_axis (device, i, val, &retval[axis]); + meta_input_device_x11_translate_axis (device, i, val, &retval[axis]); break; } } @@ -1179,7 +1180,7 @@ scroll_valuators_changed (ClutterInputDevice *device, uint32_t n_axes, n_val, i; double *values; - n_axes = clutter_input_device_get_n_axes (device); + n_axes = meta_input_device_x11_get_n_axes (device); values = valuators->values; *dx_p = *dy_p = 0.0; @@ -1785,7 +1786,7 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, GINT_TO_POINTER (xev->sourceid)); if (device) { - _clutter_input_device_reset_axes (device); + meta_input_device_x11_reset_axes (device); translate_device_classes (clutter_x11_get_default_display (), device, xev->classes, diff --git a/src/tests/clutter/interactive/test-devices.c b/src/tests/clutter/interactive/test-devices.c index e5b894b871c..b8d1f0fe7fa 100644 --- a/src/tests/clutter/interactive/test-devices.c +++ b/src/tests/clutter/interactive/test-devices.c @@ -49,34 +49,6 @@ device_type_name (ClutterInputDevice *device) } } -static const gchar * -axis_type_name (ClutterInputAxis axis) -{ - switch (axis) - { - case CLUTTER_INPUT_AXIS_X: - return "Absolute X"; - - case CLUTTER_INPUT_AXIS_Y: - return "Absolute Y"; - - case CLUTTER_INPUT_AXIS_PRESSURE: - return "Pressure"; - - case CLUTTER_INPUT_AXIS_XTILT: - return "X Tilt"; - - case CLUTTER_INPUT_AXIS_YTILT: - return "Y Tilt"; - - case CLUTTER_INPUT_AXIS_WHEEL: - return "Wheel"; - - default: - return "Unknown"; - } -} - static gboolean stage_button_event_cb (ClutterActor *actor, ClutterEvent *event, @@ -85,21 +57,18 @@ stage_button_event_cb (ClutterActor *actor, ClutterInputDevice *device; ClutterInputDevice *source_device; ClutterActor *hand = NULL; - gdouble *axes; - guint n_axes, i; device = clutter_event_get_device (event); source_device = clutter_event_get_source_device (event); hand = g_hash_table_lookup (app->devices, device); - g_print ("Device: '%s' (type: %s, source: '%s', axes: %d)\n", + g_print ("Device: '%s' (type: %s, source: '%s')\n", clutter_input_device_get_device_name (device), device_type_name (device), source_device != device ? clutter_input_device_get_device_name (source_device) - : "", - clutter_input_device_get_n_axes (device)); + : ""); if (hand != NULL) { @@ -109,21 +78,6 @@ stage_button_event_cb (ClutterActor *actor, clutter_actor_set_position (hand, event_x, event_y); } - axes = clutter_event_get_axes (event, &n_axes); - for (i = 0; i < n_axes; i++) - { - ClutterInputAxis axis; - - axis = clutter_input_device_get_axis (device, i); - if (axis == CLUTTER_INPUT_AXIS_IGNORE) - continue; - - g_print ("\tAxis[%2d][%s].value: %.2f\n", - i, - axis_type_name (axis), - axes[i]); - } - return FALSE; } -- GitLab From 06d577fdf3a952f1273ea315fc03beacd8e0f653 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 19 Nov 2020 02:07:53 +0100 Subject: [PATCH 72/85] clutter: Move scroll valuator accounting to backends/x11 This is just used there. Another X11 detail that got open coded. Part-of: --- .../clutter/clutter-input-device-private.h | 26 ----- clutter/clutter/clutter-input-device.c | 95 ---------------- src/backends/x11/meta-input-device-x11.c | 107 ++++++++++++++++++ src/backends/x11/meta-input-device-x11.h | 11 ++ src/backends/x11/meta-seat-x11.c | 8 +- 5 files changed, 122 insertions(+), 125 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index caed7cbe7b5..cb8fd8621d8 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -32,16 +32,6 @@ G_BEGIN_DECLS -typedef struct _ClutterScrollInfo -{ - guint axis_id; - ClutterScrollDirection direction; - double increment; - - double last_value; - guint last_value_valid : 1; -} ClutterScrollInfo; - typedef struct _ClutterPtrA11yData { int n_btn_pressed; @@ -98,8 +88,6 @@ struct _ClutterInputDevice uint32_t previous_time; int previous_button_number; - GArray *scroll_info; - char *vendor_id; char *product_id; char *node_path; @@ -128,20 +116,6 @@ CLUTTER_EXPORT void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, ClutterEvent *event); -CLUTTER_EXPORT -void _clutter_input_device_add_scroll_info (ClutterInputDevice *device, - guint index_, - ClutterScrollDirection direction, - gdouble increment); -CLUTTER_EXPORT -gboolean _clutter_input_device_get_scroll_delta (ClutterInputDevice *device, - guint index_, - gdouble value, - ClutterScrollDirection *direction_p, - gdouble *delta_p); -CLUTTER_EXPORT -void _clutter_input_device_reset_scroll_info (ClutterInputDevice *device); - CLUTTER_EXPORT void clutter_input_device_add_tool (ClutterInputDevice *device, ClutterInputDeviceTool *tool); diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 4a7b4c85c11..47888c97d42 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -95,7 +95,6 @@ clutter_input_device_dispose (GObject *gobject) if (device->accessibility_virtual_device) g_clear_object (&device->accessibility_virtual_device); - g_clear_pointer (&device->scroll_info, g_array_unref); g_clear_pointer (&device->touch_sequence_actors, g_hash_table_unref); if (device->cursor_actor) @@ -848,100 +847,6 @@ clutter_input_device_keycode_to_evdev (ClutterInputDevice *device, evdev_keycode); } -void -_clutter_input_device_add_scroll_info (ClutterInputDevice *device, - guint index_, - ClutterScrollDirection direction, - gdouble increment) -{ - ClutterScrollInfo info; - - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - - info.axis_id = index_; - info.direction = direction; - info.increment = increment; - info.last_value_valid = FALSE; - - if (device->scroll_info == NULL) - { - device->scroll_info = g_array_new (FALSE, - FALSE, - sizeof (ClutterScrollInfo)); - } - - g_array_append_val (device->scroll_info, info); -} - -gboolean -_clutter_input_device_get_scroll_delta (ClutterInputDevice *device, - guint index_, - gdouble value, - ClutterScrollDirection *direction_p, - gdouble *delta_p) -{ - guint i; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - - if (device->scroll_info == NULL) - return FALSE; - - for (i = 0; i < device->scroll_info->len; i++) - { - ClutterScrollInfo *info = &g_array_index (device->scroll_info, - ClutterScrollInfo, - i); - - if (info->axis_id == index_) - { - if (direction_p != NULL) - *direction_p = info->direction; - - if (delta_p != NULL) - *delta_p = 0.0; - - if (info->last_value_valid) - { - if (delta_p != NULL) - { - *delta_p = (value - info->last_value) - / info->increment; - } - - info->last_value = value; - } - else - { - info->last_value = value; - info->last_value_valid = TRUE; - } - - return TRUE; - } - } - - return FALSE; -} - -void -_clutter_input_device_reset_scroll_info (ClutterInputDevice *device) -{ - guint i; - - if (device->scroll_info == NULL) - return; - - for (i = 0; i < device->scroll_info->len; i++) - { - ClutterScrollInfo *info = &g_array_index (device->scroll_info, - ClutterScrollInfo, - i); - - info->last_value_valid = FALSE; - } -} - static void on_grab_actor_destroy (ClutterActor *actor, ClutterInputDevice *device) diff --git a/src/backends/x11/meta-input-device-x11.c b/src/backends/x11/meta-input-device-x11.c index 4fdd3b61b59..3d82cce5018 100644 --- a/src/backends/x11/meta-input-device-x11.c +++ b/src/backends/x11/meta-input-device-x11.c @@ -38,6 +38,7 @@ struct _MetaInputDeviceX11 float current_y; GArray *axes; + GArray *scroll_info; #ifdef HAVE_LIBWACOM GArray *group_modes; @@ -57,6 +58,16 @@ typedef struct _MetaX11AxisInfo double resolution; } MetaX11AxisInfo; +typedef struct _MetaX11ScrollInfo +{ + guint axis_id; + ClutterScrollDirection direction; + double increment; + + double last_value; + guint last_value_valid : 1; +} MetaX11ScrollInfo; + struct _MetaInputDeviceX11Class { ClutterInputDeviceClass device_class; @@ -149,6 +160,7 @@ meta_input_device_x11_finalize (GObject *object) MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (object); g_clear_pointer (&device_xi2->axes, g_array_unref); + g_clear_pointer (&device_xi2->scroll_info, g_array_unref); #ifdef HAVE_LIBWACOM if (device_xi2->group_modes) @@ -594,6 +606,101 @@ meta_input_device_x11_get_n_axes (ClutterInputDevice *device) return device_x11->axes->len; } +void +meta_input_device_x11_add_scroll_info (ClutterInputDevice *device, + int idx, + ClutterScrollDirection direction, + double increment) +{ + MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device); + MetaX11ScrollInfo info; + + g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); + + info.axis_id = idx; + info.direction = direction; + info.increment = increment; + info.last_value_valid = FALSE; + + if (device_x11->scroll_info == NULL) + { + device_x11->scroll_info = g_array_new (FALSE, + FALSE, + sizeof (MetaX11ScrollInfo)); + } + + g_array_append_val (device_x11->scroll_info, info); +} + +gboolean +meta_input_device_x11_get_scroll_delta (ClutterInputDevice *device, + int idx, + double value, + ClutterScrollDirection *direction_p, + double *delta_p) +{ + MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device); + int i; + + if (device_x11->scroll_info == NULL) + return FALSE; + + for (i = 0; i < device_x11->scroll_info->len; i++) + { + MetaX11ScrollInfo *info = &g_array_index (device_x11->scroll_info, + MetaX11ScrollInfo, + i); + + if (info->axis_id == idx) + { + if (direction_p != NULL) + *direction_p = info->direction; + + if (delta_p != NULL) + *delta_p = 0.0; + + if (info->last_value_valid) + { + if (delta_p != NULL) + { + *delta_p = (value - info->last_value) + / info->increment; + } + + info->last_value = value; + } + else + { + info->last_value = value; + info->last_value_valid = TRUE; + } + + return TRUE; + } + } + + return FALSE; +} + +void +meta_input_device_x11_reset_scroll_info (ClutterInputDevice *device) +{ + MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device); + int i; + + if (device_x11->scroll_info == NULL) + return; + + for (i = 0; i < device_x11->scroll_info->len; i++) + { + MetaX11ScrollInfo *info = &g_array_index (device_x11->scroll_info, + MetaX11ScrollInfo, + i); + + info->last_value_valid = FALSE; + } +} + #ifdef HAVE_LIBWACOM uint32_t meta_input_device_x11_get_pad_group_mode (ClutterInputDevice *device, diff --git a/src/backends/x11/meta-input-device-x11.h b/src/backends/x11/meta-input-device-x11.h index 19f1efcdd27..66e03f5814c 100644 --- a/src/backends/x11/meta-input-device-x11.h +++ b/src/backends/x11/meta-input-device-x11.h @@ -86,6 +86,17 @@ gboolean meta_input_device_x11_translate_axis (ClutterInputDevice *device, double value, double *axis_value); +void meta_input_device_x11_add_scroll_info (ClutterInputDevice *device, + int idx, + ClutterScrollDirection direction, + double increment); +gboolean meta_input_device_x11_get_scroll_delta (ClutterInputDevice *device, + int idx, + gdouble value, + ClutterScrollDirection *direction_p, + double *delta_p); +void meta_input_device_x11_reset_scroll_info (ClutterInputDevice *device); + G_END_DECLS #endif /* META_INPUT_DEVICE_X11_H */ diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index 1983c93c43b..5a889b905ab 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -197,7 +197,7 @@ translate_device_classes (Display *xdisplay, : "horizontal", scroll_info->increment); - _clutter_input_device_add_scroll_info (device, + meta_input_device_x11_add_scroll_info (device, scroll_info->number, direction, scroll_info->increment); @@ -1195,7 +1195,7 @@ scroll_valuators_changed (ClutterInputDevice *device, if (!XIMaskIsSet (valuators->mask, i)) continue; - if (_clutter_input_device_get_scroll_delta (device, i, + if (meta_input_device_x11_get_scroll_delta (device, i, values[n_val], &direction, &delta)) @@ -1794,7 +1794,7 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, } if (source_device) - _clutter_input_device_reset_scroll_info (source_device); + meta_input_device_x11_reset_scroll_info (source_device); } retval = FALSE; break; @@ -2308,7 +2308,7 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, translate_coords (stage_x11, xev->event_x, xev->event_y, &event->crossing.x, &event->crossing.y); } - _clutter_input_device_reset_scroll_info (source_device); + meta_input_device_x11_reset_scroll_info (source_device); clutter_event_set_device (event, device); clutter_event_set_source_device (event, source_device); -- GitLab From c7f989c1e22f65bfa3a0eef8a80cb635ffba25d9 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 19 Nov 2020 12:04:46 +0100 Subject: [PATCH 73/85] clutter: Drop ClutterInputDevice private tool maintenance API This is just used in the native backend (with the X11 going its own way). Just keep a HT of tools there, and drop this API. Part-of: --- .../clutter/clutter-input-device-private.h | 12 ------ clutter/clutter/clutter-input-device.c | 40 ------------------- src/backends/native/meta-seat-impl.c | 22 ++++++---- src/backends/native/meta-seat-impl.h | 1 + 4 files changed, 16 insertions(+), 59 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index cb8fd8621d8..fc9f1742ed7 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -92,8 +92,6 @@ struct _ClutterInputDevice char *product_id; char *node_path; - GPtrArray *tools; - int n_rings; int n_strips; int n_mode_groups; @@ -116,16 +114,6 @@ CLUTTER_EXPORT void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, ClutterEvent *event); -CLUTTER_EXPORT -void clutter_input_device_add_tool (ClutterInputDevice *device, - ClutterInputDeviceTool *tool); - -CLUTTER_EXPORT -ClutterInputDeviceTool * - clutter_input_device_lookup_tool (ClutterInputDevice *device, - guint64 serial, - ClutterInputDeviceToolType type); - CLUTTER_EXPORT gboolean clutter_input_device_keycode_to_evdev (ClutterInputDevice *device, guint hardware_keycode, diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 47888c97d42..4631a454f1c 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -1172,46 +1172,6 @@ clutter_input_device_get_product_id (ClutterInputDevice *device) return device->product_id; } -void -clutter_input_device_add_tool (ClutterInputDevice *device, - ClutterInputDeviceTool *tool) -{ - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - g_return_if_fail (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_LOGICAL); - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL (tool)); - - if (!device->tools) - device->tools = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); - - g_ptr_array_add (device->tools, tool); -} - -ClutterInputDeviceTool * -clutter_input_device_lookup_tool (ClutterInputDevice *device, - guint64 serial, - ClutterInputDeviceToolType type) -{ - ClutterInputDeviceTool *tool; - guint i; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - g_return_val_if_fail (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_LOGICAL, NULL); - - if (!device->tools) - return NULL; - - for (i = 0; i < device->tools->len; i++) - { - tool = g_ptr_array_index (device->tools, i); - - if (serial == clutter_input_device_tool_get_serial (tool) && - type == clutter_input_device_tool_get_tool_type (tool)) - return tool; - } - - return NULL; -} - gint clutter_input_device_get_n_rings (ClutterInputDevice *device) { diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 56f4d3652cb..32f56b120f3 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -1661,22 +1661,29 @@ input_device_update_tool (MetaSeatImpl *seat_impl, { MetaInputDeviceNative *evdev_device = META_INPUT_DEVICE_NATIVE (input_device); ClutterInputDeviceTool *tool = NULL; - ClutterInputDeviceToolType tool_type; MetaInputSettings *input_settings; - uint64_t tool_serial; if (libinput_tool) { - tool_serial = libinput_tablet_tool_get_serial (libinput_tool); - tool_type = translate_tool_type (libinput_tool); - tool = clutter_input_device_lookup_tool (input_device, - tool_serial, tool_type); + if (!seat_impl->tools) + { + seat_impl->tools = + g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) g_object_unref); + } + + tool = g_hash_table_lookup (seat_impl->tools, libinput_tool); if (!tool) { + ClutterInputDeviceToolType tool_type; + uint64_t tool_serial; + + tool_serial = libinput_tablet_tool_get_serial (libinput_tool); + tool_type = translate_tool_type (libinput_tool); tool = meta_input_device_tool_native_new (libinput_tool, tool_serial, tool_type); - clutter_input_device_add_tool (input_device, tool); + g_hash_table_insert (seat_impl->tools, libinput_tool, tool); } } @@ -2663,6 +2670,7 @@ meta_seat_impl_finalize (GObject *object) g_object_unref (device); } g_slist_free (seat_impl->devices); + g_clear_pointer (&seat_impl->tools, g_hash_table_unref); if (seat_impl->touch_states) g_hash_table_destroy (seat_impl->touch_states); diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index 30b52ffb0a8..680cee2fd5d 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -62,6 +62,7 @@ struct _MetaSeatImpl GRWLock state_lock; GSList *devices; + GHashTable *tools; ClutterInputDevice *core_pointer; ClutterInputDevice *core_keyboard; -- GitLab From 71b4c0ee02cea56373e9a64b3acd5513fdcd770b Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 19 Nov 2020 12:21:26 +0100 Subject: [PATCH 74/85] clutter: Drop keycode_to_evdev vmethod This is just used in the native backend, move it to an utility function there. Part-of: --- .../clutter/clutter-input-device-private.h | 5 --- clutter/clutter/clutter-input-device.c | 34 ------------------- clutter/clutter/clutter-input-device.h | 4 --- .../native/meta-input-device-native.c | 14 -------- .../native/meta-virtual-input-device-native.c | 6 ++-- src/backends/native/meta-xkb-utils.c | 10 ++++++ src/backends/native/meta-xkb-utils.h | 1 + src/backends/x11/meta-input-device-x11.c | 15 -------- 8 files changed, 13 insertions(+), 76 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index fc9f1742ed7..841bdfd66d1 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -114,9 +114,4 @@ CLUTTER_EXPORT void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, ClutterEvent *event); -CLUTTER_EXPORT -gboolean clutter_input_device_keycode_to_evdev (ClutterInputDevice *device, - guint hardware_keycode, - guint *evdev_keycode); - #endif /* CLUTTER_INPUT_DEVICE_PRIVATE_H */ diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 4631a454f1c..bdab32a5c78 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -813,40 +813,6 @@ _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, } } -/** - * clutter_input_device_keycode_to_evdev: - * @device: A #ClutterInputDevice - * @hardware_keycode: The hardware keycode from a #ClutterKeyEvent - * @evdev_keycode: The return location for the evdev keycode - * - * Translates a hardware keycode from a #ClutterKeyEvent to the - * equivalent evdev keycode. Note that depending on the input backend - * used by Clutter this function can fail if there is no obvious - * mapping between the key codes. The hardware keycode can be taken - * from the #ClutterKeyEvent.hardware_keycode member of #ClutterKeyEvent. - * - * Return value: %TRUE if the conversion succeeded, %FALSE otherwise. - * - * Since: 1.10 - */ -gboolean -clutter_input_device_keycode_to_evdev (ClutterInputDevice *device, - guint hardware_keycode, - guint *evdev_keycode) -{ - ClutterInputDeviceClass *device_class; - - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - - device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device); - if (device_class->keycode_to_evdev == NULL) - return FALSE; - else - return device_class->keycode_to_evdev (device, - hardware_keycode, - evdev_keycode); -} - static void on_grab_actor_destroy (ClutterActor *actor, ClutterInputDevice *device) diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index 72870c26044..c2a2521cee9 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -41,10 +41,6 @@ struct _ClutterInputDeviceClass { GObjectClass parent_class; - gboolean (* keycode_to_evdev) (ClutterInputDevice *device, - guint hardware_keycode, - guint *evdev_keycode); - gboolean (* is_mode_switch_button) (ClutterInputDevice *device, guint group, guint button); diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index 7ab48e48064..ec571cff01e 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -120,19 +120,6 @@ meta_input_device_native_get_property (GObject *object, } } -static gboolean -meta_input_device_native_keycode_to_evdev (ClutterInputDevice *device, - uint32_t hardware_keycode, - uint32_t *evdev_keycode) -{ - /* The hardware keycodes from the evdev backend are almost evdev - keycodes: we use the evdev keycode file, but xkb rules have an - offset by 8. See the comment in _clutter_key_event_new_from_evdev() - */ - *evdev_keycode = hardware_keycode - 8; - return TRUE; -} - static gboolean meta_input_device_native_is_mode_switch_button (ClutterInputDevice *device, uint32_t group, @@ -1203,7 +1190,6 @@ meta_input_device_native_class_init (MetaInputDeviceNativeClass *klass) object_class->set_property = meta_input_device_native_set_property; object_class->get_property = meta_input_device_native_get_property; - device_manager_class->keycode_to_evdev = meta_input_device_native_keycode_to_evdev; device_manager_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_manager_class->is_grouped = meta_input_device_native_is_grouped; diff --git a/src/backends/native/meta-virtual-input-device-native.c b/src/backends/native/meta-virtual-input-device-native.c index 28542dc94e8..9d19f108280 100644 --- a/src/backends/native/meta-virtual-input-device-native.c +++ b/src/backends/native/meta-virtual-input-device-native.c @@ -538,8 +538,7 @@ apply_level_modifiers (ClutterVirtualInputDevice *virtual_device, &keycode, NULL)) return; - clutter_input_device_keycode_to_evdev (virtual_evdev->impl_state->device, - keycode, &evcode); + evcode = meta_xkb_keycode_to_evdev (keycode); meta_topic (META_DEBUG_INPUT, "Emitting virtual key-%s of modifier key 0x%x (device %p)", @@ -576,8 +575,7 @@ notify_keyval (GTask *task) goto out; } - clutter_input_device_keycode_to_evdev (virtual_evdev->impl_state->device, - keycode, &evcode); + evcode = meta_xkb_keycode_to_evdev (keycode); if (get_button_type (evcode) != EVDEV_BUTTON_TYPE_KEY) { diff --git a/src/backends/native/meta-xkb-utils.c b/src/backends/native/meta-xkb-utils.c index eb2a8320136..edee5ac2f2a 100644 --- a/src/backends/native/meta-xkb-utils.c +++ b/src/backends/native/meta-xkb-utils.c @@ -118,3 +118,13 @@ meta_xkb_translate_modifiers (struct xkb_state *state, return modifiers; } + +uint32_t +meta_xkb_keycode_to_evdev (uint32_t xkb_keycode) +{ + /* The keycodes from the evdev backend are almost evdev + * keycodes: we use the evdev keycode file, but xkb rules have an + * offset by 8. See the comment in _clutter_key_event_new_from_evdev() + */ + return xkb_keycode - 8; +} diff --git a/src/backends/native/meta-xkb-utils.h b/src/backends/native/meta-xkb-utils.h index f0fa507acee..b34de1fba6d 100644 --- a/src/backends/native/meta-xkb-utils.h +++ b/src/backends/native/meta-xkb-utils.h @@ -37,5 +37,6 @@ void meta_xkb_translate_state (ClutterEvent *event, uint32_t button_state); ClutterModifierType meta_xkb_translate_modifiers (struct xkb_state *state, ClutterModifierType button_state); +uint32_t meta_xkb_keycode_to_evdev (uint32_t hardware_keycode); #endif /* META_XKB_UTILS_H */ diff --git a/src/backends/x11/meta-input-device-x11.c b/src/backends/x11/meta-input-device-x11.c index 3d82cce5018..545a3a3398f 100644 --- a/src/backends/x11/meta-input-device-x11.c +++ b/src/backends/x11/meta-input-device-x11.c @@ -106,20 +106,6 @@ meta_input_device_x11_constructed (GObject *object) #endif } -static gboolean -meta_input_device_x11_keycode_to_evdev (ClutterInputDevice *device, - uint32_t hardware_keycode, - uint32_t *evdev_keycode) -{ - /* When using evdev under X11 the hardware keycodes are the evdev - keycodes plus 8. I haven't been able to find any documentation to - know what the +8 is for. FIXME: This should probably verify that - X server is using evdev. */ - *evdev_keycode = hardware_keycode - 8; - - return TRUE; -} - static gboolean meta_input_device_x11_is_grouped (ClutterInputDevice *device, ClutterInputDevice *other_device) @@ -296,7 +282,6 @@ meta_input_device_x11_class_init (MetaInputDeviceX11Class *klass) gobject_class->set_property = meta_input_device_x11_set_property; gobject_class->get_property = meta_input_device_x11_get_property; - device_class->keycode_to_evdev = meta_input_device_x11_keycode_to_evdev; device_class->is_grouped = meta_input_device_x11_is_grouped; device_class->get_group_n_modes = meta_input_device_x11_get_group_n_modes; device_class->is_mode_switch_button = meta_input_device_x11_is_mode_switch_button; -- GitLab From e0444a3d35e35a8b1caf6ce6732f907c4d2f61bd Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 19 Nov 2020 13:51:42 +0100 Subject: [PATCH 75/85] clutter: Move ClutterInputDevice fields to private struct All that is left in the "public" struct is all state that ClutterStage delegates on ClutterInputDevice. That should move somewhere else, but not here, not now. All private fields belong to construct-only properties, with only getter API, and idempotent vmethods (except keyboard a11y, atm). This should be enough to make ClutterInputDevice obviously thread safe, outside the backend. Part-of: --- .../clutter/clutter-input-device-private.h | 23 --- clutter/clutter/clutter-input-device.c | 174 +++++++++++++----- clutter/clutter/clutter-input-pointer-a11y.c | 64 ++++--- src/backends/x11/meta-input-device-x11.c | 3 +- src/backends/x11/meta-seat-x11.c | 20 +- 5 files changed, 182 insertions(+), 102 deletions(-) diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h index 841bdfd66d1..672f3cf79de 100644 --- a/clutter/clutter/clutter-input-device-private.h +++ b/clutter/clutter/clutter-input-device-private.h @@ -53,15 +53,6 @@ struct _ClutterInputDevice { GObject parent_instance; - ClutterInputDeviceType device_type; - ClutterInputMode device_mode; - - char *device_name; - - ClutterSeat *seat; - - ClutterBackend *backend; - /* the actor underneath the pointer */ ClutterActor *cursor_actor; GHashTable *inv_touch_sequence_actors; @@ -74,10 +65,7 @@ struct _ClutterInputDevice /* the current click count */ int click_count; - - /* the current state */ int current_button_number; - ClutterModifierType current_state; /* the current touch points targets */ GHashTable *touch_sequence_actors; @@ -88,17 +76,6 @@ struct _ClutterInputDevice uint32_t previous_time; int previous_button_number; - char *vendor_id; - char *product_id; - char *node_path; - - int n_rings; - int n_strips; - int n_mode_groups; - - guint has_cursor : 1; - guint is_enabled : 1; - /* Accessiblity */ ClutterVirtualInputDevice *accessibility_virtual_device; ClutterPtrA11yData *ptr_a11y_data; diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index bdab32a5c78..87c8a6820e3 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -80,17 +80,43 @@ static void on_cursor_actor_reactive_changed (ClutterActor *actor, static GParamSpec *obj_props[PROP_LAST] = { NULL, }; -G_DEFINE_TYPE (ClutterInputDevice, clutter_input_device, G_TYPE_OBJECT); +typedef struct _ClutterInputDevicePrivate ClutterInputDevicePrivate; + +struct _ClutterInputDevicePrivate +{ + ClutterInputDeviceType device_type; + ClutterInputMode device_mode; + + char *device_name; + + ClutterSeat *seat; + + ClutterBackend *backend; + + char *vendor_id; + char *product_id; + char *node_path; + + int n_rings; + int n_strips; + int n_mode_groups; + + gboolean has_cursor; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (ClutterInputDevice, clutter_input_device, G_TYPE_OBJECT); static void clutter_input_device_dispose (GObject *gobject) { ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (gobject); + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); - g_clear_pointer (&device->device_name, g_free); - g_clear_pointer (&device->vendor_id, g_free); - g_clear_pointer (&device->product_id, g_free); - g_clear_pointer (&device->node_path, g_free); + g_clear_pointer (&priv->device_name, g_free); + g_clear_pointer (&priv->vendor_id, g_free); + g_clear_pointer (&priv->product_id, g_free); + g_clear_pointer (&priv->node_path, g_free); if (device->accessibility_virtual_device) g_clear_object (&device->accessibility_virtual_device); @@ -141,55 +167,57 @@ clutter_input_device_set_property (GObject *gobject, GParamSpec *pspec) { ClutterInputDevice *self = CLUTTER_INPUT_DEVICE (gobject); + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (self); switch (prop_id) { case PROP_DEVICE_TYPE: - self->device_type = g_value_get_enum (value); + priv->device_type = g_value_get_enum (value); break; case PROP_SEAT: - self->seat = g_value_get_object (value); + priv->seat = g_value_get_object (value); break; case PROP_DEVICE_MODE: - self->device_mode = g_value_get_enum (value); + priv->device_mode = g_value_get_enum (value); break; case PROP_BACKEND: - self->backend = g_value_get_object (value); + priv->backend = g_value_get_object (value); break; case PROP_NAME: - self->device_name = g_value_dup_string (value); + priv->device_name = g_value_dup_string (value); break; case PROP_HAS_CURSOR: - self->has_cursor = g_value_get_boolean (value); + priv->has_cursor = g_value_get_boolean (value); break; case PROP_VENDOR_ID: - self->vendor_id = g_value_dup_string (value); + priv->vendor_id = g_value_dup_string (value); break; case PROP_PRODUCT_ID: - self->product_id = g_value_dup_string (value); + priv->product_id = g_value_dup_string (value); break; case PROP_N_RINGS: - self->n_rings = g_value_get_int (value); + priv->n_rings = g_value_get_int (value); break; case PROP_N_STRIPS: - self->n_strips = g_value_get_int (value); + priv->n_strips = g_value_get_int (value); break; case PROP_N_MODE_GROUPS: - self->n_mode_groups = g_value_get_int (value); + priv->n_mode_groups = g_value_get_int (value); break; case PROP_DEVICE_NODE: - self->node_path = g_value_dup_string (value); + priv->node_path = g_value_dup_string (value); break; default: @@ -205,55 +233,57 @@ clutter_input_device_get_property (GObject *gobject, GParamSpec *pspec) { ClutterInputDevice *self = CLUTTER_INPUT_DEVICE (gobject); + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (self); switch (prop_id) { case PROP_DEVICE_TYPE: - g_value_set_enum (value, self->device_type); + g_value_set_enum (value, priv->device_type); break; case PROP_SEAT: - g_value_set_object (value, self->seat); + g_value_set_object (value, priv->seat); break; case PROP_DEVICE_MODE: - g_value_set_enum (value, self->device_mode); + g_value_set_enum (value, priv->device_mode); break; case PROP_BACKEND: - g_value_set_object (value, self->backend); + g_value_set_object (value, priv->backend); break; case PROP_NAME: - g_value_set_string (value, self->device_name); + g_value_set_string (value, priv->device_name); break; case PROP_HAS_CURSOR: - g_value_set_boolean (value, self->has_cursor); + g_value_set_boolean (value, priv->has_cursor); break; case PROP_VENDOR_ID: - g_value_set_string (value, self->vendor_id); + g_value_set_string (value, priv->vendor_id); break; case PROP_PRODUCT_ID: - g_value_set_string (value, self->product_id); + g_value_set_string (value, priv->product_id); break; case PROP_N_RINGS: - g_value_set_int (value, self->n_rings); + g_value_set_int (value, priv->n_rings); break; case PROP_N_STRIPS: - g_value_set_int (value, self->n_strips); + g_value_set_int (value, priv->n_strips); break; case PROP_N_MODE_GROUPS: - g_value_set_int (value, self->n_mode_groups); + g_value_set_int (value, priv->n_mode_groups); break; case PROP_DEVICE_NODE: - g_value_set_string (value, self->node_path); + g_value_set_string (value, priv->node_path); break; default: @@ -418,7 +448,10 @@ clutter_input_device_class_init (ClutterInputDeviceClass *klass) static void clutter_input_device_init (ClutterInputDevice *self) { - self->device_type = CLUTTER_POINTER_DEVICE; + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (self); + + priv->device_type = CLUTTER_POINTER_DEVICE; self->click_count = 0; @@ -615,10 +648,13 @@ _clutter_input_device_set_actor (ClutterInputDevice *device, ClutterInputDeviceType clutter_input_device_get_device_type (ClutterInputDevice *device) { + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), CLUTTER_POINTER_DEVICE); - return device->device_type; + return priv->device_type; } /* @@ -645,7 +681,9 @@ clutter_input_device_update (ClutterInputDevice *device, ClutterActor *new_cursor_actor; ClutterActor *old_cursor_actor; graphene_point_t point = GRAPHENE_POINT_INIT (-1.0f, -1.0f); - ClutterInputDeviceType device_type = device->device_type; + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + ClutterInputDeviceType device_type = priv->device_type; uint32_t time_ms; g_assert (device_type != CLUTTER_KEYBOARD_DEVICE && @@ -734,9 +772,12 @@ clutter_input_device_get_actor (ClutterInputDevice *device, const gchar * clutter_input_device_get_device_name (ClutterInputDevice *device) { + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - return device->device_name; + return priv->device_name; } /** @@ -753,9 +794,12 @@ clutter_input_device_get_device_name (ClutterInputDevice *device) gboolean clutter_input_device_get_has_cursor (ClutterInputDevice *device) { + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); - return device->has_cursor; + return priv->has_cursor; } /** @@ -771,10 +815,13 @@ clutter_input_device_get_has_cursor (ClutterInputDevice *device) ClutterInputMode clutter_input_device_get_device_mode (ClutterInputDevice *device) { + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), CLUTTER_INPUT_MODE_FLOATING); - return device->device_mode; + return priv->device_mode; } /*< private > @@ -817,7 +864,10 @@ static void on_grab_actor_destroy (ClutterActor *actor, ClutterInputDevice *device) { - switch (device->device_type) + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + + switch (priv->device_type) { case CLUTTER_POINTER_DEVICE: case CLUTTER_TABLET_DEVICE: @@ -857,11 +907,13 @@ clutter_input_device_grab (ClutterInputDevice *device, ClutterActor *actor) { ClutterActor **grab_actor; + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - switch (device->device_type) + switch (priv->device_type) { case CLUTTER_POINTER_DEVICE: case CLUTTER_TABLET_DEVICE: @@ -904,10 +956,12 @@ void clutter_input_device_ungrab (ClutterInputDevice *device) { ClutterActor **grab_actor; + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - switch (device->device_type) + switch (priv->device_type) { case CLUTTER_POINTER_DEVICE: case CLUTTER_TABLET_DEVICE: @@ -946,9 +1000,12 @@ clutter_input_device_ungrab (ClutterInputDevice *device) ClutterActor * clutter_input_device_get_grabbed_actor (ClutterInputDevice *device) { + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - switch (device->device_type) + switch (priv->device_type) { case CLUTTER_POINTER_DEVICE: case CLUTTER_TABLET_DEVICE: @@ -1113,10 +1170,13 @@ clutter_input_device_sequence_get_grabbed_actor (ClutterInputDevice *device, const gchar * clutter_input_device_get_vendor_id (ClutterInputDevice *device) { + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); g_return_val_if_fail (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_LOGICAL, NULL); - return device->vendor_id; + return priv->vendor_id; } /** @@ -1132,36 +1192,48 @@ clutter_input_device_get_vendor_id (ClutterInputDevice *device) const gchar * clutter_input_device_get_product_id (ClutterInputDevice *device) { + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); g_return_val_if_fail (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_LOGICAL, NULL); - return device->product_id; + return priv->product_id; } gint clutter_input_device_get_n_rings (ClutterInputDevice *device) { + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0); - return device->n_rings; + return priv->n_rings; } gint clutter_input_device_get_n_strips (ClutterInputDevice *device) { + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0); - return device->n_strips; + return priv->n_strips; } gint clutter_input_device_get_n_mode_groups (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 device->n_mode_groups; + return priv->n_mode_groups; } gint @@ -1206,13 +1278,15 @@ gint clutter_input_device_get_mode_switch_button_group (ClutterInputDevice *device, guint button) { + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); gint group; g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), -1); g_return_val_if_fail (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE, -1); - for (group = 0; group < device->n_mode_groups; group++) + for (group = 0; group < priv->n_mode_groups; group++) { if (clutter_input_device_is_mode_switch_button (device, group, button)) return group; @@ -1224,9 +1298,12 @@ clutter_input_device_get_mode_switch_button_group (ClutterInputDevice *device, const gchar * clutter_input_device_get_device_node (ClutterInputDevice *device) { + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - return device->node_path; + return priv->node_path; } gboolean @@ -1250,7 +1327,10 @@ clutter_input_device_is_grouped (ClutterInputDevice *device, ClutterSeat * clutter_input_device_get_seat (ClutterInputDevice *device) { + ClutterInputDevicePrivate *priv = + clutter_input_device_get_instance_private (device); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - return device->seat; + return priv->seat; } diff --git a/clutter/clutter/clutter-input-pointer-a11y.c b/clutter/clutter/clutter-input-pointer-a11y.c index b57ee81c086..365b85fd637 100644 --- a/clutter/clutter/clutter-input-pointer-a11y.c +++ b/clutter/clutter/clutter-input-pointer-a11y.c @@ -36,8 +36,9 @@ static gboolean is_secondary_click_enabled (ClutterInputDevice *device) { ClutterPointerA11ySettings settings; + ClutterSeat *seat = clutter_input_device_get_seat (device); - clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + clutter_seat_get_pointer_a11y_settings (seat, &settings); return (settings.controls & CLUTTER_A11Y_SECONDARY_CLICK_ENABLED); } @@ -46,8 +47,9 @@ static gboolean is_dwell_click_enabled (ClutterInputDevice *device) { ClutterPointerA11ySettings settings; + ClutterSeat *seat = clutter_input_device_get_seat (device); - clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + clutter_seat_get_pointer_a11y_settings (seat, &settings); return (settings.controls & CLUTTER_A11Y_DWELL_ENABLED); } @@ -56,8 +58,9 @@ static unsigned int get_secondary_click_delay (ClutterInputDevice *device) { ClutterPointerA11ySettings settings; + ClutterSeat *seat = clutter_input_device_get_seat (device); - clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + clutter_seat_get_pointer_a11y_settings (seat, &settings); return settings.secondary_click_delay; } @@ -66,8 +69,9 @@ static unsigned int get_dwell_delay (ClutterInputDevice *device) { ClutterPointerA11ySettings settings; + ClutterSeat *seat = clutter_input_device_get_seat (device); - clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + clutter_seat_get_pointer_a11y_settings (seat, &settings); return settings.dwell_delay; } @@ -76,8 +80,9 @@ static unsigned int get_dwell_threshold (ClutterInputDevice *device) { ClutterPointerA11ySettings settings; + ClutterSeat *seat = clutter_input_device_get_seat (device); - clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + clutter_seat_get_pointer_a11y_settings (seat, &settings); return settings.dwell_threshold; } @@ -86,8 +91,9 @@ static ClutterPointerA11yDwellMode get_dwell_mode (ClutterInputDevice *device) { ClutterPointerA11ySettings settings; + ClutterSeat *seat = clutter_input_device_get_seat (device); - clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + clutter_seat_get_pointer_a11y_settings (seat, &settings); return settings.dwell_mode; } @@ -96,8 +102,9 @@ static ClutterPointerA11yDwellClickType get_dwell_click_type (ClutterInputDevice *device) { ClutterPointerA11ySettings settings; + ClutterSeat *seat = clutter_input_device_get_seat (device); - clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + clutter_seat_get_pointer_a11y_settings (seat, &settings); return settings.dwell_click_type; } @@ -107,8 +114,9 @@ get_dwell_click_type_for_direction (ClutterInputDevice *device, ClutterPointerA11yDwellDirection direction) { ClutterPointerA11ySettings settings; + ClutterSeat *seat = clutter_input_device_get_seat (device); - clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + clutter_seat_get_pointer_a11y_settings (seat, &settings); if (direction == settings.dwell_gesture_single) return CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY; @@ -163,11 +171,12 @@ static gboolean trigger_secondary_click (gpointer data) { ClutterInputDevice *device = data; + ClutterSeat *seat = clutter_input_device_get_seat (device); device->ptr_a11y_data->secondary_click_triggered = TRUE; device->ptr_a11y_data->secondary_click_timer = 0; - g_signal_emit_by_name (device->seat, + g_signal_emit_by_name (seat, "ptr-a11y-timeout-stopped", device, CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK, @@ -180,11 +189,12 @@ static void start_secondary_click_timeout (ClutterInputDevice *device) { unsigned int delay = get_secondary_click_delay (device); + ClutterSeat *seat = clutter_input_device_get_seat (device); device->ptr_a11y_data->secondary_click_timer = clutter_threads_add_timeout (delay, trigger_secondary_click, device); - g_signal_emit_by_name (device->seat, + g_signal_emit_by_name (seat, "ptr-a11y-timeout-started", device, CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK, @@ -194,12 +204,14 @@ start_secondary_click_timeout (ClutterInputDevice *device) static void stop_secondary_click_timeout (ClutterInputDevice *device) { + ClutterSeat *seat = clutter_input_device_get_seat (device); + if (device->ptr_a11y_data->secondary_click_timer) { g_clear_handle_id (&device->ptr_a11y_data->secondary_click_timer, g_source_remove); - g_signal_emit_by_name (device->seat, + g_signal_emit_by_name (seat, "ptr-a11y-timeout-stopped", device, CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK, @@ -302,8 +314,9 @@ update_dwell_click_type (ClutterInputDevice *device) { ClutterPointerA11ySettings settings; ClutterPointerA11yDwellClickType dwell_click_type; + ClutterSeat *seat = clutter_input_device_get_seat (device); - clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + clutter_seat_get_pointer_a11y_settings (seat, &settings); dwell_click_type = settings.dwell_click_type; switch (dwell_click_type) @@ -328,9 +341,9 @@ update_dwell_click_type (ClutterInputDevice *device) if (dwell_click_type != settings.dwell_click_type) { settings.dwell_click_type = dwell_click_type; - clutter_seat_set_pointer_a11y_settings (device->seat, &settings); + clutter_seat_set_pointer_a11y_settings (seat, &settings); - g_signal_emit_by_name (device->seat, + g_signal_emit_by_name (seat, "ptr-a11y-dwell-click-type-changed", dwell_click_type); } @@ -424,6 +437,7 @@ trigger_dwell_gesture (gpointer data) ClutterInputDevice *device = data; ClutterPointerA11yDwellDirection direction; unsigned int delay = get_dwell_delay (device); + ClutterSeat *seat = clutter_input_device_get_seat (device); restore_dwell_position (device); direction = get_dwell_direction (device); @@ -435,7 +449,7 @@ trigger_dwell_gesture (gpointer data) device->ptr_a11y_data->dwell_timer = clutter_threads_add_timeout (delay, trigger_clear_dwell_gesture, device); - g_signal_emit_by_name (device->seat, + g_signal_emit_by_name (seat, "ptr-a11y-timeout-stopped", device, CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE, @@ -448,12 +462,13 @@ static void start_dwell_gesture_timeout (ClutterInputDevice *device) { unsigned int delay = get_dwell_delay (device); + ClutterSeat *seat = clutter_input_device_get_seat (device); device->ptr_a11y_data->dwell_timer = clutter_threads_add_timeout (delay, trigger_dwell_gesture, device); device->ptr_a11y_data->dwell_gesture_started = TRUE; - g_signal_emit_by_name (device->seat, + g_signal_emit_by_name (seat, "ptr-a11y-timeout-started", device, CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE, @@ -464,10 +479,11 @@ static gboolean trigger_dwell_click (gpointer data) { ClutterInputDevice *device = data; + ClutterSeat *seat = clutter_input_device_get_seat (device); device->ptr_a11y_data->dwell_timer = 0; - g_signal_emit_by_name (device->seat, + g_signal_emit_by_name (seat, "ptr-a11y-timeout-stopped", device, CLUTTER_A11Y_TIMEOUT_TYPE_DWELL, @@ -493,11 +509,12 @@ static void start_dwell_timeout (ClutterInputDevice *device) { unsigned int delay = get_dwell_delay (device); + ClutterSeat *seat = clutter_input_device_get_seat (device); device->ptr_a11y_data->dwell_timer = clutter_threads_add_timeout (delay, trigger_dwell_click, device); - g_signal_emit_by_name (device->seat, + g_signal_emit_by_name (seat, "ptr-a11y-timeout-started", device, CLUTTER_A11Y_TIMEOUT_TYPE_DWELL, @@ -507,12 +524,14 @@ start_dwell_timeout (ClutterInputDevice *device) static void stop_dwell_timeout (ClutterInputDevice *device) { + ClutterSeat *seat = clutter_input_device_get_seat (device); + if (device->ptr_a11y_data->dwell_timer) { g_clear_handle_id (&device->ptr_a11y_data->dwell_timer, g_source_remove); device->ptr_a11y_data->dwell_gesture_started = FALSE; - g_signal_emit_by_name (device->seat, + g_signal_emit_by_name (seat, "ptr-a11y-timeout-stopped", device, CLUTTER_A11Y_TIMEOUT_TYPE_DWELL, @@ -570,8 +589,9 @@ static gboolean is_device_core_pointer (ClutterInputDevice *device) { ClutterInputDevice *core_pointer; + ClutterSeat *seat = clutter_input_device_get_seat (device); - core_pointer = clutter_seat_get_pointer (device->seat); + core_pointer = clutter_seat_get_pointer (seat); if (core_pointer == NULL) return FALSE; @@ -581,11 +601,13 @@ is_device_core_pointer (ClutterInputDevice *device) void _clutter_input_pointer_a11y_add_device (ClutterInputDevice *device) { + ClutterSeat *seat = clutter_input_device_get_seat (device); + if (!is_device_core_pointer (device)) return; device->accessibility_virtual_device = - clutter_seat_create_virtual_device (device->seat, + clutter_seat_create_virtual_device (seat, CLUTTER_POINTER_DEVICE); device->ptr_a11y_data = g_new0 (ClutterPtrA11yData, 1); diff --git a/src/backends/x11/meta-input-device-x11.c b/src/backends/x11/meta-input-device-x11.c index 545a3a3398f..0c4e023d1d1 100644 --- a/src/backends/x11/meta-input-device-x11.c +++ b/src/backends/x11/meta-input-device-x11.c @@ -447,7 +447,8 @@ meta_input_device_x11_get_pointer_location (ClutterInputDevice *device, MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device); g_return_val_if_fail (META_IS_INPUT_DEVICE_X11 (device), FALSE); - g_return_val_if_fail (device->device_type == CLUTTER_POINTER_DEVICE, FALSE); + g_return_val_if_fail (clutter_input_device_get_device_type (device) == + CLUTTER_POINTER_DEVICE, FALSE); /* Throttle XServer queries and roundtrips using an idle timeout */ if (device_xi2->inhibit_pointer_query_timer == 0) diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index 5a889b905ab..ce1fae3c002 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -897,7 +897,7 @@ translate_raw_event (MetaSeatX11 *seat_x11, case XI_RawMotion: g_debug ("raw motion: device:%d '%s'", meta_input_device_x11_get_device_id (device), - device->device_name); + clutter_input_device_get_device_name (device)); /* We don't get actual pointer location with raw events, and we cannot * rely on `clutter_input_device_get_coords()` either because of @@ -914,7 +914,7 @@ translate_raw_event (MetaSeatX11 *seat_x11, ? "press " : "release", meta_input_device_x11_get_device_id (device), - device->device_name, + clutter_input_device_get_device_name (device), xev->detail); _clutter_input_pointer_a11y_on_button_event (device, xev->detail, @@ -1019,7 +1019,7 @@ translate_pad_event (ClutterEvent *event, : "pad strip", (unsigned int) xev->event, meta_input_device_x11_get_device_id (device), - device->device_name, + clutter_input_device_get_device_name (device), event->any.time, value); return TRUE; @@ -1946,7 +1946,7 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, : "pad button release", (unsigned int) stage_x11->xwin, meta_input_device_x11_get_device_id (device), - device->device_name, + clutter_input_device_get_device_name (device), event->any.time, event->pad_button.button); retval = TRUE; @@ -1996,7 +1996,7 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, "emulated:%s)", (unsigned int) stage_x11->xwin, meta_input_device_x11_get_device_id (device), - device->device_name, + clutter_input_device_get_device_name (device), event->any.time, event->scroll.direction == CLUTTER_SCROLL_UP ? "up" : event->scroll.direction == CLUTTER_SCROLL_DOWN ? "down" : @@ -2042,7 +2042,7 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, : "button release", (unsigned int) stage_x11->xwin, meta_input_device_x11_get_device_id (device), - device->device_name, + clutter_input_device_get_device_name (device), event->any.time, event->button.button, event->button.x, @@ -2105,7 +2105,7 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, g_debug ("smooth scroll: win:0x%x device:%d '%s' (x:%.2f, y:%.2f, delta:%f, %f)", (unsigned int) stage_x11->xwin, meta_input_device_x11_get_device_id (event->scroll.device), - event->scroll.device->device_name, + clutter_input_device_get_device_name (event->scroll.device), event->scroll.x, event->scroll.y, delta_x, delta_y); @@ -2141,7 +2141,7 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, g_debug ("motion: win:0x%x device:%d '%s' (x:%.2f, y:%.2f, axes:%s)", (unsigned int) stage_x11->xwin, meta_input_device_x11_get_device_id (event->motion.device), - event->motion.device->device_name, + clutter_input_device_get_device_name (event->motion.device), event->motion.x, event->motion.y, event->motion.axes != NULL ? "yes" : "no"); @@ -2213,7 +2213,7 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, event->type == CLUTTER_TOUCH_BEGIN ? "begin" : "end", (unsigned int) stage_x11->xwin, meta_input_device_x11_get_device_id (event->touch.device), - event->touch.device->device_name, + clutter_input_device_get_device_name (event->touch.device), GPOINTER_TO_UINT (event->touch.sequence), event->touch.x, event->touch.y, @@ -2264,7 +2264,7 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat, g_debug ("touch update: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f, axes:%s)", (unsigned int) stage_x11->xwin, meta_input_device_x11_get_device_id (event->touch.device), - event->touch.device->device_name, + clutter_input_device_get_device_name (event->touch.device), GPOINTER_TO_UINT (event->touch.sequence), event->touch.x, event->touch.y, -- GitLab From 7547891a76cb71b4dc639903e14ac7a768fe1cc8 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 19 Nov 2020 16:00:12 +0100 Subject: [PATCH 76/85] backends: Straighten MetaInputSettings creation We have "create" and "get" methods, and a "create" vmethod. Make it all "get" so the backend implementations can keep their own reference without completely lying. Part-of: --- src/backends/meta-backend-private.h | 2 +- src/backends/meta-backend.c | 51 ++++++++----------- src/backends/native/meta-backend-native.c | 4 +- src/backends/x11/cm/meta-backend-x11-cm.c | 13 +++-- .../x11/nested/meta-backend-x11-nested.c | 4 +- 5 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index b4dc5de10c1..80df654bc67 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -69,7 +69,7 @@ struct _MetaBackendClass MetaCursorTracker * (* create_cursor_tracker) (MetaBackend *backend); MetaRenderer * (* create_renderer) (MetaBackend *backend, GError **error); - MetaInputSettings * (* create_input_settings) (MetaBackend *backend); + MetaInputSettings * (* get_input_settings) (MetaBackend *backend); gboolean (* grab_device) (MetaBackend *backend, int device_id, diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index ddedfdd60e2..b208a53957a 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -122,7 +122,6 @@ struct _MetaBackendPrivate MetaMonitorManager *monitor_manager; MetaOrientationManager *orientation_manager; MetaCursorTracker *cursor_tracker; - MetaInputSettings *input_settings; MetaInputMapper *input_mapper; MetaRenderer *renderer; #ifdef HAVE_EGL @@ -202,7 +201,6 @@ meta_backend_finalize (GObject *object) g_clear_object (&priv->current_device); g_clear_object (&priv->monitor_manager); g_clear_object (&priv->orientation_manager); - g_clear_object (&priv->input_settings); #ifdef HAVE_REMOTE_DESKTOP g_clear_object (&priv->remote_desktop); g_clear_object (&priv->screen_cast); @@ -521,21 +519,12 @@ create_device_monitors (MetaBackend *backend, g_list_free (devices); } -static MetaInputSettings * -meta_backend_create_input_settings (MetaBackend *backend) -{ - return META_BACKEND_GET_CLASS (backend)->create_input_settings (backend); -} - static void input_mapper_device_mapped_cb (MetaInputMapper *mapper, ClutterInputDevice *device, float matrix[6], - MetaBackend *backend) + MetaInputSettings *input_settings) { - MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); - MetaInputSettings *input_settings = priv->input_settings; - meta_input_settings_set_device_matrix (input_settings, device, matrix); } @@ -543,11 +532,8 @@ static void input_mapper_device_enabled_cb (MetaInputMapper *mapper, ClutterInputDevice *device, gboolean enabled, - MetaBackend *backend) + MetaInputSettings *input_settings) { - MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); - MetaInputSettings *input_settings = priv->input_settings; - meta_input_settings_set_device_enabled (input_settings, device, enabled); } @@ -555,11 +541,8 @@ static void input_mapper_device_aspect_ratio_cb (MetaInputMapper *mapper, ClutterInputDevice *device, double aspect_ratio, - MetaBackend *backend) + MetaInputSettings *input_settings) { - MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); - MetaInputSettings *input_settings = priv->input_settings; - meta_input_settings_set_device_aspect_ratio (input_settings, device, aspect_ratio); } @@ -576,6 +559,7 @@ meta_backend_real_post_init (MetaBackend *backend) { MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); ClutterSeat *seat = clutter_backend_get_default_seat (priv->clutter_backend); + MetaInputSettings *input_settings; priv->stage = meta_stage_new (backend); clutter_actor_realize (priv->stage); @@ -599,15 +583,22 @@ meta_backend_real_post_init (MetaBackend *backend) G_CALLBACK (on_device_removed), backend, G_CONNECT_AFTER); - priv->input_settings = meta_backend_create_input_settings (backend); - priv->input_mapper = meta_input_mapper_new (); - g_signal_connect (priv->input_mapper, "device-mapped", - G_CALLBACK (input_mapper_device_mapped_cb), backend); - g_signal_connect (priv->input_mapper, "device-enabled", - G_CALLBACK (input_mapper_device_enabled_cb), backend); - g_signal_connect (priv->input_mapper, "device-aspect-ratio", - G_CALLBACK (input_mapper_device_aspect_ratio_cb), backend); + + input_settings = meta_backend_get_input_settings (backend); + + if (input_settings) + { + g_signal_connect (priv->input_mapper, "device-mapped", + G_CALLBACK (input_mapper_device_mapped_cb), + input_settings); + g_signal_connect (priv->input_mapper, "device-enabled", + G_CALLBACK (input_mapper_device_enabled_cb), + input_settings); + g_signal_connect (priv->input_mapper, "device-aspect-ratio", + G_CALLBACK (input_mapper_device_aspect_ratio_cb), + input_settings); + } #ifdef HAVE_REMOTE_DESKTOP priv->dbus_session_watcher = g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL); @@ -1521,9 +1512,7 @@ meta_backend_get_input_mapper (MetaBackend *backend) MetaInputSettings * meta_backend_get_input_settings (MetaBackend *backend) { - MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); - - return priv->input_settings; + return META_BACKEND_GET_CLASS (backend)->get_input_settings (backend); } /** diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index a78c0866f6e..79da95fa111 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -259,7 +259,7 @@ meta_backend_native_create_renderer (MetaBackend *backend, } static MetaInputSettings * -meta_backend_native_create_input_settings (MetaBackend *backend) +meta_backend_native_get_input_settings (MetaBackend *backend) { MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); @@ -555,7 +555,7 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass) backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager; backend_class->get_cursor_renderer = meta_backend_native_get_cursor_renderer; backend_class->create_renderer = meta_backend_native_create_renderer; - backend_class->create_input_settings = meta_backend_native_create_input_settings; + backend_class->get_input_settings = meta_backend_native_get_input_settings; backend_class->get_current_logical_monitor = meta_backend_native_get_current_logical_monitor; diff --git a/src/backends/x11/cm/meta-backend-x11-cm.c b/src/backends/x11/cm/meta-backend-x11-cm.c index 35e1acf9f05..3b39178e0db 100644 --- a/src/backends/x11/cm/meta-backend-x11-cm.c +++ b/src/backends/x11/cm/meta-backend-x11-cm.c @@ -46,6 +46,8 @@ struct _MetaBackendX11Cm char *keymap_variants; char *keymap_options; int locked_group; + + MetaInputSettings *input_settings; }; G_DEFINE_TYPE (MetaBackendX11Cm, meta_backend_x11_cm, META_TYPE_BACKEND_X11) @@ -87,8 +89,11 @@ meta_backend_x11_cm_post_init (MetaBackend *backend) { MetaBackendClass *parent_backend_class = META_BACKEND_CLASS (meta_backend_x11_cm_parent_class); + MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (backend); ClutterSeat *seat; + x11_cm->input_settings = g_object_new (META_TYPE_INPUT_SETTINGS_X11, NULL); + parent_backend_class->post_init (backend); seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); @@ -143,9 +148,11 @@ meta_backend_x11_cm_create_cursor_tracker (MetaBackend *backend) } static MetaInputSettings * -meta_backend_x11_cm_create_input_settings (MetaBackend *backend) +meta_backend_x11_cm_get_input_settings (MetaBackend *backend) { - return g_object_new (META_TYPE_INPUT_SETTINGS_X11, NULL); + MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (backend); + + return x11_cm->input_settings; } static void @@ -457,7 +464,7 @@ meta_backend_x11_cm_class_init (MetaBackendX11CmClass *klass) backend_class->create_monitor_manager = meta_backend_x11_cm_create_monitor_manager; backend_class->get_cursor_renderer = meta_backend_x11_cm_get_cursor_renderer; backend_class->create_cursor_tracker = meta_backend_x11_cm_create_cursor_tracker; - backend_class->create_input_settings = meta_backend_x11_cm_create_input_settings; + backend_class->get_input_settings = meta_backend_x11_cm_get_input_settings; backend_class->update_screen_size = meta_backend_x11_cm_update_screen_size; backend_class->select_stage_events = meta_backend_x11_cm_select_stage_events; backend_class->lock_layout_group = meta_backend_x11_cm_lock_layout_group; diff --git a/src/backends/x11/nested/meta-backend-x11-nested.c b/src/backends/x11/nested/meta-backend-x11-nested.c index 041f4b87afa..425ddcb1a17 100644 --- a/src/backends/x11/nested/meta-backend-x11-nested.c +++ b/src/backends/x11/nested/meta-backend-x11-nested.c @@ -84,7 +84,7 @@ meta_backend_x11_nested_get_cursor_renderer (MetaBackend *backend, } static MetaInputSettings * -meta_backend_x11_nested_create_input_settings (MetaBackend *backend) +meta_backend_x11_nested_get_input_settings (MetaBackend *backend) { return NULL; } @@ -289,7 +289,7 @@ meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass) backend_class->create_renderer = meta_backend_x11_nested_create_renderer; backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager; backend_class->get_cursor_renderer = meta_backend_x11_nested_get_cursor_renderer; - backend_class->create_input_settings = meta_backend_x11_nested_create_input_settings; + backend_class->get_input_settings = meta_backend_x11_nested_get_input_settings; backend_class->update_screen_size = meta_backend_x11_nested_update_screen_size; backend_class->select_stage_events = meta_backend_x11_nested_select_stage_events; backend_class->lock_layout_group = meta_backend_x11_nested_lock_layout_group; -- GitLab From ceefa72ade79e313bfa3d519163fa2c895c1057a Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 21 Nov 2020 12:52:45 +0100 Subject: [PATCH 77/85] backends/native: Shuffle keyboard a11y signal connection into MetaSeatImpl This signal gets emitted in the input thread, and does things that belong to it. Make it clear by moving to the MetaSeatImpl. Part-of: --- src/backends/native/meta-backend-native.c | 35 +++++------------------ src/backends/native/meta-seat-impl.c | 13 +++++++++ 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index 79da95fa111..c397a7893b5 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -74,7 +74,6 @@ struct _MetaBackendNative MetaLauncher *launcher; MetaUdev *udev; MetaKms *kms; - MetaInputSettings *input_settings; gulong udev_device_added_handler_id; }; @@ -102,7 +101,6 @@ meta_backend_native_finalize (GObject *object) g_clear_object (&native->udev); g_clear_object (&native->kms); meta_launcher_free (native->launcher); - g_clear_object (&native->input_settings); G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object); } @@ -163,33 +161,10 @@ update_viewports (MetaBackend *backend) g_object_unref (viewports); } -static void -kbd_a11y_changed_cb (MetaInputSettings *input_settings, - MetaKbdA11ySettings *a11y_settings, - MetaBackend *backend) -{ - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); - ClutterInputDevice *device; - - device = clutter_seat_get_keyboard (seat); - if (device) - meta_input_device_native_apply_kbd_a11y_settings (META_INPUT_DEVICE_NATIVE (device), - a11y_settings); -} - static void meta_backend_native_post_init (MetaBackend *backend) { - MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); MetaSettings *settings = meta_backend_get_settings (backend); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - MetaSeatNative *seat = - META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend)); - - backend_native->input_settings = meta_seat_impl_get_input_settings (seat->impl); - g_signal_connect_object (backend_native->input_settings, "kbd-a11y-changed", - G_CALLBACK (kbd_a11y_changed_cb), backend, 0); META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend); @@ -261,9 +236,11 @@ meta_backend_native_create_renderer (MetaBackend *backend, static MetaInputSettings * meta_backend_native_get_input_settings (MetaBackend *backend) { - MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + MetaSeatNative *seat_native = + META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend)); - return backend_native->input_settings; + return meta_seat_impl_get_input_settings (seat_native->impl); } static MetaLogicalMonitor * @@ -667,6 +644,7 @@ void meta_backend_native_resume (MetaBackendNative *native) MetaSeatNative *seat = META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend)); MetaRenderer *renderer = meta_backend_get_renderer (backend); + MetaInputSettings *input_settings; COGL_TRACE_BEGIN_SCOPED (MetaBackendNativeResume, "Backend (resume)"); @@ -683,7 +661,8 @@ void meta_backend_native_resume (MetaBackendNative *native) idle_monitor = meta_idle_monitor_get_core (); meta_idle_monitor_reset_idletime (idle_monitor); - meta_input_settings_maybe_restore_numlock_state (native->input_settings); + input_settings = meta_backend_get_input_settings (backend); + meta_input_settings_maybe_restore_numlock_state (input_settings); clutter_seat_ensure_a11y_state (CLUTTER_SEAT (seat)); } diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 32f56b120f3..bafc69e0323 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -2476,6 +2476,17 @@ static const struct libinput_interface libinput_interface = { close_restricted }; +static void +kbd_a11y_changed_cb (MetaInputSettings *input_settings, + MetaKbdA11ySettings *a11y_settings, + MetaSeatImpl *seat_impl) +{ + MetaInputDeviceNative *keyboard; + + keyboard = META_INPUT_DEVICE_NATIVE (seat_impl->core_keyboard); + meta_input_device_native_apply_kbd_a11y_settings (keyboard, a11y_settings); +} + static void meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, gboolean numlock_state) @@ -2568,6 +2579,8 @@ meta_seat_impl_constructed (GObject *object) udev_unref (udev); seat_impl->input_settings = meta_input_settings_native_new (seat_impl); + g_signal_connect_object (seat_impl->input_settings, "kbd-a11y-changed", + G_CALLBACK (kbd_a11y_changed_cb), seat_impl, 0); seat_impl->udev_client = g_udev_client_new ((const char *[]) { "input", NULL }); -- GitLab From 18fdcfc95afe62273668f6f637efdc2245e0ffe1 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 21 Nov 2020 12:52:55 +0100 Subject: [PATCH 78/85] backends/native: Make MetaInputSettingsNative vmethods "async" Those that are exposed via MetaInputSettings API that's still accessible in other parts of the backend. Part-of: --- .../native/meta-input-settings-native.c | 89 ++++++++++++++++--- 1 file changed, 78 insertions(+), 11 deletions(-) diff --git a/src/backends/native/meta-input-settings-native.c b/src/backends/native/meta-input-settings-native.c index c0550f8d16a..754c01a0f10 100644 --- a/src/backends/native/meta-input-settings-native.c +++ b/src/backends/native/meta-input-settings-native.c @@ -82,14 +82,17 @@ meta_input_settings_native_get_property (GObject *object, } } -static void -meta_input_settings_native_set_send_events (MetaInputSettings *settings, - ClutterInputDevice *device, - GDesktopDeviceSendEvents mode) +static gboolean +set_send_events (GTask *task) { + GDesktopDeviceSendEvents mode; + ClutterInputDevice *device; enum libinput_config_send_events_mode libinput_mode; struct libinput_device *libinput_device; + device = g_task_get_source_object (task); + mode = GPOINTER_TO_UINT (g_task_get_task_data (task)); + switch (mode) { case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED: @@ -106,9 +109,39 @@ meta_input_settings_native_set_send_events (MetaInputSettings *settings, } libinput_device = meta_input_device_native_get_libinput_device (device); - if (!libinput_device) - return; libinput_device_config_send_events_set_mode (libinput_device, libinput_mode); + + return G_SOURCE_REMOVE; +} + +static void +meta_input_settings_native_set_send_events (MetaInputSettings *settings, + ClutterInputDevice *device, + GDesktopDeviceSendEvents mode) +{ + MetaInputSettingsNative *input_settings_native; + GTask *task; + + task = g_task_new (device, NULL, NULL, NULL); + g_task_set_task_data (task, GUINT_TO_POINTER (mode), NULL); + + input_settings_native = META_INPUT_SETTINGS_NATIVE (settings); + meta_seat_impl_run_input_task (input_settings_native->seat_impl, + task, (GSourceFunc) set_send_events); + g_object_unref (task); +} + +static gboolean +set_matrix (GTask *task) +{ + ClutterInputDevice *device; + cairo_matrix_t *dev_matrix; + + device = g_task_get_source_object (task); + dev_matrix = g_task_get_task_data (task); + g_object_set (device, "device-matrix", dev_matrix, NULL); + + return G_SOURCE_REMOVE; } static void @@ -116,22 +149,32 @@ meta_input_settings_native_set_matrix (MetaInputSettings *settings, ClutterInputDevice *device, gfloat matrix[6]) { - cairo_matrix_t dev_matrix; + MetaInputSettingsNative *input_settings_native; + cairo_matrix_t *dev_matrix; + GTask *task; + + dev_matrix = g_new0 (cairo_matrix_t, 1); if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE || meta_input_device_native_get_mapping_mode (device) == META_INPUT_DEVICE_MAPPING_ABSOLUTE) { - cairo_matrix_init (&dev_matrix, matrix[0], matrix[3], matrix[1], + cairo_matrix_init (dev_matrix, matrix[0], matrix[3], matrix[1], matrix[4], matrix[2], matrix[5]); } else { - cairo_matrix_init_identity (&dev_matrix); + cairo_matrix_init_identity (dev_matrix); } - g_object_set (device, "device-matrix", &dev_matrix, NULL); + task = g_task_new (device, NULL, NULL, NULL); + g_task_set_task_data (task, dev_matrix, g_free); + + input_settings_native = META_INPUT_SETTINGS_NATIVE (settings); + meta_seat_impl_run_input_task (input_settings_native->seat_impl, + task, (GSourceFunc) set_matrix); + g_object_unref (task); } static void @@ -596,16 +639,40 @@ meta_input_settings_native_set_tablet_mapping (MetaInputSettings *settings, meta_input_device_native_set_mapping_mode (device, dev_mapping); } +static gboolean +set_tablet_aspect_ratio (GTask *task) +{ + ClutterInputDevice *device; + double *aspect_ratio; + + device = g_task_get_source_object (task); + aspect_ratio = g_task_get_task_data (task); + g_object_set (device, "output-aspect-ratio", *aspect_ratio, NULL); + + return G_SOURCE_REMOVE; +} + static void meta_input_settings_native_set_tablet_aspect_ratio (MetaInputSettings *settings, ClutterInputDevice *device, gdouble aspect_ratio) { + MetaInputSettingsNative *input_settings_native; + GTask *task; + if (meta_input_device_native_get_mapping_mode (device) == META_INPUT_DEVICE_MAPPING_RELATIVE) aspect_ratio = 0; - g_object_set (device, "output-aspect-ratio", aspect_ratio, NULL); + task = g_task_new (device, NULL, NULL, NULL); + g_task_set_task_data (task, + g_memdup (&aspect_ratio, sizeof (double)), + g_free); + + input_settings_native = META_INPUT_SETTINGS_NATIVE (settings); + meta_seat_impl_run_input_task (input_settings_native->seat_impl, + task, (GSourceFunc) set_tablet_aspect_ratio); + g_object_unref (task); } static void -- GitLab From f117a157dcd0e009d0cde82d9f8094a245cced82 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 19 Nov 2020 18:51:58 +0100 Subject: [PATCH 79/85] 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: --- clutter/clutter/clutter-enums.h | 7 ++ clutter/clutter/clutter-input-device.c | 46 ++++++++ clutter/clutter/clutter-input-device.h | 12 +++ .../native/meta-input-device-native.c | 102 ++++++++++++++++-- .../native/meta-input-device-native.h | 1 + src/wayland/meta-wayland-tablet-pad-group.c | 30 ++---- src/wayland/meta-wayland-tablet-pad.c | 68 ++---------- 7 files changed, 178 insertions(+), 88 deletions(-) diff --git a/clutter/clutter/clutter-enums.h b/clutter/clutter/clutter-enums.h index bcc848b3834..9b0c29fa0cc 100644 --- a/clutter/clutter/clutter-enums.h +++ b/clutter/clutter/clutter-enums.h @@ -1611,6 +1611,13 @@ typedef enum CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER, } ClutterInputDevicePadSource; +typedef enum +{ + CLUTTER_PAD_FEATURE_BUTTON, + CLUTTER_PAD_FEATURE_RING, + CLUTTER_PAD_FEATURE_STRIP, +} ClutterInputDevicePadFeature; + typedef enum { CLUTTER_INPUT_CONTENT_HINT_COMPLETION = 1 << 0, diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 87c8a6820e3..a6df0064380 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -67,6 +67,7 @@ enum PROP_N_STRIPS, PROP_N_RINGS, PROP_N_MODE_GROUPS, + PROP_N_BUTTONS, PROP_DEVICE_NODE, PROP_LAST @@ -100,6 +101,7 @@ struct _ClutterInputDevicePrivate int n_rings; int n_strips; int n_mode_groups; + int n_buttons; gboolean has_cursor; }; @@ -216,6 +218,10 @@ clutter_input_device_set_property (GObject *gobject, priv->n_mode_groups = g_value_get_int (value); break; + case PROP_N_BUTTONS: + priv->n_buttons = g_value_get_int (value); + break; + case PROP_DEVICE_NODE: priv->node_path = g_value_dup_string (value); break; @@ -282,6 +288,10 @@ clutter_input_device_get_property (GObject *gobject, g_value_set_int (value, priv->n_mode_groups); break; + case PROP_N_BUTTONS: + g_value_set_int (value, priv->n_buttons); + break; + case PROP_DEVICE_NODE: g_value_set_string (value, priv->node_path); break; @@ -432,6 +442,13 @@ clutter_input_device_class_init (ClutterInputDeviceClass *klass) 0, G_MAXINT, 0, 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] = g_param_spec_string ("device-node", P_("Device node path"), @@ -1236,6 +1253,19 @@ clutter_input_device_get_n_mode_groups (ClutterInputDevice *device) 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 clutter_input_device_get_group_n_modes (ClutterInputDevice *device, gint group) @@ -1295,6 +1325,22 @@ clutter_input_device_get_mode_switch_button_group (ClutterInputDevice *device, 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 * clutter_input_device_get_device_node (ClutterInputDevice *device) { diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index c2a2521cee9..28ab0443b3d 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -50,6 +50,10 @@ struct _ClutterInputDeviceClass gboolean (* is_grouped) (ClutterInputDevice *device, ClutterInputDevice *other_device); + int (* get_pad_feature_group) (ClutterInputDevice *device, + ClutterInputDevicePadFeature feature, + int n_feature); + /* Keyboard accessbility */ void (* process_kbd_a11y_event) (ClutterEvent *event, ClutterInputDevice *device, @@ -128,6 +132,9 @@ CLUTTER_EXPORT gint clutter_input_device_get_n_strips (ClutterInputDevice *device); CLUTTER_EXPORT gint clutter_input_device_get_n_mode_groups (ClutterInputDevice *device); +CLUTTER_EXPORT +int clutter_input_device_get_n_buttons (ClutterInputDevice *device); + CLUTTER_EXPORT gint clutter_input_device_get_group_n_modes (ClutterInputDevice *device, @@ -150,6 +157,11 @@ gboolean clutter_input_device_is_grouped (ClutterInputDev CLUTTER_EXPORT 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 #endif /* __CLUTTER_INPUT_DEVICE_H__ */ diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index ec571cff01e..86a61be128a 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -52,6 +52,15 @@ typedef struct _SlowKeysEventPending guint timer; } SlowKeysEventPending; +typedef struct _PadFeature PadFeature; + +struct _PadFeature +{ + ClutterInputDevicePadFeature feature; + int n_feature; + int group; +}; + static void clear_slow_keys (MetaInputDeviceNative *device); static void stop_bounce_keys (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_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); } @@ -160,6 +171,31 @@ meta_input_device_native_is_grouped (ClutterInputDevice *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 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 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); object_class->finalize = meta_input_device_native_finalize; object_class->set_property = meta_input_device_native_set_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_manager_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_manager_class->process_kbd_a11y_event = meta_input_device_native_process_kbd_a11y_event; + device_class->is_mode_switch_button = meta_input_device_native_is_mode_switch_button; + device_class->get_group_n_modes = meta_input_device_native_get_group_n_modes; + device_class->is_grouped = meta_input_device_native_is_grouped; + 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] = g_param_spec_boxed ("device-matrix", @@ -1219,6 +1256,53 @@ meta_input_device_native_init (MetaInputDeviceNative *self) 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: * @manager: the device manager @@ -1235,7 +1319,7 @@ meta_input_device_native_new (MetaSeatImpl *seat_impl, MetaInputDeviceNative *device; ClutterInputDeviceType type; 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; 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_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 = 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-strips", n_strips, "n-mode-groups", n_groups, + "n-buttons", n_buttons, "device-node", node_path, "seat", seat_impl->seat_native, NULL); @@ -1274,6 +1360,10 @@ meta_input_device_native_new (MetaSeatImpl *seat_impl, g_free (product); 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) device->device_aspect_ratio = width / height; diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h index e76aade71b0..4203be90721 100644 --- a/src/backends/native/meta-input-device-native.h +++ b/src/backends/native/meta-input-device-native.h @@ -71,6 +71,7 @@ struct _MetaInputDeviceNative struct libinput_device *libinput_device; MetaSeatImpl *seat_impl; ClutterInputDeviceTool *last_tool; + GArray *pad_features; cairo_matrix_t device_matrix; double device_aspect_ratio; /* w:h */ diff --git a/src/wayland/meta-wayland-tablet-pad-group.c b/src/wayland/meta-wayland-tablet-pad-group.c index 4229f834a72..46d3d21fc5f 100644 --- a/src/wayland/meta-wayland-tablet-pad-group.c +++ b/src/wayland/meta-wayland-tablet-pad-group.c @@ -32,12 +32,6 @@ #include "wayland/meta-wayland-tablet-pad.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" static void @@ -123,26 +117,14 @@ gboolean meta_wayland_tablet_pad_group_has_button (MetaWaylandTabletPadGroup *group, guint button) { -#ifdef HAVE_NATIVE_BACKEND - MetaBackend *backend = meta_get_backend (); - - if (META_IS_BACKEND_NATIVE (backend)) - { - struct libinput_device *libinput_device; - struct libinput_tablet_pad_mode_group *mode_group; - guint n_group; + int n_group = g_list_index (group->pad->groups, group); - libinput_device = meta_input_device_native_get_libinput_device (group->pad->device); - n_group = g_list_index (group->pad->groups, group); - mode_group = libinput_device_tablet_pad_get_mode_group (libinput_device, n_group); + if (clutter_input_device_get_pad_feature_group (group->pad->device, + CLUTTER_PAD_FEATURE_BUTTON, + button) == n_group) + return TRUE; - return libinput_tablet_pad_mode_group_has_button (mode_group, button); - } - else -#endif - { - return g_list_length (group->pad->groups) == 1; - } + return FALSE; } static void diff --git a/src/wayland/meta-wayland-tablet-pad.c b/src/wayland/meta-wayland-tablet-pad.c index d96bdfed45f..22704aee73d 100644 --- a/src/wayland/meta-wayland-tablet-pad.c +++ b/src/wayland/meta-wayland-tablet-pad.c @@ -38,12 +38,6 @@ #include "wayland/meta-wayland-tablet-seat.h" #include "wayland/meta-wayland-tablet.h" -#ifdef HAVE_NATIVE_BACKEND -#include -#include "backends/native/meta-backend-native.h" -#include "backends/native/meta-input-device-native.h" -#endif - #include "tablet-unstable-v2-server-protocol.h" static void @@ -66,41 +60,20 @@ group_rings_strips (MetaWaylandTabletPad *pad) { gint n_group, n_elem; 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) { 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) { MetaWaylandTabletPadRing *ring = l->data; -#ifdef HAVE_NATIVE_BACKEND - if (mode_group) - { - if (libinput_tablet_pad_mode_group_has_ring (mode_group, n_elem)) - 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); - } + if (clutter_input_device_get_pad_feature_group (pad->device, + CLUTTER_PAD_FEATURE_RING, + n_elem) == n_group) + meta_wayland_tablet_pad_ring_set_group (ring, group); + n_elem++; } @@ -108,19 +81,10 @@ group_rings_strips (MetaWaylandTabletPad *pad) { MetaWaylandTabletPadStrip *strip = l->data; -#ifdef HAVE_NATIVE_BACKEND - if (mode_group) - { - if (libinput_tablet_pad_mode_group_has_strip (mode_group, n_elem)) - 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); - } + if (clutter_input_device_get_pad_feature_group (pad->device, + CLUTTER_PAD_FEATURE_STRIP, + n_elem) == n_group) + meta_wayland_tablet_pad_strip_set_group (strip, group); n_elem++; } @@ -133,9 +97,6 @@ MetaWaylandTabletPad * meta_wayland_tablet_pad_new (ClutterInputDevice *device, MetaWaylandTabletSeat *tablet_seat) { -#ifdef HAVE_NATIVE_BACKEND - MetaBackend *backend = meta_get_backend (); -#endif MetaWaylandTabletPad *pad; 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, (GDestroyNotify) g_free); -#ifdef HAVE_NATIVE_BACKEND - /* 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 + pad->n_buttons = clutter_input_device_get_n_buttons (device); n_elems = clutter_input_device_get_n_mode_groups (pad->device); -- GitLab From 2ff5bb4299a9638bc6dc42d295e2c1aeeee3e497 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 19 Nov 2020 23:58:56 +0100 Subject: [PATCH 80/85] backends/native: Update keyboard a11y status in seat impl Instead of going through the event queue, stage handling code, and back to the input device via a vmethod call, do this directly in the MetaSeatImpl. This is not too different from X11, where everything happens inside the backend. Part-of: --- clutter/clutter/clutter-input-device.h | 8 --- clutter/clutter/clutter-main.c | 19 +------ .../native/meta-input-device-native.c | 54 ++++++++----------- .../native/meta-input-device-native.h | 2 + src/backends/native/meta-seat-impl.c | 14 +++-- src/backends/native/meta-xkb-utils.c | 9 +++- src/backends/native/meta-xkb-utils.h | 1 + 7 files changed, 44 insertions(+), 63 deletions(-) diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index 28ab0443b3d..5e377cdcc19 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -34,9 +34,6 @@ G_BEGIN_DECLS -typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event, - ClutterInputDevice *device); - struct _ClutterInputDeviceClass { GObjectClass parent_class; @@ -53,11 +50,6 @@ struct _ClutterInputDeviceClass int (* get_pad_feature_group) (ClutterInputDevice *device, ClutterInputDevicePadFeature feature, int n_feature); - - /* Keyboard accessbility */ - void (* process_kbd_a11y_event) (ClutterEvent *event, - ClutterInputDevice *device, - ClutterEmitInputDeviceEvent emit_event_func); }; #define CLUTTER_TYPE_INPUT_DEVICE (clutter_input_device_get_type ()) diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index 035ed944413..e21d3d3fa04 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -1488,8 +1488,8 @@ emit_touch_event (ClutterEvent *event, } static inline void -emit_keyboard_event (ClutterEvent *event, - ClutterInputDevice *device) +process_key_event (ClutterEvent *event, + ClutterInputDevice *device) { if (_clutter_event_process_filters (event)) return; @@ -1500,21 +1500,6 @@ emit_keyboard_event (ClutterEvent *event, emit_event_chain (event); } -static inline void -process_key_event (ClutterEvent *event, - ClutterInputDevice *device) -{ - ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device); - - if (device_class->process_kbd_a11y_event) - { - device_class->process_kbd_a11y_event (event, device, emit_keyboard_event); - return; - } - - emit_keyboard_event (event, device); -} - static gboolean is_off_stage (ClutterActor *stage, gfloat x, diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index 86a61be128a..899c2613b97 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -48,7 +48,6 @@ typedef struct _SlowKeysEventPending { MetaInputDeviceNative *device; ClutterEvent *event; - ClutterEmitInputDeviceEvent emit_event_func; guint timer; } SlowKeysEventPending; @@ -242,8 +241,7 @@ trigger_slow_keys (gpointer data) /* Alter timestamp and emit the event */ key_event->time = us2ms (g_get_monotonic_time ()); - slow_keys_event->emit_event_func (slow_keys_event->event, - CLUTTER_INPUT_DEVICE (device)); + _clutter_event_push (slow_keys_event->event, TRUE); /* Then remote the pending event */ device->slow_keys_list = g_list_remove (device->slow_keys_list, slow_keys_event); @@ -266,21 +264,19 @@ find_pending_event_by_keycode (gconstpointer a, return kb->hardware_keycode - ka->hardware_keycode; } -static void -start_slow_keys (ClutterEvent *event, - MetaInputDeviceNative *device, - ClutterEmitInputDeviceEvent emit_event_func) +static gboolean +start_slow_keys (ClutterEvent *event, + MetaInputDeviceNative *device) { SlowKeysEventPending *slow_keys_event; ClutterKeyEvent *key_event = (ClutterKeyEvent *) event; if (key_event->flags & CLUTTER_EVENT_FLAG_REPEATED) - return; + return TRUE; slow_keys_event = g_new0 (SlowKeysEventPending, 1); slow_keys_event->device = device; slow_keys_event->event = clutter_event_copy (event); - slow_keys_event->emit_event_func = emit_event_func; slow_keys_event->timer = clutter_threads_add_timeout (get_slow_keys_delay (CLUTTER_INPUT_DEVICE (device)), trigger_slow_keys, @@ -289,12 +285,13 @@ start_slow_keys (ClutterEvent *event, if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_PRESS) meta_input_device_native_bell_notify (device); + + return TRUE; } -static void -stop_slow_keys (ClutterEvent *event, - MetaInputDeviceNative *device, - ClutterEmitInputDeviceEvent emit_event_func) +static gboolean +stop_slow_keys (ClutterEvent *event, + MetaInputDeviceNative *device) { GList *item; @@ -310,11 +307,11 @@ stop_slow_keys (ClutterEvent *event, if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_REJECT) meta_input_device_native_bell_notify (device); - return; + return TRUE; } /* If no key press event was pending, just emit the key release as-is */ - emit_event_func (event, CLUTTER_INPUT_DEVICE (device)); + return FALSE; } static guint @@ -1105,17 +1102,12 @@ handle_mousekeys_release (ClutterEvent *event, return FALSE; } -static void -meta_input_device_native_process_kbd_a11y_event (ClutterEvent *event, - ClutterInputDevice *device, - ClutterEmitInputDeviceEvent emit_event_func) +gboolean +meta_input_device_native_process_kbd_a11y_event (ClutterInputDevice *device, + ClutterEvent *event) { MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device); - /* Ignore key events injected from IM */ - if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD) - goto emit_event; - if (device_evdev->a11y_flags & META_A11Y_KEYBOARD_ENABLED) { if (event->type == CLUTTER_KEY_PRESS) @@ -1128,10 +1120,10 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve { if (event->type == CLUTTER_KEY_PRESS && handle_mousekeys_press (event, device_evdev)) - return; /* swallow event */ + return TRUE; /* swallow event */ if (event->type == CLUTTER_KEY_RELEASE && handle_mousekeys_release (event, device_evdev)) - return; /* swallow event */ + return TRUE; /* swallow event */ } if ((device_evdev->a11y_flags & META_A11Y_BOUNCE_KEYS_ENABLED) && @@ -1141,7 +1133,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve { notify_bounce_keys_reject (device_evdev); - return; + return TRUE; } else if (event->type == CLUTTER_KEY_RELEASE) start_bounce_keys (event, device_evdev); @@ -1151,11 +1143,9 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve (get_slow_keys_delay (device) != 0)) { if (event->type == CLUTTER_KEY_PRESS) - start_slow_keys (event, device_evdev, emit_event_func); + return start_slow_keys (event, device_evdev); else if (event->type == CLUTTER_KEY_RELEASE) - stop_slow_keys (event, device_evdev, emit_event_func); - - return; + return stop_slow_keys (event, device_evdev); } if (device_evdev->a11y_flags & META_A11Y_STICKY_KEYS_ENABLED) @@ -1166,8 +1156,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve handle_stickykeys_release (event, device_evdev); } -emit_event: - emit_event_func (event, device); + return FALSE; } void @@ -1230,7 +1219,6 @@ meta_input_device_native_class_init (MetaInputDeviceNativeClass *klass) device_class->get_group_n_modes = meta_input_device_native_get_group_n_modes; device_class->is_grouped = meta_input_device_native_is_grouped; 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] = g_param_spec_boxed ("device-matrix", diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h index 4203be90721..560081dfd66 100644 --- a/src/backends/native/meta-input-device-native.h +++ b/src/backends/native/meta-input-device-native.h @@ -149,5 +149,7 @@ void meta_input_device_native_set_coords (MetaInputDeviceNat void meta_input_device_native_get_coords (MetaInputDeviceNative *device_native, float *x, float *y); +gboolean meta_input_device_native_process_kbd_a11y_event (ClutterInputDevice *device, + ClutterEvent *event); #endif /* META_INPUT_DEVICE_NATIVE_H */ diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index bafc69e0323..309e4bae8ec 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -320,6 +320,7 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, { ClutterEvent *event = NULL; enum xkb_state_component changed_state; + uint32_t keycode; if (state != AUTOREPEAT_VALUE) { @@ -342,12 +343,13 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, us2ms (time_us), key, state); meta_event_native_set_event_code (event, key); + keycode = meta_xkb_evdev_to_keycode (key); + /* We must be careful and not pass multiple releases to xkb, otherwise it gets confused and locks the modifiers */ if (state != AUTOREPEAT_VALUE) { - changed_state = xkb_state_update_key (seat_impl->xkb, - event->key.hardware_keycode, + changed_state = xkb_state_update_key (seat_impl->xkb, keycode, state ? XKB_KEY_DOWN : XKB_KEY_UP); } else @@ -356,7 +358,11 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_REPEATED); } - queue_event (seat_impl, event); + if (!meta_input_device_native_process_kbd_a11y_event (seat_impl->core_keyboard, + event)) + queue_event (seat_impl, event); + else + clutter_event_free (event); if (update_keys && (changed_state & XKB_STATE_LEDS)) { @@ -380,7 +386,7 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, if (state == 0 || /* key release */ !seat_impl->repeat || !xkb_keymap_key_repeats (xkb_state_get_keymap (seat_impl->xkb), - event->key.hardware_keycode)) + keycode)) { meta_seat_impl_clear_repeat_timer (seat_impl); return; diff --git a/src/backends/native/meta-xkb-utils.c b/src/backends/native/meta-xkb-utils.c index edee5ac2f2a..45f89bec7ff 100644 --- a/src/backends/native/meta-xkb-utils.c +++ b/src/backends/native/meta-xkb-utils.c @@ -62,7 +62,7 @@ meta_key_event_new_from_evdev (ClutterInputDevice *device, * 0, whereas X11's minimum keycode, for really stupid reasons, is 8. * So the evdev XKB rules are based on the keycodes all being shifted * upwards by 8. */ - key += 8; + key = meta_xkb_evdev_to_keycode (key); n = xkb_key_get_syms (xkb_state, key, &syms); if (n == 1) @@ -128,3 +128,10 @@ meta_xkb_keycode_to_evdev (uint32_t xkb_keycode) */ return xkb_keycode - 8; } + +uint32_t +meta_xkb_evdev_to_keycode (uint32_t evcode) +{ + /* The inverse of meta_xkb_keycode_to_evdev */ + return evcode + 8; +} diff --git a/src/backends/native/meta-xkb-utils.h b/src/backends/native/meta-xkb-utils.h index b34de1fba6d..d605813e6dc 100644 --- a/src/backends/native/meta-xkb-utils.h +++ b/src/backends/native/meta-xkb-utils.h @@ -38,5 +38,6 @@ void meta_xkb_translate_state (ClutterEvent *event, ClutterModifierType meta_xkb_translate_modifiers (struct xkb_state *state, ClutterModifierType button_state); uint32_t meta_xkb_keycode_to_evdev (uint32_t hardware_keycode); +uint32_t meta_xkb_evdev_to_keycode (uint32_t evcode); #endif /* META_XKB_UTILS_H */ -- GitLab From 424f3b702ee78624e1253708008516c52739c441 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 23 Nov 2020 18:35:36 +0100 Subject: [PATCH 81/85] clutter: Do not emit signals during ClutterBackend finalization Missed because nobody does that ATM. Part-of: --- clutter/clutter/clutter-backend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clutter/clutter/clutter-backend.c b/clutter/clutter/clutter-backend.c index 5e98a2bbe55..91298c964c1 100644 --- a/clutter/clutter/clutter-backend.c +++ b/clutter/clutter/clutter-backend.c @@ -111,7 +111,7 @@ clutter_backend_finalize (GObject *gobject) g_source_destroy (backend->cogl_source); g_free (backend->font_name); - clutter_backend_set_font_options (backend, NULL); + g_clear_pointer (&backend->font_options, cairo_font_options_destroy); g_clear_object (&backend->input_method); G_OBJECT_CLASS (clutter_backend_parent_class)->finalize (gobject); -- GitLab From 321b971a9613dca63795df1c601c55e0a7b713aa Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sat, 21 Nov 2020 14:05:08 +0100 Subject: [PATCH 82/85] backends/native: Add missing seat finalization paths On finalize we leak the clutter backend, which leaks the stage and seat. Part-of: --- src/backends/meta-backend.c | 2 ++ src/backends/native/meta-clutter-backend-native.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index b208a53957a..aca0d6fc995 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -231,6 +231,8 @@ meta_backend_finalize (GObject *object) g_clear_object (&priv->profiler); #endif + g_clear_object (&priv->clutter_backend); + G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object); } diff --git a/src/backends/native/meta-clutter-backend-native.c b/src/backends/native/meta-clutter-backend-native.c index 58d6afa44fc..a1d0d097168 100644 --- a/src/backends/native/meta-clutter-backend-native.c +++ b/src/backends/native/meta-clutter-backend-native.c @@ -125,6 +125,17 @@ meta_clutter_backend_native_is_display_server (ClutterBackend *backend) return TRUE; } +static void +meta_clutter_backend_native_finalize (GObject *object) +{ + MetaClutterBackendNative *backend_native = META_CLUTTER_BACKEND_NATIVE (object); + + g_clear_object (&backend_native->main_seat); + g_clear_object (&backend_native->stage_native); + + G_OBJECT_CLASS (meta_clutter_backend_native_parent_class)->finalize (object); +} + static void meta_clutter_backend_native_init (MetaClutterBackendNative *clutter_backend_nativen) { @@ -133,8 +144,11 @@ meta_clutter_backend_native_init (MetaClutterBackendNative *clutter_backend_nati static void meta_clutter_backend_native_class_init (MetaClutterBackendNativeClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); ClutterBackendClass *clutter_backend_class = CLUTTER_BACKEND_CLASS (klass); + object_class->finalize = meta_clutter_backend_native_finalize; + clutter_backend_class->get_renderer = meta_clutter_backend_native_get_renderer; clutter_backend_class->create_stage = meta_clutter_backend_native_create_stage; clutter_backend_class->init_events = meta_clutter_backend_native_init_events; -- GitLab From 820262e5379b5b7d81a2b2a7af67bba3cc5f9f85 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 12 Aug 2020 18:04:34 +0200 Subject: [PATCH 83/85] backends/native: Add input thread inside MetaSeatImpl This (now) doesn't change anything in regards to the API that the UI thread should access from the MetaSeatImpl. The MetaInputDeviceNative, MetaInputSettings and MetaKeymap objects are now considered owned by the input thread, as well as all of libinput objects. The MetaEventSource now dispatches events in a GMainContext that is the thread default to this thread, and all UI-thread-accessible API (seat and virtual input device API) will be handled in a serialized manner by that same input thread. The MetaSeatImpl itself is still considered to be owned by the caller thread, and all the signals that this object emits will be emitted in the GMainContext that is default at the time of calling meta_seat_impl_new(). The MetaInputSettings configuration changes will likewise be handled in the input thread, close to libinput devices. Part-of: --- .../native/meta-input-device-native.c | 63 ++-- .../native/meta-input-device-native.h | 6 +- src/backends/native/meta-seat-impl.c | 279 +++++++++++++----- src/backends/native/meta-seat-impl.h | 9 +- 4 files changed, 256 insertions(+), 101 deletions(-) diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index 899c2613b97..d64bdbd0166 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -48,7 +48,7 @@ typedef struct _SlowKeysEventPending { MetaInputDeviceNative *device; ClutterEvent *event; - guint timer; + GSource *timer; } SlowKeysEventPending; typedef struct _PadFeature PadFeature; @@ -207,7 +207,7 @@ meta_input_device_native_free_pending_slow_key (gpointer data) SlowKeysEventPending *slow_keys_event = data; clutter_event_free (slow_keys_event->event); - g_clear_handle_id (&slow_keys_event->timer, g_source_remove); + g_clear_pointer (&slow_keys_event->timer, g_source_destroy); g_free (slow_keys_event); } @@ -264,6 +264,24 @@ find_pending_event_by_keycode (gconstpointer a, return kb->hardware_keycode - ka->hardware_keycode; } +static GSource * +timeout_source_new (MetaSeatImpl *seat_impl, + guint interval, + GSourceFunc func, + gpointer user_data) +{ + GSource *source; + + source = g_timeout_source_new (interval); + g_source_set_callback (source, + func, + user_data, NULL); + g_source_attach (source, seat_impl->input_context); + g_source_unref (source); + + return source; +} + static gboolean start_slow_keys (ClutterEvent *event, MetaInputDeviceNative *device) @@ -278,9 +296,10 @@ start_slow_keys (ClutterEvent *event, slow_keys_event->device = device; slow_keys_event->event = clutter_event_copy (event); slow_keys_event->timer = - clutter_threads_add_timeout (get_slow_keys_delay (CLUTTER_INPUT_DEVICE (device)), - trigger_slow_keys, - slow_keys_event); + timeout_source_new (device->seat_impl, + get_slow_keys_delay (CLUTTER_INPUT_DEVICE (device)), + trigger_slow_keys, + slow_keys_event); device->slow_keys_list = g_list_append (device->slow_keys_list, slow_keys_event); if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_PRESS) @@ -346,15 +365,16 @@ start_bounce_keys (ClutterEvent *event, device->debounce_key = ((ClutterKeyEvent *) event)->hardware_keycode; device->debounce_timer = - clutter_threads_add_timeout (get_debounce_delay (CLUTTER_INPUT_DEVICE (device)), - clear_bounce_keys, - device); + timeout_source_new (device->seat_impl, + get_debounce_delay (CLUTTER_INPUT_DEVICE (device)), + clear_bounce_keys, + device); } static void stop_bounce_keys (MetaInputDeviceNative *device) { - g_clear_handle_id (&device->debounce_timer, g_source_remove); + g_clear_pointer (&device->debounce_timer, g_source_destroy); } static void @@ -625,15 +645,16 @@ start_toggle_slowkeys (MetaInputDeviceNative *device) return; device->toggle_slowkeys_timer = - clutter_threads_add_timeout (8 * 1000 /* 8 secs */, - trigger_toggle_slowkeys, - device); + timeout_source_new (device->seat_impl, + 8 * 1000 /* 8 secs */, + trigger_toggle_slowkeys, + device); } static void stop_toggle_slowkeys (MetaInputDeviceNative *device) { - g_clear_handle_id (&device->toggle_slowkeys_timer, g_source_remove); + g_clear_pointer (&device->toggle_slowkeys_timer, g_source_destroy); } static void @@ -892,18 +913,20 @@ trigger_mousekeys_move (gpointer data) { /* This is the first move, Secdule at mk_init_delay */ device->move_mousekeys_timer = - clutter_threads_add_timeout (device->mousekeys_init_delay, - trigger_mousekeys_move, - device); + timeout_source_new (device->seat_impl, + device->mousekeys_init_delay, + trigger_mousekeys_move, + device); } else { /* More moves, reschedule at mk_interval */ device->move_mousekeys_timer = - clutter_threads_add_timeout (100, /* msec between mousekey events */ - trigger_mousekeys_move, - device); + timeout_source_new (device->seat_impl, + 100, /* msec between mousekey events */ + trigger_mousekeys_move, + device); } /* Pointer motion */ @@ -964,7 +987,7 @@ stop_mousekeys_move (MetaInputDeviceNative *device) device->mousekeys_first_motion_time = 0; device->mousekeys_last_motion_time = 0; - g_clear_handle_id (&device->move_mousekeys_timer, g_source_remove); + g_clear_pointer (&device->move_mousekeys_timer, g_source_destroy); } static void diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h index 560081dfd66..603579708b4 100644 --- a/src/backends/native/meta-input-device-native.h +++ b/src/backends/native/meta-input-device-native.h @@ -85,12 +85,12 @@ struct _MetaInputDeviceNative /* Keyboard a11y */ MetaKeyboardA11yFlags a11y_flags; GList *slow_keys_list; - guint debounce_timer; + GSource *debounce_timer; uint16_t debounce_key; xkb_mod_mask_t stickykeys_depressed_mask; xkb_mod_mask_t stickykeys_latched_mask; xkb_mod_mask_t stickykeys_locked_mask; - guint toggle_slowkeys_timer; + GSource *toggle_slowkeys_timer; uint16_t shift_count; uint32_t last_shift_time; int mousekeys_btn; @@ -101,7 +101,7 @@ struct _MetaInputDeviceNative guint mousekeys_accel_time; guint mousekeys_max_speed; double mousekeys_curve_factor; - guint move_mousekeys_timer; + GSource *move_mousekeys_timer; uint16_t last_mousekeys_key; }; diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 309e4bae8ec..27e83304a6d 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -119,7 +119,11 @@ enum static guint signals[N_SIGNALS] = { 0 }; -G_DEFINE_TYPE (MetaSeatImpl, meta_seat_impl, G_TYPE_OBJECT) +static void meta_seat_impl_initable_iface_init (GInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaSeatImpl, meta_seat_impl, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + meta_seat_impl_initable_iface_init)) static void process_events (MetaSeatImpl *seat_impl); void meta_seat_impl_constrain_pointer (MetaSeatImpl *seat_impl, @@ -135,7 +139,7 @@ void meta_seat_impl_filter_relative_motion (MetaSeatImpl *seat_impl, float y, float *dx, float *dy); -void meta_seat_impl_clear_repeat_timer (MetaSeatImpl *seat_impl); +void meta_seat_impl_clear_repeat_source (MetaSeatImpl *seat_impl); void meta_seat_impl_run_input_task (MetaSeatImpl *seat_impl, @@ -238,11 +242,11 @@ meta_seat_impl_release_touch_state (MetaSeatImpl *seat_impl, } void -meta_seat_impl_clear_repeat_timer (MetaSeatImpl *seat_impl) +meta_seat_impl_clear_repeat_source (MetaSeatImpl *seat_impl) { - if (seat_impl->repeat_timer) + if (seat_impl->repeat_source) { - g_clear_handle_id (&seat_impl->repeat_timer, g_source_remove); + g_source_destroy (seat_impl->repeat_source); g_clear_object (&seat_impl->repeat_device); } } @@ -258,20 +262,18 @@ static gboolean keyboard_repeat (gpointer data) { MetaSeatImpl *seat_impl = data; - GSource *source; /* There might be events queued in libinput that could cancel the repeat timer. */ dispatch_libinput (seat_impl); - if (!seat_impl->repeat_timer) + if (!seat_impl->repeat_source) return G_SOURCE_REMOVE; g_return_val_if_fail (seat_impl->repeat_device != NULL, G_SOURCE_REMOVE); - source = g_main_context_find_source_by_id (NULL, seat_impl->repeat_timer); meta_seat_impl_notify_key (seat_impl, seat_impl->repeat_device, - g_source_get_time (source), + g_source_get_time (seat_impl->repeat_source), seat_impl->repeat_key, AUTOREPEAT_VALUE, FALSE); @@ -310,6 +312,65 @@ update_button_count (MetaSeatImpl *seat_impl, } } +typedef struct +{ + MetaSeatImpl *seat_impl; + guint signal_id; + GArray *args; +} MetaSeatSignalData; + +static gboolean +emit_signal_in_main (MetaSeatSignalData *data) +{ + g_signal_emitv ((GValue *) data->args->data, + data->signal_id, + 0, NULL); + + return G_SOURCE_REMOVE; +} + +static void +signal_data_free (MetaSeatSignalData *data) +{ + g_array_unref (data->args); + g_free (data); +} + +static void +emit_signal (MetaSeatImpl *seat_impl, + guint signal_id, + GValue *args, + int n_args) +{ + MetaSeatSignalData *emit_signal_data; + GSource *source; + GArray *array; + GValue self = G_VALUE_INIT; + + g_value_init (&self, META_TYPE_SEAT_IMPL); + g_value_set_object (&self, seat_impl); + + array = g_array_new (FALSE, FALSE, sizeof (GValue)); + g_array_append_val (array, self); + if (args && n_args > 0) + g_array_append_vals (array, args, n_args); + + emit_signal_data = g_new0 (MetaSeatSignalData, 1); + emit_signal_data->seat_impl = seat_impl; + emit_signal_data->signal_id = signal_id; + emit_signal_data->args = array; + + source = g_idle_source_new (); + g_source_set_priority (source, G_PRIORITY_HIGH); + g_source_set_callback (source, + (GSourceFunc) emit_signal_in_main, + emit_signal_data, + (GDestroyNotify) signal_data_free); + + g_source_attach (source, seat_impl->main_context); + g_source_unref (source); +} + void meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, ClutterInputDevice *device, @@ -369,7 +430,7 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, MetaInputDeviceNative *keyboard_native; gboolean numlock_active; - g_signal_emit (seat_impl, signals[MODS_STATE_CHANGED], 0); + emit_signal (seat_impl, signals[MODS_STATE_CHANGED], NULL, 0); meta_seat_impl_sync_leds (seat_impl); numlock_active = @@ -388,7 +449,8 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, !xkb_keymap_key_repeats (xkb_state_get_keymap (seat_impl->xkb), keycode)) { - meta_seat_impl_clear_repeat_timer (seat_impl); + seat_impl->repeat_count = 0; + meta_seat_impl_clear_repeat_source (seat_impl); return; } @@ -405,7 +467,7 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, { uint32_t interval; - meta_seat_impl_clear_repeat_timer (seat_impl); + meta_seat_impl_clear_repeat_source (seat_impl); seat_impl->repeat_device = g_object_ref (device); if (seat_impl->repeat_count == 1) @@ -413,12 +475,11 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, else interval = seat_impl->repeat_interval; - seat_impl->repeat_timer = - clutter_threads_add_timeout_full (CLUTTER_PRIORITY_EVENTS, - interval, - keyboard_repeat, - seat_impl, - NULL); + seat_impl->repeat_source = g_timeout_source_new (interval); + g_source_set_priority (seat_impl->repeat_source, CLUTTER_PRIORITY_EVENTS); + g_source_set_callback (seat_impl->repeat_source, + keyboard_repeat, seat_impl, NULL); + g_source_attach (seat_impl->repeat_source, seat_impl->input_context); return; } default: @@ -887,26 +948,13 @@ meta_seat_impl_notify_touch_event (MetaSeatImpl *seat_impl, /* * MetaEventSource for reading input devices */ -static gboolean -meta_event_prepare (GSource *source, - int *timeout) -{ - gboolean retval; - - *timeout = -1; - retval = clutter_events_pending (); - - return retval; -} - static gboolean meta_event_check (GSource *source) { MetaEventSource *event_source = (MetaEventSource *) source; gboolean retval; - retval = ((event_source->event_poll_fd.revents & G_IO_IN) || - clutter_events_pending ()); + retval = !!(event_source->event_poll_fd.revents & G_IO_IN); return retval; } @@ -1384,19 +1432,13 @@ meta_event_dispatch (GSource *g_source, seat_impl = source->seat_impl; - /* Don't queue more events if we haven't finished handling the previous batch - */ - if (clutter_events_pending ()) - goto queue_event; - dispatch_libinput (seat_impl); - queue_event: - return TRUE; } + static GSourceFuncs event_funcs = { - meta_event_prepare, + NULL, meta_event_check, meta_event_dispatch, NULL @@ -1423,7 +1465,7 @@ meta_event_source_new (MetaSeatImpl *seat_impl) g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS); g_source_add_poll (source, &event_source->event_poll_fd); g_source_set_can_recurse (source, TRUE); - g_source_attach (source, NULL); + g_source_attach (source, seat_impl->input_context); return event_source; } @@ -1506,8 +1548,13 @@ update_touch_mode (MetaSeatImpl *seat_impl) if (seat_impl->touch_mode != touch_mode) { + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_BOOLEAN); + g_value_set_boolean (&value, touch_mode); seat_impl->touch_mode = touch_mode; - g_signal_emit (seat_impl, signals[TOUCH_MODE], 0, touch_mode); + emit_signal (seat_impl, signals[TOUCH_MODE], &value, 1); + g_value_unset (&value); } } @@ -1564,8 +1611,8 @@ evdev_remove_device (MetaSeatImpl *seat_impl, if (is_touchscreen || is_tablet_switch) update_touch_mode (seat_impl); - if (seat_impl->repeat_timer && seat_impl->repeat_device == device) - meta_seat_impl_clear_repeat_timer (seat_impl); + if (seat_impl->repeat_source && seat_impl->repeat_device == device) + meta_seat_impl_clear_repeat_source (seat_impl); g_object_unref (device); } @@ -2535,35 +2582,21 @@ meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, meta_keymap_native_update (seat_impl->keymap); } -static void -meta_seat_impl_constructed (GObject *object) +static gpointer +input_thread (MetaSeatImpl *seat_impl) { - MetaSeatImpl *seat_impl = META_SEAT_IMPL (object); - ClutterInputDevice *device; MetaEventSource *source; struct udev *udev; struct xkb_keymap *xkb_keymap; - device = meta_input_device_native_new_virtual ( - seat_impl, CLUTTER_POINTER_DEVICE, - CLUTTER_INPUT_MODE_LOGICAL); - seat_impl->pointer_x = INITIAL_POINTER_X; - seat_impl->pointer_y = INITIAL_POINTER_Y; - meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (device), - seat_impl->pointer_x, - seat_impl->pointer_y); - seat_impl->core_pointer = device; - - device = meta_input_device_native_new_virtual ( - seat_impl, CLUTTER_KEYBOARD_DEVICE, - CLUTTER_INPUT_MODE_LOGICAL); - seat_impl->core_keyboard = device; + g_main_context_push_thread_default (seat_impl->input_context); udev = udev_new (); if (G_UNLIKELY (udev == NULL)) { g_warning ("Failed to create udev object"); - return; + seat_impl->input_thread_initialized = TRUE; + return NULL; } seat_impl->libinput = libinput_udev_create_context (&libinput_interface, @@ -2571,7 +2604,8 @@ meta_seat_impl_constructed (GObject *object) if (seat_impl->libinput == NULL) { g_critical ("Failed to create the libinput object."); - return; + seat_impl->input_thread_initialized = TRUE; + return NULL; } if (libinput_udev_assign_seat (seat_impl->libinput, seat_impl->seat_id) == -1) @@ -2579,7 +2613,8 @@ meta_seat_impl_constructed (GObject *object) g_critical ("Failed to assign a seat to the libinput object."); libinput_unref (seat_impl->libinput); seat_impl->libinput = NULL; - return; + seat_impl->input_thread_initialized = TRUE; + return NULL; } udev_unref (udev); @@ -2588,12 +2623,11 @@ meta_seat_impl_constructed (GObject *object) g_signal_connect_object (seat_impl->input_settings, "kbd-a11y-changed", G_CALLBACK (kbd_a11y_changed_cb), seat_impl, 0); - seat_impl->udev_client = g_udev_client_new ((const char *[]) { "input", NULL }); - source = meta_event_source_new (seat_impl); seat_impl->event_source = source; seat_impl->keymap = g_object_new (META_TYPE_KEYMAP_NATIVE, NULL); + xkb_keymap = meta_keymap_native_get_keyboard_map (seat_impl->keymap); if (xkb_keymap) @@ -2615,6 +2649,71 @@ meta_seat_impl_constructed (GObject *object) seat_impl->has_tablet_switch = has_tablet_switch (seat_impl); update_touch_mode (seat_impl); + g_mutex_lock (&seat_impl->init_mutex); + seat_impl->input_thread_initialized = TRUE; + g_cond_signal (&seat_impl->init_cond); + g_mutex_unlock (&seat_impl->init_mutex); + + seat_impl->input_loop = g_main_loop_new (seat_impl->input_context, FALSE); + g_main_loop_run (seat_impl->input_loop); + g_main_loop_unref (seat_impl->input_loop); + + g_main_context_pop_thread_default (seat_impl->input_context); + + return NULL; +} + +static gboolean +meta_seat_impl_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MetaSeatImpl *seat_impl = META_SEAT_IMPL (initable); + + seat_impl->input_context = g_main_context_new (); + seat_impl->main_context = g_main_context_ref_thread_default (); + g_assert (seat_impl->main_context == g_main_context_default ()); + + seat_impl->input_thread = + g_thread_try_new ("Mutter Input Thread", + (GThreadFunc) input_thread, + initable, + error); + if (!seat_impl->input_thread) + return FALSE; + + /* Initialize thread synchronously */ + g_mutex_lock (&seat_impl->init_mutex); + while (!seat_impl->input_thread_initialized) + g_cond_wait (&seat_impl->init_cond, &seat_impl->init_mutex); + g_mutex_unlock (&seat_impl->init_mutex); + + return TRUE; +} + +static void +meta_seat_impl_constructed (GObject *object) +{ + MetaSeatImpl *seat_impl = META_SEAT_IMPL (object); + ClutterInputDevice *device; + + device = meta_input_device_native_new_virtual ( + seat_impl, CLUTTER_POINTER_DEVICE, + CLUTTER_INPUT_MODE_LOGICAL); + seat_impl->pointer_x = INITIAL_POINTER_X; + seat_impl->pointer_y = INITIAL_POINTER_Y; + meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (device), + seat_impl->pointer_x, + seat_impl->pointer_y); + seat_impl->core_pointer = device; + + device = meta_input_device_native_new_virtual ( + seat_impl, CLUTTER_KEYBOARD_DEVICE, + CLUTTER_INPUT_MODE_LOGICAL); + seat_impl->core_keyboard = device; + + seat_impl->udev_client = g_udev_client_new ((const char *[]) { "input", NULL }); + if (G_OBJECT_CLASS (meta_seat_impl_parent_class)->constructed) G_OBJECT_CLASS (meta_seat_impl_parent_class)->constructed (object); } @@ -2682,6 +2781,9 @@ meta_seat_impl_finalize (GObject *object) gboolean numlock_active; GSList *iter; + g_main_loop_quit (seat_impl->input_loop); + g_thread_join (seat_impl->input_thread); + for (iter = seat_impl->devices; iter; iter = g_slist_next (iter)) { ClutterInputDevice *device = iter->data; @@ -2707,7 +2809,7 @@ meta_seat_impl_finalize (GObject *object) xkb_state_unref (seat_impl->xkb); - meta_seat_impl_clear_repeat_timer (seat_impl); + meta_seat_impl_clear_repeat_source (seat_impl); g_free (seat_impl->seat_id); @@ -2833,6 +2935,12 @@ meta_seat_impl_query_state (MetaSeatImpl *seat_impl, return retval; } +static void +meta_seat_impl_initable_iface_init (GInitableIface *iface) +{ + iface->init = meta_seat_impl_initable_init; +} + static void meta_seat_impl_class_init (MetaSeatImplClass *klass) { @@ -2907,6 +3015,9 @@ meta_seat_impl_init (MetaSeatImpl *seat_impl) seat_impl->repeat_delay = 250; /* ms */ seat_impl->repeat_interval = 33; /* ms */ + g_mutex_init (&seat_impl->init_mutex); + g_cond_init (&seat_impl->init_cond); + seat_impl->barrier_manager = meta_barrier_manager_native_new (); } @@ -3269,10 +3380,11 @@ MetaSeatImpl * meta_seat_impl_new (MetaSeatNative *seat_native, const char *seat_id) { - return g_object_new (META_TYPE_SEAT_IMPL, - "seat", seat_native, - "seat-id", seat_id, - NULL); + return g_initable_new (META_TYPE_SEAT_IMPL, + NULL, NULL, + "seat", seat_native, + "seat-id", seat_id, + NULL); } void @@ -3281,12 +3393,18 @@ meta_seat_impl_notify_kbd_a11y_flags_changed (MetaSeatImpl *seat_impl, MetaKeyboardA11yFlags what_changed) { MetaInputSettings *input_settings; + GValue values[] = { G_VALUE_INIT, G_VALUE_INIT }; input_settings = seat_impl->input_settings; meta_input_settings_notify_kbd_a11y_change (input_settings, new_flags, what_changed); - g_signal_emit (seat_impl, signals[KBD_A11Y_FLAGS_CHANGED], 0, - new_flags, what_changed); + g_value_init (&values[0], G_TYPE_UINT); + g_value_set_uint (&values[0], new_flags); + g_value_init (&values[1], G_TYPE_UINT); + g_value_set_uint (&values[1], what_changed); + + emit_signal (seat_impl, signals[KBD_A11Y_FLAGS_CHANGED], + values, G_N_ELEMENTS (values)); } void @@ -3294,14 +3412,21 @@ meta_seat_impl_notify_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_impl, xkb_mod_mask_t new_latched_mods, xkb_mod_mask_t new_locked_mods) { - g_signal_emit (seat_impl, signals[KBD_A11Y_MODS_STATE_CHANGED], 0, - new_latched_mods, new_locked_mods); + GValue values[] = { G_VALUE_INIT, G_VALUE_INIT }; + + g_value_init (&values[0], G_TYPE_UINT); + g_value_set_uint (&values[0], new_latched_mods); + g_value_init (&values[1], G_TYPE_UINT); + g_value_set_uint (&values[1], new_locked_mods); + + emit_signal (seat_impl, signals[KBD_A11Y_MODS_STATE_CHANGED], + values, G_N_ELEMENTS (values)); } void meta_seat_impl_notify_bell (MetaSeatImpl *seat_impl) { - g_signal_emit (seat_impl, signals[BELL], 0); + emit_signal (seat_impl, signals[BELL], NULL, 0); } MetaInputSettings * diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index 680cee2fd5d..26f9baa4f26 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -54,7 +54,13 @@ struct _MetaSeatImpl { GObject parent_instance; + GMainContext *main_context; GMainContext *input_context; + GMainLoop *input_loop; + GThread *input_thread; + GMutex init_mutex; + GCond init_cond; + MetaSeatNative *seat_native; char *seat_id; MetaEventSource *event_source; @@ -91,6 +97,7 @@ struct _MetaSeatImpl gboolean has_touchscreen; gboolean has_tablet_switch; gboolean touch_mode; + gboolean input_thread_initialized; /* keyboard repeat */ gboolean repeat; @@ -98,8 +105,8 @@ struct _MetaSeatImpl uint32_t repeat_interval; uint32_t repeat_key; uint32_t repeat_count; - uint32_t repeat_timer; ClutterInputDevice *repeat_device; + GSource *repeat_source; float pointer_x; float pointer_y; -- GitLab From c03be03cd3e02af8b2e7f4aae96a548ca7479eaf Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 20 Nov 2020 01:36:19 +0100 Subject: [PATCH 84/85] backends/native: Add a bunch of "_in_impl" suffixes to functions They're a dime a dozen. If it gets called exclusively from the input thread, it got one. Hopefully these breadcrumbs will be enough so people don't lose their way here. Part-of: --- src/backends/native/meta-barrier-native.c | 10 +- src/backends/native/meta-barrier-native.h | 10 +- .../native/meta-input-device-native.c | 84 ++-- .../native/meta-input-device-native.h | 52 +-- .../native/meta-input-device-tool-native.c | 18 +- .../native/meta-input-device-tool-native.h | 20 +- .../native/meta-input-settings-native.c | 26 +- .../native/meta-input-settings-native.h | 2 +- src/backends/native/meta-keymap-native.c | 10 +- src/backends/native/meta-keymap-native.h | 8 +- src/backends/native/meta-launcher.c | 16 +- src/backends/native/meta-seat-impl.c | 412 +++++++++--------- src/backends/native/meta-seat-impl.h | 150 +++---- .../native/meta-virtual-input-device-native.c | 271 ++++++------ 14 files changed, 548 insertions(+), 541 deletions(-) diff --git a/src/backends/native/meta-barrier-native.c b/src/backends/native/meta-barrier-native.c index d6267ceacd2..bc0620ae9df 100644 --- a/src/backends/native/meta-barrier-native.c +++ b/src/backends/native/meta-barrier-native.c @@ -500,11 +500,11 @@ clamp_to_barrier (MetaBarrierImplNative *self, } void -meta_barrier_manager_native_process (MetaBarrierManagerNative *manager, - ClutterInputDevice *device, - guint32 time, - float *x, - float *y) +meta_barrier_manager_native_process_in_impl (MetaBarrierManagerNative *manager, + ClutterInputDevice *device, + guint32 time, + float *x, + float *y) { graphene_point_t prev_pos; float prev_x; diff --git a/src/backends/native/meta-barrier-native.h b/src/backends/native/meta-barrier-native.h index 2853cfa80da..1bcf56c7c77 100644 --- a/src/backends/native/meta-barrier-native.h +++ b/src/backends/native/meta-barrier-native.h @@ -41,11 +41,11 @@ typedef struct _MetaBarrierManagerNative MetaBarrierManagerNative; MetaBarrierImpl *meta_barrier_impl_native_new (MetaBarrier *barrier); MetaBarrierManagerNative *meta_barrier_manager_native_new (void); -void meta_barrier_manager_native_process (MetaBarrierManagerNative *manager, - ClutterInputDevice *device, - guint32 time, - float *x, - float *y); +void meta_barrier_manager_native_process_in_impl (MetaBarrierManagerNative *manager, + ClutterInputDevice *device, + guint32 time, + float *x, + float *y); G_END_DECLS diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index d64bdbd0166..9aab8e07006 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -198,7 +198,7 @@ meta_input_device_native_get_pad_feature_group (ClutterInputDevice *de static void meta_input_device_native_bell_notify (MetaInputDeviceNative *device) { - meta_seat_impl_notify_bell (device->seat_impl); + meta_seat_impl_notify_bell_in_impl (device->seat_impl); } static void @@ -419,9 +419,9 @@ key_event_is_modifier (ClutterEvent *event) static void notify_stickykeys_mask (MetaInputDeviceNative *device) { - meta_seat_impl_notify_kbd_a11y_mods_state_changed (device->seat_impl, - device->stickykeys_latched_mask, - device->stickykeys_locked_mask); + meta_seat_impl_notify_kbd_a11y_mods_state_changed_in_impl (device->seat_impl, + device->stickykeys_latched_mask, + device->stickykeys_locked_mask); } static void @@ -438,7 +438,7 @@ update_internal_xkb_state (MetaInputDeviceNative *device, g_rw_lock_writer_lock (&seat_impl->state_lock); - xkb_state = meta_seat_impl_get_xkb_state (seat_impl); + xkb_state = meta_seat_impl_get_xkb_state_in_impl (seat_impl); depressed_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED); latched_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LATCHED); locked_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LOCKED); @@ -478,7 +478,7 @@ update_stickykeys_event (ClutterEvent *event, update_internal_xkb_state (device, new_latched_mask, new_locked_mask); - xkb_state = meta_seat_impl_get_xkb_state (seat_impl); + xkb_state = meta_seat_impl_get_xkb_state_in_impl (seat_impl); effective_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE); latched_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LATCHED); locked_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LOCKED); @@ -498,9 +498,9 @@ notify_stickykeys_change (MetaInputDeviceNative *device) device->stickykeys_depressed_mask = 0; update_internal_xkb_state (device, 0, 0); - meta_seat_impl_notify_kbd_a11y_flags_changed (device->seat_impl, - device->a11y_flags, - META_A11Y_STICKY_KEYS_ENABLED); + meta_seat_impl_notify_kbd_a11y_flags_changed_in_impl (device->seat_impl, + device->a11y_flags, + META_A11Y_STICKY_KEYS_ENABLED); } static void @@ -530,9 +530,9 @@ set_slowkeys_off (MetaInputDeviceNative *device) { device->a11y_flags &= ~META_A11Y_SLOW_KEYS_ENABLED; - meta_seat_impl_notify_kbd_a11y_flags_changed (device->seat_impl, - device->a11y_flags, - META_A11Y_SLOW_KEYS_ENABLED); + meta_seat_impl_notify_kbd_a11y_flags_changed_in_impl (device->seat_impl, + device->a11y_flags, + META_A11Y_SLOW_KEYS_ENABLED); } static void @@ -540,9 +540,9 @@ set_slowkeys_on (MetaInputDeviceNative *device) { device->a11y_flags |= META_A11Y_SLOW_KEYS_ENABLED; - meta_seat_impl_notify_kbd_a11y_flags_changed (device->seat_impl, - device->a11y_flags, - META_A11Y_SLOW_KEYS_ENABLED); + meta_seat_impl_notify_kbd_a11y_flags_changed_in_impl (device->seat_impl, + device->a11y_flags, + META_A11Y_SLOW_KEYS_ENABLED); } static void @@ -565,7 +565,7 @@ handle_stickykeys_press (ClutterEvent *event, return; } - xkb_state = meta_seat_impl_get_xkb_state (seat_impl); + xkb_state = meta_seat_impl_get_xkb_state_in_impl (seat_impl); depressed_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED); /* Ignore the lock modifier mask, that one cannot be sticky, yet the * CAPS_LOCK key itself counts as a modifier as it might be remapped @@ -602,7 +602,7 @@ handle_stickykeys_release (ClutterEvent *event, MetaSeatImpl *seat_impl = device->seat_impl; struct xkb_state *xkb_state; - xkb_state = meta_seat_impl_get_xkb_state (seat_impl); + xkb_state = meta_seat_impl_get_xkb_state_in_impl (seat_impl); device->stickykeys_depressed_mask = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED); @@ -846,7 +846,7 @@ is_numlock_active (MetaInputDeviceNative *device) MetaSeatImpl *seat_impl = device->seat_impl; struct xkb_state *xkb_state; - xkb_state = meta_seat_impl_get_xkb_state (seat_impl); + xkb_state = meta_seat_impl_get_xkb_state_in_impl (seat_impl); return xkb_state_mod_name_is_active (xkb_state, "Mod2", @@ -1126,8 +1126,8 @@ handle_mousekeys_release (ClutterEvent *event, } gboolean -meta_input_device_native_process_kbd_a11y_event (ClutterInputDevice *device, - ClutterEvent *event) +meta_input_device_native_process_kbd_a11y_event_in_impl (ClutterInputDevice *device, + ClutterEvent *event) { MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device); @@ -1183,8 +1183,8 @@ meta_input_device_native_process_kbd_a11y_event (ClutterInputDevice *device, } void -meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device, - MetaKbdA11ySettings *settings) +meta_input_device_native_apply_kbd_a11y_settings_in_impl (MetaInputDeviceNative *device, + MetaKbdA11ySettings *settings) { MetaKeyboardA11yFlags changed_flags = (device->a11y_flags ^ settings->controls); @@ -1222,7 +1222,7 @@ meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device, } void -meta_input_device_native_a11y_maybe_notify_toggle_keys (MetaInputDeviceNative *device) +meta_input_device_native_a11y_maybe_notify_toggle_keys_in_impl (MetaInputDeviceNative *device) { if (device->a11y_flags & META_A11Y_TOGGLE_KEYS_ENABLED) meta_input_device_native_bell_notify (device); @@ -1324,8 +1324,8 @@ update_pad_features (MetaInputDeviceNative *device_native) * it with the provided seat. */ ClutterInputDevice * -meta_input_device_native_new (MetaSeatImpl *seat_impl, - struct libinput_device *libinput_device) +meta_input_device_native_new_in_impl (MetaSeatImpl *seat_impl, + struct libinput_device *libinput_device) { MetaInputDeviceNative *device; ClutterInputDeviceType type; @@ -1334,7 +1334,7 @@ meta_input_device_native_new (MetaSeatImpl *seat_impl, char *node_path; double width, height; - type = meta_input_device_native_determine_type (libinput_device); + type = meta_input_device_native_determine_type_in_impl (libinput_device); vendor = g_strdup_printf ("%.4x", libinput_device_get_id_vendor (libinput_device)); product = g_strdup_printf ("%.4x", libinput_device_get_id_product (libinput_device)); node_path = g_strdup_printf ("/dev/input/%s", libinput_device_get_sysname (libinput_device)); @@ -1431,8 +1431,8 @@ meta_input_device_native_get_seat_impl (MetaInputDeviceNative *device) } void -meta_input_device_native_update_leds (MetaInputDeviceNative *device, - enum libinput_led leds) +meta_input_device_native_update_leds_in_impl (MetaInputDeviceNative *device, + enum libinput_led leds) { if (!device->libinput_device) return; @@ -1441,7 +1441,7 @@ meta_input_device_native_update_leds (MetaInputDeviceNative *device, } ClutterInputDeviceType -meta_input_device_native_determine_type (struct libinput_device *ldev) +meta_input_device_native_determine_type_in_impl (struct libinput_device *ldev) { /* This setting is specific to touchpads and alike, only in these * devices there is this additional layer of touch event interpretation. @@ -1486,10 +1486,10 @@ meta_input_device_native_get_libinput_device (ClutterInputDevice *device) } void -meta_input_device_native_translate_coordinates (ClutterInputDevice *device, - MetaViewportInfo *viewports, - float *x, - float *y) +meta_input_device_native_translate_coordinates_in_impl (ClutterInputDevice *device, + MetaViewportInfo *viewports, + float *x, + float *y) { MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device); double min_x = 0, min_y = 0, max_x = 1, max_y = 1; @@ -1521,7 +1521,7 @@ meta_input_device_native_translate_coordinates (ClutterInputDevice *device, } MetaInputDeviceMapping -meta_input_device_native_get_mapping_mode (ClutterInputDevice *device) +meta_input_device_native_get_mapping_mode_in_impl (ClutterInputDevice *device) { MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); ClutterInputDeviceType device_type; @@ -1539,8 +1539,8 @@ meta_input_device_native_get_mapping_mode (ClutterInputDevice *device) } void -meta_input_device_native_set_mapping_mode (ClutterInputDevice *device, - MetaInputDeviceMapping mapping) +meta_input_device_native_set_mapping_mode_in_impl (ClutterInputDevice *device, + MetaInputDeviceMapping mapping) { MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); ClutterInputDeviceType device_type; @@ -1556,18 +1556,18 @@ meta_input_device_native_set_mapping_mode (ClutterInputDevice *device, } void -meta_input_device_native_set_coords (MetaInputDeviceNative *device_native, - float x, - float y) +meta_input_device_native_set_coords_in_impl (MetaInputDeviceNative *device_native, + float x, + float y) { device_native->pointer_x = x; device_native->pointer_y = y; } void -meta_input_device_native_get_coords (MetaInputDeviceNative *device_native, - float *x, - float *y) +meta_input_device_native_get_coords_in_impl (MetaInputDeviceNative *device_native, + float *x, + float *y) { if (x) *x = device_native->pointer_x; diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h index 603579708b4..db28d0516c4 100644 --- a/src/backends/native/meta-input-device-native.h +++ b/src/backends/native/meta-input-device-native.h @@ -112,44 +112,44 @@ struct _MetaInputDeviceNativeClass GType meta_input_device_native_get_type (void) G_GNUC_CONST; -ClutterInputDevice * meta_input_device_native_new (MetaSeatImpl *seat_impl, +ClutterInputDevice * meta_input_device_native_new_in_impl (MetaSeatImpl *seat_impl, struct libinput_device *libinput_device); -ClutterInputDevice * meta_input_device_native_new_virtual (MetaSeatImpl *seat_impl, - ClutterInputDeviceType type, - ClutterInputMode mode); +ClutterInputDevice * meta_input_device_native_new_virtual (MetaSeatImpl *seat_impl, + ClutterInputDeviceType type, + ClutterInputMode mode); -MetaSeatImpl * meta_input_device_native_get_seat_impl (MetaInputDeviceNative *device); +MetaSeatImpl * meta_input_device_native_get_seat_impl (MetaInputDeviceNative *device); -void meta_input_device_native_update_leds (MetaInputDeviceNative *device, - enum libinput_led leds); +void meta_input_device_native_update_leds_in_impl (MetaInputDeviceNative *device, + enum libinput_led leds); -ClutterInputDeviceType meta_input_device_native_determine_type (struct libinput_device *libinput_device); +ClutterInputDeviceType meta_input_device_native_determine_type_in_impl (struct libinput_device *libinput_device); -void meta_input_device_native_translate_coordinates (ClutterInputDevice *device, - MetaViewportInfo *viewports, - float *x, - float *y); +void meta_input_device_native_translate_coordinates_in_impl (ClutterInputDevice *device, + MetaViewportInfo *viewports, + float *x, + float *y); -MetaInputDeviceMapping meta_input_device_native_get_mapping_mode (ClutterInputDevice *device); -void meta_input_device_native_set_mapping_mode (ClutterInputDevice *device, - MetaInputDeviceMapping mapping); +MetaInputDeviceMapping meta_input_device_native_get_mapping_mode_in_impl (ClutterInputDevice *device); +void meta_input_device_native_set_mapping_mode_in_impl (ClutterInputDevice *device, + MetaInputDeviceMapping mapping); -void meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device, - MetaKbdA11ySettings *settings); +void meta_input_device_native_apply_kbd_a11y_settings_in_impl (MetaInputDeviceNative *device, + MetaKbdA11ySettings *settings); -void meta_input_device_native_a11y_maybe_notify_toggle_keys (MetaInputDeviceNative *device_evdev); +void meta_input_device_native_a11y_maybe_notify_toggle_keys_in_impl (MetaInputDeviceNative *device_evdev); struct libinput_device * meta_input_device_native_get_libinput_device (ClutterInputDevice *device); -void meta_input_device_native_set_coords (MetaInputDeviceNative *device_native, - float x, - float y); -void meta_input_device_native_get_coords (MetaInputDeviceNative *device_native, - float *x, - float *y); -gboolean meta_input_device_native_process_kbd_a11y_event (ClutterInputDevice *device, - ClutterEvent *event); +void meta_input_device_native_set_coords_in_impl (MetaInputDeviceNative *device_native, + float x, + float y); +void meta_input_device_native_get_coords_in_impl (MetaInputDeviceNative *device_native, + float *x, + float *y); +gboolean meta_input_device_native_process_kbd_a11y_event_in_impl (ClutterInputDevice *device, + ClutterEvent *event); #endif /* META_INPUT_DEVICE_NATIVE_H */ diff --git a/src/backends/native/meta-input-device-tool-native.c b/src/backends/native/meta-input-device-tool-native.c index dc47b81a73c..ad6a3bdb6ab 100644 --- a/src/backends/native/meta-input-device-tool-native.c +++ b/src/backends/native/meta-input-device-tool-native.c @@ -90,8 +90,8 @@ meta_input_device_tool_native_new (struct libinput_tablet_tool *tool, } void -meta_input_device_tool_native_set_pressure_curve (ClutterInputDeviceTool *tool, - double curve[4]) +meta_input_device_tool_native_set_pressure_curve_in_impl (ClutterInputDeviceTool *tool, + double curve[4]) { MetaInputDeviceToolNative *evdev_tool; @@ -109,9 +109,9 @@ meta_input_device_tool_native_set_pressure_curve (ClutterInputDeviceTool *tool, } void -meta_input_device_tool_native_set_button_code (ClutterInputDeviceTool *tool, - uint32_t button, - uint32_t evcode) +meta_input_device_tool_native_set_button_code_in_impl (ClutterInputDeviceTool *tool, + uint32_t button, + uint32_t evcode) { MetaInputDeviceToolNative *evdev_tool; @@ -152,8 +152,8 @@ calculate_bezier_position (double pos, } double -meta_input_device_tool_native_translate_pressure (ClutterInputDeviceTool *tool, - double pressure) +meta_input_device_tool_native_translate_pressure_in_impl (ClutterInputDeviceTool *tool, + double pressure) { MetaInputDeviceToolNative *evdev_tool; @@ -169,8 +169,8 @@ meta_input_device_tool_native_translate_pressure (ClutterInputDeviceTool *tool, } uint32_t -meta_input_device_tool_native_get_button_code (ClutterInputDeviceTool *tool, - uint32_t button) +meta_input_device_tool_native_get_button_code_in_impl (ClutterInputDeviceTool *tool, + uint32_t button) { MetaInputDeviceToolNative *evdev_tool; diff --git a/src/backends/native/meta-input-device-tool-native.h b/src/backends/native/meta-input-device-tool-native.h index 83e79930a8c..3eff6261c76 100644 --- a/src/backends/native/meta-input-device-tool-native.h +++ b/src/backends/native/meta-input-device-tool-native.h @@ -70,16 +70,16 @@ ClutterInputDeviceTool * meta_input_device_tool_native_new (struct libinput uint64_t serial, ClutterInputDeviceToolType type); -gdouble meta_input_device_tool_native_translate_pressure (ClutterInputDeviceTool *tool, - double pressure); -uint32_t meta_input_device_tool_native_get_button_code (ClutterInputDeviceTool *tool, - uint32_t button); - -void meta_input_device_tool_native_set_pressure_curve (ClutterInputDeviceTool *tool, - double curve[4]); -void meta_input_device_tool_native_set_button_code (ClutterInputDeviceTool *tool, - uint32_t button, - uint32_t evcode); +gdouble meta_input_device_tool_native_translate_pressure_in_impl (ClutterInputDeviceTool *tool, + double pressure); +uint32_t meta_input_device_tool_native_get_button_code_in_impl (ClutterInputDeviceTool *tool, + uint32_t button); + +void meta_input_device_tool_native_set_pressure_curve_in_impl (ClutterInputDeviceTool *tool, + double curve[4]); +void meta_input_device_tool_native_set_button_code_in_impl (ClutterInputDeviceTool *tool, + uint32_t button, + uint32_t evcode); G_END_DECLS diff --git a/src/backends/native/meta-input-settings-native.c b/src/backends/native/meta-input-settings-native.c index 754c01a0f10..becf557db5c 100644 --- a/src/backends/native/meta-input-settings-native.c +++ b/src/backends/native/meta-input-settings-native.c @@ -157,7 +157,7 @@ meta_input_settings_native_set_matrix (MetaInputSettings *settings, if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE || - meta_input_device_native_get_mapping_mode (device) == + meta_input_device_native_get_mapping_mode_in_impl (device) == META_INPUT_DEVICE_MAPPING_ABSOLUTE) { cairo_matrix_init (dev_matrix, matrix[0], matrix[3], matrix[1], @@ -504,8 +504,8 @@ meta_input_settings_native_set_keyboard_repeat (MetaInputSettings *settings, MetaInputSettingsNative *input_settings_native; input_settings_native = META_INPUT_SETTINGS_NATIVE (settings); - meta_seat_impl_set_keyboard_repeat (input_settings_native->seat_impl, - enabled, delay, interval); + meta_seat_impl_set_keyboard_repeat_in_impl (input_settings_native->seat_impl, + enabled, delay, interval); } static void @@ -636,7 +636,7 @@ meta_input_settings_native_set_tablet_mapping (MetaInputSettings *settings, else return; - meta_input_device_native_set_mapping_mode (device, dev_mapping); + meta_input_device_native_set_mapping_mode_in_impl (device, dev_mapping); } static gboolean @@ -660,7 +660,7 @@ meta_input_settings_native_set_tablet_aspect_ratio (MetaInputSettings *settings MetaInputSettingsNative *input_settings_native; GTask *task; - if (meta_input_device_native_get_mapping_mode (device) == + if (meta_input_device_native_get_mapping_mode_in_impl (device) == META_INPUT_DEVICE_MAPPING_RELATIVE) aspect_ratio = 0; @@ -718,7 +718,7 @@ meta_input_settings_native_set_stylus_pressure (MetaInputSettings *settings pressure_curve[2] = (gdouble) curve[2] / 100; pressure_curve[3] = (gdouble) curve[3] / 100; - meta_input_device_tool_native_set_pressure_curve (tool, pressure_curve); + meta_input_device_tool_native_set_pressure_curve_in_impl (tool, pressure_curve); } static guint @@ -748,12 +748,12 @@ meta_input_settings_native_set_stylus_button_map (MetaInputSettings *se GDesktopStylusButtonAction secondary, GDesktopStylusButtonAction tertiary) { - meta_input_device_tool_native_set_button_code (tool, CLUTTER_BUTTON_MIDDLE, - action_to_evcode (primary)); - meta_input_device_tool_native_set_button_code (tool, CLUTTER_BUTTON_SECONDARY, - action_to_evcode (secondary)); - meta_input_device_tool_native_set_button_code (tool, 8, /* Back */ - action_to_evcode (tertiary)); + meta_input_device_tool_native_set_button_code_in_impl (tool, CLUTTER_BUTTON_MIDDLE, + action_to_evcode (primary)); + meta_input_device_tool_native_set_button_code_in_impl (tool, CLUTTER_BUTTON_SECONDARY, + action_to_evcode (secondary)); + meta_input_device_tool_native_set_button_code_in_impl (tool, 8, /* Back */ + action_to_evcode (tertiary)); } static void @@ -870,7 +870,7 @@ meta_input_settings_native_init (MetaInputSettingsNative *settings) } MetaInputSettings * -meta_input_settings_native_new (MetaSeatImpl *seat_impl) +meta_input_settings_native_new_in_impl (MetaSeatImpl *seat_impl) { return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, "seat-impl", seat_impl, diff --git a/src/backends/native/meta-input-settings-native.h b/src/backends/native/meta-input-settings-native.h index dece62aaa00..43926fd5fda 100644 --- a/src/backends/native/meta-input-settings-native.h +++ b/src/backends/native/meta-input-settings-native.h @@ -47,6 +47,6 @@ struct _MetaInputSettingsNativeClass GType meta_input_settings_native_get_type (void) G_GNUC_CONST; -MetaInputSettings * meta_input_settings_native_new (MetaSeatImpl *seat_impl); +MetaInputSettings * meta_input_settings_native_new_in_impl (MetaSeatImpl *seat_impl); #endif /* META_INPUT_SETTINGS_NATIVE_H */ diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c index ee56443b584..036eb6b4d9a 100644 --- a/src/backends/native/meta-keymap-native.c +++ b/src/backends/native/meta-keymap-native.c @@ -107,8 +107,8 @@ meta_keymap_native_init (MetaKeymapNative *keymap) } void -meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap, - struct xkb_keymap *xkb_keymap) +meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap, + struct xkb_keymap *xkb_keymap) { g_return_if_fail (xkb_keymap != NULL); @@ -118,19 +118,19 @@ meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap, } struct xkb_keymap * -meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap) +meta_keymap_native_get_keyboard_map_in_impl (MetaKeymapNative *keymap) { return keymap->keymap; } void -meta_keymap_native_update (MetaKeymapNative *keymap) +meta_keymap_native_update_in_impl (MetaKeymapNative *keymap) { struct xkb_state *xkb_state; ClutterSeat *seat; seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); - xkb_state = meta_seat_impl_get_xkb_state (META_SEAT_NATIVE (seat)->impl); + xkb_state = meta_seat_impl_get_xkb_state_in_impl (META_SEAT_NATIVE (seat)->impl); keymap->num_lock = xkb_state_mod_name_is_active (xkb_state, diff --git a/src/backends/native/meta-keymap-native.h b/src/backends/native/meta-keymap-native.h index 8b276df5d6f..49da0775d01 100644 --- a/src/backends/native/meta-keymap-native.h +++ b/src/backends/native/meta-keymap-native.h @@ -29,9 +29,9 @@ G_DECLARE_FINAL_TYPE (MetaKeymapNative, meta_keymap_native, META, KEYMAP_NATIVE, ClutterKeymap) -void meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap, - struct xkb_keymap *xkb_keymap); -struct xkb_keymap * meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap); -void meta_keymap_native_update (MetaKeymapNative *keymap); +void meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap, + struct xkb_keymap *xkb_keymap); +struct xkb_keymap * meta_keymap_native_get_keyboard_map_in_impl (MetaKeymapNative *keymap); +void meta_keymap_native_update_in_impl (MetaKeymapNative *keymap); #endif /* META_KEYMAP_NATIVE_H */ diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c index 3f20fbc74c5..c794563ef3b 100644 --- a/src/backends/native/meta-launcher.c +++ b/src/backends/native/meta-launcher.c @@ -385,10 +385,10 @@ out: } static int -on_evdev_device_open (const char *path, - int flags, - gpointer user_data, - GError **error) +on_evdev_device_open_in_input_impl (const char *path, + int flags, + gpointer user_data, + GError **error) { MetaLauncher *self = user_data; @@ -420,8 +420,8 @@ on_evdev_device_open (const char *path, } static void -on_evdev_device_close (int fd, - gpointer user_data) +on_evdev_device_close_in_input_impl (int fd, + gpointer user_data) { MetaLauncher *self = user_data; @@ -530,8 +530,8 @@ meta_launcher_new (GError **error) meta_clutter_backend_native_set_seat_id (self->seat_id); - meta_seat_impl_set_device_callbacks (on_evdev_device_open, - on_evdev_device_close, + meta_seat_impl_set_device_callbacks (on_evdev_device_open_in_input_impl, + on_evdev_device_close_in_input_impl, self); g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self); diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 27e83304a6d..2075ddd34f9 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -159,7 +159,7 @@ meta_seat_impl_run_input_task (MetaSeatImpl *seat_impl, } void -meta_seat_impl_sync_leds (MetaSeatImpl *seat_impl) +meta_seat_impl_sync_leds_in_impl (MetaSeatImpl *seat_impl) { GSList *iter; MetaInputDeviceNative *device_native; @@ -183,13 +183,13 @@ meta_seat_impl_sync_leds (MetaSeatImpl *seat_impl) for (iter = seat_impl->devices; iter; iter = iter->next) { device_native = iter->data; - meta_input_device_native_update_leds (device_native, leds); + meta_input_device_native_update_leds_in_impl (device_native, leds); } } MetaTouchState * -meta_seat_impl_lookup_touch_state (MetaSeatImpl *seat_impl, - int seat_slot) +meta_seat_impl_lookup_touch_state_in_impl (MetaSeatImpl *seat_impl, + int seat_slot) { if (!seat_impl->touch_states) return NULL; @@ -205,8 +205,8 @@ meta_touch_state_free (MetaTouchState *state) } MetaTouchState * -meta_seat_impl_acquire_touch_state (MetaSeatImpl *seat_impl, - int seat_slot) +meta_seat_impl_acquire_touch_state_in_impl (MetaSeatImpl *seat_impl, + int seat_slot) { MetaTouchState *touch_state; @@ -233,8 +233,8 @@ meta_seat_impl_acquire_touch_state (MetaSeatImpl *seat_impl, } void -meta_seat_impl_release_touch_state (MetaSeatImpl *seat_impl, - int seat_slot) +meta_seat_impl_release_touch_state_in_impl (MetaSeatImpl *seat_impl, + int seat_slot) { if (!seat_impl->touch_states) return; @@ -271,12 +271,12 @@ keyboard_repeat (gpointer data) g_return_val_if_fail (seat_impl->repeat_device != NULL, G_SOURCE_REMOVE); - meta_seat_impl_notify_key (seat_impl, - seat_impl->repeat_device, - g_source_get_time (seat_impl->repeat_source), - seat_impl->repeat_key, - AUTOREPEAT_VALUE, - FALSE); + meta_seat_impl_notify_key_in_impl (seat_impl, + seat_impl->repeat_device, + g_source_get_time (seat_impl->repeat_source), + seat_impl->repeat_key, + AUTOREPEAT_VALUE, + FALSE); return G_SOURCE_CONTINUE; } @@ -372,12 +372,12 @@ emit_signal (MetaSeatImpl *seat_impl, } void -meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, - ClutterInputDevice *device, - uint64_t time_us, - uint32_t key, - uint32_t state, - gboolean update_keys) +meta_seat_impl_notify_key_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *device, + uint64_t time_us, + uint32_t key, + uint32_t state, + gboolean update_keys) { ClutterEvent *event = NULL; enum xkb_state_component changed_state; @@ -419,8 +419,8 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_REPEATED); } - if (!meta_input_device_native_process_kbd_a11y_event (seat_impl->core_keyboard, - event)) + if (!meta_input_device_native_process_kbd_a11y_event_in_impl (seat_impl->core_keyboard, + event)) queue_event (seat_impl, event); else clutter_event_free (event); @@ -431,7 +431,7 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, gboolean numlock_active; emit_signal (seat_impl, signals[MODS_STATE_CHANGED], NULL, 0); - meta_seat_impl_sync_leds (seat_impl); + meta_seat_impl_sync_leds_in_impl (seat_impl); numlock_active = xkb_state_mod_name_is_active (seat_impl->xkb, XKB_MOD_NAME_NUM, @@ -441,7 +441,7 @@ meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, numlock_active); keyboard_native = META_INPUT_DEVICE_NATIVE (seat_impl->core_keyboard); - meta_input_device_native_a11y_maybe_notify_toggle_keys (keyboard_native); + meta_input_device_native_a11y_maybe_notify_toggle_keys_in_impl (keyboard_native); } if (state == 0 || /* key release */ @@ -518,10 +518,10 @@ new_absolute_motion_event (MetaSeatImpl *seat_impl, /* This may happen early at startup */ if (seat_impl->viewports) { - meta_input_device_native_translate_coordinates (input_device, - seat_impl->viewports, - &event->motion.x, - &event->motion.y); + meta_input_device_native_translate_coordinates_in_impl (input_device, + seat_impl->viewports, + &event->motion.x, + &event->motion.y); } event->motion.axes = axes; @@ -537,14 +537,14 @@ new_absolute_motion_event (MetaSeatImpl *seat_impl, clutter_event_set_device_tool (event, device_native->last_tool); clutter_event_set_device (event, input_device); - meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (input_device), - x, y); + meta_input_device_native_set_coords_in_impl (META_INPUT_DEVICE_NATIVE (input_device), + x, y); } else { clutter_event_set_device (event, seat_impl->core_pointer); - meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), - x, y); + meta_input_device_native_set_coords_in_impl (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), + x, y); } if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE) @@ -559,13 +559,13 @@ new_absolute_motion_event (MetaSeatImpl *seat_impl, } void -meta_seat_impl_notify_relative_motion (MetaSeatImpl *seat_impl, - ClutterInputDevice *input_device, - uint64_t time_us, - float dx, - float dy, - float dx_unaccel, - float dy_unaccel) +meta_seat_impl_notify_relative_motion_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + float dx, + float dy, + float dx_unaccel, + float dy_unaccel) { float new_x, new_y; ClutterEvent *event; @@ -590,12 +590,12 @@ meta_seat_impl_notify_relative_motion (MetaSeatImpl *seat_impl, } void -meta_seat_impl_notify_absolute_motion (MetaSeatImpl *seat_impl, - ClutterInputDevice *input_device, - uint64_t time_us, - float x, - float y, - double *axes) +meta_seat_impl_notify_absolute_motion_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + float x, + float y, + double *axes) { ClutterEvent *event; @@ -605,11 +605,11 @@ meta_seat_impl_notify_absolute_motion (MetaSeatImpl *seat_impl, } void -meta_seat_impl_notify_button (MetaSeatImpl *seat_impl, - ClutterInputDevice *input_device, - uint64_t time_us, - uint32_t button, - uint32_t state) +meta_seat_impl_notify_button_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + uint32_t button, + uint32_t state) { MetaInputDeviceNative *device_native = (MetaInputDeviceNative *) input_device; ClutterEvent *event = NULL; @@ -692,15 +692,15 @@ meta_seat_impl_notify_button (MetaSeatImpl *seat_impl, if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) { - meta_input_device_native_get_coords (device_native, - &event->button.x, - &event->button.y); + meta_input_device_native_get_coords_in_impl (device_native, + &event->button.x, + &event->button.y); } else { - meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), - &event->button.x, - &event->button.y); + meta_input_device_native_get_coords_in_impl (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), + &event->button.x, + &event->button.y); } clutter_event_set_device (event, seat_impl->core_pointer); @@ -711,8 +711,8 @@ meta_seat_impl_notify_button (MetaSeatImpl *seat_impl, /* Apply the button event code as per the tool mapping */ uint32_t mapped_button; - mapped_button = meta_input_device_tool_native_get_button_code (device_native->last_tool, - button_nr); + mapped_button = meta_input_device_tool_native_get_button_code_in_impl (device_native->last_tool, + button_nr); if (mapped_button != 0) button = mapped_button; } @@ -850,13 +850,13 @@ check_notify_discrete_scroll (MetaSeatImpl *seat_impl, } void -meta_seat_impl_notify_scroll_continuous (MetaSeatImpl *seat_impl, - ClutterInputDevice *input_device, - uint64_t time_us, - double dx, - double dy, - ClutterScrollSource scroll_source, - ClutterScrollFinishFlags finish_flags) +meta_seat_impl_notify_scroll_continuous_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + double dx, + double dy, + ClutterScrollSource scroll_source, + ClutterScrollFinishFlags finish_flags) { if (finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL) seat_impl->accum_scroll_dx = 0; @@ -891,12 +891,12 @@ discrete_to_direction (double discrete_dx, } void -meta_seat_impl_notify_discrete_scroll (MetaSeatImpl *seat_impl, - ClutterInputDevice *input_device, - uint64_t time_us, - double discrete_dx, - double discrete_dy, - ClutterScrollSource scroll_source) +meta_seat_impl_notify_discrete_scroll_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + double discrete_dx, + double discrete_dy, + ClutterScrollSource scroll_source) { notify_scroll (input_device, time_us, discrete_dx * DISCRETE_SCROLL_STEP, @@ -910,13 +910,13 @@ meta_seat_impl_notify_discrete_scroll (MetaSeatImpl *seat_impl, } void -meta_seat_impl_notify_touch_event (MetaSeatImpl *seat_impl, - ClutterInputDevice *input_device, - ClutterEventType evtype, - uint64_t time_us, - int slot, - double x, - double y) +meta_seat_impl_notify_touch_event_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + ClutterEventType evtype, + uint64_t time_us, + int slot, + double x, + double y) { ClutterEvent *event = NULL; @@ -926,10 +926,10 @@ meta_seat_impl_notify_touch_event (MetaSeatImpl *seat_impl, event->touch.time = us2ms (time_us); event->touch.x = x; event->touch.y = y; - meta_input_device_native_translate_coordinates (input_device, - seat_impl->viewports, - &event->touch.x, - &event->touch.y); + meta_input_device_native_translate_coordinates_in_impl (input_device, + seat_impl->viewports, + &event->touch.x, + &event->touch.y); /* "NULL" sequences are special cased in clutter */ event->touch.sequence = GINT_TO_POINTER (MAX (1, slot + 1)); @@ -966,10 +966,10 @@ constrain_to_barriers (MetaSeatImpl *seat_impl, float *new_x, float *new_y) { - meta_barrier_manager_native_process (seat_impl->barrier_manager, - device, - time, - new_x, new_y); + meta_barrier_manager_native_process_in_impl (seat_impl->barrier_manager, + device, + time, + new_x, new_y); } /* @@ -990,8 +990,8 @@ constrain_all_screen_monitors (ClutterInputDevice *device, float cx, cy; int i, n_views; - meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (device), - &cx, &cy); + meta_input_device_native_get_coords_in_impl (META_INPUT_DEVICE_NATIVE (device), + &cx, &cy); /* if we're trying to escape, clamp to the CRTC we're coming from */ @@ -1180,11 +1180,11 @@ meta_seat_impl_filter_relative_motion (MetaSeatImpl *seat_impl, } static void -notify_absolute_motion (ClutterInputDevice *input_device, - uint64_t time_us, - float x, - float y, - double *axes) +notify_absolute_motion_in_impl (ClutterInputDevice *input_device, + uint64_t time_us, + float x, + float y, + double *axes) { MetaSeatImpl *seat_impl; ClutterEvent *event; @@ -1196,11 +1196,11 @@ notify_absolute_motion (ClutterInputDevice *input_device, } static void -notify_relative_tool_motion (ClutterInputDevice *input_device, - uint64_t time_us, - float dx, - float dy, - double *axes) +notify_relative_tool_motion_in_impl (ClutterInputDevice *input_device, + uint64_t time_us, + float dx, + float dy, + double *axes) { MetaInputDeviceNative *device_native; ClutterEvent *event; @@ -1243,9 +1243,9 @@ notify_pinch_gesture_event (ClutterInputDevice *input_device, event = clutter_event_new (CLUTTER_TOUCHPAD_PINCH); - meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), - &event->touchpad_pinch.x, - &event->touchpad_pinch.y); + meta_input_device_native_get_coords_in_impl (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), + &event->touchpad_pinch.x, + &event->touchpad_pinch.y); meta_event_native_set_time_usec (event, time_us); event->touchpad_pinch.phase = phase; @@ -1283,9 +1283,9 @@ notify_swipe_gesture_event (ClutterInputDevice *input_device, event->touchpad_swipe.phase = phase; event->touchpad_swipe.time = us2ms (time_us); - meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), - &event->touchpad_swipe.x, - &event->touchpad_swipe.y); + meta_input_device_native_get_coords_in_impl (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), + &event->touchpad_swipe.x, + &event->touchpad_swipe.y); event->touchpad_swipe.dx = dx; event->touchpad_swipe.dy = dy; event->touchpad_swipe.n_fingers = n_fingers; @@ -1566,13 +1566,13 @@ evdev_add_device (MetaSeatImpl *seat_impl, ClutterInputDevice *device; gboolean is_touchscreen, is_tablet_switch; - device = meta_input_device_native_new (seat_impl, libinput_device); + device = meta_input_device_native_new_in_impl (seat_impl, libinput_device); seat_impl->devices = g_slist_prepend (seat_impl->devices, device); /* Clutter assumes that device types are exclusive in the * ClutterInputDevice API */ - type = meta_input_device_native_determine_type (libinput_device); + type = meta_input_device_native_determine_type_in_impl (libinput_device); is_touchscreen = type == CLUTTER_TOUCHSCREEN_DEVICE; is_tablet_switch = @@ -1772,7 +1772,7 @@ translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event, if (libinput_tablet_tool_has_pressure (libinput_tool)) { value = libinput_event_tablet_tool_get_pressure (tablet_event); - value = meta_input_device_tool_native_translate_pressure (tool, value); + value = meta_input_device_tool_native_translate_pressure_in_impl (tool, value); axes[CLUTTER_INPUT_AXIS_PRESSURE] = value; } @@ -1834,9 +1834,9 @@ notify_continuous_axis (MetaSeatImpl *seat_impl, finish_flags |= CLUTTER_SCROLL_FINISHED_VERTICAL; } - meta_seat_impl_notify_scroll_continuous (seat_impl, device, time_us, - dx, dy, - scroll_source, finish_flags); + meta_seat_impl_notify_scroll_continuous_in_impl (seat_impl, device, time_us, + dx, dy, + scroll_source, finish_flags); } static void @@ -1861,10 +1861,10 @@ notify_discrete_axis (MetaSeatImpl *seat_impl, axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); } - meta_seat_impl_notify_discrete_scroll (seat_impl, device, - time_us, - discrete_dx, discrete_dy, - scroll_source); + meta_seat_impl_notify_discrete_scroll_in_impl (seat_impl, device, + time_us, + discrete_dx, discrete_dy, + scroll_source); } static void @@ -1891,19 +1891,19 @@ process_tablet_axis (MetaSeatImpl *seat_impl, time = libinput_event_tablet_tool_get_time_usec (tablet_event); - if (meta_input_device_native_get_mapping_mode (device) == META_INPUT_DEVICE_MAPPING_RELATIVE || + if (meta_input_device_native_get_mapping_mode_in_impl (device) == META_INPUT_DEVICE_MAPPING_RELATIVE || clutter_input_device_tool_get_tool_type (evdev_device->last_tool) == CLUTTER_INPUT_DEVICE_TOOL_MOUSE || clutter_input_device_tool_get_tool_type (evdev_device->last_tool) == CLUTTER_INPUT_DEVICE_TOOL_LENS) { dx = libinput_event_tablet_tool_get_dx (tablet_event); dy = libinput_event_tablet_tool_get_dy (tablet_event); - notify_relative_tool_motion (device, time, dx, dy, axes); + notify_relative_tool_motion_in_impl (device, time, dx, dy, axes); } else { x = libinput_event_tablet_tool_get_x_transformed (tablet_event, stage_width); y = libinput_event_tablet_tool_get_y_transformed (tablet_event, stage_height); - notify_absolute_motion (device, time, x, y, axes); + notify_absolute_motion_in_impl (device, time, x, y, axes); } } @@ -1947,9 +1947,9 @@ process_device_event (MetaSeatImpl *seat_impl, break; } - meta_seat_impl_notify_key (seat_impl, - device, - time_us, key, key_state, TRUE); + meta_seat_impl_notify_key_in_impl (seat_impl, + device, + time_us, key, key_state, TRUE); break; } @@ -1971,11 +1971,11 @@ process_device_event (MetaSeatImpl *seat_impl, dx_unaccel = libinput_event_pointer_get_dx_unaccelerated (pointer_event); dy_unaccel = libinput_event_pointer_get_dy_unaccelerated (pointer_event); - meta_seat_impl_notify_relative_motion (seat_impl, - device, - time_us, - dx, dy, - dx_unaccel, dy_unaccel); + meta_seat_impl_notify_relative_motion_in_impl (seat_impl, + device, + time_us, + dx, dy, + dx_unaccel, dy_unaccel); break; } @@ -1998,11 +1998,11 @@ process_device_event (MetaSeatImpl *seat_impl, y = libinput_event_pointer_get_absolute_y_transformed (motion_event, stage_height); - meta_seat_impl_notify_absolute_motion (seat_impl, - device, - time_us, - x, y, - NULL); + meta_seat_impl_notify_absolute_motion_in_impl (seat_impl, + device, + time_us, + x, y, + NULL); break; } @@ -2036,8 +2036,8 @@ process_device_event (MetaSeatImpl *seat_impl, break; } - meta_seat_impl_notify_button (seat_impl, device, - time_us, button, button_state); + meta_seat_impl_notify_button_in_impl (seat_impl, device, + time_us, button, button_state); break; } @@ -2101,18 +2101,18 @@ process_device_event (MetaSeatImpl *seat_impl, g_rw_lock_writer_lock (&seat_impl->state_lock); - touch_state = meta_seat_impl_acquire_touch_state (seat_impl, seat_slot); + touch_state = meta_seat_impl_acquire_touch_state_in_impl (seat_impl, seat_slot); touch_state->coords.x = x; touch_state->coords.y = y; g_rw_lock_writer_unlock (&seat_impl->state_lock); - meta_seat_impl_notify_touch_event (seat_impl, device, - CLUTTER_TOUCH_BEGIN, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); + meta_seat_impl_notify_touch_event_in_impl (seat_impl, device, + CLUTTER_TOUCH_BEGIN, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); break; } @@ -2129,18 +2129,18 @@ process_device_event (MetaSeatImpl *seat_impl, seat_slot = libinput_event_touch_get_seat_slot (touch_event); time_us = libinput_event_touch_get_time_usec (touch_event); - touch_state = meta_seat_impl_lookup_touch_state (seat_impl, seat_slot); + touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat_impl, seat_slot); if (!touch_state) break; - meta_seat_impl_notify_touch_event (seat_impl, device, - CLUTTER_TOUCH_END, time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); + meta_seat_impl_notify_touch_event_in_impl (seat_impl, device, + CLUTTER_TOUCH_END, time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); g_rw_lock_writer_lock (&seat_impl->state_lock); - meta_seat_impl_release_touch_state (seat_impl, seat_slot); + meta_seat_impl_release_touch_state_in_impl (seat_impl, seat_slot); g_rw_lock_writer_unlock (&seat_impl->state_lock); break; } @@ -2169,7 +2169,7 @@ process_device_event (MetaSeatImpl *seat_impl, stage_height); g_rw_lock_writer_lock (&seat_impl->state_lock); - touch_state = meta_seat_impl_lookup_touch_state (seat_impl, seat_slot); + touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat_impl, seat_slot); if (touch_state) { touch_state->coords.x = x; @@ -2180,12 +2180,12 @@ process_device_event (MetaSeatImpl *seat_impl, if (!touch_state) break; - meta_seat_impl_notify_touch_event (seat_impl, device, - CLUTTER_TOUCH_UPDATE, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); + meta_seat_impl_notify_touch_event_in_impl (seat_impl, device, + CLUTTER_TOUCH_UPDATE, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); break; } case LIBINPUT_EVENT_TOUCH_CANCEL: @@ -2201,19 +2201,19 @@ process_device_event (MetaSeatImpl *seat_impl, time_us = libinput_event_touch_get_time_usec (touch_event); seat_slot = libinput_event_touch_get_seat_slot (touch_event); - touch_state = meta_seat_impl_lookup_touch_state (seat_impl, seat_slot); + touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat_impl, seat_slot); if (!touch_state) break; - meta_seat_impl_notify_touch_event (touch_state->seat_impl, - CLUTTER_INPUT_DEVICE (device_native), - CLUTTER_TOUCH_CANCEL, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); + meta_seat_impl_notify_touch_event_in_impl (touch_state->seat_impl, + CLUTTER_INPUT_DEVICE (device_native), + CLUTTER_TOUCH_CANCEL, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); - meta_seat_impl_release_touch_state (seat_impl, seat_slot); + meta_seat_impl_release_touch_state_in_impl (seat_impl, seat_slot); break; } case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: @@ -2345,8 +2345,8 @@ process_device_event (MetaSeatImpl *seat_impl, button_state = libinput_event_tablet_tool_get_button_state (tablet_event) == LIBINPUT_BUTTON_STATE_PRESSED; - meta_seat_impl_notify_button (seat_impl, device, - time_us, tablet_button, button_state); + meta_seat_impl_notify_button_in_impl (seat_impl, device, + time_us, tablet_button, button_state); break; } case LIBINPUT_EVENT_TABLET_TOOL_TIP: @@ -2367,8 +2367,8 @@ process_device_event (MetaSeatImpl *seat_impl, if (button_state) process_tablet_axis (seat_impl, event); - meta_seat_impl_notify_button (seat_impl, device, - time_us, BTN_TOUCH, button_state); + meta_seat_impl_notify_button_in_impl (seat_impl, device, + time_us, BTN_TOUCH, button_state); if (!button_state) process_tablet_axis (seat_impl, event); break; @@ -2537,12 +2537,12 @@ kbd_a11y_changed_cb (MetaInputSettings *input_settings, MetaInputDeviceNative *keyboard; keyboard = META_INPUT_DEVICE_NATIVE (seat_impl->core_keyboard); - meta_input_device_native_apply_kbd_a11y_settings (keyboard, a11y_settings); + meta_input_device_native_apply_kbd_a11y_settings_in_impl (keyboard, a11y_settings); } static void -meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, - gboolean numlock_state) +meta_seat_impl_set_keyboard_numlock_in_impl (MetaSeatImpl *seat_impl, + gboolean numlock_state) { xkb_mod_mask_t depressed_mods; xkb_mod_mask_t latched_mods; @@ -2553,7 +2553,7 @@ meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, MetaKeymapNative *keymap; keymap = seat_impl->keymap; - xkb_keymap = meta_keymap_native_get_keyboard_map (keymap); + xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (keymap); numlock = (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod2")); @@ -2578,8 +2578,8 @@ meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl, 0, 0, group_mods); - meta_seat_impl_sync_leds (seat_impl); - meta_keymap_native_update (seat_impl->keymap); + meta_seat_impl_sync_leds_in_impl (seat_impl); + meta_keymap_native_update_in_impl (seat_impl->keymap); } static gpointer @@ -2619,7 +2619,7 @@ input_thread (MetaSeatImpl *seat_impl) udev_unref (udev); - seat_impl->input_settings = meta_input_settings_native_new (seat_impl); + seat_impl->input_settings = meta_input_settings_native_new_in_impl (seat_impl); g_signal_connect_object (seat_impl->input_settings, "kbd-a11y-changed", G_CALLBACK (kbd_a11y_changed_cb), seat_impl, 0); @@ -2628,7 +2628,7 @@ input_thread (MetaSeatImpl *seat_impl) seat_impl->keymap = g_object_new (META_TYPE_KEYMAP_NATIVE, NULL); - xkb_keymap = meta_keymap_native_get_keyboard_map (seat_impl->keymap); + xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (seat_impl->keymap); if (xkb_keymap) { @@ -2643,7 +2643,7 @@ input_thread (MetaSeatImpl *seat_impl) } if (meta_input_settings_maybe_restore_numlock_state (seat_impl->input_settings)) - meta_seat_impl_set_keyboard_numlock (seat_impl, TRUE); + meta_seat_impl_set_keyboard_numlock_in_impl (seat_impl, TRUE); seat_impl->has_touchscreen = has_touchscreen (seat_impl); seat_impl->has_tablet_switch = has_tablet_switch (seat_impl); @@ -2702,9 +2702,9 @@ meta_seat_impl_constructed (GObject *object) CLUTTER_INPUT_MODE_LOGICAL); seat_impl->pointer_x = INITIAL_POINTER_X; seat_impl->pointer_y = INITIAL_POINTER_Y; - meta_input_device_native_set_coords (META_INPUT_DEVICE_NATIVE (device), - seat_impl->pointer_x, - seat_impl->pointer_y); + meta_input_device_native_set_coords_in_impl (META_INPUT_DEVICE_NATIVE (device), + seat_impl->pointer_x, + seat_impl->pointer_y); seat_impl->core_pointer = device; device = meta_input_device_native_new_virtual ( @@ -2831,7 +2831,7 @@ meta_seat_impl_get_keyboard (MetaSeatImpl *seat_impl) } GSList * -meta_seat_impl_get_devices (MetaSeatImpl *seat_impl) +meta_seat_impl_get_devices_in_impl (MetaSeatImpl *seat_impl) { return g_slist_copy_deep (seat_impl->devices, (GCopyFunc) g_object_ref, @@ -2845,14 +2845,14 @@ meta_seat_impl_get_keymap (MetaSeatImpl *seat_impl) } static gboolean -warp_pointer (GTask *task) +warp_pointer_in_impl (GTask *task) { MetaSeatImpl *seat = g_task_get_source_object (task); graphene_point_t *point; point = g_task_get_task_data (task); - notify_absolute_motion (seat->core_pointer, 0, - point->x, point->y, NULL); + notify_absolute_motion_in_impl (seat->core_pointer, 0, + point->x, point->y, NULL); g_task_return_boolean (task, TRUE); return G_SOURCE_REMOVE; @@ -2872,7 +2872,8 @@ meta_seat_impl_warp_pointer (MetaSeatImpl *seat_impl, task = g_task_new (seat_impl, NULL, NULL, NULL); g_task_set_task_data (task, point, (GDestroyNotify) graphene_point_free); - meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) warp_pointer); + meta_seat_impl_run_input_task (seat_impl, task, + (GSourceFunc) warp_pointer_in_impl); g_object_unref (task); } @@ -2895,7 +2896,7 @@ meta_seat_impl_query_state (MetaSeatImpl *seat_impl, int slot; slot = meta_event_native_sequence_get_slot (sequence); - touch_state = meta_seat_impl_lookup_touch_state (seat_impl, slot); + touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat_impl, slot); if (!touch_state) goto out; @@ -3047,7 +3048,7 @@ meta_seat_impl_set_device_callbacks (MetaOpenDeviceCallback open_callback, } void -meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl) +meta_seat_impl_update_xkb_state_in_impl (MetaSeatImpl *seat_impl) { xkb_mod_mask_t latched_mods = 0; xkb_mod_mask_t locked_mods = 0; @@ -3055,7 +3056,7 @@ meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl) g_rw_lock_writer_lock (&seat_impl->state_lock); - xkb_keymap = meta_keymap_native_get_keyboard_map (seat_impl->keymap); + xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (seat_impl->keymap); if (seat_impl->xkb) { @@ -3081,8 +3082,8 @@ meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl) seat_impl->scroll_lock_led = xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL); - meta_seat_impl_sync_leds (seat_impl); - meta_keymap_native_update (seat_impl->keymap); + meta_seat_impl_sync_leds_in_impl (seat_impl); + meta_keymap_native_update_in_impl (seat_impl->keymap); g_rw_lock_writer_unlock (&seat_impl->state_lock); } @@ -3142,7 +3143,7 @@ reclaim_devices (GTask *task) if (seat_impl->released) { libinput_resume (seat_impl->libinput); - meta_seat_impl_update_xkb_state (seat_impl); + meta_seat_impl_update_xkb_state_in_impl (seat_impl); process_events (seat_impl); seat_impl->released = FALSE; @@ -3189,9 +3190,9 @@ set_keyboard_map (GTask *task) MetaKeymapNative *keymap; keymap = seat_impl->keymap; - meta_keymap_native_set_keyboard_map (keymap, xkb_keymap); + meta_keymap_native_set_keyboard_map_in_impl (keymap, xkb_keymap); - meta_seat_impl_update_xkb_state (seat_impl); + meta_seat_impl_update_xkb_state_in_impl (seat_impl); g_task_return_boolean (task, TRUE); return G_SOURCE_REMOVE; @@ -3243,7 +3244,7 @@ set_keyboard_layout_index (GTask *task) locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED); xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx); - meta_keymap_native_update (seat_impl->keymap); + meta_keymap_native_update_in_impl (seat_impl->keymap); seat_impl->layout_idx = idx; @@ -3276,9 +3277,8 @@ meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, g_object_unref (task); } - /** - * meta_seat_impl_set_keyboard_repeat: + * meta_seat_impl_set_keyboard_repeat_in_impl: * @seat: the #ClutterSeat created by the evdev backend * @repeat: whether to enable or disable keyboard repeat events * @delay: the delay in ms between the hardware key press event and @@ -3290,10 +3290,10 @@ meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, * delay and interval period to be specified. */ void -meta_seat_impl_set_keyboard_repeat (MetaSeatImpl *seat_impl, - gboolean repeat, - uint32_t delay, - uint32_t interval) +meta_seat_impl_set_keyboard_repeat_in_impl (MetaSeatImpl *seat_impl, + gboolean repeat, + uint32_t delay, + uint32_t interval) { g_return_if_fail (META_IS_SEAT_IMPL (seat_impl)); @@ -3303,7 +3303,7 @@ meta_seat_impl_set_keyboard_repeat (MetaSeatImpl *seat_impl, } struct xkb_state * -meta_seat_impl_get_xkb_state (MetaSeatImpl *seat_impl) +meta_seat_impl_get_xkb_state_in_impl (MetaSeatImpl *seat_impl) { return seat_impl->xkb; } @@ -3388,9 +3388,9 @@ meta_seat_impl_new (MetaSeatNative *seat_native, } void -meta_seat_impl_notify_kbd_a11y_flags_changed (MetaSeatImpl *seat_impl, - MetaKeyboardA11yFlags new_flags, - MetaKeyboardA11yFlags what_changed) +meta_seat_impl_notify_kbd_a11y_flags_changed_in_impl (MetaSeatImpl *seat_impl, + MetaKeyboardA11yFlags new_flags, + MetaKeyboardA11yFlags what_changed) { MetaInputSettings *input_settings; GValue values[] = { G_VALUE_INIT, G_VALUE_INIT }; @@ -3408,9 +3408,9 @@ meta_seat_impl_notify_kbd_a11y_flags_changed (MetaSeatImpl *seat_impl, } void -meta_seat_impl_notify_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_impl, - xkb_mod_mask_t new_latched_mods, - xkb_mod_mask_t new_locked_mods) +meta_seat_impl_notify_kbd_a11y_mods_state_changed_in_impl (MetaSeatImpl *seat_impl, + xkb_mod_mask_t new_latched_mods, + xkb_mod_mask_t new_locked_mods) { GValue values[] = { G_VALUE_INIT, G_VALUE_INIT }; @@ -3424,7 +3424,7 @@ meta_seat_impl_notify_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_impl, } void -meta_seat_impl_notify_bell (MetaSeatImpl *seat_impl) +meta_seat_impl_notify_bell_in_impl (MetaSeatImpl *seat_impl) { emit_signal (seat_impl, signals[BELL], NULL, 0); } diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index 26f9baa4f26..ac5b7e42d41 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -129,67 +129,67 @@ void meta_seat_impl_run_input_task (MetaSeatImpl *seat_impl, GTask *task, GSourceFunc dispatch_func); -void meta_seat_impl_notify_key (MetaSeatImpl *seat_impl, - ClutterInputDevice *device, - uint64_t time_us, - uint32_t key, - uint32_t state, - gboolean update_keys); - -void meta_seat_impl_notify_relative_motion (MetaSeatImpl *seat_impl, - ClutterInputDevice *input_device, - uint64_t time_us, - float dx, - float dy, - float dx_unaccel, - float dy_unaccel); - -void meta_seat_impl_notify_absolute_motion (MetaSeatImpl *seat_impl, - ClutterInputDevice *input_device, - uint64_t time_us, - float x, - float y, - double *axes); - -void meta_seat_impl_notify_button (MetaSeatImpl *seat_impl, - ClutterInputDevice *input_device, - uint64_t time_us, - uint32_t button, - uint32_t state); - -void meta_seat_impl_notify_scroll_continuous (MetaSeatImpl *seat_impl, - ClutterInputDevice *input_device, - uint64_t time_us, - double dx, - double dy, - ClutterScrollSource source, - ClutterScrollFinishFlags flags); - -void meta_seat_impl_notify_discrete_scroll (MetaSeatImpl *seat_impl, - ClutterInputDevice *input_device, - uint64_t time_us, - double discrete_dx, - double discrete_dy, - ClutterScrollSource source); - -void meta_seat_impl_notify_touch_event (MetaSeatImpl *seat_impl, - ClutterInputDevice *input_device, - ClutterEventType evtype, +void meta_seat_impl_notify_key_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *device, uint64_t time_us, - int slot, - double x, - double y); - -void meta_seat_impl_sync_leds (MetaSeatImpl *seat_impl); - -MetaTouchState * meta_seat_impl_acquire_touch_state (MetaSeatImpl *seat_impl, - int seat_slot); -MetaTouchState * meta_seat_impl_lookup_touch_state (MetaSeatImpl *seat_impl, - int seat_slot); -void meta_seat_impl_release_touch_state (MetaSeatImpl *seat_impl, - int seat_slot); - -void meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl); + uint32_t key, + uint32_t state, + gboolean update_keys); + +void meta_seat_impl_notify_relative_motion_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + float dx, + float dy, + float dx_unaccel, + float dy_unaccel); + +void meta_seat_impl_notify_absolute_motion_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + float x, + float y, + double *axes); + +void meta_seat_impl_notify_button_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + uint32_t button, + uint32_t state); + +void meta_seat_impl_notify_scroll_continuous_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + double dx, + double dy, + ClutterScrollSource source, + ClutterScrollFinishFlags flags); + +void meta_seat_impl_notify_discrete_scroll_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + uint64_t time_us, + double discrete_dx, + double discrete_dy, + ClutterScrollSource source); + +void meta_seat_impl_notify_touch_event_in_impl (MetaSeatImpl *seat_impl, + ClutterInputDevice *input_device, + ClutterEventType evtype, + uint64_t time_us, + int slot, + double x, + double y); + +void meta_seat_impl_sync_leds_in_impl (MetaSeatImpl *seat_impl); + +MetaTouchState * meta_seat_impl_acquire_touch_state_in_impl (MetaSeatImpl *seat_impl, + int seat_slot); +MetaTouchState * meta_seat_impl_lookup_touch_state_in_impl (MetaSeatImpl *seat_impl, + int seat_slot); +void meta_seat_impl_release_touch_state_in_impl (MetaSeatImpl *seat_impl, + int seat_slot); + +void meta_seat_impl_update_xkb_state_in_impl (MetaSeatImpl *seat_impl); /** * MetaOpenDeviceCallback: @@ -214,18 +214,18 @@ void meta_seat_impl_set_device_callbacks (MetaOpenDeviceCallback open_callback void meta_seat_impl_release_devices (MetaSeatImpl *seat_impl); void meta_seat_impl_reclaim_devices (MetaSeatImpl *seat_impl); -struct xkb_state * meta_seat_impl_get_xkb_state (MetaSeatImpl *seat_impl); +struct xkb_state * meta_seat_impl_get_xkb_state_in_impl (MetaSeatImpl *seat_impl); -void meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat_impl, - struct xkb_keymap *keymap); +void meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat_impl, + struct xkb_keymap *keymap); void meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat_impl, xkb_layout_index_t idx); -void meta_seat_impl_set_keyboard_repeat (MetaSeatImpl *seat_impl, - gboolean repeat, - uint32_t delay, - uint32_t interval); +void meta_seat_impl_set_keyboard_repeat_in_impl (MetaSeatImpl *seat_impl, + gboolean repeat, + uint32_t delay, + uint32_t interval); MetaBarrierManagerNative * meta_seat_impl_get_barrier_manager (MetaSeatImpl *seat_impl); @@ -244,17 +244,17 @@ gboolean meta_seat_impl_query_state (MetaSeatImpl *seat_impl, ClutterModifierType *modifiers); ClutterInputDevice * meta_seat_impl_get_pointer (MetaSeatImpl *seat_impl); ClutterInputDevice * meta_seat_impl_get_keyboard (MetaSeatImpl *seat_impl); -GSList * meta_seat_impl_get_devices (MetaSeatImpl *seat_impl); +GSList * meta_seat_impl_get_devices_in_impl (MetaSeatImpl *seat_impl); MetaKeymapNative * meta_seat_impl_get_keymap (MetaSeatImpl *seat_impl); -void meta_seat_impl_notify_kbd_a11y_flags_changed (MetaSeatImpl *seat_impl, - MetaKeyboardA11yFlags new_flags, - MetaKeyboardA11yFlags what_changed); -void meta_seat_impl_notify_kbd_a11y_mods_state_changed (MetaSeatImpl *seat_impl, - xkb_mod_mask_t new_latched_mods, - xkb_mod_mask_t new_locked_mods); -void meta_seat_impl_notify_bell (MetaSeatImpl *seat_impl); +void meta_seat_impl_notify_kbd_a11y_flags_changed_in_impl (MetaSeatImpl *seat_impl, + MetaKeyboardA11yFlags new_flags, + MetaKeyboardA11yFlags what_changed); +void meta_seat_impl_notify_kbd_a11y_mods_state_changed_in_impl (MetaSeatImpl *seat_impl, + xkb_mod_mask_t new_latched_mods, + xkb_mod_mask_t new_locked_mods); +void meta_seat_impl_notify_bell_in_impl (MetaSeatImpl *seat_impl); MetaInputSettings * meta_seat_impl_get_input_settings (MetaSeatImpl *seat_impl); diff --git a/src/backends/native/meta-virtual-input-device-native.c b/src/backends/native/meta-virtual-input-device-native.c index 9d19f108280..39caa8b092f 100644 --- a/src/backends/native/meta-virtual-input-device-native.c +++ b/src/backends/native/meta-virtual-input-device-native.c @@ -109,9 +109,9 @@ typedef enum _EvdevButtonType } EvdevButtonType; static int -update_button_count (MetaVirtualInputDeviceNative *virtual_evdev, - uint32_t button, - uint32_t state) +update_button_count_in_impl (MetaVirtualInputDeviceNative *virtual_evdev, + uint32_t button, + uint32_t state) { if (state) return ++virtual_evdev->impl_state->button_count[button]; @@ -156,7 +156,7 @@ get_button_type (uint16_t code) } static gboolean -release_device (GTask *task) +release_device_in_impl (GTask *task) { ImplState *impl_state = g_task_get_task_data (task); MetaInputDeviceNative *device_native; @@ -180,19 +180,19 @@ release_device (GTask *task) switch (get_button_type (code)) { case EVDEV_BUTTON_TYPE_KEY: - meta_seat_impl_notify_key (seat_impl, - impl_state->device, - time_us, - code, - CLUTTER_KEY_STATE_RELEASED, - TRUE); + meta_seat_impl_notify_key_in_impl (seat_impl, + impl_state->device, + time_us, + code, + CLUTTER_KEY_STATE_RELEASED, + TRUE); break; case EVDEV_BUTTON_TYPE_BUTTON: - meta_seat_impl_notify_button (seat_impl, - impl_state->device, - time_us, - code, - CLUTTER_BUTTON_STATE_RELEASED); + meta_seat_impl_notify_button_in_impl (seat_impl, + impl_state->device, + time_us, + code, + CLUTTER_BUTTON_STATE_RELEASED); break; case EVDEV_BUTTON_TYPE_NONE: g_assert_not_reached (); @@ -206,7 +206,7 @@ release_device (GTask *task) } static gboolean -notify_relative_motion (GTask *task) +notify_relative_motion_in_impl (GTask *task) { MetaVirtualInputDeviceNative *virtual_evdev = g_task_get_source_object (task); @@ -216,11 +216,11 @@ notify_relative_motion (GTask *task) if (event->time_us == CLUTTER_CURRENT_TIME) event->time_us = g_get_monotonic_time (); - meta_seat_impl_notify_relative_motion (seat, - virtual_evdev->impl_state->device, - event->time_us, - event->x, event->y, - event->x, event->y); + meta_seat_impl_notify_relative_motion_in_impl (seat, + virtual_evdev->impl_state->device, + event->time_us, + event->x, event->y, + event->x, event->y); g_task_return_boolean (task, TRUE); return G_SOURCE_REMOVE; } @@ -246,12 +246,12 @@ meta_virtual_input_device_native_notify_relative_motion (ClutterVirtualInputDevi task = g_task_new (virtual_device, NULL, NULL, NULL); g_task_set_task_data (task, event, g_free); meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, - (GSourceFunc) notify_relative_motion); + (GSourceFunc) notify_relative_motion_in_impl); g_object_unref (task); } static gboolean -notify_absolute_motion (GTask *task) +notify_absolute_motion_in_impl (GTask *task) { MetaVirtualInputDeviceNative *virtual_evdev = g_task_get_source_object (task); @@ -261,11 +261,11 @@ notify_absolute_motion (GTask *task) if (event->time_us == CLUTTER_CURRENT_TIME) event->time_us = g_get_monotonic_time (); - meta_seat_impl_notify_absolute_motion (seat, - virtual_evdev->impl_state->device, - event->time_us, - event->x, event->y, - NULL); + meta_seat_impl_notify_absolute_motion_in_impl (seat, + virtual_evdev->impl_state->device, + event->time_us, + event->x, event->y, + NULL); g_task_return_boolean (task, TRUE); return G_SOURCE_REMOVE; } @@ -291,7 +291,7 @@ meta_virtual_input_device_native_notify_absolute_motion (ClutterVirtualInputDevi task = g_task_new (virtual_device, NULL, NULL, NULL); g_task_set_task_data (task, event, g_free); meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, - (GSourceFunc) notify_absolute_motion); + (GSourceFunc) notify_absolute_motion_in_impl); g_object_unref (task); } @@ -316,7 +316,7 @@ translate_to_evdev_button (int clutter_button) } static gboolean -notify_button (GTask *task) +notify_button_in_impl (GTask *task) { MetaVirtualInputDeviceNative *virtual_evdev = g_task_get_source_object (task); @@ -337,14 +337,14 @@ notify_button (GTask *task) goto out; } - button_count = update_button_count (virtual_evdev, evdev_button, - event->button_state); + button_count = update_button_count_in_impl (virtual_evdev, evdev_button, + event->button_state); if (button_count < 0 || button_count > 1) { g_warning ("Received multiple virtual 0x%x button %s (ignoring)", evdev_button, event->button_state == CLUTTER_BUTTON_STATE_PRESSED ? "presses" : "releases"); - update_button_count (virtual_evdev, evdev_button, 1 - event->button_state); + update_button_count_in_impl (virtual_evdev, evdev_button, 1 - event->button_state); goto out; } @@ -354,11 +354,11 @@ notify_button (GTask *task) "press" : "release", evdev_button, virtual_evdev); - meta_seat_impl_notify_button (seat, - virtual_evdev->impl_state->device, - event->time_us, - evdev_button, - event->button_state); + meta_seat_impl_notify_button_in_impl (seat, + virtual_evdev->impl_state->device, + event->time_us, + evdev_button, + event->button_state); out: g_task_return_boolean (task, TRUE); return G_SOURCE_REMOVE; @@ -385,12 +385,12 @@ meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtu task = g_task_new (virtual_device, NULL, NULL, NULL); g_task_set_task_data (task, event, g_free); meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, - (GSourceFunc) notify_button); + (GSourceFunc) notify_button_in_impl); g_object_unref (task); } static gboolean -notify_key (GTask *task) +notify_key_in_impl (GTask *task) { MetaVirtualInputDeviceNative *virtual_evdev = g_task_get_source_object (task); @@ -407,13 +407,13 @@ notify_key (GTask *task) goto out; } - key_count = update_button_count (virtual_evdev, event->key, event->key_state); + key_count = update_button_count_in_impl (virtual_evdev, event->key, event->key_state); if (key_count < 0 || key_count > 1) { g_warning ("Received multiple virtual 0x%x key %s (ignoring)", event->key, event->key_state == CLUTTER_KEY_STATE_PRESSED ? "presses" : "releases"); - update_button_count (virtual_evdev, event->key, 1 - event->key_state); + update_button_count_in_impl (virtual_evdev, event->key, 1 - event->key_state); goto out; } @@ -422,12 +422,12 @@ notify_key (GTask *task) event->key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release", event->key, virtual_evdev); - meta_seat_impl_notify_key (seat, - virtual_evdev->impl_state->device, - event->time_us, - event->key, - event->key_state, - TRUE); + meta_seat_impl_notify_key_in_impl (seat, + virtual_evdev->impl_state->device, + event->time_us, + event->key, + event->key_state, + TRUE); out: g_task_return_boolean (task, TRUE); @@ -455,15 +455,15 @@ meta_virtual_input_device_native_notify_key (ClutterVirtualInputDevice *virtual_ task = g_task_new (virtual_device, NULL, NULL, NULL); g_task_set_task_data (task, event, g_free); meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, - (GSourceFunc) notify_key); + (GSourceFunc) notify_key_in_impl); g_object_unref (task); } static gboolean -pick_keycode_for_keyval_in_current_group (ClutterVirtualInputDevice *virtual_device, - guint keyval, - guint *keycode_out, - guint *level_out) +pick_keycode_for_keyval_in_current_group_in_impl (ClutterVirtualInputDevice *virtual_device, + guint keyval, + guint *keycode_out, + guint *level_out) { MetaVirtualInputDeviceNative *virtual_evdev = META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); @@ -476,8 +476,8 @@ pick_keycode_for_keyval_in_current_group (ClutterVirtualInputDevice *virtual_dev backend = clutter_get_default_backend (); keymap = clutter_seat_get_keymap (clutter_backend_get_default_seat (backend)); - xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap)); - state = meta_seat_impl_get_xkb_state (virtual_evdev->seat->impl); + xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (META_KEYMAP_NATIVE (keymap)); + state = meta_seat_impl_get_xkb_state_in_impl (virtual_evdev->seat->impl); layout = xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE); min_keycode = xkb_keymap_min_keycode (xkb_keymap); @@ -508,10 +508,10 @@ pick_keycode_for_keyval_in_current_group (ClutterVirtualInputDevice *virtual_dev } static void -apply_level_modifiers (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t level, - uint32_t key_state) +apply_level_modifiers_in_impl (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t level, + uint32_t key_state) { MetaVirtualInputDeviceNative *virtual_evdev = META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); @@ -534,8 +534,8 @@ apply_level_modifiers (ClutterVirtualInputDevice *virtual_device, return; } - if (!pick_keycode_for_keyval_in_current_group (virtual_device, keysym, - &keycode, NULL)) + if (!pick_keycode_for_keyval_in_current_group_in_impl (virtual_device, keysym, + &keycode, NULL)) return; evcode = meta_xkb_keycode_to_evdev (keycode); @@ -545,16 +545,16 @@ apply_level_modifiers (ClutterVirtualInputDevice *virtual_device, key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release", evcode, virtual_device); - meta_seat_impl_notify_key (virtual_evdev->seat->impl, - virtual_evdev->impl_state->device, - time_us, - evcode, - key_state, - TRUE); + meta_seat_impl_notify_key_in_impl (virtual_evdev->seat->impl, + virtual_evdev->impl_state->device, + time_us, + evcode, + key_state, + TRUE); } static gboolean -notify_keyval (GTask *task) +notify_keyval_in_impl (GTask *task) { MetaVirtualInputDeviceNative *virtual_evdev = g_task_get_source_object (task); @@ -568,8 +568,9 @@ notify_keyval (GTask *task) if (event->time_us == CLUTTER_CURRENT_TIME) event->time_us = g_get_monotonic_time (); - if (!pick_keycode_for_keyval_in_current_group (virtual_device, - event->key, &keycode, &level)) + if (!pick_keycode_for_keyval_in_current_group_in_impl (virtual_device, + event->key, + &keycode, &level)) { g_warning ("No keycode found for keyval %x in current group", event->key); goto out; @@ -583,13 +584,13 @@ notify_keyval (GTask *task) goto out; } - key_count = update_button_count (virtual_evdev, evcode, event->key_state); + key_count = update_button_count_in_impl (virtual_evdev, evcode, event->key_state); if (key_count < 0 || key_count > 1) { g_warning ("Received multiple virtual 0x%x key %s (ignoring)", evcode, event->key_state == CLUTTER_KEY_STATE_PRESSED ? "presses" : "releases"); - update_button_count (virtual_evdev, evcode, 1 - event->key_state); + update_button_count_in_impl (virtual_evdev, evcode, 1 - event->key_state); goto out; } @@ -600,17 +601,23 @@ notify_keyval (GTask *task) evcode, level, key_count, virtual_evdev); if (event->key_state) - apply_level_modifiers (virtual_device, event->time_us, level, event->key_state); + { + apply_level_modifiers_in_impl (virtual_device, event->time_us, + level, event->key_state); + } - meta_seat_impl_notify_key (seat, - virtual_evdev->impl_state->device, - event->time_us, - evcode, - event->key_state, - TRUE); + meta_seat_impl_notify_key_in_impl (seat, + virtual_evdev->impl_state->device, + event->time_us, + evcode, + event->key_state, + TRUE); if (!event->key_state) - apply_level_modifiers (virtual_device, event->time_us, level, event->key_state); + { + apply_level_modifiers_in_impl (virtual_device, event->time_us, + level, event->key_state); + } out: g_task_return_boolean (task, TRUE); @@ -638,7 +645,7 @@ meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtu task = g_task_new (virtual_device, NULL, NULL, NULL); g_task_set_task_data (task, event, g_free); meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, - (GSourceFunc) notify_keyval); + (GSourceFunc) notify_keyval_in_impl); g_object_unref (task); } @@ -672,7 +679,7 @@ direction_to_discrete (ClutterScrollDirection direction, } static gboolean -notify_discrete_scroll (GTask *task) +notify_discrete_scroll_in_impl (GTask *task) { MetaVirtualInputDeviceNative *virtual_evdev = g_task_get_source_object (task); @@ -685,11 +692,11 @@ notify_discrete_scroll (GTask *task) direction_to_discrete (event->direction, &discrete_dx, &discrete_dy); - meta_seat_impl_notify_discrete_scroll (seat, - virtual_evdev->impl_state->device, - event->time_us, - discrete_dx, discrete_dy, - event->scroll_source); + meta_seat_impl_notify_discrete_scroll_in_impl (seat, + virtual_evdev->impl_state->device, + event->time_us, + discrete_dx, discrete_dy, + event->scroll_source); g_task_return_boolean (task, TRUE); return G_SOURCE_REMOVE; @@ -716,12 +723,12 @@ meta_virtual_input_device_native_notify_discrete_scroll (ClutterVirtualInputDevi task = g_task_new (virtual_device, NULL, NULL, NULL); g_task_set_task_data (task, event, g_free); meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, - (GSourceFunc) notify_discrete_scroll); + (GSourceFunc) notify_discrete_scroll_in_impl); g_object_unref (task); } static gboolean -notify_scroll_continuous (GTask *task) +notify_scroll_continuous_in_impl (GTask *task) { MetaVirtualInputDeviceNative *virtual_evdev = g_task_get_source_object (task); @@ -731,12 +738,12 @@ notify_scroll_continuous (GTask *task) if (event->time_us == CLUTTER_CURRENT_TIME) event->time_us = g_get_monotonic_time (); - meta_seat_impl_notify_scroll_continuous (seat, - virtual_evdev->impl_state->device, - event->time_us, - event->dx, event->dy, - event->scroll_source, - CLUTTER_SCROLL_FINISHED_NONE); + meta_seat_impl_notify_scroll_continuous_in_impl (seat, + virtual_evdev->impl_state->device, + event->time_us, + event->dx, event->dy, + event->scroll_source, + CLUTTER_SCROLL_FINISHED_NONE); g_task_return_boolean (task, TRUE); return G_SOURCE_REMOVE; } @@ -766,12 +773,12 @@ meta_virtual_input_device_native_notify_scroll_continuous (ClutterVirtualInputDe task = g_task_new (virtual_device, NULL, NULL, NULL); g_task_set_task_data (task, event, g_free); meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, - (GSourceFunc) notify_scroll_continuous); + (GSourceFunc) notify_scroll_continuous_in_impl); g_object_unref (task); } static gboolean -notify_touch_down (GTask *task) +notify_touch_down_in_impl (GTask *task) { MetaVirtualInputDeviceNative *virtual_evdev = g_task_get_source_object (task); @@ -782,21 +789,21 @@ notify_touch_down (GTask *task) if (event->time_us == CLUTTER_CURRENT_TIME) event->time_us = g_get_monotonic_time (); - touch_state = meta_seat_impl_acquire_touch_state (seat, - event->device_slot); + touch_state = meta_seat_impl_acquire_touch_state_in_impl (seat, + event->device_slot); if (!touch_state) goto out; touch_state->coords.x = event->x; touch_state->coords.y = event->y; - meta_seat_impl_notify_touch_event (seat, - virtual_evdev->impl_state->device, - CLUTTER_TOUCH_BEGIN, - event->time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); + meta_seat_impl_notify_touch_event_in_impl (seat, + virtual_evdev->impl_state->device, + CLUTTER_TOUCH_BEGIN, + event->time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); out: g_task_return_boolean (task, TRUE); @@ -826,12 +833,12 @@ meta_virtual_input_device_native_notify_touch_down (ClutterVirtualInputDevice *v task = g_task_new (virtual_device, NULL, NULL, NULL); g_task_set_task_data (task, event, g_free); meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, - (GSourceFunc) notify_touch_down); + (GSourceFunc) notify_touch_down_in_impl); g_object_unref (task); } static gboolean -notify_touch_motion (GTask *task) +notify_touch_motion_in_impl (GTask *task) { MetaVirtualInputDeviceNative *virtual_evdev = g_task_get_source_object (task); @@ -842,21 +849,21 @@ notify_touch_motion (GTask *task) if (event->time_us == CLUTTER_CURRENT_TIME) event->time_us = g_get_monotonic_time (); - touch_state = meta_seat_impl_lookup_touch_state (seat, - event->device_slot); + touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat, + event->device_slot); if (!touch_state) goto out; touch_state->coords.x = event->x; touch_state->coords.y = event->y; - meta_seat_impl_notify_touch_event (seat, - virtual_evdev->impl_state->device, - CLUTTER_TOUCH_UPDATE, - event->time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); + meta_seat_impl_notify_touch_event_in_impl (seat, + virtual_evdev->impl_state->device, + CLUTTER_TOUCH_UPDATE, + event->time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); out: g_task_return_boolean (task, TRUE); @@ -886,12 +893,12 @@ meta_virtual_input_device_native_notify_touch_motion (ClutterVirtualInputDevice task = g_task_new (virtual_device, NULL, NULL, NULL); g_task_set_task_data (task, event, g_free); meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, - (GSourceFunc) notify_touch_motion); + (GSourceFunc) notify_touch_motion_in_impl); g_object_unref (task); } static gboolean -notify_touch_up (GTask *task) +notify_touch_up_in_impl (GTask *task) { MetaVirtualInputDeviceNative *virtual_evdev = g_task_get_source_object (task); @@ -902,21 +909,21 @@ notify_touch_up (GTask *task) if (event->time_us == CLUTTER_CURRENT_TIME) event->time_us = g_get_monotonic_time (); - touch_state = meta_seat_impl_lookup_touch_state (seat, - event->device_slot); + touch_state = meta_seat_impl_lookup_touch_state_in_impl (seat, + event->device_slot); if (!touch_state) goto out; - meta_seat_impl_notify_touch_event (seat, - virtual_evdev->impl_state->device, - CLUTTER_TOUCH_END, - event->time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); + meta_seat_impl_notify_touch_event_in_impl (seat, + virtual_evdev->impl_state->device, + CLUTTER_TOUCH_END, + event->time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); - meta_seat_impl_release_touch_state (virtual_evdev->seat->impl, - touch_state->seat_slot); + meta_seat_impl_release_touch_state_in_impl (virtual_evdev->seat->impl, + touch_state->seat_slot); out: g_task_return_boolean (task, TRUE); @@ -942,7 +949,7 @@ meta_virtual_input_device_native_notify_touch_up (ClutterVirtualInputDevice *vir task = g_task_new (virtual_device, NULL, NULL, NULL); g_task_set_task_data (task, event, g_free); meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, - (GSourceFunc) notify_touch_up); + (GSourceFunc) notify_touch_up_in_impl); g_object_unref (task); } @@ -1039,7 +1046,7 @@ meta_virtual_input_device_native_dispose (GObject *object) g_task_set_task_data (task, virtual_evdev->impl_state, (GDestroyNotify) impl_state_free); meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task, - (GSourceFunc) release_device); + (GSourceFunc) release_device_in_impl); g_object_unref (task); virtual_evdev->impl_state = NULL; -- GitLab From 8b6ea12fac49552e960bc8b8f64ea3ef10addb06 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 20 Nov 2020 23:53:46 +0100 Subject: [PATCH 85/85] backends/native: Add distinct meta-input-thread.h header Make it impossible to add individual includes of input thread objects. This must go through meta-input-thread.h now, which should be enough to make anyone think it twice. Part-of: --- .../native/meta-backend-native-types.h | 2 ++ src/backends/native/meta-backend-native.c | 3 +- src/backends/native/meta-event-native.c | 2 +- .../native/meta-input-device-native.c | 4 +-- .../native/meta-input-device-native.h | 4 +++ .../native/meta-input-device-tool-native.c | 2 +- .../native/meta-input-device-tool-native.h | 4 +++ .../native/meta-input-settings-native.c | 3 +- .../native/meta-input-settings-native.h | 4 +++ src/backends/native/meta-input-thread.h | 33 +++++++++++++++++++ src/backends/native/meta-keymap-native.c | 2 +- src/backends/native/meta-keymap-native.h | 4 +++ src/backends/native/meta-launcher.c | 2 +- src/backends/native/meta-seat-impl.c | 7 +--- src/backends/native/meta-seat-impl.h | 4 +++ src/backends/native/meta-seat-native.c | 3 +- src/backends/native/meta-seat-native.h | 4 +-- .../native/meta-virtual-input-device-native.c | 3 +- 18 files changed, 67 insertions(+), 23 deletions(-) create mode 100644 src/backends/native/meta-input-thread.h diff --git a/src/backends/native/meta-backend-native-types.h b/src/backends/native/meta-backend-native-types.h index bfc506788a6..ba73b4a563c 100644 --- a/src/backends/native/meta-backend-native-types.h +++ b/src/backends/native/meta-backend-native-types.h @@ -23,5 +23,7 @@ typedef struct _MetaBackendNative MetaBackendNative; typedef struct _MetaSeatNative MetaSeatNative; +typedef struct _MetaSeatImpl MetaSeatImpl; +typedef struct _MetaKeymapNative MetaKeymapNative; #endif /* META_BACKEND_NATIVE_TYPES_H */ diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index c397a7893b5..939885a64a2 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -36,6 +36,7 @@ #include "backends/native/meta-backend-native.h" #include "backends/native/meta-backend-native-private.h" +#include "backends/native/meta-input-thread.h" #include #include @@ -50,8 +51,6 @@ #include "backends/meta-stage-private.h" #include "backends/native/meta-clutter-backend-native.h" #include "backends/native/meta-event-native.h" -#include "backends/native/meta-input-device-native.h" -#include "backends/native/meta-input-settings-native.h" #include "backends/native/meta-kms.h" #include "backends/native/meta-kms-device.h" #include "backends/native/meta-launcher.h" diff --git a/src/backends/native/meta-event-native.c b/src/backends/native/meta-event-native.c index 61603d19efa..8a1d8f3482c 100644 --- a/src/backends/native/meta-event-native.c +++ b/src/backends/native/meta-event-native.c @@ -21,7 +21,7 @@ #include "config.h" #include "backends/native/meta-event-native.h" -#include "backends/native/meta-input-device-native.h" +#include "backends/native/meta-input-thread.h" #include "clutter/clutter-mutter.h" typedef struct _MetaEventNative MetaEventNative; diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index 9aab8e07006..2878675f236 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -25,9 +25,7 @@ #include #include "backends/meta-backend-private.h" -#include "backends/native/meta-input-device-tool-native.h" -#include "backends/native/meta-input-device-native.h" -#include "backends/native/meta-seat-impl.h" +#include "backends/native/meta-input-thread.h" #include "clutter/clutter-mutter.h" G_DEFINE_TYPE (MetaInputDeviceNative, diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h index db28d0516c4..2000888dc48 100644 --- a/src/backends/native/meta-input-device-native.h +++ b/src/backends/native/meta-input-device-native.h @@ -26,6 +26,10 @@ #ifndef META_INPUT_DEVICE_NATIVE_H #define META_INPUT_DEVICE_NATIVE_H +#ifndef META_INPUT_THREAD_H_INSIDE +#error "This header cannot be included directly. Use "backends/native/meta-input-thread.h"" +#endif /* META_INPUT_THREAD_H_INSIDE */ + #include #include "backends/meta-input-device-private.h" diff --git a/src/backends/native/meta-input-device-tool-native.c b/src/backends/native/meta-input-device-tool-native.c index ad6a3bdb6ab..e6ec0c75854 100644 --- a/src/backends/native/meta-input-device-tool-native.c +++ b/src/backends/native/meta-input-device-tool-native.c @@ -19,7 +19,7 @@ #include "config.h" -#include "backends/native/meta-input-device-tool-native.h" +#include "backends/native/meta-input-thread.h" G_DEFINE_TYPE (MetaInputDeviceToolNative, meta_input_device_tool_native, CLUTTER_TYPE_INPUT_DEVICE_TOOL) diff --git a/src/backends/native/meta-input-device-tool-native.h b/src/backends/native/meta-input-device-tool-native.h index 3eff6261c76..fa12358adef 100644 --- a/src/backends/native/meta-input-device-tool-native.h +++ b/src/backends/native/meta-input-device-tool-native.h @@ -20,6 +20,10 @@ #ifndef META_INPUT_DEVICE_NATIVE_TOOL_H #define META_INPUT_DEVICE_NATIVE_TOOL_H +#ifndef META_INPUT_THREAD_H_INSIDE +#error "This header cannot be included directly. Use "backends/native/meta-input-thread.h"" +#endif /* META_INPUT_THREAD_H_INSIDE */ + #include #include "clutter/clutter.h" diff --git a/src/backends/native/meta-input-settings-native.c b/src/backends/native/meta-input-settings-native.c index becf557db5c..3f9f71fe7fc 100644 --- a/src/backends/native/meta-input-settings-native.c +++ b/src/backends/native/meta-input-settings-native.c @@ -27,8 +27,7 @@ #include #include "backends/native/meta-backend-native.h" -#include "backends/native/meta-input-device-native.h" -#include "backends/native/meta-input-device-tool-native.h" +#include "backends/native/meta-input-thread.h" #include "backends/native/meta-input-settings-native.h" G_DEFINE_TYPE (MetaInputSettingsNative, meta_input_settings_native, META_TYPE_INPUT_SETTINGS) diff --git a/src/backends/native/meta-input-settings-native.h b/src/backends/native/meta-input-settings-native.h index 43926fd5fda..cddd5b15f97 100644 --- a/src/backends/native/meta-input-settings-native.h +++ b/src/backends/native/meta-input-settings-native.h @@ -22,6 +22,10 @@ #ifndef META_INPUT_SETTINGS_NATIVE_H #define META_INPUT_SETTINGS_NATIVE_H +#ifndef META_INPUT_THREAD_H_INSIDE +#error "This header cannot be included directly. Use "backends/native/meta-input-thread.h"" +#endif /* META_INPUT_THREAD_H_INSIDE */ + #include "backends/meta-input-settings-private.h" #define META_TYPE_INPUT_SETTINGS_NATIVE (meta_input_settings_native_get_type ()) diff --git a/src/backends/native/meta-input-thread.h b/src/backends/native/meta-input-thread.h new file mode 100644 index 00000000000..196adc27bb6 --- /dev/null +++ b/src/backends/native/meta-input-thread.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Carlos Garnacho + */ + +#ifndef META_INPUT_THREAD_H +#define META_INPUT_THREAD_H + +#define META_INPUT_THREAD_H_INSIDE + +#include "src/backends/native/meta-input-device-native.h" +#include "src/backends/native/meta-input-device-tool-native.h" +#include "src/backends/native/meta-input-settings-native.h" +#include "src/backends/native/meta-keymap-native.h" +#include "src/backends/native/meta-seat-impl.h" + +#undef META_INPUT_THREAD_H_INSIDE + +#endif /* META_INPUT_THREAD_H */ diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c index 036eb6b4d9a..d3348e8a95a 100644 --- a/src/backends/native/meta-keymap-native.c +++ b/src/backends/native/meta-keymap-native.c @@ -22,7 +22,7 @@ #include "config.h" #include "backends/meta-keymap-utils.h" -#include "backends/native/meta-keymap-native.h" +#include "backends/native/meta-input-thread.h" #include "backends/native/meta-seat-native.h" static const char *option_xkb_layout = "us"; diff --git a/src/backends/native/meta-keymap-native.h b/src/backends/native/meta-keymap-native.h index 49da0775d01..6a6b12d9aa3 100644 --- a/src/backends/native/meta-keymap-native.h +++ b/src/backends/native/meta-keymap-native.h @@ -21,6 +21,10 @@ #ifndef META_KEYMAP_NATIVE_H #define META_KEYMAP_NATIVE_H +#ifndef META_INPUT_THREAD_H_INSIDE +#error "This header cannot be included directly. Use "backends/native/meta-input-thread.h"" +#endif /* META_INPUT_THREAD_H_INSIDE */ + #include "backends/native/meta-xkb-utils.h" #include "clutter/clutter.h" diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c index c794563ef3b..190d0fa887d 100644 --- a/src/backends/native/meta-launcher.c +++ b/src/backends/native/meta-launcher.c @@ -39,8 +39,8 @@ #include "backends/native/meta-backend-native.h" #include "backends/native/meta-clutter-backend-native.h" #include "backends/native/meta-cursor-renderer-native.h" +#include "backends/native/meta-input-thread.h" #include "backends/native/meta-renderer-native.h" -#include "backends/native/meta-seat-native.h" #include "clutter/clutter.h" #include "meta-dbus-login1.h" diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 2075ddd34f9..f5e45e5d017 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -27,8 +27,6 @@ #include "config.h" -#include "backends/native/meta-seat-impl.h" - #include #include #include @@ -38,10 +36,7 @@ #include "backends/meta-cursor-tracker-private.h" #include "backends/native/meta-barrier-native.h" #include "backends/native/meta-event-native.h" -#include "backends/native/meta-input-device-native.h" -#include "backends/native/meta-input-device-tool-native.h" -#include "backends/native/meta-input-settings-native.h" -#include "backends/native/meta-keymap-native.h" +#include "backends/native/meta-input-thread.h" #include "backends/native/meta-virtual-input-device-native.h" #include "clutter/clutter-mutter.h" #include "core/bell.h" diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index ac5b7e42d41..ab0ef75d38a 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -23,6 +23,10 @@ #ifndef META_SEAT_IMPL_H #define META_SEAT_IMPL_H +#ifndef META_INPUT_THREAD_H_INSIDE +#error "This header cannot be included directly. Use "backends/native/meta-input-thread.h"" +#endif /* META_INPUT_THREAD_H_INSIDE */ + #include #include #include diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 432b0fc0070..73abb9052dd 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -32,8 +32,7 @@ #include "backends/meta-keymap-utils.h" #include "backends/native/meta-barrier-native.h" #include "backends/native/meta-event-native.h" -#include "backends/native/meta-input-device-native.h" -#include "backends/native/meta-input-device-tool-native.h" +#include "backends/native/meta-input-thread.h" #include "backends/native/meta-keymap-native.h" #include "backends/native/meta-virtual-input-device-native.h" #include "clutter/clutter-mutter.h" diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h index 4f7c30e460c..7f94828d0e0 100644 --- a/src/backends/native/meta-seat-native.h +++ b/src/backends/native/meta-seat-native.h @@ -27,12 +27,12 @@ #include #include +#include "backends/meta-input-settings-private.h" #include "backends/meta-viewport-info.h" +#include "backends/native/meta-backend-native-types.h" #include "backends/native/meta-barrier-native.h" #include "backends/native/meta-cursor-renderer-native.h" -#include "backends/native/meta-keymap-native.h" #include "backends/native/meta-pointer-constraint-native.h" -#include "backends/native/meta-seat-impl.h" #include "backends/native/meta-xkb-utils.h" #include "clutter/clutter.h" diff --git a/src/backends/native/meta-virtual-input-device-native.c b/src/backends/native/meta-virtual-input-device-native.c index 39caa8b092f..9291d3f3d36 100644 --- a/src/backends/native/meta-virtual-input-device-native.c +++ b/src/backends/native/meta-virtual-input-device-native.c @@ -22,8 +22,7 @@ #include #include -#include "backends/native/meta-input-device-native.h" -#include "backends/native/meta-keymap-native.h" +#include "backends/native/meta-input-thread.h" #include "backends/native/meta-seat-native.h" #include "backends/native/meta-virtual-input-device-native.h" #include "clutter/clutter-mutter.h" -- GitLab