wayland: Port to new input protocol mechanism

This replaces the wl_input_device with wl_pointer, wl_keyboard, wl_touch all
tied together under a wl_seat.

This is quite a radical change in protocol and for now keyboard handling is
disabled.
This commit is contained in:
Rob Bradford 2012-07-11 14:29:43 +01:00
parent b1a5b19b4a
commit 3eb0b195ed
4 changed files with 375 additions and 59 deletions

View File

@ -54,15 +54,21 @@ typedef struct _GdkWaylandSelectionOffer GdkWaylandSelectionOffer;
struct _GdkWaylandDevice
{
struct wl_seat *wl_seat;
struct wl_pointer *wl_pointer;
struct wl_keyboard *wl_keyboard;
GdkDisplay *display;
GdkDeviceManager *device_manager;
GdkDevice *pointer;
GdkDevice *keyboard;
GdkModifierType modifiers;
GdkWindow *pointer_focus;
GdkWindow *keyboard_focus;
struct wl_input_device *device;
struct wl_data_device *data_device;
int32_t x, y, surface_x, surface_y;
double surface_x, surface_y;
uint32_t time;
GdkWindow *pointer_grab_window;
uint32_t pointer_grab_time;
@ -198,10 +204,13 @@ gdk_device_core_query_state (GdkDevice *device,
*root_window = gdk_screen_get_root_window (default_screen);
if (child_window)
*child_window = wd->pointer_focus;
/* Do something clever for relative here */
#if 0
if (root_x)
*root_x = wd->x;
if (root_y)
*root_y = wd->y;
#endif
if (win_x)
*win_x = wd->surface_x;
if (win_y)
@ -248,7 +257,7 @@ gdk_device_core_grab (GdkDevice *device,
* compositor.
*/
_gdk_wayland_window_set_device_grabbed (window,
wayland_device->device,
wayland_device->wl_seat,
time_);
}
@ -338,12 +347,26 @@ gdk_device_core_init (GdkDeviceCore *device_core)
_gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
}
struct wl_input_device *
_gdk_wayland_device_get_device (GdkDevice *device)
struct wl_seat *
_gdk_wayland_device_get_wl_seat (GdkDevice *device)
{
return GDK_DEVICE_CORE (device)->device->device;
return GDK_DEVICE_CORE (device)->device->wl_seat;
}
struct wl_pointer *
_gdk_wayland_device_get_wl_pointer (GdkDevice *device)
{
return GDK_DEVICE_CORE (device)->device->wl_pointer;
}
struct wl_keyboard *
_gdk_wayland_device_get_wl_keyboard (GdkDevice *device)
{
return GDK_DEVICE_CORE (device)->device->wl_keyboard;
}
#if 0
static void
input_handle_motion(void *data, struct wl_input_device *input_device,
uint32_t time,
@ -746,6 +769,7 @@ static const struct wl_input_device_listener input_device_listener = {
input_handle_pointer_focus,
input_handle_keyboard_focus,
};
#endif
struct _DataOffer {
struct wl_data_offer *offer;
@ -906,61 +930,350 @@ static const struct wl_data_device_listener data_device_listener = {
data_device_selection
};
static void
pointer_handle_enter (void *data,
struct wl_pointer *pointer,
uint32_t serial,
struct wl_surface *surface,
wl_fixed_t sx,
wl_fixed_t sy)
{
GdkWaylandDevice *device = data;
GdkEvent *event;
device->pointer_focus = wl_surface_get_user_data(surface);
g_object_ref(device->pointer_focus);
event = gdk_event_new (GDK_ENTER_NOTIFY);
event->crossing.window = g_object_ref (device->pointer_focus);
gdk_event_set_device (event, device->pointer);
event->crossing.subwindow = NULL;
event->crossing.time = (guint32)(g_get_monotonic_time () / 1000);
event->crossing.x = wl_fixed_to_double (sx);
event->crossing.y = wl_fixed_to_double (sy);
event->crossing.mode = GDK_CROSSING_NORMAL;
event->crossing.detail = GDK_NOTIFY_ANCESTOR;
event->crossing.focus = TRUE;
event->crossing.state = 0;
device->surface_x = wl_fixed_to_double (sx);
device->surface_y = wl_fixed_to_double (sy);
_gdk_wayland_display_deliver_event (device->display, event);
GDK_NOTE (EVENTS,
g_message ("enter, device %p surface %p",
device, device->pointer_focus));
}
static void
pointer_handle_leave (void *data,
struct wl_pointer *pointer,
uint32_t serial,
struct wl_surface *surface)
{
GdkWaylandDevice *device = data;
GdkEvent *event;
event = gdk_event_new (GDK_LEAVE_NOTIFY);
event->crossing.window = g_object_ref (device->pointer_focus);
gdk_event_set_device (event, device->pointer);
event->crossing.subwindow = NULL;
event->crossing.time = (guint32)(g_get_monotonic_time () / 1000);
event->crossing.x = device->surface_x;
event->crossing.y = device->surface_y;
event->crossing.mode = GDK_CROSSING_NORMAL;
event->crossing.detail = GDK_NOTIFY_ANCESTOR;
event->crossing.focus = TRUE;
event->crossing.state = 0;
_gdk_wayland_display_deliver_event (device->display, event);
GDK_NOTE (EVENTS,
g_message ("leave, device %p surface %p",
device, device->pointer_focus));
g_object_unref(device->pointer_focus);
device->pointer_focus = NULL;
}
static void
pointer_handle_motion (void *data,
struct wl_pointer *pointer,
uint32_t time,
wl_fixed_t sx,
wl_fixed_t sy)
{
GdkWaylandDevice *device = data;
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
GdkEvent *event;
event = gdk_event_new (GDK_NOTHING);
device->time = time;
device->surface_x = wl_fixed_to_double (sx);
device->surface_y = wl_fixed_to_double (sy);
event->motion.type = GDK_MOTION_NOTIFY;
event->motion.window = g_object_ref (device->pointer_focus);
gdk_event_set_device (event, device->pointer);
event->motion.time = time;
event->motion.x = wl_fixed_to_double (sx);
event->motion.y = wl_fixed_to_double (sy);
event->motion.axes = NULL;
event->motion.state = device->modifiers;
event->motion.is_hint = 0;
gdk_event_set_screen (event, display->screen);
GDK_NOTE (EVENTS,
g_message ("motion %d %d, state %d",
sx, sy, event->button.state));
_gdk_wayland_display_deliver_event (device->display, event);
}
static void
pointer_handle_button (void *data,
struct wl_pointer *pointer,
uint32_t serial,
uint32_t time,
uint32_t button,
uint32_t state)
{
GdkWaylandDevice *device = data;
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
GdkEvent *event;
uint32_t modifier;
int gdk_button;
switch (button) {
case 273:
gdk_button = 3;
break;
case 274:
gdk_button = 2;
break;
default:
gdk_button = button - 271;
break;
}
device->time = time;
event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
event->button.window = g_object_ref (device->pointer_focus);
gdk_event_set_device (event, device->pointer);
event->button.time = time;
event->button.x = device->surface_x;
event->button.y = device->surface_y;
event->button.axes = NULL;
event->button.state = device->modifiers;
event->button.button = gdk_button;
gdk_event_set_screen (event, display->screen);
modifier = 1 << (8 + gdk_button - 1);
if (state)
device->modifiers |= modifier;
else
device->modifiers &= ~modifier;
GDK_NOTE (EVENTS,
g_message ("button %d %s, state %d",
event->button.button,
state ? "press" : "release", event->button.state));
_gdk_wayland_display_deliver_event (device->display, event);
}
static void
pointer_handle_axis (void *data,
struct wl_pointer *pointer,
uint32_t time,
uint32_t axis,
wl_fixed_t value)
{
}
static void
keyboard_handle_keymap (void *data,
struct wl_keyboard *keyboard,
uint32_t format,
int fd,
uint32_t size)
{
}
static void
keyboard_handle_enter (void *data,
struct wl_keyboard *keyboard,
uint32_t serial,
struct wl_surface *surface,
struct wl_array *keys)
{
}
static void
keyboard_handle_leave (void *data,
struct wl_keyboard *keyboard,
uint32_t serial,
struct wl_surface *surface)
{
}
static void
keyboard_handle_key (void *data,
struct wl_keyboard *keyboard,
uint32_t serial,
uint32_t time,
uint32_t key,
uint32_t state_w)
{
}
static void
keyboard_handle_modifiers (void *data,
struct wl_keyboard *keyboard,
uint32_t serial,
uint32_t mods_depressed,
uint32_t mods_latched,
uint32_t mods_locked,
uint32_t group)
{
}
static const struct wl_pointer_listener pointer_listener = {
pointer_handle_enter,
pointer_handle_leave,
pointer_handle_motion,
pointer_handle_button,
pointer_handle_axis,
};
static const struct wl_keyboard_listener keyboard_listener = {
keyboard_handle_keymap,
keyboard_handle_enter,
keyboard_handle_leave,
keyboard_handle_key,
keyboard_handle_modifiers,
};
static void
seat_handle_capabilities(void *data, struct wl_seat *seat,
enum wl_seat_capability caps)
{
GdkWaylandDevice *device = data;
GdkDeviceManagerCore *device_manager_core =
GDK_DEVICE_MANAGER_CORE(device->device_manager);
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !device->wl_pointer)
{
device->wl_pointer = wl_seat_get_pointer(seat);
wl_pointer_set_user_data(device->wl_pointer, device);
wl_pointer_add_listener(device->wl_pointer, &pointer_listener,
device);
device->pointer = g_object_new (GDK_TYPE_DEVICE_CORE,
"name", "Core Pointer",
"type", GDK_DEVICE_TYPE_MASTER,
"input-source", GDK_SOURCE_MOUSE,
"input-mode", GDK_MODE_SCREEN,
"has-cursor", TRUE,
"display", device->display,
"device-manager", device->device_manager,
NULL);
GDK_DEVICE_CORE (device->pointer)->device = device;
device_manager_core->devices =
g_list_prepend (device_manager_core->devices, device->pointer);
}
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && device->wl_pointer)
{
wl_pointer_destroy(device->wl_pointer);
device->wl_pointer = NULL;
device_manager_core->devices =
g_list_remove (device_manager_core->devices, device->pointer);
g_object_unref (device->pointer);
device->pointer = NULL;
}
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !device->wl_keyboard)
{
device->wl_keyboard = wl_seat_get_keyboard(seat);
wl_keyboard_set_user_data(device->wl_keyboard, device);
wl_keyboard_add_listener(device->wl_keyboard, &keyboard_listener,
device);
device->keyboard = g_object_new (GDK_TYPE_DEVICE_CORE,
"name", "Core Keyboard",
"type", GDK_DEVICE_TYPE_MASTER,
"input-source", GDK_SOURCE_KEYBOARD,
"input-mode", GDK_MODE_SCREEN,
"has-cursor", FALSE,
"display", device->display,
"device-manager", device->device_manager,
NULL);
GDK_DEVICE_CORE (device->keyboard)->device = device;
device_manager_core->devices =
g_list_prepend (device_manager_core->devices, device->keyboard);
}
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && device->wl_keyboard)
{
wl_keyboard_destroy(device->wl_keyboard);
device->wl_keyboard = NULL;
device_manager_core->devices =
g_list_remove (device_manager_core->devices, device->keyboard);
g_object_unref (device->keyboard);
device->keyboard = NULL;
}
if (device->keyboard && device->pointer)
{
_gdk_device_set_associated_device (device->pointer, device->keyboard);
_gdk_device_set_associated_device (device->keyboard, device->pointer);
}
}
static const struct wl_seat_listener seat_listener = {
seat_handle_capabilities,
};
void
_gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager,
struct wl_input_device *wl_device)
struct wl_seat *wl_seat)
{
GdkDisplay *display;
GdkWaylandDisplay *display_wayland;
GdkDeviceManagerCore *device_manager_core =
GDK_DEVICE_MANAGER_CORE(device_manager);
GdkWaylandDevice *device;
device = g_new0 (GdkWaylandDevice, 1);
display = gdk_device_manager_get_display (device_manager);
display_wayland = GDK_WAYLAND_DISPLAY (display);
device = g_new0 (GdkWaylandDevice, 1);
device->display = display;
device->pointer = g_object_new (GDK_TYPE_DEVICE_CORE,
"name", "Core Pointer",
"type", GDK_DEVICE_TYPE_MASTER,
"input-source", GDK_SOURCE_MOUSE,
"input-mode", GDK_MODE_SCREEN,
"has-cursor", TRUE,
"display", display,
"device-manager", device_manager,
NULL);
device->device_manager = device_manager;
device->keyboard = g_object_new (GDK_TYPE_DEVICE_CORE,
"name", "Core Keyboard",
"type", GDK_DEVICE_TYPE_MASTER,
"input-source", GDK_SOURCE_KEYBOARD,
"input-mode", GDK_MODE_SCREEN,
"has-cursor", FALSE,
"display", display,
"device-manager", device_manager,
NULL);
device->wl_seat = wl_seat;
GDK_DEVICE_CORE (device->pointer)->device = device;
GDK_DEVICE_CORE (device->keyboard)->device = device;
device->device = wl_device;
wl_input_device_add_listener(device->device,
&input_device_listener, device);
wl_seat_add_listener (device->wl_seat, &seat_listener, device);
wl_seat_set_user_data (device->wl_seat, device);
device->data_device =
wl_data_device_manager_get_data_device (display_wayland->data_device_manager,
device->device);
device->wl_seat);
wl_data_device_add_listener (device->data_device,
&data_device_listener, device);
device_manager_core->devices =
g_list_prepend (device_manager_core->devices, device->keyboard);
device_manager_core->devices =
g_list_prepend (device_manager_core->devices, device->pointer);
_gdk_device_set_associated_device (device->pointer, device->keyboard);
_gdk_device_set_associated_device (device->keyboard, device->pointer);
}
static void

View File

@ -124,7 +124,7 @@ gdk_display_handle_global(struct wl_display *display, uint32_t id,
{
GdkWaylandDisplay *display_wayland = data;
GdkDisplay *gdk_display = GDK_DISPLAY_OBJECT (data);
struct wl_input_device *input;
struct wl_seat *seat;
if (strcmp(interface, "wl_compositor") == 0) {
display_wayland->compositor =
@ -141,10 +141,10 @@ gdk_display_handle_global(struct wl_display *display, uint32_t id,
wl_display_bind(display, id, &wl_output_interface);
wl_output_add_listener(display_wayland->output,
&output_listener, display_wayland);
} else if (strcmp(interface, "wl_input_device") == 0) {
input = wl_display_bind(display, id, &wl_input_device_interface);
} else if (strcmp(interface, "wl_seat") == 0) {
seat = wl_display_bind (display, id, &wl_seat_interface);
_gdk_wayland_device_manager_add_device (gdk_display->device_manager,
input);
seat);
} else if (strcmp(interface, "wl_data_device_manager") == 0) {
display_wayland->data_device_manager =
wl_display_bind(display, id,

View File

@ -122,8 +122,11 @@ gchar * _gdk_wayland_display_utf8_to_string_target (GdkDisplay *display,
GdkDeviceManager *_gdk_wayland_device_manager_new (GdkDisplay *display);
void _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager,
struct wl_input_device *device);
struct wl_input_device *_gdk_wayland_device_get_device (GdkDevice *device);
struct wl_seat *seat);
struct wl_seat *_gdk_wayland_device_get_wl_seat (GdkDevice *device);
struct wl_pointer *_gdk_wayland_device_get_wl_pointer (GdkDevice *device);
struct wl_keyboard *_gdk_wayland_device_get_wl_keyboard (GdkDevice *device);
void _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event);
GSource *_gdk_wayland_display_event_source_new (GdkDisplay *display);
@ -146,8 +149,8 @@ void _gdk_wayland_display_manager_add_display (GdkDisplayManager *manager,
void _gdk_wayland_display_manager_remove_display (GdkDisplayManager *manager,
GdkDisplay *display);
void _gdk_wayland_window_set_device_grabbed (GdkWindow *window,
struct wl_input_device *input_device,
guint32 time_);
void _gdk_wayland_window_set_device_grabbed (GdkWindow *window,
struct wl_seat *seat,
guint32 time_);
#endif /* __GDK_PRIVATE_WAYLAND_H__ */

View File

@ -130,7 +130,7 @@ struct _GdkWindowImplWayland
GdkGeometry geometry_hints;
GdkWindowHints geometry_mask;
struct wl_input_device *grab_input_device;
struct wl_seat *grab_input_seat;
guint32 grab_time;
};
@ -635,7 +635,7 @@ gdk_wayland_window_map (GdkWindow *window)
* grab before showing the popup window.
*/
wl_shell_surface_set_popup (impl->shell_surface,
parent->grab_input_device, parent->grab_time,
parent->grab_input_seat, parent->grab_time,
parent->shell_surface,
window->x, window->y, 0);
} else {
@ -1425,7 +1425,7 @@ gdk_wayland_window_begin_resize_drag (GdkWindow *window,
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
wl_shell_surface_resize (impl->shell_surface,
_gdk_wayland_device_get_device (device),
_gdk_wayland_device_get_wl_seat (device),
timestamp, grab_type);
/* This is needed since Wayland will absorb all the pointer events after the
@ -1451,7 +1451,7 @@ gdk_wayland_window_begin_move_drag (GdkWindow *window,
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
wl_shell_surface_move (impl->shell_surface,
_gdk_wayland_device_get_device (device), timestamp);
_gdk_wayland_device_get_wl_seat (device), timestamp);
/* This is needed since Wayland will absorb all the pointer events after the
* above function - FIXME: Is this always safe..?
@ -1689,9 +1689,9 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
void
_gdk_wayland_window_set_device_grabbed (GdkWindow *window,
struct wl_input_device *input_device,
guint32 time_)
_gdk_wayland_window_set_device_grabbed (GdkWindow *window,
struct wl_seat *seat,
guint32 time_)
{
GdkWindowImplWayland *impl;
@ -1699,6 +1699,6 @@ _gdk_wayland_window_set_device_grabbed (GdkWindow *window,
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
impl->grab_input_device = input_device;
impl->grab_input_seat = seat;
impl->grab_time = time_;
}