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;
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
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
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);
}
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;
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
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;
/* 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);
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);
}