From 37ffc3c14b07a2fd37aeff6d16153a639bc6db89 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Fri, 15 Jun 2012 17:27:35 +0300 Subject: [PATCH] compositor: Track pointer image protocol change The request pointer.attach was replaced with pointer.set_cursor that lets a client set the cursor surface for a given pointer. --- clients/simple-egl.c | 2 +- clients/window.c | 13 +++++- src/compositor-wayland.c | 2 +- src/compositor.c | 112 +++++++++++++++++++++++++++++++++++------------ src/compositor.h | 1 + 5 files changed, 99 insertions(+), 31 deletions(-) diff --git a/clients/simple-egl.c b/clients/simple-egl.c index cceca9e..25c7bdf 100644 --- a/clients/simple-egl.c +++ b/clients/simple-egl.c @@ -360,7 +360,7 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, struct display *display = data; if (display->window->fullscreen) - wl_pointer_attach(pointer, serial, NULL, 0, 0); + wl_pointer_set_cursor(pointer, serial, NULL, 0, 0); } static void diff --git a/clients/window.c b/clients/window.c index 53022aa..57443d9 100644 --- a/clients/window.c +++ b/clients/window.c @@ -189,6 +189,7 @@ struct input { struct window *pointer_focus; struct window *keyboard_focus; int current_cursor; + struct wl_surface *pointer_surface; uint32_t modifiers; uint32_t pointer_enter_serial; float sx, sy; @@ -2295,8 +2296,12 @@ input_set_pointer_image_index(struct input *input, int pointer, int index) return; input->current_cursor = pointer; - wl_pointer_attach(input->pointer, input->pointer_enter_serial, - buffer, image->hotspot_x, image->hotspot_y); + wl_pointer_set_cursor(input->pointer, input->display->serial, + input->pointer_surface, + image->hotspot_x, image->hotspot_y); + wl_surface_attach(input->pointer_surface, buffer, 0, 0); + wl_surface_damage(input->pointer_surface, 0, 0, + image->width, image->height); } void @@ -3168,6 +3173,8 @@ display_add_input(struct display *d, uint32_t id) input->seat); wl_data_device_add_listener(input->data_device, &data_device_listener, input); + + input->pointer_surface = wl_compositor_create_surface(d->compositor); } static void @@ -3190,6 +3197,8 @@ input_destroy(struct input *input) wl_data_device_destroy(input->data_device); fini_xkb(input); + wl_surface_destroy(input->pointer_surface); + wl_list_remove(&input->link); wl_seat_destroy(input->seat); free(input); diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index f09463e..d498e84 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -505,7 +505,7 @@ input_handle_pointer_enter(void *data, struct wl_pointer *pointer, output = wl_surface_get_user_data(surface); notify_pointer_focus(&c->base.seat->seat, &output->base, x, y); - wl_pointer_attach(input->pointer, serial, NULL, 0, 0); + wl_pointer_set_cursor(input->pointer, serial, NULL, 0, 0); } static void diff --git a/src/compositor.c b/src/compositor.c index db49c35..4a8fdad 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -2064,13 +2064,59 @@ notify_touch(struct wl_seat *seat, uint32_t time, int touch_id, } static void -pointer_attach(struct wl_client *client, struct wl_resource *resource, - uint32_t serial, struct wl_resource *buffer_resource, - int32_t x, int32_t y) +pointer_handle_sprite_destroy(struct wl_listener *listener, void *data) +{ + struct weston_seat *seat = container_of(listener, struct weston_seat, + sprite_destroy_listener); + + seat->sprite = NULL; +} + +static void +pointer_cursor_surface_configure(struct weston_surface *es, + int32_t dx, int32_t dy) +{ + struct weston_seat *seat = es->private; + int x, y; + + assert(es == seat->sprite); + + seat->hotspot_x -= dx; + seat->hotspot_y -= dy; + + x = wl_fixed_to_int(seat->seat.pointer->x) - seat->hotspot_x; + y = wl_fixed_to_int(seat->seat.pointer->y) - seat->hotspot_y; + + weston_surface_configure(seat->sprite, x, y, + es->buffer->width, es->buffer->height); + + if (!weston_surface_is_mapped(es)) { + wl_list_insert(&es->compositor->cursor_layer.surface_list, + &es->layer_link); + weston_surface_assign_output(es); + empty_region(&es->input); + } +} + +static void +pointer_unmap_sprite(struct weston_seat *seat) +{ + if (weston_surface_is_mapped(seat->sprite)) + weston_surface_unmap(seat->sprite); + + wl_list_remove(&seat->sprite_destroy_listener.link); + seat->sprite->configure = NULL; + seat->sprite->private = NULL; + seat->sprite = NULL; +} + +static void +pointer_set_cursor(struct wl_client *client, struct wl_resource *resource, + uint32_t serial, struct wl_resource *surface_resource, + int32_t x, int32_t y) { struct weston_seat *seat = resource->data; - struct weston_compositor *compositor = seat->compositor; - struct wl_buffer *buffer = NULL; + struct weston_surface *surface = NULL; if (serial < seat->seat.pointer->focus_serial) return; @@ -2079,35 +2125,41 @@ pointer_attach(struct wl_client *client, struct wl_resource *resource, if (seat->seat.pointer->focus->resource.client != client) return; - if (buffer_resource) - buffer = buffer_resource->data; + if (surface_resource) + surface = container_of(surface_resource->data, + struct weston_surface, surface); - weston_surface_attach(&seat->sprite->surface, buffer); - empty_region(&seat->sprite->input); + if (surface && surface != seat->sprite && surface->configure) { + wl_resource_post_error(&surface->surface.resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "surface->configure already set"); + return; + } - if (!buffer) + if (seat->sprite) + pointer_unmap_sprite(seat); + + if (!surface) return; - if (!weston_surface_is_mapped(seat->sprite)) { - wl_list_insert(&compositor->cursor_layer.surface_list, - &seat->sprite->layer_link); - weston_surface_assign_output(seat->sprite); - } + wl_signal_add(&surface->surface.resource.destroy_signal, + &seat->sprite_destroy_listener); + surface->configure = pointer_cursor_surface_configure; + surface->private = seat; + empty_region(&surface->input); + seat->sprite = surface; seat->hotspot_x = x; seat->hotspot_y = y; - weston_surface_configure(seat->sprite, - wl_fixed_to_int(seat->seat.pointer->x) - x, - wl_fixed_to_int(seat->seat.pointer->y) - y, - buffer->width, buffer->height); - surface_damage(NULL, &seat->sprite->surface.resource, - 0, 0, buffer->width, buffer->height); + weston_surface_set_position(surface, + wl_fixed_to_int(seat->seat.pointer->x) - x, + wl_fixed_to_int(seat->seat.pointer->y) - y); } static const struct wl_pointer_interface pointer_interface = { - pointer_attach, + pointer_set_cursor }; static void @@ -2428,8 +2480,8 @@ weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec) wl_display_add_global(ec->wl_display, &wl_seat_interface, seat, bind_seat); - seat->sprite = weston_surface_create(ec); - seat->sprite->surface.resource.data = seat->sprite; + seat->sprite = NULL; + seat->sprite_destroy_listener.notify = pointer_handle_sprite_destroy; seat->compositor = ec; seat->hotspot_x = 16; @@ -2456,7 +2508,7 @@ weston_seat_release(struct weston_seat *seat) /* The global object is destroyed at wl_display_destroy() time. */ if (seat->sprite) - destroy_surface(&seat->sprite->surface.resource); + pointer_unmap_sprite(seat); if (seat->xkb_state.state != NULL) xkb_state_unref(seat->xkb_state.state); @@ -2512,12 +2564,18 @@ device_release_drag_surface(struct weston_seat *seat) static void device_map_drag_surface(struct weston_seat *seat) { + struct wl_list *list; + if (weston_surface_is_mapped(seat->drag_surface) || !seat->drag_surface->buffer) return; - wl_list_insert(&seat->sprite->layer_link, - &seat->drag_surface->layer_link); + if (seat->sprite && weston_surface_is_mapped(seat->sprite)) + list = &seat->sprite->layer_link; + else + list = &seat->compositor->cursor_layer.surface_list; + + wl_list_insert(list, &seat->drag_surface->layer_link); weston_surface_assign_output(seat->drag_surface); empty_region(&seat->drag_surface->input); } diff --git a/src/compositor.h b/src/compositor.h index b5136fc..4147811 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -207,6 +207,7 @@ struct weston_seat { struct weston_compositor *compositor; struct weston_surface *sprite; + struct wl_listener sprite_destroy_listener; struct weston_surface *drag_surface; struct wl_listener drag_surface_destroy_listener; int32_t hotspot_x, hotspot_y; -- 2.7.4