diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index ac81658688..c818596cc8 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -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 diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 89c5349502..c50d09c8a1 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -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, diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index 62815911f2..262f74dd82 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -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__ */ diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index a0e2d7ec9f..88e76ca16e 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -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_; }