compositor: Split dnd setup up into weston_seat_start_drag()
This makes the drag-and-drop code available to in-weston data sources,
similar to how we can set a selection data source internally. The
wl_data_device.start_drag entry point now calls this function after
validating protocol arguments.
diff --git a/src/data-device.c b/src/data-device.c
index 1eb1925..ec3df33 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -358,50 +358,30 @@
drag->icon = NULL;
}
-static void
-data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
- struct wl_resource *source_resource,
- struct wl_resource *origin_resource,
- struct wl_resource *icon_resource, uint32_t serial)
+WL_EXPORT int
+weston_seat_start_drag(struct weston_seat *seat,
+ struct weston_data_source *source,
+ struct weston_surface *icon,
+ struct wl_client *client)
{
- struct weston_seat *seat = wl_resource_get_user_data(resource);
struct weston_drag *drag;
- struct weston_surface *icon = NULL;
-
- if (seat->pointer->button_count == 0 ||
- seat->pointer->grab_serial != serial ||
- seat->pointer->focus != wl_resource_get_user_data(origin_resource))
- return;
-
- /* FIXME: Check that the data source type array isn't empty. */
-
- if (icon_resource)
- icon = wl_resource_get_user_data(icon_resource);
- if (icon && icon->configure) {
- wl_resource_post_error(icon_resource,
- WL_DISPLAY_ERROR_INVALID_OBJECT,
- "surface->configure already set");
- return;
- }
drag = zalloc(sizeof *drag);
- if (drag == NULL) {
- wl_resource_post_no_memory(resource);
- return;
- }
+ if (drag == NULL)
+ return -1;
drag->grab.interface = &drag_grab_interface;
drag->client = client;
+ drag->data_source = source;
+ drag->icon = icon;
- if (source_resource) {
- drag->data_source = wl_resource_get_user_data(source_resource);
+ if (source) {
drag->data_source_listener.notify = destroy_data_device_source;
- wl_resource_add_destroy_listener(source_resource,
- &drag->data_source_listener);
+ wl_signal_add(&source->destroy_signal,
+ &drag->data_source_listener);
}
if (icon) {
- drag->icon = icon;
drag->icon_destroy_listener.notify = handle_drag_icon_destroy;
wl_signal_add(&icon->destroy_signal,
&drag->icon_destroy_listener);
@@ -416,6 +396,38 @@
}
static void
+data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
+ struct wl_resource *source_resource,
+ struct wl_resource *origin_resource,
+ struct wl_resource *icon_resource, uint32_t serial)
+{
+ struct weston_seat *seat = wl_resource_get_user_data(resource);
+ struct weston_data_source *source;
+ struct weston_surface *icon = NULL;
+
+ if (seat->pointer->button_count == 0 ||
+ seat->pointer->grab_serial != serial ||
+ seat->pointer->focus != wl_resource_get_user_data(origin_resource))
+ return;
+
+ /* FIXME: Check that the data source type array isn't empty. */
+
+ if (source_resource)
+ source = wl_resource_get_user_data(source_resource);
+ if (icon_resource)
+ icon = wl_resource_get_user_data(icon_resource);
+ if (icon && icon->configure) {
+ wl_resource_post_error(icon_resource,
+ WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "surface->configure already set");
+ return;
+ }
+
+ if (weston_seat_start_drag(seat, source, icon, client) < 0)
+ wl_resource_post_no_memory(resource);
+}
+
+static void
destroy_selection_data_source(struct wl_listener *listener, void *data)
{
struct weston_seat *seat = container_of(listener, struct weston_seat,