---
 src/compositor.c |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/compositor.h |    1 +
 2 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index a519893..e2d9b4e 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -772,6 +772,8 @@ weston_compositor_top(struct weston_compositor *compositor)
                list = list->next;
        if (list->next == &input_device->sprite->link)
                list = list->next;
+       if (list->next == &input_device->drag_surface->link)
+               list = list->next;
 
        return list;
 }
@@ -903,6 +905,9 @@ struct weston_frame_callback {
 };
 
 static void
+update_drag_surface(struct wl_input_device *input_device, int dx, int dy);
+
+static void
 weston_output_repaint(struct weston_output *output, int msecs)
 {
        struct weston_compositor *ec = output->compositor;
@@ -923,6 +928,8 @@ weston_output_repaint(struct weston_output *output, int 
msecs)
        pixman_region32_init(&opaque);
        pixman_region32_init(&overlap);
 
+       update_drag_surface(ec->input_device, 0, 0);
+
        wl_list_for_each(es, &ec->surface_list, link) {
                weston_surface_update_transform(es);
 
@@ -1286,6 +1293,31 @@ idle_handler(void *data)
        return 1;
 }
 
+static void
+update_drag_surface(struct wl_input_device *input_device, int dx, int dy)
+{
+       struct weston_input_device *device =
+               (struct weston_input_device *) input_device;
+       struct weston_surface *drag_surface = device->drag_surface;
+
+       weston_surface_damage_below(drag_surface);
+
+       if (device->input_device.drag_icon_x != 0 ||
+           device->input_device.drag_icon_y != 0) {
+               drag_surface->geometry.x = device->input_device.x +
+                       device->input_device.drag_icon_x;
+               drag_surface->geometry.y = device->input_device.y +
+                       device->input_device.drag_icon_y;
+
+               device->input_device.drag_icon_x = 0;
+               device->input_device.drag_icon_y = 0;
+       }
+
+       drag_surface->geometry.x = drag_surface->geometry.x + dx;
+       drag_surface->geometry.y = drag_surface->geometry.y + dy;
+       drag_surface->geometry.dirty = 1;
+}
+
 WL_EXPORT void
 notify_motion(struct wl_input_device *device, uint32_t time, int x, int y)
 {
@@ -1330,6 +1362,8 @@ notify_motion(struct wl_input_device *device, uint32_t 
time, int x, int y)
                        y = max_y;
        }
 
+       update_drag_surface(device, x - device->x, y - device->y);
+
        device->x = x;
        device->y = y;
 
@@ -1460,6 +1494,8 @@ notify_pointer_focus(struct wl_input_device *device,
        struct weston_compositor *compositor = wd->compositor;
 
        if (output) {
+               update_drag_surface(device, x - device->x, y - device->y);
+
                device->x = x;
                device->y = y;
                compositor->focus = 1;
@@ -1717,6 +1753,26 @@ bind_input_device(struct wl_client *client,
        resource->destroy = unbind_input_device;
 }
 
+static void
+input_create_drag_surface(struct weston_input_device *device)
+{
+       struct weston_surface *drag_surface;
+
+       drag_surface = weston_surface_create(device->compositor);
+       device->drag_surface = drag_surface;
+
+       drag_surface->surface.resource.destroy = NULL;
+       drag_surface->surface.resource.client = NULL;
+       drag_surface->surface.resource.object.interface =
+               &wl_surface_interface;
+       drag_surface->surface.resource.object.implementation =
+               (void (**)(void)) &surface_interface;
+       drag_surface->surface.resource.data = device->drag_surface;
+
+       wl_data_device_set_drag_surface(&device->input_device,
+                                       &drag_surface->surface);
+}
+
 WL_EXPORT void
 weston_input_device_init(struct weston_input_device *device,
                         struct weston_compositor *ec)
@@ -1734,6 +1790,8 @@ weston_input_device_init(struct weston_input_device 
*device,
        device->modifier_state = 0;
        device->num_tp = 0;
 
+       input_create_drag_surface(device);
+
        wl_list_insert(ec->input_device_list.prev, &device->link);
 }
 
@@ -1746,6 +1804,8 @@ weston_input_device_release(struct weston_input_device 
*device)
        if (device->sprite)
                destroy_surface(&device->sprite->surface.resource);
 
+       destroy_surface(&device->drag_surface->surface.resource);
+
        wl_input_device_release(&device->input_device);
 }
 
diff --git a/src/compositor.h b/src/compositor.h
index 80b848d..c3f571f 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -83,6 +83,7 @@ struct weston_input_device {
        struct wl_input_device input_device;
        struct weston_compositor *compositor;
        struct weston_surface *sprite;
+       struct weston_surface *drag_surface;
        int32_t hotspot_x, hotspot_y;
        struct wl_list link;
        uint32_t modifier_state;
-- 
1.7.4.1

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to