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.
This commit is contained in:
Kristian Høgsberg 2013-09-04 20:44:26 -07:00
parent 0749e3f470
commit 85de9c25fe
2 changed files with 49 additions and 32 deletions

View file

@ -392,6 +392,11 @@ wl_data_device_manager_init(struct wl_display *display);
void
weston_seat_set_selection(struct weston_seat *seat,
struct weston_data_source *source, uint32_t serial);
int
weston_seat_start_drag(struct weston_seat *seat,
struct weston_data_source *source,
struct weston_surface *icon,
struct wl_client *client);
struct weston_xkb_info {
struct xkb_keymap *keymap;

View file

@ -358,50 +358,30 @@ handle_drag_icon_destroy(struct wl_listener *listener, void *data)
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);
@ -415,6 +395,38 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
weston_pointer_start_grab(seat->pointer, &drag->grab);
}
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)
{