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

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to