forked from AuroraMiddleware/gtk
wayland: Add GdkSeat implementation
GdkWaylandDeviceData conceptually gathers the data that belongs to a seat, so it's been renamed (although the old typedef stays, plenty of refactoring is due here...). The methods in GdkSeatClass have also been implemented, the most remarkable is ::grab, which ensures the grab is performed on all the relevant "master" devices. https://bugzilla.gnome.org/show_bug.cgi?id=759309
This commit is contained in:
parent
f663d17c14
commit
17525ef7a6
@ -1212,6 +1212,7 @@ gdk_window_impl_x11_get_type
|
||||
<INCLUDE>gdk/gdkwayland.h</INCLUDE>
|
||||
<TITLE>Wayland Interaction</TITLE>
|
||||
<FILE>wayland_interaction</FILE>
|
||||
gdk_wayland_seat_get_wl_seat
|
||||
gdk_wayland_device_get_wl_keyboard
|
||||
gdk_wayland_device_get_wl_pointer
|
||||
gdk_wayland_device_get_wl_seat
|
||||
|
@ -45,6 +45,7 @@ libgdk_wayland_la_SOURCES = \
|
||||
gdkglcontext-wayland.c \
|
||||
gdkglcontext-wayland.h \
|
||||
gdkscreen-wayland.c \
|
||||
gdkseat-wayland.h \
|
||||
gdkselection-wayland.c \
|
||||
gdkwindow-wayland.c \
|
||||
gdkwayland.h \
|
||||
|
@ -25,10 +25,12 @@
|
||||
#include <gdk/gdkwindow.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkseat-wayland.h"
|
||||
#include "gdkwayland.h"
|
||||
#include "gdkkeysyms.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevicemanagerprivate.h"
|
||||
#include "gdkseatprivate.h"
|
||||
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
@ -52,8 +54,10 @@ struct _GdkWaylandTouchData
|
||||
guint initial_touch : 1;
|
||||
};
|
||||
|
||||
struct _GdkWaylandDeviceData
|
||||
struct _GdkWaylandSeat
|
||||
{
|
||||
GdkSeat parent_instance;
|
||||
|
||||
guint32 id;
|
||||
struct wl_seat *wl_seat;
|
||||
struct wl_pointer *wl_pointer;
|
||||
@ -114,6 +118,8 @@ struct _GdkWaylandDeviceData
|
||||
gdouble gesture_scale;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandSeat, gdk_wayland_seat, GDK_TYPE_SEAT)
|
||||
|
||||
struct _GdkWaylandDevice
|
||||
{
|
||||
GdkDevice parent_instance;
|
||||
@ -397,6 +403,7 @@ emulate_crossing (GdkWindow *window,
|
||||
event->crossing.detail = GDK_NOTIFY_NONLINEAR;
|
||||
gdk_event_set_device (event, device);
|
||||
gdk_event_set_source_device (event, device);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
||||
|
||||
gdk_window_get_device_position_double (window, device,
|
||||
&event->crossing.x, &event->crossing.y,
|
||||
@ -427,6 +434,7 @@ emulate_touch_crossing (GdkWindow *window,
|
||||
event->crossing.detail = GDK_NOTIFY_NONLINEAR;
|
||||
gdk_event_set_device (event, device);
|
||||
gdk_event_set_source_device (event, source);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
||||
|
||||
event->crossing.x = touch->x;
|
||||
event->crossing.y = touch->y;
|
||||
@ -449,6 +457,7 @@ emulate_focus (GdkWindow *window,
|
||||
event->focus_change.in = focus_in;
|
||||
gdk_event_set_device (event, device);
|
||||
gdk_event_set_source_device (event, device);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
||||
|
||||
_gdk_wayland_display_deliver_event (gdk_window_get_display (window), event);
|
||||
}
|
||||
@ -942,6 +951,7 @@ pointer_handle_enter (void *data,
|
||||
event->crossing.window = g_object_ref (device->pointer_focus);
|
||||
gdk_event_set_device (event, device->master_pointer);
|
||||
gdk_event_set_source_device (event, device->pointer);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
||||
event->crossing.subwindow = NULL;
|
||||
event->crossing.time = (guint32)(g_get_monotonic_time () / 1000);
|
||||
event->crossing.mode = GDK_CROSSING_NORMAL;
|
||||
@ -989,6 +999,7 @@ pointer_handle_leave (void *data,
|
||||
event->crossing.window = g_object_ref (device->pointer_focus);
|
||||
gdk_event_set_device (event, device->master_pointer);
|
||||
gdk_event_set_source_device (event, device->pointer);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
||||
event->crossing.subwindow = NULL;
|
||||
event->crossing.time = (guint32)(g_get_monotonic_time () / 1000);
|
||||
event->crossing.mode = GDK_CROSSING_NORMAL;
|
||||
@ -1041,6 +1052,7 @@ pointer_handle_motion (void *data,
|
||||
event->motion.window = g_object_ref (device->pointer_focus);
|
||||
gdk_event_set_device (event, device->master_pointer);
|
||||
gdk_event_set_source_device (event, device->pointer);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
||||
event->motion.time = time;
|
||||
event->motion.axes = NULL;
|
||||
event->motion.state = device->button_modifiers | device->key_modifiers;
|
||||
@ -1105,6 +1117,7 @@ pointer_handle_button (void *data,
|
||||
event->button.window = g_object_ref (device->pointer_focus);
|
||||
gdk_event_set_device (event, device->master_pointer);
|
||||
gdk_event_set_source_device (event, device->pointer);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
||||
event->button.time = time;
|
||||
event->button.axes = NULL;
|
||||
event->button.state = device->button_modifiers | device->key_modifiers;
|
||||
@ -1168,6 +1181,7 @@ pointer_handle_axis (void *data,
|
||||
event->scroll.window = g_object_ref (device->pointer_focus);
|
||||
gdk_event_set_device (event, device->master_pointer);
|
||||
gdk_event_set_source_device (event, device->pointer);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
||||
event->scroll.time = time;
|
||||
event->scroll.direction = GDK_SCROLL_SMOOTH;
|
||||
event->scroll.delta_x = delta_x;
|
||||
@ -1232,6 +1246,7 @@ keyboard_handle_enter (void *data,
|
||||
event->focus_change.in = TRUE;
|
||||
gdk_event_set_device (event, device->master_keyboard);
|
||||
gdk_event_set_source_device (event, device->keyboard);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("focus in, device %p surface %p",
|
||||
@ -1277,6 +1292,7 @@ keyboard_handle_leave (void *data,
|
||||
event->focus_change.in = FALSE;
|
||||
gdk_event_set_device (event, device->master_keyboard);
|
||||
gdk_event_set_source_device (event, device->keyboard);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device->master_keyboard));
|
||||
|
||||
g_object_unref (device->keyboard_focus);
|
||||
device->keyboard_focus = NULL;
|
||||
@ -1454,6 +1470,7 @@ deliver_key_event (GdkWaylandDeviceData *device,
|
||||
event->key.window = device->keyboard_focus ? g_object_ref (device->keyboard_focus) : NULL;
|
||||
gdk_event_set_device (event, device->master_keyboard);
|
||||
gdk_event_set_source_device (event, device->keyboard);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device->master_keyboard));
|
||||
event->key.time = time_;
|
||||
event->key.state = device->button_modifiers | device->key_modifiers;
|
||||
event->key.group = 0;
|
||||
@ -1617,6 +1634,7 @@ _create_touch_event (GdkWaylandDeviceData *device,
|
||||
event->touch.window = g_object_ref (touch->window);
|
||||
gdk_event_set_device (event, device->touch_master);
|
||||
gdk_event_set_source_device (event, device->touch);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device->touch_master));
|
||||
event->touch.time = time;
|
||||
event->touch.state = device->button_modifiers | device->key_modifiers;
|
||||
gdk_event_set_screen (event, display->screen);
|
||||
@ -1785,6 +1803,7 @@ emit_gesture_swipe_event (GdkWaylandDeviceData *device,
|
||||
event->touchpad_swipe.window = g_object_ref (device->pointer_focus);
|
||||
gdk_event_set_device (event, device->master_pointer);
|
||||
gdk_event_set_source_device (event, device->pointer);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
||||
event->touchpad_swipe.time = _time;
|
||||
event->touchpad_swipe.state = device->button_modifiers | device->key_modifiers;
|
||||
gdk_event_set_screen (event, display->screen);
|
||||
@ -1887,6 +1906,7 @@ emit_gesture_pinch_event (GdkWaylandDeviceData *device,
|
||||
event->touchpad_pinch.window = g_object_ref (device->pointer_focus);
|
||||
gdk_event_set_device (event, device->master_pointer);
|
||||
gdk_event_set_source_device (event, device->pointer);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device->master_pointer));
|
||||
event->touchpad_pinch.time = _time;
|
||||
event->touchpad_pinch.state = device->button_modifiers | device->key_modifiers;
|
||||
gdk_event_set_screen (event, display->screen);
|
||||
@ -2037,6 +2057,7 @@ seat_handle_capabilities (void *data,
|
||||
"has-cursor", TRUE,
|
||||
"display", device->display,
|
||||
"device-manager", device->device_manager,
|
||||
"seat", device,
|
||||
NULL);
|
||||
_gdk_device_set_associated_device (device->pointer, device->master_pointer);
|
||||
GDK_WAYLAND_DEVICE (device->pointer)->device = device;
|
||||
@ -2093,6 +2114,7 @@ seat_handle_capabilities (void *data,
|
||||
"has-cursor", FALSE,
|
||||
"display", device->display,
|
||||
"device-manager", device->device_manager,
|
||||
"seat", device,
|
||||
NULL);
|
||||
_gdk_device_set_associated_device (device->keyboard, device->master_keyboard);
|
||||
GDK_WAYLAND_DEVICE (device->keyboard)->device = device;
|
||||
@ -2130,6 +2152,7 @@ seat_handle_capabilities (void *data,
|
||||
"has-cursor", TRUE,
|
||||
"display", device->display,
|
||||
"device-manager", device->device_manager,
|
||||
"seat", device,
|
||||
NULL);
|
||||
GDK_WAYLAND_DEVICE (device->touch_master)->device = device;
|
||||
_gdk_device_set_associated_device (device->touch_master, device->master_keyboard);
|
||||
@ -2146,6 +2169,7 @@ seat_handle_capabilities (void *data,
|
||||
"has-cursor", FALSE,
|
||||
"display", device->display,
|
||||
"device-manager", device->device_manager,
|
||||
"seat", device,
|
||||
NULL);
|
||||
_gdk_device_set_associated_device (device->touch, device->touch_master);
|
||||
GDK_WAYLAND_DEVICE (device->touch)->device = device;
|
||||
@ -2210,6 +2234,7 @@ init_devices (GdkWaylandDeviceData *device)
|
||||
"has-cursor", TRUE,
|
||||
"display", device->display,
|
||||
"device-manager", device_manager,
|
||||
"seat", device,
|
||||
NULL);
|
||||
GDK_WAYLAND_DEVICE (device->master_pointer)->device = device;
|
||||
|
||||
@ -2226,6 +2251,7 @@ init_devices (GdkWaylandDeviceData *device)
|
||||
"has-cursor", FALSE,
|
||||
"display", device->display,
|
||||
"device-manager", device_manager,
|
||||
"seat", device,
|
||||
NULL);
|
||||
GDK_WAYLAND_DEVICE (device->master_keyboard)->device = device;
|
||||
|
||||
@ -2328,6 +2354,259 @@ create_foreign_dnd_window (GdkDisplay *display)
|
||||
return gdk_window_new (gdk_screen_get_root_window (screen), &attrs, mask);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_seat_finalize (GObject *object)
|
||||
{
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (object);
|
||||
|
||||
seat_handle_capabilities (seat, seat->wl_seat, 0);
|
||||
g_object_unref (seat->keymap);
|
||||
wl_surface_destroy (seat->pointer_surface);
|
||||
/* FIXME: destroy data_device */
|
||||
g_clear_object (&seat->keyboard_settings);
|
||||
g_clear_object (&seat->drop_context);
|
||||
g_hash_table_destroy (seat->touches);
|
||||
gdk_window_destroy (seat->foreign_dnd_window);
|
||||
stop_key_repeat (seat);
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_seat_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static GdkSeatCapabilities
|
||||
gdk_wayland_seat_get_capabilities (GdkSeat *seat)
|
||||
{
|
||||
GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
|
||||
GdkSeatCapabilities caps = 0;
|
||||
|
||||
if (wayland_seat->master_pointer)
|
||||
caps |= GDK_SEAT_CAPABILITY_POINTER;
|
||||
if (wayland_seat->master_keyboard)
|
||||
caps |= GDK_SEAT_CAPABILITY_KEYBOARD;
|
||||
if (wayland_seat->touch_master)
|
||||
caps |= GDK_SEAT_CAPABILITY_TOUCH;
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static GdkGrabStatus
|
||||
gdk_wayland_seat_grab (GdkSeat *seat,
|
||||
GdkWindow *window,
|
||||
GdkSeatCapabilities capabilities,
|
||||
gboolean owner_events,
|
||||
GdkCursor *cursor,
|
||||
const GdkEvent *event,
|
||||
GdkSeatGrabPrepareFunc prepare_func,
|
||||
gpointer prepare_func_data)
|
||||
{
|
||||
GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
|
||||
guint32 evtime = event ? gdk_event_get_time (event) : GDK_CURRENT_TIME;
|
||||
GdkDisplay *display = gdk_seat_get_display (seat);
|
||||
GdkWindow *native;
|
||||
|
||||
native = gdk_window_get_toplevel (window);
|
||||
|
||||
while (native->window_type == GDK_WINDOW_OFFSCREEN)
|
||||
{
|
||||
native = gdk_offscreen_window_get_embedder (native);
|
||||
|
||||
if (native == NULL ||
|
||||
(!_gdk_window_has_impl (native) &&
|
||||
!gdk_window_is_viewable (native)))
|
||||
return GDK_GRAB_NOT_VIEWABLE;
|
||||
|
||||
native = gdk_window_get_toplevel (native);
|
||||
}
|
||||
|
||||
if (native == NULL || GDK_WINDOW_DESTROYED (native))
|
||||
return GDK_GRAB_NOT_VIEWABLE;
|
||||
|
||||
wayland_seat->pointer_grab_window = window;
|
||||
wayland_seat->pointer_grab_time = evtime;
|
||||
_gdk_wayland_window_set_grab_seat (window, seat);
|
||||
|
||||
if (prepare_func)
|
||||
(prepare_func) (seat, window, prepare_func_data);
|
||||
|
||||
if (!gdk_window_is_visible (window))
|
||||
{
|
||||
_gdk_wayland_window_set_grab_seat (window, NULL);
|
||||
g_critical ("Window %p has not been made visible in GdkSeatGrabPrepareFunc",
|
||||
window);
|
||||
return GDK_GRAB_NOT_VIEWABLE;
|
||||
}
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_POINTER)
|
||||
{
|
||||
GdkWindow *prev_focus = gdk_wayland_device_get_focus (wayland_seat->master_pointer);
|
||||
|
||||
if (prev_focus != window)
|
||||
device_emit_grab_crossing (wayland_seat->master_pointer, prev_focus,
|
||||
window, GDK_CROSSING_GRAB, evtime);
|
||||
|
||||
_gdk_display_add_device_grab (display,
|
||||
wayland_seat->master_pointer,
|
||||
window,
|
||||
native,
|
||||
GDK_OWNERSHIP_NONE,
|
||||
owner_events,
|
||||
GDK_ALL_EVENTS_MASK,
|
||||
_gdk_display_get_next_serial (display),
|
||||
evtime,
|
||||
FALSE);
|
||||
|
||||
g_set_object (&wayland_seat->cursor, cursor);
|
||||
gdk_wayland_device_update_window_cursor (wayland_seat);
|
||||
}
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_TOUCH)
|
||||
{
|
||||
GdkWindow *prev_focus = gdk_wayland_device_get_focus (wayland_seat->touch_master);
|
||||
|
||||
if (prev_focus != window)
|
||||
device_emit_grab_crossing (wayland_seat->touch_master, prev_focus,
|
||||
window, GDK_CROSSING_GRAB, evtime);
|
||||
|
||||
_gdk_display_add_device_grab (display,
|
||||
wayland_seat->touch_master,
|
||||
window,
|
||||
native,
|
||||
GDK_OWNERSHIP_NONE,
|
||||
owner_events,
|
||||
GDK_ALL_EVENTS_MASK,
|
||||
_gdk_display_get_next_serial (display),
|
||||
evtime,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_KEYBOARD)
|
||||
{
|
||||
GdkWindow *prev_focus = gdk_wayland_device_get_focus (wayland_seat->master_keyboard);
|
||||
|
||||
if (prev_focus != window)
|
||||
device_emit_grab_crossing (wayland_seat->master_keyboard, prev_focus,
|
||||
window, GDK_CROSSING_GRAB, evtime);
|
||||
|
||||
_gdk_display_add_device_grab (display,
|
||||
wayland_seat->master_keyboard,
|
||||
window,
|
||||
native,
|
||||
GDK_OWNERSHIP_NONE,
|
||||
owner_events,
|
||||
GDK_ALL_EVENTS_MASK,
|
||||
_gdk_display_get_next_serial (display),
|
||||
evtime,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
return GDK_GRAB_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_seat_ungrab (GdkSeat *seat)
|
||||
{
|
||||
GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
|
||||
GdkDisplay *display = gdk_seat_get_display (seat);;
|
||||
GdkDeviceGrabInfo *grab;
|
||||
|
||||
if (wayland_seat->master_pointer)
|
||||
{
|
||||
GdkWindow *focus, *prev_focus = NULL;
|
||||
|
||||
grab = _gdk_display_get_last_device_grab (display, wayland_seat->master_pointer);
|
||||
|
||||
if (grab)
|
||||
{
|
||||
grab->serial_end = grab->serial_start;
|
||||
prev_focus = grab->window;
|
||||
}
|
||||
|
||||
focus = gdk_wayland_device_get_focus (wayland_seat->master_pointer);
|
||||
|
||||
if (focus != prev_focus)
|
||||
device_emit_grab_crossing (wayland_seat->master_pointer, prev_focus,
|
||||
focus, GDK_CROSSING_UNGRAB,
|
||||
GDK_CURRENT_TIME);
|
||||
|
||||
gdk_wayland_device_update_window_cursor (wayland_seat);
|
||||
}
|
||||
|
||||
if (wayland_seat->master_keyboard)
|
||||
{
|
||||
grab = _gdk_display_get_last_device_grab (display, wayland_seat->master_keyboard);
|
||||
|
||||
if (grab)
|
||||
grab->serial_end = grab->serial_start;
|
||||
}
|
||||
|
||||
if (wayland_seat->touch_master)
|
||||
{
|
||||
grab = _gdk_display_get_last_device_grab (display, wayland_seat->touch_master);
|
||||
|
||||
if (grab)
|
||||
grab->serial_end = grab->serial_start;
|
||||
}
|
||||
|
||||
if (wayland_seat->pointer_grab_window)
|
||||
{
|
||||
_gdk_wayland_window_set_grab_seat (wayland_seat->pointer_grab_window,
|
||||
NULL);
|
||||
wayland_seat->pointer_grab_window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
gdk_wayland_seat_get_master (GdkSeat *seat,
|
||||
GdkSeatCapabilities capabilities)
|
||||
{
|
||||
GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
|
||||
|
||||
if (capabilities == GDK_SEAT_CAPABILITY_POINTER)
|
||||
return wayland_seat->master_pointer;
|
||||
else if (capabilities == GDK_SEAT_CAPABILITY_KEYBOARD)
|
||||
return wayland_seat->master_keyboard;
|
||||
else if (capabilities == GDK_SEAT_CAPABILITY_TOUCH)
|
||||
return wayland_seat->touch_master;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GList *
|
||||
gdk_wayland_seat_get_slaves (GdkSeat *seat,
|
||||
GdkSeatCapabilities capabilities)
|
||||
{
|
||||
GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
|
||||
GList *slaves = NULL;
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_POINTER)
|
||||
slaves = g_list_prepend (slaves, wayland_seat->pointer);
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_KEYBOARD)
|
||||
slaves = g_list_prepend (slaves, wayland_seat->keyboard);
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_TOUCH)
|
||||
slaves = g_list_prepend (slaves, wayland_seat->touch);
|
||||
|
||||
return slaves;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_seat_class_init (GdkWaylandSeatClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkSeatClass *seat_class = GDK_SEAT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_wayland_seat_finalize;
|
||||
|
||||
seat_class->get_capabilities = gdk_wayland_seat_get_capabilities;
|
||||
seat_class->grab = gdk_wayland_seat_grab;
|
||||
seat_class->ungrab = gdk_wayland_seat_ungrab;
|
||||
seat_class->get_master = gdk_wayland_seat_get_master;
|
||||
seat_class->get_slaves = gdk_wayland_seat_get_slaves;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_seat_init (GdkWaylandSeat *seat)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_device_manager_add_seat (GdkDeviceManager *device_manager,
|
||||
guint32 id,
|
||||
@ -2335,70 +2614,65 @@ _gdk_wayland_device_manager_add_seat (GdkDeviceManager *device_manager,
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
GdkWaylandDeviceData *device;
|
||||
GdkWaylandSeat *seat;
|
||||
|
||||
display = gdk_device_manager_get_display (device_manager);
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
device = g_new0 (GdkWaylandDeviceData, 1);
|
||||
device->id = id;
|
||||
device->keymap = _gdk_wayland_keymap_new ();
|
||||
device->display = display;
|
||||
device->device_manager = device_manager;
|
||||
device->touches = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
device->foreign_dnd_window = create_foreign_dnd_window (display);
|
||||
device->wl_seat = wl_seat;
|
||||
seat = g_object_new (GDK_TYPE_WAYLAND_SEAT,
|
||||
"display", display,
|
||||
NULL);
|
||||
seat->id = id;
|
||||
seat->keymap = _gdk_wayland_keymap_new ();
|
||||
seat->display = display;
|
||||
seat->device_manager = device_manager;
|
||||
seat->touches = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
seat->foreign_dnd_window = create_foreign_dnd_window (display);
|
||||
seat->wl_seat = wl_seat;
|
||||
|
||||
device->pending_selection = GDK_NONE;
|
||||
seat->pending_selection = GDK_NONE;
|
||||
|
||||
wl_seat_add_listener (device->wl_seat, &seat_listener, device);
|
||||
wl_seat_set_user_data (device->wl_seat, device);
|
||||
wl_seat_add_listener (seat->wl_seat, &seat_listener, seat);
|
||||
wl_seat_set_user_data (seat->wl_seat, seat);
|
||||
|
||||
device->data_device =
|
||||
seat->data_device =
|
||||
wl_data_device_manager_get_data_device (display_wayland->data_device_manager,
|
||||
device->wl_seat);
|
||||
device->drop_context = _gdk_wayland_drop_context_new (device->data_device);
|
||||
wl_data_device_add_listener (device->data_device,
|
||||
&data_device_listener, device);
|
||||
seat->wl_seat);
|
||||
seat->drop_context = _gdk_wayland_drop_context_new (seat->data_device);
|
||||
wl_data_device_add_listener (seat->data_device,
|
||||
&data_device_listener, seat);
|
||||
|
||||
device->current_output_scale = 1;
|
||||
device->pointer_surface =
|
||||
seat->current_output_scale = 1;
|
||||
seat->pointer_surface =
|
||||
wl_compositor_create_surface (display_wayland->compositor);
|
||||
wl_surface_add_listener (device->pointer_surface,
|
||||
wl_surface_add_listener (seat->pointer_surface,
|
||||
&pointer_surface_listener,
|
||||
device);
|
||||
seat);
|
||||
|
||||
init_devices (device);
|
||||
init_devices (seat);
|
||||
|
||||
gdk_display_add_seat (display, GDK_SEAT (seat));
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_device_manager_remove_seat (GdkDeviceManager *manager,
|
||||
guint32 id)
|
||||
{
|
||||
GdkWaylandDeviceManager *device_manager = GDK_WAYLAND_DEVICE_MANAGER (manager);
|
||||
GdkDisplay *display = gdk_device_manager_get_display (manager);
|
||||
GList *l;
|
||||
|
||||
for (l = device_manager->devices; l != NULL; l = l->next)
|
||||
l = gdk_display_list_seats (display);
|
||||
|
||||
while (l)
|
||||
{
|
||||
GdkWaylandDevice *wayland_device = l->data;
|
||||
GdkWaylandDeviceData *device = wayland_device->device;
|
||||
GdkWaylandSeat *seat = l->data;
|
||||
|
||||
if (device->id == id)
|
||||
{
|
||||
seat_handle_capabilities (device, device->wl_seat, 0);
|
||||
g_object_unref (device->keymap);
|
||||
wl_surface_destroy (device->pointer_surface);
|
||||
/* FIXME: destroy data_device */
|
||||
g_clear_object (&device->keyboard_settings);
|
||||
g_clear_object (&device->drop_context);
|
||||
g_hash_table_destroy (device->touches);
|
||||
gdk_window_destroy (device->foreign_dnd_window);
|
||||
stop_key_repeat (device);
|
||||
g_free (device);
|
||||
if (seat->id != id)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
gdk_display_remove_seat (display, GDK_SEAT (seat));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2615,6 +2889,15 @@ gdk_wayland_device_unset_grab (GdkDevice *gdk_device)
|
||||
device->button_modifiers = 0;
|
||||
gdk_event_set_device (event, gdk_device);
|
||||
gdk_event_set_source_device (event, gdk_device);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (gdk_device));
|
||||
|
||||
_gdk_wayland_display_deliver_event (gdk_device_get_display (gdk_device), event);
|
||||
}
|
||||
|
||||
struct wl_seat *
|
||||
gdk_wayland_seat_get_wl_seat (GdkSeat *seat)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_WAYLAND_SEAT (seat), NULL);
|
||||
|
||||
return GDK_WAYLAND_SEAT (seat)->wl_seat;
|
||||
}
|
||||
|
@ -178,8 +178,6 @@ void _gdk_wayland_device_manager_add_seat (GdkDeviceManager *device
|
||||
void _gdk_wayland_device_manager_remove_seat (GdkDeviceManager *device_manager,
|
||||
guint32 id);
|
||||
|
||||
typedef struct _GdkWaylandDeviceData GdkWaylandDeviceData;
|
||||
|
||||
GdkKeymap *_gdk_wayland_device_get_keymap (GdkDevice *device);
|
||||
uint32_t _gdk_wayland_device_get_implicit_grab_serial(GdkWaylandDevice *device,
|
||||
const GdkEvent *event);
|
||||
|
45
gdk/wayland/gdkseat-wayland.h
Normal file
45
gdk/wayland/gdkseat-wayland.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __GDK_WAYLAND_SEAT_H__
|
||||
#define __GDK_WAYLAND_SEAT_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdkseatprivate.h>
|
||||
|
||||
#define GDK_TYPE_WAYLAND_SEAT (gdk_wayland_seat_get_type ())
|
||||
#define GDK_WAYLAND_SEAT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_WAYLAND_SEAT, GdkWaylandSeat))
|
||||
#define GDK_WAYLAND_SEAT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_WAYLAND_SEAT, GdkWaylandSeatClass))
|
||||
#define GDK_IS_WAYLAND_SEAT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_WAYLAND_SEAT))
|
||||
#define GDK_IS_WAYLAND_SEAT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_WAYLAND_SEAT))
|
||||
#define GDK_WAYLAND_SEAT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_WAYLAND_SEAT, GdkWaylandSeatClass))
|
||||
|
||||
typedef struct _GdkWaylandSeat GdkWaylandDeviceData;
|
||||
typedef struct _GdkWaylandSeat GdkWaylandSeat;
|
||||
typedef struct _GdkWaylandSeatClass GdkWaylandSeatClass;
|
||||
|
||||
struct _GdkWaylandSeatClass
|
||||
{
|
||||
GdkSeatClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_wayland_seat_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#endif /* __GDK_WAYLAND_SEAT_H__ */
|
@ -52,6 +52,9 @@ struct wl_pointer *gdk_wayland_device_get_wl_pointer (GdkDevice *device);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
struct wl_keyboard *gdk_wayland_device_get_wl_keyboard (GdkDevice *device);
|
||||
|
||||
GDK_AVAILABLE_IN_3_20
|
||||
struct wl_seat *gdk_wayland_seat_get_wl_seat (GdkSeat *seat);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user