diff --git a/clutter/evdev/clutter-device-manager-evdev.c b/clutter/evdev/clutter-device-manager-evdev.c index 64dfeeb06..edf455d27 100644 --- a/clutter/evdev/clutter-device-manager-evdev.c +++ b/clutter/evdev/clutter-device-manager-evdev.c @@ -109,8 +109,7 @@ struct _ClutterEventSource ClutterInputDeviceEvdev *device; /* back pointer to the evdev device */ GPollFD event_poll_fd; /* file descriptor of the /dev node */ - struct xkb_desc *xkb; /* compiled xkb keymap */ - uint32_t modifier_state; /* remember the modifier state */ + struct xkb_state *xkb; /* XKB state object */ gint x, y; /* last x, y position for pointers */ }; @@ -173,12 +172,14 @@ notify_key (ClutterEventSource *source, /* if we have a mapping for that device, use it to generate the event */ if (source->xkb) + { event = _clutter_key_event_new_from_evdev (input_device, stage, source->xkb, - time_, key, state, - &source->modifier_state); + time_, key, state); + xkb_state_update_key (source->xkb, key, state ? XKB_KEY_DOWN : XKB_KEY_UP); + } queue_event (event); } diff --git a/clutter/evdev/clutter-xkb-utils.c b/clutter/evdev/clutter-xkb-utils.c index c6f798071..7f50858ee 100644 --- a/clutter/evdev/clutter-xkb-utils.c +++ b/clutter/evdev/clutter-xkb-utils.c @@ -26,60 +26,6 @@ #include "clutter-keysyms.h" #include "clutter-xkb-utils.h" -/* - * print_key_sym: Translate a symbol to its printable form if any - * @symbol: the symbol to translate - * @buffer: the buffer where to put the translated string - * @len: size of the buffer - * - * Translates @symbol into a printable representation in @buffer, if possible. - * - * Return value: The number of bytes of the translated string, 0 if the - * symbol can't be printed - * - * Note: The code is derived from libX11's src/KeyBind.c - * Copyright 1985, 1987, 1998 The Open Group - * - * Note: This code works for Latin-1 symbols. clutter_keysym_to_unicode() - * does the work for the other keysyms. - */ -static int -print_keysym (uint32_t symbol, - char *buffer, - int len) -{ - unsigned long high_bytes; - unsigned char c; - - high_bytes = symbol >> 8; - if (!(len && - ((high_bytes == 0) || - ((high_bytes == 0xFF) && - (((symbol >= CLUTTER_KEY_BackSpace) && - (symbol <= CLUTTER_KEY_Clear)) || - (symbol == CLUTTER_KEY_Return) || - (symbol == CLUTTER_KEY_Escape) || - (symbol == CLUTTER_KEY_KP_Space) || - (symbol == CLUTTER_KEY_KP_Tab) || - (symbol == CLUTTER_KEY_KP_Enter) || - ((symbol >= CLUTTER_KEY_KP_Multiply) && - (symbol <= CLUTTER_KEY_KP_9)) || - (symbol == CLUTTER_KEY_KP_Equal) || - (symbol == CLUTTER_KEY_Delete)))))) - return 0; - - /* if X keysym, convert to ascii by grabbing low 7 bits */ - if (symbol == CLUTTER_KEY_KP_Space) - c = CLUTTER_KEY_space & 0x7F; /* patch encoding botch */ - else if (high_bytes == 0xFF) - c = symbol & 0x7F; - else - c = symbol & 0xFF; - - buffer[0] = c; - return 1; -} - /* * _clutter_event_new_from_evdev: Create a new Clutter ClutterKeyEvent * @device: a ClutterInputDevice @@ -97,15 +43,15 @@ print_keysym (uint32_t symbol, ClutterEvent * _clutter_key_event_new_from_evdev (ClutterInputDevice *device, ClutterStage *stage, - struct xkb_desc *xkb, + struct xkb_state *xkb_state, uint32_t _time, - uint32_t key, - uint32_t state, - uint32_t *modifier_state) + xkb_keycode_t key, + uint32_t state) { ClutterEvent *event; - uint32_t code, sym, level; - char buffer[128]; + xkb_keysym_t sym; + const xkb_keysym_t *syms; + char buffer[8]; int n; if (state) @@ -113,28 +59,27 @@ _clutter_key_event_new_from_evdev (ClutterInputDevice *device, else event = clutter_event_new (CLUTTER_KEY_RELEASE); - code = key + xkb->min_key_code; - level = 0; + /* We use a fixed offset of 8 because evdev starts KEY_* numbering from + * 0, whereas X11's minimum keycode, for really stupid reasons, is 8. + * So the evdev XKB rules are based on the keycodes all being shifted + * upwards by 8. */ + key += 8; - if (*modifier_state & CLUTTER_SHIFT_MASK && - XkbKeyGroupWidth (xkb, code, 0) > 1) - level = 1; - - sym = XkbKeySymEntry (xkb, code, level, 0); - if (state) - *modifier_state |= xkb->map->modmap[code]; + n = xkb_key_get_syms (xkb_state, key, &syms); + if (n == 1) + sym = syms[0]; else - *modifier_state &= ~xkb->map->modmap[code]; + sym = XKB_KEY_NoSymbol; event->key.device = device; event->key.stage = stage; event->key.time = _time; - event->key.modifier_state = *modifier_state; + event->key.modifier_state = + xkb_state_serialize_mods (xkb_state, XKB_STATE_EFFECTIVE); event->key.hardware_keycode = key; event->key.keyval = sym; - /* unicode_value is the printable representation */ - n = print_keysym (sym, buffer, sizeof (buffer)); + n = xkb_keysym_to_utf8 (sym, buffer, sizeof (buffer)); if (n == 0) { @@ -152,21 +97,28 @@ _clutter_key_event_new_from_evdev (ClutterInputDevice *device, } /* - * _clutter_xkb_desc_new: + * _clutter_xkb_state_new: * - * Create a new xkbcommon keymap. + * Create a new xkbcommon keymap and state object. * * FIXME: We need a way to override the layout here, a fixed or runtime - * detected layout is provided by the backend calling _clutter_xkb_desc_new(); + * detected layout is provided by the backend calling _clutter_xkb_state_new(); */ -struct xkb_desc * -_clutter_xkb_desc_new (const gchar *model, - const gchar *layout, - const gchar *variant, - const gchar *options) +struct xkb_state * +_clutter_xkb_state_new (const gchar *model, + const gchar *layout, + const gchar *variant, + const gchar *options) { + struct xkb_context *ctx; + struct xkb_keymap *keymap; + struct xkb_state *state; struct xkb_rule_names names; + ctx = xkb_context_new(0); + if (!ctx) + return NULL; + names.rules = "evdev"; if (model) names.model = model; @@ -176,5 +128,13 @@ _clutter_xkb_desc_new (const gchar *model, names.variant = variant; names.options = options; - return xkb_compile_keymap_from_rules (&names); + keymap = xkb_map_new_from_names(ctx, &names, 0); + xkb_context_unref(ctx); + if (!keymap) + return NULL; + + state = xkb_state_new(keymap); + xkb_map_unref(keymap); + + return state; } diff --git a/clutter/evdev/clutter-xkb-utils.h b/clutter/evdev/clutter-xkb-utils.h index 8c9ca9cff..f732f5b86 100644 --- a/clutter/evdev/clutter-xkb-utils.h +++ b/clutter/evdev/clutter-xkb-utils.h @@ -33,12 +33,11 @@ ClutterEvent * _clutter_key_event_new_from_evdev (ClutterInputDevice *device, ClutterStage *stage, - struct xkb_desc *xkb, + struct xkb_state *xkb_state, uint32_t _time, uint32_t key, - uint32_t state, - uint32_t *modifier_state); -struct xkb_desc * _clutter_xkb_desc_new (const gchar *model, + uint32_t state); +struct xkb_state * _clutter_xkb_state_new (const gchar *model, const gchar *layout, const gchar *variant, const gchar *options); diff --git a/clutter/wayland/clutter-backend-wayland.c b/clutter/wayland/clutter-backend-wayland.c index 6db22c901..aa945e41d 100644 --- a/clutter/wayland/clutter-backend-wayland.c +++ b/clutter/wayland/clutter-backend-wayland.c @@ -106,7 +106,8 @@ output_handle_geometry (void *data, int physical_height, int subpixel, const char *make, - const char *model) + const char *model, + int32_t transform) { } @@ -129,7 +130,7 @@ display_handle_global (struct wl_display *display, if (strcmp (interface, "wl_compositor") == 0) backend_wayland->wayland_compositor = wl_display_bind (display, id, &wl_compositor_interface); - else if (strcmp (interface, "wl_input_device") == 0) + else if (strcmp (interface, "wl_seat") == 0) { ClutterDeviceManager *device_manager = backend_wayland->device_manager; _clutter_device_manager_wayland_add_input_group (device_manager, id); @@ -342,6 +343,7 @@ create_cursor (ClutterBackendWayland *backend_wayland, int stride, fd; char *filename; GError *error = NULL; + struct wl_shm_pool *pool; struct wl_buffer *buffer; gint width, height; gsize size; @@ -381,14 +383,15 @@ create_cursor (ClutterBackendWayland *backend_wayland, set_pixbuf (pixbuf, map, width, height); - buffer = wl_shm_create_buffer (backend_wayland->wayland_shm, - fd, - width, - height, - stride, - WL_SHM_FORMAT_ARGB8888); - - close(fd); + pool = wl_shm_create_pool (backend_wayland->wayland_shm, fd, size); + close (fd); + buffer = wl_shm_pool_create_buffer (pool, + 0, + width, + height, + stride, + WL_SHM_FORMAT_ARGB8888); + wl_shm_pool_destroy (pool); munmap (map, size); return buffer; @@ -433,10 +436,13 @@ clutter_backend_wayland_load_cursor (ClutterBackendWayland *backend_wayland) if (backend_wayland->cursor_buffer) { - backend_wayland->cursor_x = 15; - backend_wayland->cursor_y = 15; + backend_wayland->cursor_x = 0; + backend_wayland->cursor_y = 0; } + backend_wayland->cursor_surface = + wl_compositor_create_surface (backend_wayland->wayland_compositor); + g_object_unref (pixbuf); } diff --git a/clutter/wayland/clutter-backend-wayland.h b/clutter/wayland/clutter-backend-wayland.h index 9ee51d9bc..5788a4590 100644 --- a/clutter/wayland/clutter-backend-wayland.h +++ b/clutter/wayland/clutter-backend-wayland.h @@ -56,6 +56,7 @@ struct _ClutterBackendWayland struct wl_compositor *wayland_compositor; struct wl_shell *wayland_shell; struct wl_shm *wayland_shm; + struct wl_surface *cursor_surface; struct wl_buffer *cursor_buffer; struct wl_output *wayland_output; diff --git a/clutter/wayland/clutter-device-manager-wayland.c b/clutter/wayland/clutter-device-manager-wayland.c index 1282a9f71..738a9ee5f 100644 --- a/clutter/wayland/clutter-device-manager-wayland.c +++ b/clutter/wayland/clutter-device-manager-wayland.c @@ -36,9 +36,8 @@ #include "clutter-device-manager-private.h" #include "clutter-private.h" -#include "evdev/clutter-xkb-utils.h" - #include +#include enum { @@ -147,10 +146,6 @@ _clutter_device_manager_wayland_init (ClutterDeviceManagerWayland *self) { } -static const char *option_xkb_layout = "us"; -static const char *option_xkb_variant = ""; -static const char *option_xkb_options = ""; - void _clutter_device_manager_wayland_add_input_group (ClutterDeviceManager *manager, uint32_t id) @@ -168,18 +163,11 @@ _clutter_device_manager_wayland_add_input_group (ClutterDeviceManager *manager, device->input_device = wl_display_bind (backend_wayland->wayland_display, id, - &wl_input_device_interface); - wl_input_device_add_listener (device->input_device, - &_clutter_input_device_wayland_listener, - device); - wl_input_device_set_user_data (device->input_device, device); - - device->xkb = _clutter_xkb_desc_new (NULL, - option_xkb_layout, - option_xkb_variant, - option_xkb_options); - if (!device->xkb) - CLUTTER_NOTE (BACKEND, "Failed to compile keymap"); + &wl_seat_interface); + wl_seat_add_listener (device->input_device, + &_clutter_seat_wayland_listener, + device); + wl_seat_set_user_data (device->input_device, device); _clutter_device_manager_add_device (manager, CLUTTER_INPUT_DEVICE (device)); } diff --git a/clutter/wayland/clutter-input-device-wayland.c b/clutter/wayland/clutter-input-device-wayland.c index c15d5a7bc..756a156fc 100644 --- a/clutter/wayland/clutter-input-device-wayland.c +++ b/clutter/wayland/clutter-input-device-wayland.c @@ -29,6 +29,8 @@ #endif #include +#include +#include #include #include @@ -53,10 +55,9 @@ G_DEFINE_TYPE (ClutterInputDeviceWayland, static void clutter_wayland_handle_motion (void *data, - struct wl_input_device *input_device, + struct wl_pointer *pointer, uint32_t _time, - int32_t x, int32_t y, - int32_t sx, int32_t sy) + wl_fixed_t x, wl_fixed_t y) { ClutterInputDeviceWayland *device = data; ClutterStageCogl *stage_cogl = device->pointer_focus; @@ -67,21 +68,19 @@ clutter_wayland_handle_motion (void *data, event->motion.device = CLUTTER_INPUT_DEVICE (device); event->motion.time = _time; event->motion.modifier_state = 0; - event->motion.x = sx; - event->motion.y = sy; + event->motion.x = wl_fixed_to_double(x); + event->motion.y = wl_fixed_to_double(y); - device->surface_x = sx; - device->surface_y = sy; - device->x = x; - device->y = y; + device->x = event->motion.x; + device->y = event->motion.y; _clutter_event_push (event, FALSE); } static void clutter_wayland_handle_button (void *data, - struct wl_input_device *input_device, - uint32_t _time, + struct wl_pointer *pointer, + uint32_t serial, uint32_t _time, uint32_t button, uint32_t state) { ClutterInputDeviceWayland *device = data; @@ -97,10 +96,11 @@ clutter_wayland_handle_button (void *data, event = clutter_event_new (type); event->button.stage = stage_cogl->wrapper; event->button.device = CLUTTER_INPUT_DEVICE (device); - event->button.time = _time; - event->button.x = device->surface_x; - event->button.y = device->surface_y; - event->button.modifier_state = device->modifier_state; + event->button.time = /*_time*/ serial; + event->button.x = device->x; + event->button.y = device->y; + event->button.modifier_state = + xkb_state_serialize_mods (device->xkb, XKB_STATE_EFFECTIVE); /* evdev button codes */ switch (button) { @@ -118,135 +118,323 @@ clutter_wayland_handle_button (void *data, _clutter_event_push (event, FALSE); } +static void +clutter_wayland_handle_axis (void *data, + struct wl_pointer *pointer, + uint32_t time, + uint32_t axis, + wl_fixed_t value) +{ + ClutterInputDeviceWayland *device = data; + ClutterStageCogl *stage_cogl = device->pointer_focus; + ClutterEvent *event; + gdouble delta_x, delta_y; + + event = clutter_event_new (CLUTTER_SCROLL); + event->scroll.time = time; + event->scroll.stage = stage_cogl->wrapper; + event->scroll.direction = CLUTTER_SCROLL_SMOOTH; + event->scroll.x = device->x; + event->scroll.y = device->y; + + if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) + { + delta_x = -wl_fixed_to_double(value) * 23; + delta_y = 0; + } + else + { + delta_x = 0; + delta_y = -wl_fixed_to_double(value) * 23; /* XXX: based on my bcm5794 */ + } + clutter_event_set_scroll_delta (event, delta_x, delta_y); + + event->scroll.modifier_state = + xkb_state_serialize_mods(device->xkb, XKB_STATE_EFFECTIVE); + + _clutter_event_push (event, FALSE); +} + +static void +clutter_wayland_handle_keymap (void *data, + struct wl_keyboard *keyboard, + uint32_t format, + int32_t fd, + uint32_t size) +{ + ClutterInputDeviceWayland *device = data; + struct xkb_context *ctx; + struct xkb_keymap *keymap; + char *map_str; + + if (device->xkb) + { + xkb_state_unref (device->xkb); + device->xkb = NULL; + } + + ctx = xkb_context_new (0); + if (!ctx) + { + close (fd); + return; + } + + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) + { + close (fd); + return; + } + + map_str = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (map_str == MAP_FAILED) + { + close(fd); + return; + } + + keymap = xkb_map_new_from_string (ctx, + map_str, + XKB_KEYMAP_FORMAT_TEXT_V1, + 0); + xkb_context_unref (ctx); + munmap (map_str, size); + close (fd); + + if (!keymap) + { + g_warning ("failed to compile keymap\n"); + return; + } + + device->xkb = xkb_state_new(keymap); + xkb_map_unref (keymap); + if (!device->xkb) + { + g_warning ("failed to create XKB state object\n"); + return; + } +} + static void clutter_wayland_handle_key (void *data, - struct wl_input_device *input_device, - uint32_t _time, + struct wl_keyboard *keyboard, + uint32_t serial, uint32_t _time, uint32_t key, uint32_t state) { ClutterInputDeviceWayland *device = data; ClutterStageCogl *stage_cogl = device->keyboard_focus; ClutterEvent *event; + if (!device->xkb) + return; + event = _clutter_key_event_new_from_evdev ((ClutterInputDevice *) device, stage_cogl->wrapper, device->xkb, - _time, key, state, - &device->modifier_state); + _time, key, state); _clutter_event_push (event, FALSE); } static void -clutter_wayland_handle_pointer_focus (void *data, - struct wl_input_device *input_device, - uint32_t _time, +clutter_wayland_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) +{ + ClutterInputDeviceWayland *device = data; + + if (!device->xkb) + return; + + xkb_state_update_mask (device->xkb, + mods_depressed, + mods_latched, + mods_locked, + 0, + 0, + group); +} + +static void +clutter_wayland_handle_pointer_enter (void *data, + struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface, - int32_t x, int32_t y, int32_t sx, int32_t sy) + wl_fixed_t x, wl_fixed_t y) +{ + ClutterInputDeviceWayland *device = data; + ClutterStageCogl *stage_cogl; + ClutterEvent *event; + ClutterBackend *backend; + ClutterBackendWayland *backend_wayland; + + stage_cogl = wl_surface_get_user_data (surface); + + device->pointer_focus = stage_cogl; + _clutter_input_device_set_stage (CLUTTER_INPUT_DEVICE (device), + stage_cogl->wrapper); + + event = clutter_event_new (CLUTTER_ENTER); + event->crossing.stage = stage_cogl->wrapper; + event->crossing.time = 0; /* ?! */ + event->crossing.x = wl_fixed_to_double(x); + event->crossing.y = wl_fixed_to_double(y); + event->crossing.source = CLUTTER_ACTOR (stage_cogl->wrapper); + event->crossing.device = CLUTTER_INPUT_DEVICE (device); + + device->x = event->crossing.x; + device->y = event->crossing.y; + + _clutter_event_push (event, FALSE); + + /* Set the cursor to the cursor loaded at backend initialisation */ + backend = clutter_get_default_backend (); + backend_wayland = CLUTTER_BACKEND_WAYLAND (backend); + + wl_pointer_set_cursor (pointer, + serial, + backend_wayland->cursor_surface, + backend_wayland->cursor_x, + backend_wayland->cursor_y); + wl_surface_attach (backend_wayland->cursor_surface, + backend_wayland->cursor_buffer, + 0, + 0); + wl_surface_damage (backend_wayland->cursor_surface, + 0, + 0, + 32, /* XXX: FFS */ + 32); +} + +static void +clutter_wayland_handle_pointer_leave (void *data, + struct wl_pointer *pointer, + uint32_t serial, + struct wl_surface *surface) { ClutterInputDeviceWayland *device = data; ClutterStageCogl *stage_cogl; ClutterEvent *event; - if (!surface) - { - stage_cogl = device->pointer_focus; + stage_cogl = wl_surface_get_user_data (surface); + g_assert (device->pointer_focus == stage_cogl); - event = clutter_event_new (CLUTTER_LEAVE); - event->crossing.stage = stage_cogl->wrapper; - event->crossing.time = _time; - event->crossing.x = sx; - event->crossing.y = sy; - event->crossing.source = CLUTTER_ACTOR (stage_cogl->wrapper); - event->crossing.device = CLUTTER_INPUT_DEVICE (device); + event = clutter_event_new (CLUTTER_LEAVE); + event->crossing.stage = stage_cogl->wrapper; + event->crossing.time = 0; /* ?! */ + event->crossing.x = device->x; + event->crossing.y = device->y; + event->crossing.source = CLUTTER_ACTOR (stage_cogl->wrapper); + event->crossing.device = CLUTTER_INPUT_DEVICE (device); - _clutter_event_push (event, FALSE); + _clutter_event_push (event, FALSE); - device->pointer_focus = NULL; - _clutter_input_device_set_stage (CLUTTER_INPUT_DEVICE (device), NULL); - } - - if (surface) - { - ClutterBackend *backend; - ClutterBackendWayland *backend_wayland; - - stage_cogl = wl_surface_get_user_data (surface); - - device->pointer_focus = stage_cogl; - _clutter_input_device_set_stage (CLUTTER_INPUT_DEVICE (device), - stage_cogl->wrapper); - - event = clutter_event_new (CLUTTER_ENTER); - event->crossing.stage = stage_cogl->wrapper; - event->crossing.time = _time; - event->crossing.x = sx; - event->crossing.y = sy; - event->crossing.source = CLUTTER_ACTOR (stage_cogl->wrapper); - event->crossing.device = CLUTTER_INPUT_DEVICE (device); - - _clutter_event_push (event, FALSE); - - device->surface_x = sx; - device->surface_y = sy; - device->x = x; - device->y = y; - - /* Set the cursor to the cursor loaded at backend initialisation */ - backend = clutter_get_default_backend (); - backend_wayland = CLUTTER_BACKEND_WAYLAND (backend); - - wl_input_device_attach (input_device, - _time, - backend_wayland->cursor_buffer, - backend_wayland->cursor_x, - backend_wayland->cursor_y); - } + device->pointer_focus = NULL; + _clutter_input_device_set_stage (CLUTTER_INPUT_DEVICE (device), NULL); } static void -clutter_wayland_handle_keyboard_focus (void *data, - struct wl_input_device *input_device, - uint32_t _time, +clutter_wayland_handle_keyboard_enter (void *data, + struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface, struct wl_array *keys) { ClutterInputDeviceWayland *device = data; ClutterStageCogl *stage_cogl; - uint32_t *k, *end; - if (device->keyboard_focus) + stage_cogl = wl_surface_get_user_data (surface); + g_assert (device->keyboard_focus == NULL); + device->keyboard_focus = stage_cogl; + + _clutter_stage_update_state (stage_cogl->wrapper, + 0, + CLUTTER_STAGE_STATE_ACTIVATED); +} + +static void +clutter_wayland_handle_keyboard_leave (void *data, + struct wl_keyboard *keyboard, + uint32_t serial, + struct wl_surface *surface) +{ + ClutterInputDeviceWayland *device = data; + ClutterStageCogl *stage_cogl; + + stage_cogl = wl_surface_get_user_data (surface); + g_assert (device->keyboard_focus == stage_cogl); + + _clutter_stage_update_state (stage_cogl->wrapper, + CLUTTER_STAGE_STATE_ACTIVATED, + 0); + + device->keyboard_focus = NULL; +} + +static const struct wl_keyboard_listener _clutter_keyboard_wayland_listener = { + clutter_wayland_handle_keymap, + clutter_wayland_handle_keyboard_enter, + clutter_wayland_handle_keyboard_leave, + clutter_wayland_handle_key, + clutter_wayland_handle_modifiers, +}; + +static const struct wl_pointer_listener _clutter_pointer_wayland_listener = { + clutter_wayland_handle_pointer_enter, + clutter_wayland_handle_pointer_leave, + clutter_wayland_handle_motion, + clutter_wayland_handle_button, + clutter_wayland_handle_axis, +}; + +static void +clutter_wayland_handle_seat (void *data, + struct wl_seat *seat, + uint32_t capabilities) +{ + ClutterInputDeviceWayland *device = data; + + /* XXX: Needs to handle removals too. */ + + if ((capabilities & WL_SEAT_CAPABILITY_POINTER) && !device->has_pointer) { - stage_cogl = device->keyboard_focus; - device->keyboard_focus = NULL; + struct wl_pointer *pointer; - _clutter_stage_update_state (stage_cogl->wrapper, - CLUTTER_STAGE_STATE_ACTIVATED, - 0); + pointer = wl_seat_get_pointer (seat); + if (pointer) + { + wl_pointer_add_listener (pointer, + &_clutter_pointer_wayland_listener, + device); + wl_pointer_set_user_data (pointer, device); + device->has_pointer = 1; + } } - if (surface) + if ((capabilities & WL_SEAT_CAPABILITY_KEYBOARD) && !device->has_keyboard) { - stage_cogl = wl_surface_get_user_data (surface); - device->keyboard_focus = stage_cogl; + struct wl_keyboard *keyboard; - _clutter_stage_update_state (stage_cogl->wrapper, - 0, - CLUTTER_STAGE_STATE_ACTIVATED); - - end = (uint32_t *)((guint8 *)keys->data + keys->size); - device->modifier_state = 0; - for (k = keys->data; k < end; k++) - device->modifier_state |= device->xkb->map->modmap[*k]; + keyboard = wl_seat_get_keyboard (seat); + if (keyboard) + { + wl_keyboard_add_listener (keyboard, + &_clutter_keyboard_wayland_listener, + device); + wl_keyboard_set_user_data (keyboard, device); + device->has_keyboard = 1; + } } } -const struct wl_input_device_listener _clutter_input_device_wayland_listener = { - clutter_wayland_handle_motion, - clutter_wayland_handle_button, - clutter_wayland_handle_key, - clutter_wayland_handle_pointer_focus, - clutter_wayland_handle_keyboard_focus, +const struct wl_seat_listener _clutter_seat_wayland_listener = { + clutter_wayland_handle_seat, }; static gboolean @@ -287,8 +475,8 @@ clutter_input_device_wayland_init (ClutterInputDeviceWayland *self) * * Since: 1.10 */ -struct wl_input_device * -clutter_wayland_input_device_get_wl_input_device (ClutterInputDevice *device) +struct wl_seat * +clutter_wayland_input_device_get_wl_seat (ClutterInputDevice *device) { ClutterInputDeviceWayland *wayland_device; diff --git a/clutter/wayland/clutter-input-device-wayland.h b/clutter/wayland/clutter-input-device-wayland.h index 8fa195837..723bde0fe 100644 --- a/clutter/wayland/clutter-input-device-wayland.h +++ b/clutter/wayland/clutter-input-device-wayland.h @@ -41,16 +41,17 @@ typedef struct _ClutterInputDeviceWayland ClutterInputDeviceWayland; struct _ClutterInputDeviceWayland { ClutterInputDevice device; - struct wl_input_device *input_device; + struct wl_seat *input_device; ClutterStageCogl *pointer_focus; ClutterStageCogl *keyboard_focus; - uint32_t modifier_state; - int32_t x, y, surface_x, surface_y; - struct xkb_desc *xkb; + gdouble x, y; + struct xkb_state *xkb; + gint has_pointer; + gint has_keyboard; }; GType clutter_input_device_wayland_get_type (void) G_GNUC_CONST; -extern const struct wl_input_device_listener _clutter_input_device_wayland_listener; +extern const struct wl_seat_listener _clutter_seat_wayland_listener; #endif /* __CLUTTER_INPUT_DEVICE_WAYLAND_H__ */ diff --git a/clutter/wayland/clutter-stage-wayland.c b/clutter/wayland/clutter-stage-wayland.c index daa78c4c3..727a9cad0 100644 --- a/clutter/wayland/clutter-stage-wayland.c +++ b/clutter/wayland/clutter-stage-wayland.c @@ -50,10 +50,17 @@ G_DEFINE_TYPE_WITH_CODE (ClutterStageWayland, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW, clutter_stage_window_iface_init)); +static void +handle_ping (void *data, + struct wl_shell_surface *shell_surface, + uint32_t serial) +{ + wl_shell_surface_pong(shell_surface, serial); +} + static void handle_configure (void *data, struct wl_shell_surface *shell_surface, - uint32_t timestamp, uint32_t edges, int32_t width, int32_t height) @@ -74,8 +81,17 @@ handle_configure (void *data, clutter_stage_ensure_viewport (stage_cogl->wrapper); } +static void +handle_popup_done (void *data, + struct wl_shell_surface *shell_surface) +{ + /* XXX: Fill me in. */ +} + static const struct wl_shell_surface_listener shell_surface_listener = { + handle_ping, handle_configure, + handle_popup_done, }; static void @@ -143,7 +159,10 @@ clutter_stage_wayland_set_fullscreen (ClutterStageWindow *stage_window, * attached */ _clutter_stage_window_redraw (stage_window); - wl_shell_surface_set_fullscreen (stage_wayland->wayland_shell_surface); + wl_shell_surface_set_fullscreen (stage_wayland->wayland_shell_surface, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, + 0, + NULL); } else { diff --git a/clutter/wayland/clutter-wayland.h b/clutter/wayland/clutter-wayland.h index 55b874876..b9ffb1bc4 100644 --- a/clutter/wayland/clutter-wayland.h +++ b/clutter/wayland/clutter-wayland.h @@ -40,7 +40,7 @@ #include G_BEGIN_DECLS -struct wl_input_device *clutter_wayland_input_device_get_wl_input_device (ClutterInputDevice *device); +struct wl_seat *clutter_wayland_input_device_get_wl_seat (ClutterInputDevice *device); struct wl_shell_surface *clutter_wayland_stage_get_wl_shell_surface (ClutterStage *stage); struct wl_surface *clutter_wayland_stage_get_wl_surface (ClutterStage *stage); G_END_DECLS