[PATCH wayland 06/10] Add cursor object representing the visible pointer
Daniel Stone
daniel at fooishbar.org
Mon Jul 23 11:54:43 PDT 2012
The wl_cursor object represents a visible on-screen cursor, with
co-ordinates and a surface image. Add hooks for compositors to be able
to discover new cursors and be informed when they change, and have the
core implementation track the location.
Signed-off-by: Daniel Stone <daniel at fooishbar.org>
---
src/data-device.c | 30 +++++++++++++++++-----
src/wayland-server.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++---
src/wayland-server.h | 27 ++++++++++++++++++--
3 files changed, 115 insertions(+), 11 deletions(-)
diff --git a/src/data-device.c b/src/data-device.c
index 82020af..c19e14f 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -212,6 +212,12 @@ drag_grab_focus(struct wl_pointer_grab *grab,
&seat->drag_focus_listener);
seat->drag_focus_resource = resource;
grab->focus = surface;
+
+ seat->pointer->cursor.icon = seat->drag_cursor.icon;
+ seat->pointer->cursor.x = seat->pointer->x;
+ seat->pointer->cursor.y = seat->pointer->y;
+ wl_signal_emit(&seat->pointer->cursor.update_signal,
+ &seat->pointer->cursor);
}
static void
@@ -223,6 +229,11 @@ drag_grab_motion(struct wl_pointer_grab *grab,
if (seat->drag_focus_resource)
wl_data_device_send_motion(seat->drag_focus_resource,
time, x, y);
+
+ seat->pointer->cursor.x = seat->pointer->x;
+ seat->pointer->cursor.y = seat->pointer->y;
+ wl_signal_emit(&seat->pointer->cursor.update_signal,
+ &seat->pointer->cursor);
}
static void
@@ -231,14 +242,15 @@ data_device_end_drag_grab(struct wl_seat *seat)
struct wl_resource *surface_resource;
struct wl_surface_interface *implementation;
- if (seat->drag_surface) {
- surface_resource = &seat->drag_surface->resource;
+ if (seat->drag_cursor.icon) {
+ surface_resource = &seat->drag_cursor.icon->resource;
implementation = (struct wl_surface_interface *)
surface_resource->object.implementation;
implementation->attach(surface_resource->client,
surface_resource, NULL, 0, 0);
wl_list_remove(&seat->drag_icon_listener.link);
+ seat->drag_cursor.icon = NULL;
}
drag_grab_focus(&seat->drag_grab, NULL,
@@ -247,7 +259,7 @@ data_device_end_drag_grab(struct wl_seat *seat)
wl_pointer_end_grab(seat->pointer);
seat->drag_data_source = NULL;
- seat->drag_surface = NULL;
+ seat->drag_cursor.icon = NULL;
seat->drag_client = NULL;
}
@@ -292,7 +304,12 @@ destroy_data_device_icon(struct wl_listener *listener, void *data)
struct wl_seat *seat = container_of(listener, struct wl_seat,
drag_icon_listener);
- seat->drag_surface = NULL;
+ if (seat->pointer->cursor.icon == seat->drag_cursor.icon) {
+ seat->pointer->cursor.icon = NULL;
+ wl_signal_emit(&seat->pointer->cursor.update_signal,
+ &seat->pointer->cursor);
+ }
+ seat->drag_cursor.icon = NULL;
}
static void
@@ -322,11 +339,12 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
}
if (icon_resource) {
- seat->drag_surface = icon_resource->data;
+ seat->drag_cursor.icon = icon_resource->data;
+ seat->drag_cursor.hotspot_x = 0;
+ seat->drag_cursor.hotspot_y = 0;
seat->drag_icon_listener.notify = destroy_data_device_icon;
wl_signal_add(&icon_resource->destroy_signal,
&seat->drag_icon_listener);
- wl_signal_emit(&seat->drag_icon_signal, icon_resource);
}
wl_pointer_set_focus(seat->pointer, NULL,
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 88e8433..f9d2522 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -519,6 +519,13 @@ default_grab_focus(struct wl_pointer_grab *grab,
return;
wl_pointer_set_focus(pointer, surface, x, y);
+
+ pointer->cursor.icon = pointer->saved_cursor.icon;
+ pointer->cursor.hotspot_x = pointer->saved_cursor.hotspot_x;
+ pointer->cursor.hotspot_y = pointer->saved_cursor.hotspot_y;
+ pointer->cursor.x = pointer->x;
+ pointer->cursor.y = pointer->y;
+ wl_signal_emit(&pointer->cursor.update_signal, &pointer->cursor);
}
static void
@@ -526,10 +533,15 @@ default_grab_motion(struct wl_pointer_grab *grab,
uint32_t time, wl_fixed_t x, wl_fixed_t y)
{
struct wl_resource *resource;
+ struct wl_pointer *pointer = grab->pointer;
- resource = grab->pointer->focus_resource;
+ resource = pointer->focus_resource;
if (resource)
wl_pointer_send_motion(resource, time, x, y);
+
+ pointer->cursor.x = pointer->x;
+ pointer->cursor.y = pointer->y;
+ wl_signal_emit(&pointer->cursor.update_signal, &pointer->cursor);
}
static void
@@ -627,6 +639,47 @@ static const struct wl_keyboard_grab_interface
default_grab_modifiers,
};
+static void
+saved_cursor_destroy_listener(struct wl_listener *listener, void *data)
+{
+ struct wl_pointer *pointer =
+ container_of(listener, struct wl_pointer, icon_listener);
+
+ if (pointer->cursor.icon == pointer->saved_cursor.icon) {
+ pointer->cursor.icon = NULL;
+ wl_signal_emit(&pointer->cursor.update_signal,
+ &pointer->cursor);
+ }
+
+ pointer->saved_cursor.icon = NULL;
+}
+
+WL_EXPORT void
+wl_pointer_set_cursor_icon(struct wl_pointer *pointer,
+ struct wl_surface *cursor,
+ int32_t hotspot_x,
+ int32_t hotspot_y)
+{
+ if (pointer->saved_cursor.icon)
+ wl_list_remove(&pointer->icon_listener.link);
+
+ pointer->saved_cursor.icon = cursor;
+ if (cursor)
+ wl_signal_add(&cursor->resource.destroy_signal,
+ &pointer->icon_listener);
+ pointer->saved_cursor.hotspot_x = hotspot_x;
+ pointer->saved_cursor.hotspot_y = hotspot_y;
+
+ /* Grabs will set their own cursor. */
+ if (pointer->grab != &pointer->default_grab)
+ return;
+
+ pointer->cursor.icon = pointer->saved_cursor.icon;
+ pointer->cursor.hotspot_x = pointer->saved_cursor.hotspot_x;
+ pointer->cursor.hotspot_y = pointer->saved_cursor.hotspot_y;
+ wl_signal_emit(&pointer->cursor.update_signal, &pointer->cursor);
+}
+
WL_EXPORT void
wl_pointer_init(struct wl_pointer *pointer)
{
@@ -638,6 +691,10 @@ wl_pointer_init(struct wl_pointer *pointer)
pointer->grab = &pointer->default_grab;
wl_signal_init(&pointer->focus_signal);
+ pointer->icon_listener.notify = saved_cursor_destroy_listener;
+ wl_signal_init(&pointer->cursor.update_signal);
+ wl_signal_init(&pointer->cursor.destroy_signal);
+
/* FIXME: Pick better co-ords. */
pointer->x = wl_fixed_from_int(100);
pointer->y = wl_fixed_from_int(100);
@@ -649,6 +706,10 @@ wl_pointer_release(struct wl_pointer *pointer)
/* XXX: What about pointer->resource_list? */
if (pointer->focus_resource)
wl_list_remove(&pointer->focus_listener.link);
+ if (pointer->saved_cursor.icon)
+ wl_list_remove(&pointer->icon_listener.link);
+ wl_signal_emit(&pointer->cursor.destroy_signal,
+ &pointer->cursor);
}
WL_EXPORT void
@@ -700,7 +761,7 @@ wl_seat_init(struct wl_seat *seat)
wl_list_init(&seat->base_resource_list);
wl_signal_init(&seat->selection_signal);
wl_list_init(&seat->drag_resource_list);
- wl_signal_init(&seat->drag_icon_signal);
+ wl_signal_init(&seat->cursor_signal);
}
WL_EXPORT void
@@ -742,8 +803,10 @@ wl_seat_set_pointer(struct wl_seat *seat, struct wl_pointer *pointer)
return;
seat->pointer = pointer;
- if (pointer)
+ if (pointer) {
pointer->seat = seat;
+ wl_signal_emit(&seat->cursor_signal, &pointer->cursor);
+ }
seat_send_updated_caps(seat);
}
diff --git a/src/wayland-server.h b/src/wayland-server.h
index f092145..f7a0957 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -239,6 +239,19 @@ struct wl_data_source {
void (*cancel)(struct wl_data_source *source);
};
+struct wl_cursor {
+ struct wl_signal update_signal;
+ struct wl_signal destroy_signal;
+
+ struct wl_surface *icon;
+
+ wl_fixed_t x;
+ wl_fixed_t y;
+
+ int32_t hotspot_x;
+ int32_t hotspot_y;
+};
+
struct wl_pointer {
struct wl_seat *seat;
@@ -260,6 +273,10 @@ struct wl_pointer {
struct wl_surface *current;
wl_fixed_t current_x, current_y;
+ struct wl_cursor cursor;
+ struct wl_cursor saved_cursor;
+ struct wl_listener icon_listener;
+
uint32_t button_count;
};
@@ -307,6 +324,8 @@ struct wl_seat {
struct wl_keyboard *keyboard;
struct wl_touch *touch;
+ struct wl_signal cursor_signal;
+
uint32_t selection_serial;
struct wl_data_source *selection_data_source;
struct wl_listener selection_data_source_listener;
@@ -320,9 +339,8 @@ struct wl_seat {
struct wl_resource *drag_focus_resource;
struct wl_listener drag_focus_listener;
struct wl_pointer_grab drag_grab;
- struct wl_surface *drag_surface;
+ struct wl_cursor drag_cursor;
struct wl_listener drag_icon_listener;
- struct wl_signal drag_icon_signal;
};
/*
@@ -389,6 +407,11 @@ wl_pointer_start_grab(struct wl_pointer *pointer,
struct wl_pointer_grab *grab);
void
wl_pointer_end_grab(struct wl_pointer *pointer);
+void
+wl_pointer_set_cursor_icon(struct wl_pointer *pointer,
+ struct wl_surface *cursor,
+ wl_fixed_t hotspot_x,
+ wl_fixed_t hotspot_y);
void
wl_keyboard_init(struct wl_keyboard *keyboard);
--
1.7.10.4
More information about the wayland-devel
mailing list