From: Kristian Høgsberg Date: Sat, 28 Aug 2010 00:29:56 +0000 (-0400) Subject: Update drag protocol to use fd passing for data transfer X-Git-Tag: 0.85.0~862 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4eb536091af7983847cef482072f053f1ab9d8b2;p=profile%2Fivi%2Fweston.git Update drag protocol to use fd passing for data transfer --- diff --git a/clients/dnd.c b/clients/dnd.c index 3df1202..07b8053 100644 --- a/clients/dnd.c +++ b/clients/dnd.c @@ -47,6 +47,8 @@ struct dnd { struct wl_buffer *buffer; int hotspot_x, hotspot_y; + uint32_t tag; + const char *drag_type; }; struct item { @@ -221,9 +223,20 @@ drag_pointer_focus(void *data, uint32_t time, struct wl_surface *surface, int32_t x, int32_t y, int32_t surface_x, int32_t surface_y) { + struct dnd *dnd = data; + + /* FIXME: We need the offered types before we get the + * pointer_focus event so we know which one we want and can + * send the accept request back. */ + fprintf(stderr, "drag pointer focus %p\n", surface); - wl_drag_accept(drag, "text/plain"); + if (surface) { + wl_drag_accept(drag, "text/plain"); + dnd->drag_type = "text/plain"; + } else { + dnd->drag_type = NULL; + } } static void @@ -239,13 +252,14 @@ drag_motion(void *data, uint32_t time, int32_t x, int32_t y, int32_t surface_x, int32_t surface_y) { - fprintf(stderr, "drag motion %d,%d\n", surface_x, surface_y); + struct dnd *dnd = data; /* FIXME: Need to correlate this with the offer event. * Problem is, we don't know when we've seen that last offer * event, and we might need to look at all of them before we * can decide which one to go with. */ wl_drag_accept(drag, "text/plain"); + dnd->drag_type = "text/plain"; } static void @@ -256,32 +270,63 @@ drag_target(void *data, struct input *input; struct wl_input_device *device; - fprintf(stderr, "target %s\n", mime_type); - input = wl_drag_get_user_data(drag); device = input_get_input_device(input); wl_input_device_attach(device, dnd->buffer, dnd->hotspot_x, dnd->hotspot_y); } +static gboolean +drop_io_func(GIOChannel *source, GIOCondition condition, gpointer data) +{ + struct dnd *dnd = data; + char buffer[256]; + int fd; + unsigned int len; + GError *err = NULL; + + g_io_channel_read_chars(source, buffer, sizeof buffer, &len, &err); + fprintf(stderr, "read %d bytes: %s\n", len, buffer); + fd = g_io_channel_unix_get_fd(source); + close(fd); + g_source_remove(dnd->tag); + + g_io_channel_unref(source); + + return TRUE; +} + static void -drag_finish(void *data, struct wl_drag *drag) +drag_drop(void *data, struct wl_drag *drag) { - fprintf(stderr, "drag finish\n"); - struct wl_array a; - char text[] = "[drop data]"; + struct dnd *dnd = data; + int p[2]; + GIOChannel *channel; - a.data = text; - a.size = sizeof text; + if (!dnd->drag_type) { + fprintf(stderr, "got 'drop', but no target\n"); + return; + } - wl_drag_send(drag, &a); + fprintf(stderr, "got 'drop', sending write end of pipe\n"); + + pipe(p); + wl_drag_receive(drag, p[1]); + close(p[1]); + + channel = g_io_channel_unix_new(p[0]); + dnd->tag = g_io_add_watch(channel, G_IO_IN, drop_io_func, dnd); } static void -drag_data(void *data, - struct wl_drag *drag, struct wl_array *contents) +drag_finish(void *data, struct wl_drag *drag, int fd) { - fprintf(stderr, "drag drop, data %s\n", (char *) contents->data); + char text[] = "[drop data]"; + + fprintf(stderr, "got 'finish', fd %d, sending message\n", fd); + + write(fd, text, sizeof text); + close(fd); } static const struct wl_drag_listener drag_listener = { @@ -290,8 +335,8 @@ static const struct wl_drag_listener drag_listener = { drag_offer, drag_motion, drag_target, - drag_finish, - drag_data + drag_drop, + drag_finish }; static void diff --git a/clients/window.c b/clients/window.c index 7c2579d..24f1a70 100644 --- a/clients/window.c +++ b/clients/window.c @@ -1120,13 +1120,12 @@ drag_target(void *data, } static void -drag_finish(void *data, struct wl_drag *drag) +drag_drop(void *data, struct wl_drag *drag) { } static void -drag_data(void *data, - struct wl_drag *drag, struct wl_array *contents) +drag_finish(void *data, struct wl_drag *drag, int fd) { } @@ -1136,8 +1135,8 @@ static const struct wl_drag_listener drag_listener = { drag_offer, drag_motion, drag_target, - drag_finish, - drag_data + drag_drop, + drag_finish }; static void diff --git a/compositor.c b/compositor.c index 09c77ca..4f82f5b 100644 --- a/compositor.c +++ b/compositor.c @@ -823,9 +823,10 @@ wlsc_input_device_end_grab(struct wlsc_input_device *device, uint32_t time) switch (device->grab) { case WLSC_DEVICE_GRAB_DRAG: + if (drag->target) + wl_client_post_event(drag->target, + &drag->base, WL_DRAG_DROP); wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0); - wl_surface_post_event(drag->source, &drag->base, - WL_DRAG_FINISH); wl_drag_reset(drag); break; default: @@ -1030,6 +1031,7 @@ wl_drag_set_pointer_focus(struct wl_drag *drag, drag->pointer_focus = &surface->base; + drag->target = NULL; } static void @@ -1043,12 +1045,12 @@ wl_drag_reset(struct wl_drag *drag) wl_array_release(&drag->types); wl_array_init(&drag->types); - drag->source = NULL; - /* FIXME: We need to reset drag->target too, but can't right * now because we need it for send/drop. * - * drag->target = NULL; */ + * drag->target = NULL; + * drag->source = NULL; + */ drag->time = 0; drag->pointer_focus = NULL; } @@ -1132,14 +1134,6 @@ drag_cancel(struct wl_client *client, struct wl_drag *drag) } static void -drag_send(struct wl_client *client, - struct wl_drag *drag, struct wl_array *contents) -{ - wl_client_post_event(drag->target, - &drag->base, WL_DRAG_DROP, contents); -} - -static void drag_accept(struct wl_client *client, struct wl_drag *drag, const char *type) { @@ -1181,13 +1175,21 @@ drag_accept(struct wl_client *client, WL_DRAG_TARGET, drag->type); } +static void +drag_receive(struct wl_client *client, + struct wl_drag *drag, int fd) +{ + wl_surface_post_event(drag->source, &drag->base, WL_DRAG_FINISH, fd); + close(fd); +} + static const struct wl_drag_interface drag_interface = { drag_prepare, drag_offer, drag_activate, drag_cancel, - drag_send, - drag_accept + drag_accept, + drag_receive }; static void diff --git a/protocol.xml b/protocol.xml index 01d8a73..390fb23 100644 --- a/protocol.xml +++ b/protocol.xml @@ -115,17 +115,19 @@ - - - - - + + + + + @@ -167,18 +169,23 @@ - - - - - - + + + + + + +