--- /dev/null
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gdkdevice-wayland-private.h"
+#include "gdkprivate-wayland.h"
+#include "gdkcursorprivate.h"
+#include "gdkeventsprivate.h"
+
+#define GDK_SLOT_TO_EVENT_SEQUENCE(s) ((GdkEventSequence *) GUINT_TO_POINTER((s) + 1))
+#define GDK_EVENT_SEQUENCE_TO_SLOT(s) (GPOINTER_TO_UINT(s) - 1)
+
+typedef struct
+{
+ GdkWaylandTouchData *emulating_touch; /* Only used on wd->logical_touch */
+ GdkWaylandPointerData *pointer;
+} GdkWaylandDevicePrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (GdkWaylandDevice, gdk_wayland_device, GDK_TYPE_DEVICE)
+
+static void
+gdk_wayland_device_set_surface_cursor (GdkDevice *device,
+ GdkSurface *surface,
+ GdkCursor *cursor)
+{
+ GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
+ GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
+ GdkWaylandPointerData *pointer =
+ gdk_wayland_device_get_pointer (wayland_device);
+
+ if (device == seat->logical_touch)
+ return;
+
+ if (seat->grab_cursor)
+ cursor = seat->grab_cursor;
+
+ if (pointer->cursor != NULL &&
+ cursor != NULL &&
+ gdk_cursor_equal (cursor, pointer->cursor))
+ return;
+
+ if (cursor == NULL)
+ {
+ if (!pointer->cursor_is_default)
+ {
+ g_clear_object (&pointer->cursor);
+ pointer->cursor = gdk_cursor_new_from_name ("default", NULL);
+ pointer->cursor_is_default = TRUE;
+
+ gdk_wayland_seat_stop_cursor_animation (seat, pointer);
+ gdk_wayland_device_update_surface_cursor (device);
+ }
+ else
+ {
+ /* Nothing to do, we'already using the default cursor */
+ }
+ }
+ else
+ {
+ g_set_object (&pointer->cursor, cursor);
+ pointer->cursor_is_default = FALSE;
+
+ gdk_wayland_seat_stop_cursor_animation (seat, pointer);
+ gdk_wayland_device_update_surface_cursor (device);
+ }
+}
+
+static GdkGrabStatus
+gdk_wayland_device_grab (GdkDevice *device,
+ GdkSurface *surface,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkSurface *confine_to,
+ GdkCursor *cursor,
+ guint32 time_)
+{
+ GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
+ GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
+ GdkWaylandPointerData *pointer =
+ gdk_wayland_device_get_pointer (wayland_device);
+
+ if (GDK_IS_DRAG_SURFACE (surface) &&
+ gdk_surface_get_mapped (surface))
+ {
+ g_warning ("Surface %p is already mapped at the time of grabbing. "
+ "gdk_seat_grab() should be used to simultaneously grab input "
+ "and show this popup. You may find oddities ahead.",
+ surface);
+ }
+
+ gdk_wayland_device_maybe_emit_grab_crossing (device, surface, time_);
+
+ if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+ {
+ /* Device is a keyboard */
+ gdk_wayland_surface_inhibit_shortcuts (surface,
+ gdk_device_get_seat (device));
+ return GDK_GRAB_SUCCESS;
+ }
+ else
+ {
+ /* Device is a pointer */
+ if (pointer->grab_surface != NULL &&
+ time_ != 0 && pointer->grab_time > time_)
+ {
+ return GDK_GRAB_ALREADY_GRABBED;
+ }
+
+ if (time_ == 0)
+ time_ = pointer->time;
+
+ pointer->grab_surface = surface;
+ pointer->grab_time = time_;
+ _gdk_wayland_surface_set_grab_seat (surface, GDK_SEAT (wayland_seat));
+
+ g_clear_object (&wayland_seat->cursor);
+
+ if (cursor)
+ wayland_seat->cursor = g_object_ref (cursor);
+
+ gdk_wayland_device_update_surface_cursor (device);
+ }
+
+ return GDK_GRAB_SUCCESS;
+}
+
+static void
+gdk_wayland_device_ungrab (GdkDevice *device,
+ guint32 time_)
+{
+ GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
+ GdkWaylandPointerData *pointer =
+ gdk_wayland_device_get_pointer (wayland_device);
+ GdkSurface *prev_focus;
+
+ prev_focus = gdk_wayland_device_maybe_emit_ungrab_crossing (device, time_);
+
+ if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+ {
+ /* Device is a keyboard */
+ if (prev_focus)
+ gdk_wayland_surface_restore_shortcuts (prev_focus,
+ gdk_device_get_seat (device));
+ }
+ else
+ {
+ /* Device is a pointer */
+ gdk_wayland_device_update_surface_cursor (device);
+
+ if (pointer->grab_surface)
+ _gdk_wayland_surface_set_grab_seat (pointer->grab_surface,
+ NULL);
+ }
+}
+
+static GdkSurface *
+gdk_wayland_device_surface_at_position (GdkDevice *device,
+ double *win_x,
+ double *win_y,
+ GdkModifierType *mask)
+{
+ GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
+ GdkWaylandPointerData *pointer;
+
+ pointer = gdk_wayland_device_get_pointer (wayland_device);
+
+ if (!pointer)
+ return NULL;
+
+ if (win_x)
+ *win_x = pointer->surface_x;
+ if (win_y)
+ *win_y = pointer->surface_y;
+ if (mask)
+ *mask = gdk_wayland_device_get_modifiers (device);
+
+ return pointer->focus;
+}
+
+static void
+gdk_wayland_device_class_init (GdkWaylandDeviceClass *klass)
+{
+ GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
+
+ device_class->set_surface_cursor = gdk_wayland_device_set_surface_cursor;
+ device_class->grab = gdk_wayland_device_grab;
+ device_class->ungrab = gdk_wayland_device_ungrab;
+ device_class->surface_at_position = gdk_wayland_device_surface_at_position;
+}
+
+static void
+gdk_wayland_device_init (GdkWaylandDevice *device_core)
+{
+ GdkDevice *device;
+
+ device = GDK_DEVICE (device_core);
+
+ _gdk_device_add_axis (device, GDK_AXIS_X, 0, 0, 1);
+ _gdk_device_add_axis (device, GDK_AXIS_Y, 0, 0, 1);
+}
+
+GdkWaylandPointerData *
+gdk_wayland_device_get_pointer (GdkWaylandDevice *wayland_device)
+{
+ GdkWaylandDevicePrivate *priv =
+ gdk_wayland_device_get_instance_private (wayland_device);
+
+ return priv->pointer;
+}
+
+void
+gdk_wayland_device_set_pointer (GdkWaylandDevice *wayland_device,
+ GdkWaylandPointerData *pointer)
+{
+ GdkWaylandDevicePrivate *priv =
+ gdk_wayland_device_get_instance_private (wayland_device);
+
+ priv->pointer = pointer;
+}
+
+GdkWaylandTouchData *
+gdk_wayland_device_get_emulating_touch (GdkWaylandDevice *wayland_device)
+{
+ GdkWaylandDevicePrivate *priv =
+ gdk_wayland_device_get_instance_private (wayland_device);
+
+ return priv->emulating_touch;
+}
+
+void
+gdk_wayland_device_set_emulating_touch (GdkWaylandDevice *wayland_device,
+ GdkWaylandTouchData *touch)
+{
+ GdkWaylandDevicePrivate *priv =
+ gdk_wayland_device_get_instance_private (wayland_device);
+
+ priv->emulating_touch = touch;
+}
+
+gboolean
+gdk_wayland_device_update_surface_cursor (GdkDevice *device)
+{
+ GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
+ GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
+ GdkWaylandPointerData *pointer =
+ gdk_wayland_device_get_pointer (wayland_device);
+ struct wl_buffer *buffer;
+ int x, y, w, h, scale;
+ guint next_image_index, next_image_delay;
+ gboolean retval = G_SOURCE_REMOVE;
+ GdkWaylandTabletData *tablet;
+
+ tablet = gdk_wayland_seat_find_tablet (seat, device);
+
+ if (pointer->cursor)
+ {
+ buffer = _gdk_wayland_cursor_get_buffer (GDK_WAYLAND_DISPLAY (seat->display),
+ pointer->cursor,
+ pointer->current_output_scale,
+ pointer->cursor_image_index,
+ &x, &y, &w, &h, &scale);
+ }
+ else
+ {
+ pointer->cursor_timeout_id = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+ if (tablet)
+ {
+ if (!tablet->current_tool)
+ {
+ pointer->cursor_timeout_id = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+ zwp_tablet_tool_v2_set_cursor (tablet->current_tool->wp_tablet_tool,
+ pointer->enter_serial,
+ pointer->pointer_surface,
+ x, y);
+ }
+ else if (seat->wl_pointer)
+ {
+ wl_pointer_set_cursor (seat->wl_pointer,
+ pointer->enter_serial,
+ pointer->pointer_surface,
+ x, y);
+ }
+ else
+ {
+ pointer->cursor_timeout_id = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+ if (buffer)
+ {
+ wl_surface_attach (pointer->pointer_surface, buffer, 0, 0);
+ wl_surface_set_buffer_scale (pointer->pointer_surface, scale);
+ wl_surface_damage (pointer->pointer_surface, 0, 0, w, h);
+ wl_surface_commit (pointer->pointer_surface);
+ }
+ else
+ {
+ wl_surface_attach (pointer->pointer_surface, NULL, 0, 0);
+ wl_surface_commit (pointer->pointer_surface);
+ }
+
+ next_image_index =
+ _gdk_wayland_cursor_get_next_image_index (GDK_WAYLAND_DISPLAY (seat->display),
+ pointer->cursor,
+ pointer->current_output_scale,
+ pointer->cursor_image_index,
+ &next_image_delay);
+
+ if (next_image_index != pointer->cursor_image_index)
+ {
+ if (next_image_delay != pointer->cursor_image_delay ||
+ pointer->cursor_timeout_id == 0)
+ {
+ guint id;
+ GSource *source;
+
+ gdk_wayland_seat_stop_cursor_animation (seat, pointer);
+
+ /* Queue timeout for next frame */
+ id = g_timeout_add (next_image_delay,
+ (GSourceFunc) gdk_wayland_device_update_surface_cursor,
+ device);
+ source = g_main_context_find_source_by_id (NULL, id);
+ g_source_set_static_name (source, "[gtk] gdk_wayland_device_update_surface_cursor");
+ pointer->cursor_timeout_id = id;
+ }
+ else
+ retval = G_SOURCE_CONTINUE;
+
+ pointer->cursor_image_index = next_image_index;
+ pointer->cursor_image_delay = next_image_delay;
+ }
+ else
+ gdk_wayland_seat_stop_cursor_animation (seat, pointer);
+
+ return retval;
+}
+
+GdkModifierType
+gdk_wayland_device_get_modifiers (GdkDevice *device)
+{
+ GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
+ GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
+ GdkWaylandPointerData *pointer =
+ gdk_wayland_device_get_pointer (wayland_device);
+ GdkModifierType mask;
+
+ mask = seat->key_modifiers;
+
+ if (pointer)
+ mask |= pointer->button_modifiers;
+
+ return mask;
+}
+
+void
+gdk_wayland_device_query_state (GdkDevice *device,
+ GdkSurface *surface,
+ double *win_x,
+ double *win_y,
+ GdkModifierType *mask)
+{
+ GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
+ GdkWaylandPointerData *pointer;
+ double x, y;
+
+ if (mask)
+ *mask = gdk_wayland_device_get_modifiers (device);
+
+ pointer = gdk_wayland_device_get_pointer (wayland_device);
+
+ if (pointer->focus == surface)
+ {
+ x = pointer->surface_x;
+ y = pointer->surface_y;
+ }
+ else
+ {
+ x = y = -1;
+ }
+
+ if (win_x)
+ *win_x = x;
+ if (win_y)
+ *win_y = y;
+}
+
+GdkSurface *
+gdk_wayland_device_get_focus (GdkDevice *device)
+{
+ GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
+ GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
+ GdkWaylandPointerData *pointer;
+
+ if (device == wayland_seat->logical_keyboard)
+ return wayland_seat->keyboard_focus;
+ else
+ {
+ pointer = gdk_wayland_device_get_pointer (wayland_device);
+
+ if (pointer)
+ return pointer->focus;
+ }
+
+ return NULL;
+}
+
+static void
+emulate_touch_crossing (GdkSurface *surface,
+ GdkSurface *child_surface,
+ GdkDevice *device,
+ GdkDevice *source,
+ GdkWaylandTouchData *touch,
+ GdkEventType type,
+ GdkCrossingMode mode,
+ guint32 time_)
+{
+ GdkEvent *event;
+
+ event = gdk_crossing_event_new (type,
+ surface,
+ device,
+ time_,
+ 0,
+ touch->x, touch->y,
+ mode,
+ GDK_NOTIFY_NONLINEAR);
+
+ _gdk_wayland_display_deliver_event (gdk_surface_get_display (surface), event);
+}
+
+void
+gdk_wayland_device_unset_touch_grab (GdkDevice *gdk_device,
+ GdkEventSequence *sequence)
+{
+ GdkWaylandSeat *seat;
+ GdkWaylandTouchData *touch;
+ GdkEvent *event;
+
+ g_return_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device));
+
+ seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (gdk_device));
+ touch = gdk_wayland_seat_get_touch (seat,
+ GDK_EVENT_SEQUENCE_TO_SLOT (sequence));
+
+ if (touch ==
+ gdk_wayland_device_get_emulating_touch (GDK_WAYLAND_DEVICE (seat->logical_touch)))
+ {
+ gdk_wayland_device_set_emulating_touch (GDK_WAYLAND_DEVICE (seat->logical_touch),
+ NULL);
+ emulate_touch_crossing (touch->surface, NULL,
+ seat->logical_touch, seat->touch,
+ touch, GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL,
+ GDK_CURRENT_TIME);
+ }
+
+ event = gdk_touch_event_new (GDK_TOUCH_CANCEL,
+ GDK_SLOT_TO_EVENT_SEQUENCE (touch->id),
+ touch->surface,
+ seat->logical_touch,
+ GDK_CURRENT_TIME,
+ gdk_wayland_device_get_modifiers (seat->logical_touch),
+ touch->x, touch->y,
+ NULL,
+ touch->initial_touch);
+ _gdk_wayland_display_deliver_event (seat->display, event);
+}
+
+/**
+ * gdk_wayland_device_get_wl_seat: (skip)
+ * @device: (type GdkWaylandDevice): a `GdkDevice`
+ *
+ * Returns the Wayland `wl_seat` of a `GdkDevice`.
+ *
+ * Returns: (transfer none): a Wayland `wl_seat`
+ */
+struct wl_seat *
+gdk_wayland_device_get_wl_seat (GdkDevice *device)
+{
+ GdkWaylandSeat *seat;
+
+ g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL);
+
+ seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
+ return seat->wl_seat;
+}
+
+/**
+ * gdk_wayland_device_get_wl_pointer: (skip)
+ * @device: (type GdkWaylandDevice): a `GdkDevice`
+ *
+ * Returns the Wayland `wl_pointer` of a `GdkDevice`.
+ *
+ * Returns: (transfer none): a Wayland `wl_pointer`
+ */
+struct wl_pointer *
+gdk_wayland_device_get_wl_pointer (GdkDevice *device)
+{
+ GdkWaylandSeat *seat;
+
+ g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL);
+
+ seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
+ return seat->wl_pointer;
+}
+
+/**
+ * gdk_wayland_device_get_wl_keyboard: (skip)
+ * @device: (type GdkWaylandDevice): a `GdkDevice`
+ *
+ * Returns the Wayland `wl_keyboard` of a `GdkDevice`.
+ *
+ * Returns: (transfer none): a Wayland `wl_keyboard`
+ */
+struct wl_keyboard *
+gdk_wayland_device_get_wl_keyboard (GdkDevice *device)
+{
+ GdkWaylandSeat *seat;
+
+ g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL);
+
+ seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
+ return seat->wl_keyboard;
+}
+
+/**
+ * gdk_wayland_device_get_xkb_keymap:
+ * @device: (type GdkWaylandDevice): a `GdkDevice`
+ *
+ * Returns the `xkb_keymap` of a `GdkDevice`.
+ *
+ * Returns: (transfer none): a `struct xkb_keymap`
+ *
+ * Since: 4.4
+ */
+struct xkb_keymap *
+gdk_wayland_device_get_xkb_keymap (GdkDevice *device)
+{
+ GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
+ return _gdk_wayland_keymap_get_xkb_keymap (seat->keymap);
+}
+
+GdkKeymap *
+_gdk_wayland_device_get_keymap (GdkDevice *device)
+{
+ GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
+ return seat->keymap;
+}
+
+/**
+ * gdk_wayland_device_get_data_device: (skip)
+ * @gdk_device: (type GdkWaylandDevice): a `GdkDevice`
+ *
+ * Returns the Wayland `wl_data_device` of a `GdkDevice`.
+ *
+ * Returns: (transfer none): a Wayland `wl_data_device`
+ */
+struct wl_data_device *
+gdk_wayland_device_get_data_device (GdkDevice *gdk_device)
+{
+ GdkWaylandSeat *seat;
+
+ g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device), NULL);
+
+ seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (gdk_device));
+ return seat->data_device;
+}
+
+/**
+ * gdk_wayland_device_set_selection: (skip)
+ * @gdk_device: (type GdkWaylandDevice): a `GdkDevice`
+ * @source: the data source for the selection
+ *
+ * Sets the selection of the `GdkDevice.
+ *
+ * This is calling wl_data_device_set_selection() on
+ * the `wl_data_device` of @gdk_device.
+ */
+void
+gdk_wayland_device_set_selection (GdkDevice *gdk_device,
+ struct wl_data_source *source)
+{
+ GdkWaylandSeat *seat;
+ guint32 serial;
+
+ g_return_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device));
+
+ seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (gdk_device));
+ serial = _gdk_wayland_seat_get_last_implicit_grab_serial (seat, NULL);
+ wl_data_device_set_selection (seat->data_device, source, serial);
+}
+
+/**
+ * gdk_wayland_device_get_node_path:
+ * @device: (type GdkWaylandDevice): a `GdkDevice`
+ *
+ * Returns the `/dev/input/event*` path of this device.
+ *
+ * For `GdkDevice`s that possibly coalesce multiple hardware
+ * devices (eg. mouse, keyboard, touch,...), this function
+ * will return %NULL.
+ *
+ * This is most notably implemented for devices of type
+ * %GDK_SOURCE_PEN, %GDK_SOURCE_TABLET_PAD.
+ *
+ * Returns: (nullable) (transfer none): the `/dev/input/event*`
+ * path of this device
+ */
+const char *
+gdk_wayland_device_get_node_path (GdkDevice *device)
+{
+ GdkWaylandTabletData *tablet;
+ GdkWaylandTabletPadData *pad;
+
+ GdkSeat *seat;
+
+ g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
+
+ seat = gdk_device_get_seat (device);
+ tablet = gdk_wayland_seat_find_tablet (GDK_WAYLAND_SEAT (seat), device);
+ if (tablet)
+ return tablet->path;
+
+ pad = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat), device);
+ if (pad)
+ return pad->path;
+
+ return NULL;
+}
+
+static void
+emulate_focus (GdkSurface *surface,
+ GdkDevice *device,
+ gboolean focus_in,
+ guint32 time_)
+{
+ GdkEvent *event = gdk_focus_event_new (surface, device, focus_in);
+
+ _gdk_wayland_display_deliver_event (gdk_surface_get_display (surface), event);
+}
+
+static void
+emulate_crossing (GdkSurface *surface,
+ GdkSurface *child_surface,
+ GdkDevice *device,
+ GdkEventType type,
+ GdkCrossingMode mode,
+ guint32 time_)
+{
+ GdkEvent *event;
+ GdkModifierType state;
+ double x, y;
+
+ gdk_surface_get_device_position (surface, device, &x, &y, &state);
+ event = gdk_crossing_event_new (type,
+ surface,
+ device,
+ time_,
+ state,
+ x, y,
+ mode,
+ GDK_NOTIFY_NONLINEAR);
+
+ _gdk_wayland_display_deliver_event (gdk_surface_get_display (surface), event);
+}
+
+static void
+device_emit_grab_crossing (GdkDevice *device,
+ GdkSurface *from,
+ GdkSurface *to,
+ GdkCrossingMode mode,
+ guint32 time_)
+{
+ if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+ {
+ if (from)
+ emulate_focus (from, device, FALSE, time_);
+ if (to)
+ emulate_focus (to, device, TRUE, time_);
+ }
+ else
+ {
+ if (from)
+ emulate_crossing (from, to, device, GDK_LEAVE_NOTIFY, mode, time_);
+ if (to)
+ emulate_crossing (to, from, device, GDK_ENTER_NOTIFY, mode, time_);
+ }
+}
+
+void
+gdk_wayland_device_maybe_emit_grab_crossing (GdkDevice *device,
+ GdkSurface *window,
+ guint32 time)
+{
+ GdkSurface *surface = gdk_wayland_device_get_focus (device);
+ GdkSurface *focus = window;
+
+ if (focus != surface)
+ device_emit_grab_crossing (device, focus, window, GDK_CROSSING_GRAB, time);
+}
+
+GdkSurface*
+gdk_wayland_device_maybe_emit_ungrab_crossing (GdkDevice *device,
+ guint32 time_)
+{
+ GdkDeviceGrabInfo *grab;
+ GdkSurface *focus = NULL;
+ GdkSurface *surface = NULL;
+ GdkSurface *prev_focus = NULL;
+
+ focus = gdk_wayland_device_get_focus (device);
+ grab = _gdk_display_get_last_device_grab (gdk_device_get_display (device), device);
+
+ if (grab)
+ {
+ prev_focus = grab->surface;
+ surface = grab->surface;
+ }
+
+ if (focus != surface)
+ device_emit_grab_crossing (device, prev_focus, focus, GDK_CROSSING_UNGRAB, time_);
+
+ return prev_focus;
+}
G_DEFINE_TYPE (GdkWaylandSeat, gdk_wayland_seat, GDK_TYPE_SEAT)
-typedef struct
-{
- GdkWaylandTouchData *emulating_touch; /* Only used on wd->logical_touch */
- GdkWaylandPointerData *pointer;
-} GdkWaylandDevicePrivate;
-
-G_DEFINE_TYPE_WITH_PRIVATE (GdkWaylandDevice, gdk_wayland_device, GDK_TYPE_DEVICE)
-
static void init_pointer_data (GdkWaylandPointerData *pointer_data,
GdkDisplay *display_wayland,
GdkDevice *logical_device);
uint32_t state,
gboolean from_key_repeat);
-static void
-gdk_wayland_pointer_stop_cursor_animation (GdkWaylandPointerData *pointer)
+void
+gdk_wayland_seat_stop_cursor_animation (GdkWaylandSeat *seat,
+ GdkWaylandPointerData *pointer)
{
if (pointer->cursor_timeout_id > 0)
{
pointer->cursor_image_index = 0;
}
-static GdkWaylandTabletData *
+GdkWaylandTabletData *
gdk_wayland_seat_find_tablet (GdkWaylandSeat *seat,
GdkDevice *device)
{
return NULL;
}
-static GdkWaylandPointerData *
-gdk_wayland_device_get_pointer (GdkWaylandDevice *wayland_device)
-{
- GdkWaylandDevicePrivate *priv =
- gdk_wayland_device_get_instance_private (wayland_device);
-
- return priv->pointer;
-}
-
-static void
-gdk_wayland_device_set_pointer (GdkWaylandDevice *wayland_device,
- GdkWaylandPointerData *pointer)
-{
- GdkWaylandDevicePrivate *priv =
- gdk_wayland_device_get_instance_private (wayland_device);
-
- priv->pointer = pointer;
-}
-
-static GdkWaylandTouchData *
-gdk_wayland_device_get_emulating_touch (GdkWaylandDevice *wayland_device)
-{
- GdkWaylandDevicePrivate *priv =
- gdk_wayland_device_get_instance_private (wayland_device);
-
- return priv->emulating_touch;
-}
-
-static void
-gdk_wayland_device_set_emulating_touch (GdkWaylandDevice *wayland_device,
- GdkWaylandTouchData *touch)
-{
- GdkWaylandDevicePrivate *priv =
- gdk_wayland_device_get_instance_private (wayland_device);
-
- priv->emulating_touch = touch;
-}
-
-static gboolean
-gdk_wayland_device_update_surface_cursor (GdkDevice *device)
-{
- GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
- GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
- GdkWaylandPointerData *pointer =
- gdk_wayland_device_get_pointer (wayland_device);
- struct wl_buffer *buffer;
- int x, y, w, h, scale;
- guint next_image_index, next_image_delay;
- gboolean retval = G_SOURCE_REMOVE;
- GdkWaylandTabletData *tablet;
-
- tablet = gdk_wayland_seat_find_tablet (seat, device);
-
- if (pointer->cursor)
- {
- buffer = _gdk_wayland_cursor_get_buffer (GDK_WAYLAND_DISPLAY (seat->display),
- pointer->cursor,
- pointer->current_output_scale,
- pointer->cursor_image_index,
- &x, &y, &w, &h, &scale);
- }
- else
- {
- pointer->cursor_timeout_id = 0;
- return G_SOURCE_REMOVE;
- }
-
- if (tablet)
- {
- if (!tablet->current_tool)
- {
- pointer->cursor_timeout_id = 0;
- return G_SOURCE_REMOVE;
- }
-
- zwp_tablet_tool_v2_set_cursor (tablet->current_tool->wp_tablet_tool,
- pointer->enter_serial,
- pointer->pointer_surface,
- x, y);
- }
- else if (seat->wl_pointer)
- {
- wl_pointer_set_cursor (seat->wl_pointer,
- pointer->enter_serial,
- pointer->pointer_surface,
- x, y);
- }
- else
- {
- pointer->cursor_timeout_id = 0;
- return G_SOURCE_REMOVE;
- }
-
- if (buffer)
- {
- wl_surface_attach (pointer->pointer_surface, buffer, 0, 0);
- wl_surface_set_buffer_scale (pointer->pointer_surface, scale);
- wl_surface_damage (pointer->pointer_surface, 0, 0, w, h);
- wl_surface_commit (pointer->pointer_surface);
- }
- else
- {
- wl_surface_attach (pointer->pointer_surface, NULL, 0, 0);
- wl_surface_commit (pointer->pointer_surface);
- }
-
- next_image_index =
- _gdk_wayland_cursor_get_next_image_index (GDK_WAYLAND_DISPLAY (seat->display),
- pointer->cursor,
- pointer->current_output_scale,
- pointer->cursor_image_index,
- &next_image_delay);
-
- if (next_image_index != pointer->cursor_image_index)
- {
- if (next_image_delay != pointer->cursor_image_delay ||
- pointer->cursor_timeout_id == 0)
- {
- guint id;
- GSource *source;
-
- gdk_wayland_pointer_stop_cursor_animation (pointer);
-
- /* Queue timeout for next frame */
- id = g_timeout_add (next_image_delay,
- (GSourceFunc) gdk_wayland_device_update_surface_cursor,
- device);
- source = g_main_context_find_source_by_id (NULL, id);
- g_source_set_static_name (source, "[gtk] gdk_wayland_device_update_surface_cursor");
- pointer->cursor_timeout_id = id;
- }
- else
- retval = G_SOURCE_CONTINUE;
-
- pointer->cursor_image_index = next_image_index;
- pointer->cursor_image_delay = next_image_delay;
- }
- else
- gdk_wayland_pointer_stop_cursor_animation (pointer);
-
- return retval;
-}
-
-static void
-gdk_wayland_device_set_surface_cursor (GdkDevice *device,
- GdkSurface *surface,
- GdkCursor *cursor)
-{
- GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
- GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
- GdkWaylandPointerData *pointer =
- gdk_wayland_device_get_pointer (wayland_device);
-
- if (device == seat->logical_touch)
- return;
-
- if (seat->grab_cursor)
- cursor = seat->grab_cursor;
-
- if (pointer->cursor != NULL &&
- cursor != NULL &&
- gdk_cursor_equal (cursor, pointer->cursor))
- return;
-
- if (cursor == NULL)
- {
- if (!pointer->cursor_is_default)
- {
- g_clear_object (&pointer->cursor);
- pointer->cursor = gdk_cursor_new_from_name ("default", NULL);
- pointer->cursor_is_default = TRUE;
-
- gdk_wayland_pointer_stop_cursor_animation (pointer);
- gdk_wayland_device_update_surface_cursor (device);
- }
- else
- {
- /* Nothing to do, we'already using the default cursor */
- }
- }
- else
- {
- g_set_object (&pointer->cursor, cursor);
- pointer->cursor_is_default = FALSE;
-
- gdk_wayland_pointer_stop_cursor_animation (pointer);
- gdk_wayland_device_update_surface_cursor (device);
- }
-}
-
-static GdkModifierType
-device_get_modifiers (GdkDevice *device)
-{
- GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
- GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
- GdkWaylandPointerData *pointer =
- gdk_wayland_device_get_pointer (wayland_device);
- GdkModifierType mask;
-
- mask = seat->key_modifiers;
-
- if (pointer)
- mask |= pointer->button_modifiers;
-
- return mask;
-}
-
-void
-gdk_wayland_device_query_state (GdkDevice *device,
- GdkSurface *surface,
- double *win_x,
- double *win_y,
- GdkModifierType *mask)
-{
- GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
- GdkWaylandPointerData *pointer;
- double x, y;
-
- if (mask)
- *mask = device_get_modifiers (device);
-
- pointer = gdk_wayland_device_get_pointer (wayland_device);
-
- if (pointer->focus == surface)
- {
- x = pointer->surface_x;
- y = pointer->surface_y;
- }
- else
- {
- x = y = -1;
- }
-
- if (win_x)
- *win_x = x;
- if (win_y)
- *win_y = y;
-}
-
static void
emulate_crossing (GdkSurface *surface,
GdkSurface *child_surface,
_gdk_wayland_display_deliver_event (gdk_surface_get_display (surface), event);
}
-static void
-emulate_focus (GdkSurface *surface,
- GdkDevice *device,
- gboolean focus_in,
- guint32 time_)
-{
- GdkEvent *event = gdk_focus_event_new (surface, device, focus_in);
-
- _gdk_wayland_display_deliver_event (gdk_surface_get_display (surface), event);
-}
-
-static void
-device_emit_grab_crossing (GdkDevice *device,
- GdkSurface *from,
- GdkSurface *to,
- GdkCrossingMode mode,
- guint32 time_)
-{
- if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
- {
- if (from)
- emulate_focus (from, device, FALSE, time_);
- if (to)
- emulate_focus (to, device, TRUE, time_);
- }
- else
- {
- if (from)
- emulate_crossing (from, to, device, GDK_LEAVE_NOTIFY, mode, time_);
- if (to)
- emulate_crossing (to, from, device, GDK_ENTER_NOTIFY, mode, time_);
- }
-}
-
-GdkSurface *
-gdk_wayland_device_get_focus (GdkDevice *device)
-{
- GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
- GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
- GdkWaylandPointerData *pointer;
-
- if (device == wayland_seat->logical_keyboard)
- return wayland_seat->keyboard_focus;
- else
- {
- pointer = gdk_wayland_device_get_pointer (wayland_device);
-
- if (pointer)
- return pointer->focus;
- }
-
- return NULL;
-}
-
-static void
-device_maybe_emit_grab_crossing (GdkDevice *device,
- GdkSurface *window,
- guint32 time)
-{
- GdkSurface *surface = gdk_wayland_device_get_focus (device);
- GdkSurface *focus = window;
-
- if (focus != surface)
- device_emit_grab_crossing (device, focus, window, GDK_CROSSING_GRAB, time);
-}
-
-static GdkSurface*
-device_maybe_emit_ungrab_crossing (GdkDevice *device,
- guint32 time_)
-{
- GdkDeviceGrabInfo *grab;
- GdkSurface *focus = NULL;
- GdkSurface *surface = NULL;
- GdkSurface *prev_focus = NULL;
-
- focus = gdk_wayland_device_get_focus (device);
- grab = _gdk_display_get_last_device_grab (gdk_device_get_display (device), device);
-
- if (grab)
- {
- prev_focus = grab->surface;
- surface = grab->surface;
- }
-
- if (focus != surface)
- device_emit_grab_crossing (device, prev_focus, focus, GDK_CROSSING_UNGRAB, time_);
-
- return prev_focus;
-}
-
-static GdkGrabStatus
-gdk_wayland_device_grab (GdkDevice *device,
- GdkSurface *surface,
- gboolean owner_events,
- GdkEventMask event_mask,
- GdkSurface *confine_to,
- GdkCursor *cursor,
- guint32 time_)
-{
- GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
- GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
- GdkWaylandPointerData *pointer =
- gdk_wayland_device_get_pointer (wayland_device);
-
- if (GDK_IS_DRAG_SURFACE (surface) &&
- gdk_surface_get_mapped (surface))
- {
- g_warning ("Surface %p is already mapped at the time of grabbing. "
- "gdk_seat_grab() should be used to simultaneously grab input "
- "and show this popup. You may find oddities ahead.",
- surface);
- }
-
- device_maybe_emit_grab_crossing (device, surface, time_);
-
- if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
- {
- /* Device is a keyboard */
- gdk_wayland_surface_inhibit_shortcuts (surface,
- gdk_device_get_seat (device));
- return GDK_GRAB_SUCCESS;
- }
- else
- {
- /* Device is a pointer */
- if (pointer->grab_surface != NULL &&
- time_ != 0 && pointer->grab_time > time_)
- {
- return GDK_GRAB_ALREADY_GRABBED;
- }
-
- if (time_ == 0)
- time_ = pointer->time;
-
- pointer->grab_surface = surface;
- pointer->grab_time = time_;
- _gdk_wayland_surface_set_grab_seat (surface, GDK_SEAT (wayland_seat));
-
- g_clear_object (&wayland_seat->cursor);
-
- if (cursor)
- wayland_seat->cursor = g_object_ref (cursor);
-
- gdk_wayland_device_update_surface_cursor (device);
- }
-
- return GDK_GRAB_SUCCESS;
-}
-
-static void
-gdk_wayland_device_ungrab (GdkDevice *device,
- guint32 time_)
-{
- GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
- GdkWaylandPointerData *pointer =
- gdk_wayland_device_get_pointer (wayland_device);
- GdkSurface *prev_focus;
-
- prev_focus = device_maybe_emit_ungrab_crossing (device, time_);
-
- if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
- {
- /* Device is a keyboard */
- if (prev_focus)
- gdk_wayland_surface_restore_shortcuts (prev_focus,
- gdk_device_get_seat (device));
- }
- else
- {
- /* Device is a pointer */
- gdk_wayland_device_update_surface_cursor (device);
-
- if (pointer->grab_surface)
- _gdk_wayland_surface_set_grab_seat (pointer->grab_surface,
- NULL);
- }
-}
-
-static GdkSurface *
-gdk_wayland_device_surface_at_position (GdkDevice *device,
- double *win_x,
- double *win_y,
- GdkModifierType *mask)
-{
- GdkWaylandDevice *wayland_device = GDK_WAYLAND_DEVICE (device);
- GdkWaylandPointerData *pointer;
-
- pointer = gdk_wayland_device_get_pointer (wayland_device);
-
- if (!pointer)
- return NULL;
-
- if (win_x)
- *win_x = pointer->surface_x;
- if (win_y)
- *win_y = pointer->surface_y;
- if (mask)
- *mask = device_get_modifiers (device);
-
- return pointer->focus;
-}
-
-static void
-gdk_wayland_device_class_init (GdkWaylandDeviceClass *klass)
-{
- GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
-
- device_class->set_surface_cursor = gdk_wayland_device_set_surface_cursor;
- device_class->grab = gdk_wayland_device_grab;
- device_class->ungrab = gdk_wayland_device_ungrab;
- device_class->surface_at_position = gdk_wayland_device_surface_at_position;
-}
-
-static void
-gdk_wayland_device_init (GdkWaylandDevice *device_core)
-{
- GdkDevice *device;
-
- device = GDK_DEVICE (device_core);
-
- _gdk_device_add_axis (device, GDK_AXIS_X, 0, 0, 1);
- _gdk_device_add_axis (device, GDK_AXIS_Y, 0, 0, 1);
-}
-
-/**
- * gdk_wayland_device_get_wl_seat: (skip)
- * @device: (type GdkWaylandDevice): a `GdkDevice`
- *
- * Returns the Wayland `wl_seat` of a `GdkDevice`.
- *
- * Returns: (transfer none): a Wayland `wl_seat`
- */
-struct wl_seat *
-gdk_wayland_device_get_wl_seat (GdkDevice *device)
-{
- GdkWaylandSeat *seat;
-
- g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL);
-
- seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
- return seat->wl_seat;
-}
-
-/**
- * gdk_wayland_device_get_wl_pointer: (skip)
- * @device: (type GdkWaylandDevice): a `GdkDevice`
- *
- * Returns the Wayland `wl_pointer` of a `GdkDevice`.
- *
- * Returns: (transfer none): a Wayland `wl_pointer`
- */
-struct wl_pointer *
-gdk_wayland_device_get_wl_pointer (GdkDevice *device)
-{
- GdkWaylandSeat *seat;
-
- g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL);
-
- seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
- return seat->wl_pointer;
-}
-
-/**
- * gdk_wayland_device_get_wl_keyboard: (skip)
- * @device: (type GdkWaylandDevice): a `GdkDevice`
- *
- * Returns the Wayland `wl_keyboard` of a `GdkDevice`.
- *
- * Returns: (transfer none): a Wayland `wl_keyboard`
- */
-struct wl_keyboard *
-gdk_wayland_device_get_wl_keyboard (GdkDevice *device)
-{
- GdkWaylandSeat *seat;
-
- g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (device), NULL);
-
- seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
- return seat->wl_keyboard;
-}
-
-/**
- * gdk_wayland_device_get_xkb_keymap:
- * @device: (type GdkWaylandDevice): a `GdkDevice`
- *
- * Returns the `xkb_keymap` of a `GdkDevice`.
- *
- * Returns: (transfer none): a `struct xkb_keymap`
- *
- * Since: 4.4
- */
-struct xkb_keymap *
-gdk_wayland_device_get_xkb_keymap (GdkDevice *device)
-{
- GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
- return _gdk_wayland_keymap_get_xkb_keymap (seat->keymap);
-}
-
-GdkKeymap *
-_gdk_wayland_device_get_keymap (GdkDevice *device)
-{
- GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
- return seat->keymap;
-}
-
static void
gdk_wayland_seat_discard_pending_offer (GdkWaylandSeat *seat)
{
source,
NULL,
seat->pointer_info.time,
- device_get_modifiers (seat->logical_pointer),
+ gdk_wayland_device_get_modifiers (seat->logical_pointer),
direction,
value120_x,
value120_y);
source,
NULL,
seat->pointer_info.time,
- device_get_modifiers (seat->logical_pointer),
+ gdk_wayland_device_get_modifiers (seat->logical_pointer),
direction);
}
}
source,
NULL,
seat->pointer_info.time,
- device_get_modifiers (seat->logical_pointer),
+ gdk_wayland_device_get_modifiers (seat->logical_pointer),
delta_x, delta_y,
is_stop,
GDK_SCROLL_UNIT_SURFACE);
g_object_unref (seat->pointer_info.focus);
seat->pointer_info.focus = NULL;
if (seat->cursor)
- gdk_wayland_pointer_stop_cursor_animation (&seat->pointer_info);
+ gdk_wayland_seat_stop_cursor_animation (seat, &seat->pointer_info);
if (display_wayland->seat_version < WL_POINTER_HAS_FRAME)
gdk_wayland_seat_flush_frame_event (seat);
seat->logical_pointer,
NULL,
time,
- device_get_modifiers (seat->logical_pointer),
+ gdk_wayland_device_get_modifiers (seat->logical_pointer),
seat->pointer_info.surface_x,
seat->pointer_info.surface_y,
NULL);
seat->logical_pointer,
NULL,
time,
- device_get_modifiers (seat->logical_pointer),
+ gdk_wayland_device_get_modifiers (seat->logical_pointer),
gdk_button,
seat->pointer_info.surface_x,
seat->pointer_info.surface_y,
seat->logical_keyboard,
time_,
key,
- device_get_modifiers (seat->logical_pointer),
+ gdk_wayland_device_get_modifiers (seat->logical_pointer),
_gdk_wayland_keymap_key_is_modifier (keymap, key),
&translated,
&no_lock,
return touch;
}
-static GdkWaylandTouchData *
+GdkWaylandTouchData *
gdk_wayland_seat_get_touch (GdkWaylandSeat *seat,
uint32_t id)
{
touch->surface,
seat->logical_touch,
time,
- device_get_modifiers (seat->logical_touch),
+ gdk_wayland_device_get_modifiers (seat->logical_touch),
touch->x, touch->y,
NULL,
touch->initial_touch);
touch->surface,
seat->logical_touch,
time,
- device_get_modifiers (seat->logical_touch),
+ gdk_wayland_device_get_modifiers (seat->logical_touch),
touch->x, touch->y,
NULL,
touch->initial_touch);
touch->surface,
seat->logical_touch,
time,
- device_get_modifiers (seat->logical_touch),
+ gdk_wayland_device_get_modifiers (seat->logical_touch),
touch->x, touch->y,
NULL,
touch->initial_touch);
touch->surface,
seat->logical_touch,
GDK_CURRENT_TIME,
- device_get_modifiers (seat->logical_touch),
+ gdk_wayland_device_get_modifiers (seat->logical_touch),
touch->x, touch->y,
NULL,
touch->initial_touch);
GDK_SLOT_TO_EVENT_SEQUENCE (seat->pointer_info.touchpad_event_sequence),
seat->logical_pointer,
_time,
- device_get_modifiers (seat->logical_pointer),
+ gdk_wayland_device_get_modifiers (seat->logical_pointer),
phase,
seat->pointer_info.surface_x,
seat->pointer_info.surface_y,
GDK_SLOT_TO_EVENT_SEQUENCE (seat->pointer_info.touchpad_event_sequence),
seat->logical_pointer,
_time,
- device_get_modifiers (seat->logical_pointer),
+ gdk_wayland_device_get_modifiers (seat->logical_pointer),
phase,
seat->pointer_info.surface_x,
seat->pointer_info.surface_y,
GDK_SLOT_TO_EVENT_SEQUENCE (seat->pointer_info.touchpad_event_sequence),
seat->logical_pointer,
_time,
- device_get_modifiers (seat->logical_pointer),
+ gdk_wayland_device_get_modifiers (seat->logical_pointer),
phase,
seat->pointer_info.surface_x,
seat->pointer_info.surface_y,
tablet->pointer_info.time);
gdk_wayland_tablet_set_frame_event (tablet, event);
- gdk_wayland_pointer_stop_cursor_animation (&tablet->pointer_info);
+ gdk_wayland_seat_stop_cursor_animation (GDK_WAYLAND_SEAT (tool->seat),
+ &tablet->pointer_info);
tablet->pointer_info.pointer_surface_outputs =
g_slist_remove (tablet->pointer_info.pointer_surface_outputs,
tablet->logical_device,
tablet->current_tool->tool,
tablet->pointer_info.time,
- device_get_modifiers (tablet->logical_device),
+ gdk_wayland_device_get_modifiers (tablet->logical_device),
button,
tablet->pointer_info.surface_x,
tablet->pointer_info.surface_y,
tablet->logical_device,
tool->tool,
tablet->pointer_info.time,
- device_get_modifiers (tablet->logical_device),
+ gdk_wayland_device_get_modifiers (tablet->logical_device),
tablet->pointer_info.surface_x,
tablet->pointer_info.surface_y,
tablet_copy_axes (tablet));
tablet->logical_device,
tablet->current_tool->tool,
tablet->pointer_info.time,
- device_get_modifiers (tablet->logical_device),
+ gdk_wayland_device_get_modifiers (tablet->logical_device),
0, clicks,
FALSE,
GDK_SCROLL_UNIT_WHEEL);
if (wayland_seat->logical_pointer &&
capabilities & GDK_SEAT_CAPABILITY_POINTER)
{
- device_maybe_emit_grab_crossing (wayland_seat->logical_pointer,
- surface, evtime);
+ gdk_wayland_device_maybe_emit_grab_crossing (wayland_seat->logical_pointer,
+ surface, evtime);
_gdk_display_add_device_grab (display,
wayland_seat->logical_pointer,
if (wayland_seat->logical_touch &&
capabilities & GDK_SEAT_CAPABILITY_TOUCH)
{
- device_maybe_emit_grab_crossing (wayland_seat->logical_touch,
- surface, evtime);
+ gdk_wayland_device_maybe_emit_grab_crossing (wayland_seat->logical_touch,
+ surface, evtime);
_gdk_display_add_device_grab (display,
wayland_seat->logical_touch,
if (wayland_seat->logical_keyboard &&
capabilities & GDK_SEAT_CAPABILITY_KEYBOARD)
{
- device_maybe_emit_grab_crossing (wayland_seat->logical_keyboard,
- surface, evtime);
+ gdk_wayland_device_maybe_emit_grab_crossing (wayland_seat->logical_keyboard,
+ surface, evtime);
_gdk_display_add_device_grab (display,
wayland_seat->logical_keyboard,
{
GdkWaylandTabletData *tablet = l->data;
- device_maybe_emit_grab_crossing (tablet->logical_device,
- surface,
- evtime);
+ gdk_wayland_device_maybe_emit_grab_crossing (tablet->logical_device,
+ surface,
+ evtime);
_gdk_display_add_device_grab (display,
tablet->logical_device,
if (wayland_seat->logical_pointer)
{
- device_maybe_emit_ungrab_crossing (wayland_seat->logical_pointer,
- GDK_CURRENT_TIME);
+ gdk_wayland_device_maybe_emit_ungrab_crossing (wayland_seat->logical_pointer,
+ GDK_CURRENT_TIME);
gdk_wayland_device_update_surface_cursor (wayland_seat->logical_pointer);
}
{
GdkSurface *prev_focus;
- prev_focus = device_maybe_emit_ungrab_crossing (wayland_seat->logical_keyboard,
- GDK_CURRENT_TIME);
+ prev_focus = gdk_wayland_device_maybe_emit_ungrab_crossing (wayland_seat->logical_keyboard,
+ GDK_CURRENT_TIME);
if (prev_focus)
gdk_wayland_surface_restore_shortcuts (prev_focus, seat);
}
return serial;
}
-void
-gdk_wayland_device_unset_touch_grab (GdkDevice *gdk_device,
- GdkEventSequence *sequence)
-{
- GdkWaylandSeat *seat;
- GdkWaylandTouchData *touch;
- GdkEvent *event;
-
- g_return_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device));
-
- seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (gdk_device));
- touch = gdk_wayland_seat_get_touch (seat,
- GDK_EVENT_SEQUENCE_TO_SLOT (sequence));
-
- if (touch ==
- gdk_wayland_device_get_emulating_touch (GDK_WAYLAND_DEVICE (seat->logical_touch)))
- {
- gdk_wayland_device_set_emulating_touch (GDK_WAYLAND_DEVICE (seat->logical_touch),
- NULL);
- emulate_touch_crossing (touch->surface, NULL,
- seat->logical_touch, seat->touch,
- touch, GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL,
- GDK_CURRENT_TIME);
- }
-
- event = gdk_touch_event_new (GDK_TOUCH_CANCEL,
- GDK_SLOT_TO_EVENT_SEQUENCE (touch->id),
- touch->surface,
- seat->logical_touch,
- GDK_CURRENT_TIME,
- device_get_modifiers (seat->logical_touch),
- touch->x, touch->y,
- NULL,
- touch->initial_touch);
- _gdk_wayland_display_deliver_event (seat->display, event);
-}
-
void
gdk_wayland_seat_set_global_cursor (GdkSeat *seat,
GdkCursor *cursor)
pointer = gdk_seat_get_pointer (seat);
g_set_object (&wayland_seat->grab_cursor, cursor);
- gdk_wayland_device_set_surface_cursor (pointer,
- gdk_wayland_device_get_focus (pointer),
- NULL);
+ GDK_DEVICE_GET_CLASS (pointer)->set_surface_cursor (pointer,
+ gdk_wayland_device_get_focus (pointer),
+ NULL);
}
void
g_set_object (&wayland_seat->drag, drag);
}
-/**
- * gdk_wayland_device_get_data_device: (skip)
- * @gdk_device: (type GdkWaylandDevice): a `GdkDevice`
- *
- * Returns the Wayland `wl_data_device` of a `GdkDevice`.
- *
- * Returns: (transfer none): a Wayland `wl_data_device`
- */
-struct wl_data_device *
-gdk_wayland_device_get_data_device (GdkDevice *gdk_device)
-{
- GdkWaylandSeat *seat;
-
- g_return_val_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device), NULL);
-
- seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (gdk_device));
- return seat->data_device;
-}
-
-/**
- * gdk_wayland_device_set_selection: (skip)
- * @gdk_device: (type GdkWaylandDevice): a `GdkDevice`
- * @source: the data source for the selection
- *
- * Sets the selection of the `GdkDevice.
- *
- * This is calling wl_data_device_set_selection() on
- * the `wl_data_device` of @gdk_device.
- */
-void
-gdk_wayland_device_set_selection (GdkDevice *gdk_device,
- struct wl_data_source *source)
-{
- GdkWaylandSeat *seat;
- guint32 serial;
-
- g_return_if_fail (GDK_IS_WAYLAND_DEVICE (gdk_device));
-
- seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (gdk_device));
- serial = _gdk_wayland_seat_get_last_implicit_grab_serial (seat, NULL);
- wl_data_device_set_selection (seat->data_device, source, serial);
-}
-
/**
* gdk_wayland_seat_get_wl_seat: (skip)
* @seat: (type GdkWaylandSeat): a `GdkSeat`
return GDK_WAYLAND_SEAT (seat)->wl_seat;
}
-
-/**
- * gdk_wayland_device_get_node_path:
- * @device: (type GdkWaylandDevice): a `GdkDevice`
- *
- * Returns the `/dev/input/event*` path of this device.
- *
- * For `GdkDevice`s that possibly coalesce multiple hardware
- * devices (eg. mouse, keyboard, touch,...), this function
- * will return %NULL.
- *
- * This is most notably implemented for devices of type
- * %GDK_SOURCE_PEN, %GDK_SOURCE_TABLET_PAD.
- *
- * Returns: (nullable) (transfer none): the `/dev/input/event*`
- * path of this device
- */
-const char *
-gdk_wayland_device_get_node_path (GdkDevice *device)
-{
- GdkWaylandTabletData *tablet;
- GdkWaylandTabletPadData *pad;
-
- GdkSeat *seat;
-
- g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
-
- seat = gdk_device_get_seat (device);
- tablet = gdk_wayland_seat_find_tablet (GDK_WAYLAND_SEAT (seat), device);
- if (tablet)
- return tablet->path;
-
- pad = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat), device);
- if (pad)
- return pad->path;
-
- return NULL;
-}