[RFC wayland] seat: add wl_relative_pointer
Philipp Brüschweiler
blei42 at gmail.com
Sat Sep 1 08:49:50 PDT 2012
This pointer is equivalent to the "normal" pointer, except that it sends
relative motion events.
---
protocol/wayland.xml | 93 +++++++++++++++++++++++++++++++++++++++++++++++
src/data-device.c | 3 +-
src/wayland-server.c | 101 +++++++++++++++++++++++++++++++++++++++------------
src/wayland-server.h | 16 ++++++--
4 Dateien geändert, 185 Zeilen hinzugefügt(+), 28 Zeilen entfernt(-)
diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index 5e56cb8..a789ac3 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -755,6 +755,14 @@
<arg name="id" type="new_id" interface="wl_pointer"/>
</request>
+ <request name="get_relative_pointer">
+ <description summary="return pointer object">
+ The ID provided will be initialized to the wl_relative_pointer
+ interface for this seat.
+ </description>
+ <arg name="id" type="new_id" interface="wl_relative_pointer"/>
+ </request>
+
<request name="get_keyboard">
<description summary="return pointer object">
The ID provided will be initialized to the wl_keyboard interface
@@ -872,6 +880,91 @@
</event>
</interface>
+ <interface name="wl_relative_pointer" version="1">
+ <request name="set_cursor">
+ <description summary="set the pointer surface">
+ Set the pointer surface, i.e., the surface that contains the
+ pointer image. This request only takes effect if the pointer
+ focus for this device is one of the requesting client surfaces
+ or the surface parameter is the current pointer surface. If
+ there was a previous surface set with this request it is
+ replaced. If surface is NULL, the pointer image is hidden.
+
+ The parameters hotspot_x and hotspot_y define the position of
+ the pointer surface relative to the pointer location. Its
+ top-left corner is always at (x, y) - (hotspot_x, hotspot_y),
+ where (x, y) are the coordinates of the pointer location.
+
+ On surface.attach requests to the pointer surface, hotspot_x
+ and hotspot_y are decremented by the x and y parameters
+ passed to the request.
+
+ The hotspot can also be updated by passing the current set
+ pointer surface to this request with new values for hotspot_x
+ and/or hotspot_y.
+ </description>
+
+ <arg name="serial" type="uint"/>
+ <arg name="surface" type="object" interface="wl_surface" allow-null="true"/>
+ <arg name="hotspot_x" type="int"/>
+ <arg name="hotspot_y" type="int"/>
+ </request>
+
+ <event name="enter">
+ <description summary="enter event">
+ Notification that this seat's pointer is focused on a certain
+ surface. When an seat's focus enters a surface, the pointer image
+ is undefined and a client should respond to this event by setting
+ an appropriate pointer image.
+ </description>
+
+ <arg name="serial" type="uint"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="surface_x" type="fixed"/>
+ <arg name="surface_y" type="fixed"/>
+ </event>
+
+ <event name="leave">
+ <description summary="leave event">
+ </description>
+ <arg name="serial" type="uint"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ </event>
+
+ <event name="motion">
+ <description summary="pointer motion event">
+ Notification of pointer location change. The arguments d[xy]
+ are the location relative to the last position that triggered an event.
+ </description>
+
+ <arg name="time" type="uint"/>
+ <arg name="dx" type="fixed"/>
+ <arg name="dy" type="fixed"/>
+ </event>
+
+ <event name="button">
+ <description summary="pointer button event">
+ Mouse button click and release notifications. The location
+ of the click is given by the last motion or pointer_focus event.
+ </description>
+
+ <arg name="serial" type="uint"/>
+ <arg name="time" type="uint"/>
+ <arg name="button" type="uint"/>
+ <arg name="state" type="uint"/>
+ </event>
+
+ <event name="axis">
+ <description summary="axis event">
+ Scroll and other axis notifications.
+ </description>
+
+ <arg name="time" type="uint"/>
+ <arg name="axis" type="uint"/>
+ <arg name="value" type="fixed"/>
+ </event>
+ </interface>
+
<interface name="wl_keyboard" version="1">
<description summary="keyboard input device">
</description>
diff --git a/src/data-device.c b/src/data-device.c
index 82020af..f2d0b21 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -216,7 +216,8 @@ drag_grab_focus(struct wl_pointer_grab *grab,
static void
drag_grab_motion(struct wl_pointer_grab *grab,
- uint32_t time, wl_fixed_t x, wl_fixed_t y)
+ uint32_t time, wl_fixed_t x, wl_fixed_t y,
+ wl_fixed_t dx, wl_fixed_t dy)
{
struct wl_seat *seat = container_of(grab, struct wl_seat, drag_grab);
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 88e8433..a30df41 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -488,7 +488,8 @@ lose_pointer_focus(struct wl_listener *listener, void *data)
struct wl_pointer *pointer =
container_of(listener, struct wl_pointer, focus_listener);
- pointer->focus_resource = NULL;
+ pointer->abs.focus_resource = NULL;
+ pointer->rel.focus_resource = NULL;
}
static void
@@ -523,13 +524,18 @@ default_grab_focus(struct wl_pointer_grab *grab,
static void
default_grab_motion(struct wl_pointer_grab *grab,
- uint32_t time, wl_fixed_t x, wl_fixed_t y)
+ uint32_t time, wl_fixed_t x, wl_fixed_t y,
+ wl_fixed_t dx, wl_fixed_t dy)
{
struct wl_resource *resource;
- resource = grab->pointer->focus_resource;
+ resource = grab->pointer->abs.focus_resource;
if (resource)
wl_pointer_send_motion(resource, time, x, y);
+
+ resource = grab->pointer->rel.focus_resource;
+ if (resource)
+ wl_relative_pointer_send_motion(resource, time, dx, dy);
}
static void
@@ -537,15 +543,27 @@ default_grab_button(struct wl_pointer_grab *grab,
uint32_t time, uint32_t button, uint32_t state_w)
{
struct wl_pointer *pointer = grab->pointer;
- struct wl_resource *resource;
+ struct wl_resource *resource, *rel_resource;
uint32_t serial;
enum wl_pointer_button_state state = state_w;
- resource = pointer->focus_resource;
- if (resource) {
+ resource = pointer->abs.focus_resource;
+ rel_resource = pointer->rel.focus_resource;
+
+ assert(!resource || !rel_resource ||
+ resource->client == rel_resource->client);
+
+ if (resource)
serial = wl_display_next_serial(resource->client->display);
+ else if (rel_resource)
+ serial = wl_display_next_serial(rel_resource->client->display);
+
+ if (resource)
wl_pointer_send_button(resource, serial, time, button, state_w);
- }
+
+ if (rel_resource)
+ wl_relative_pointer_send_button(rel_resource, serial, time,
+ button, state_w);
if (pointer->button_count == 0 &&
state == WL_POINTER_BUTTON_STATE_RELEASED)
@@ -631,7 +649,8 @@ WL_EXPORT void
wl_pointer_init(struct wl_pointer *pointer)
{
memset(pointer, 0, sizeof *pointer);
- wl_list_init(&pointer->resource_list);
+ wl_list_init(&pointer->abs.resource_list);
+ wl_list_init(&pointer->rel.resource_list);
pointer->focus_listener.notify = lose_pointer_focus;
pointer->default_grab.interface = &default_pointer_grab_interface;
pointer->default_grab.pointer = pointer;
@@ -646,8 +665,8 @@ wl_pointer_init(struct wl_pointer *pointer)
WL_EXPORT void
wl_pointer_release(struct wl_pointer *pointer)
{
- /* XXX: What about pointer->resource_list? */
- if (pointer->focus_resource)
+ /* XXX: What about pointer->{abs,rel}.resource_list? */
+ if (pointer->abs.focus_resource || pointer->rel.focus_resource)
wl_list_remove(&pointer->focus_listener.link);
}
@@ -783,23 +802,48 @@ wl_pointer_set_focus(struct wl_pointer *pointer, struct wl_surface *surface,
wl_fixed_t sx, wl_fixed_t sy)
{
struct wl_keyboard *kbd = pointer->seat->keyboard;
- struct wl_resource *resource, *kr;
+ struct wl_resource *resource, *rel_resource, *kr;
uint32_t serial;
- resource = pointer->focus_resource;
- if (resource && pointer->focus != surface) {
- serial = wl_display_next_serial(resource->client->display);
- wl_pointer_send_leave(resource, serial,
- &pointer->focus->resource);
- wl_list_remove(&pointer->focus_listener.link);
+ resource = pointer->abs.focus_resource;
+ rel_resource = pointer->rel.focus_resource;
+ if (pointer->focus != surface) {
+ if (resource)
+ serial = wl_display_next_serial(resource->client->display);
+ else if (rel_resource)
+ serial = wl_display_next_serial(rel_resource->client->display);
+
+ if (resource)
+ wl_pointer_send_leave(resource, serial,
+ &pointer->focus->resource);
+
+ if (rel_resource)
+ wl_relative_pointer_send_leave(rel_resource, serial,
+ &pointer->focus->resource);
+
+ if (resource || rel_resource)
+ wl_list_remove(&pointer->focus_listener.link);
}
- resource = find_resource_for_surface(&pointer->resource_list,
+ resource = find_resource_for_surface(&pointer->abs.resource_list,
surface);
- if (resource &&
+ rel_resource = find_resource_for_surface(&pointer->rel.resource_list,
+ surface);
+
+ if ((resource || rel_resource) &&
(pointer->focus != surface ||
- pointer->focus_resource != resource)) {
- serial = wl_display_next_serial(resource->client->display);
+ (resource && pointer->abs.focus_resource != resource ) ||
+ (rel_resource && pointer->rel.focus_resource != rel_resource))) {
+ assert(!resource || !rel_resource ||
+ resource->client == rel_resource->client);
+
+ if (resource)
+ serial = wl_display_next_serial(
+ resource->client->display);
+ else
+ serial = wl_display_next_serial(
+ rel_resource->client->display);
+
if (kbd) {
kr = find_resource_for_surface(&kbd->resource_list,
surface);
@@ -812,14 +856,23 @@ wl_pointer_set_focus(struct wl_pointer *pointer, struct wl_surface *surface,
kbd->modifiers.group);
}
}
- wl_pointer_send_enter(resource, serial, &surface->resource,
- sx, sy);
+
+ if (resource)
+ wl_pointer_send_enter(resource, serial, &surface->resource,
+ sx, sy);
+
+ if (rel_resource)
+ wl_relative_pointer_send_enter(rel_resource, serial,
+ &surface->resource,
+ sx, sy);
+
wl_signal_add(&resource->destroy_signal,
&pointer->focus_listener);
pointer->focus_serial = serial;
}
- pointer->focus_resource = resource;
+ pointer->abs.focus_resource = resource;
+ pointer->rel.focus_resource = rel_resource;
pointer->focus = surface;
pointer->default_grab.focus = surface;
wl_signal_emit(&pointer->focus_signal, pointer);
diff --git a/src/wayland-server.h b/src/wayland-server.h
index cd79801..151a277 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -194,7 +194,9 @@ struct wl_pointer_grab_interface {
void (*motion)(struct wl_pointer_grab *grab,
uint32_t time,
wl_fixed_t x,
- wl_fixed_t y);
+ wl_fixed_t y,
+ wl_fixed_t dx,
+ wl_fixed_t dy);
void (*button)(struct wl_pointer_grab *grab,
uint32_t time, uint32_t button, uint32_t state);
};
@@ -242,13 +244,21 @@ struct wl_data_source {
struct wl_pointer {
struct wl_seat *seat;
- struct wl_list resource_list;
struct wl_surface *focus;
- struct wl_resource *focus_resource;
struct wl_listener focus_listener;
uint32_t focus_serial;
struct wl_signal focus_signal;
+ struct {
+ struct wl_resource *focus_resource;
+ struct wl_list resource_list;
+ } abs;
+
+ struct {
+ struct wl_resource *focus_resource;
+ struct wl_list resource_list;
+ } rel;
+
struct wl_pointer_grab *grab;
struct wl_pointer_grab default_grab;
wl_fixed_t grab_x, grab_y;
--
1.7.12
More information about the wayland-devel
mailing list