When user drags a file to SpiceDisplay and drops it, a signal named "drag-data-received" will be emitted, the signal will be received by SpiceDisplay, then our signal handler will receive data which contains file path, and call spice_dnd_process() to transfer file to guest. Signed-off-by: Dunrong Huang <riegamaths@xxxxxxxxx> --- gtk/spice-widget.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c index cdcff03..ecb3d4e 100644 --- a/gtk/spice-widget.c +++ b/gtk/spice-widget.c @@ -38,6 +38,7 @@ #include "spice-widget-priv.h" #include "spice-gtk-session-priv.h" #include "vncdisplaykeymap.h" +#include "spice-dnd.h" #include "glib-compat.h" @@ -464,14 +465,61 @@ static gboolean grab_broken(SpiceDisplay *self, GdkEventGrabBroken *event, return false; } +/* TODO: support transfering multiple files and directories. */ +static void dnd_receive(SpiceDisplay *self, GdkDragContext *drag_context, gint x, + gint y, GtkSelectionData *data, guint info, + guint time, gpointer *user_data) +{ + int len; + char *uri = NULL; + char *buf; + int i; + GFile *f = NULL; + char *path = NULL; + + buf = (char *)gtk_selection_data_get_data_with_length(data, &len); + if (buf == NULL) { + goto done; + } + + /* original uri may terminate with network proper \r\n + e.g. file:///root/example.txt\r\n, strip \r\n */ + uri = g_malloc0(len + 1); + memcpy(uri, buf, len); + i = len - 1; + while (uri[i] == '\n' || uri[i] == '\r') { + uri[i] = '\0'; + if (--i < 0) + break; + } + + /* Gets the absolute pathname */ + f = g_file_new_for_uri(uri); + path = g_file_get_path(f); + g_object_unref(f); + if (!path) { + goto done; + } + + spice_dnd_process(self, path); + +done: + gtk_drag_finish(drag_context, TRUE, FALSE, time); + g_free(path); + g_free(uri); +} + static void spice_display_init(SpiceDisplay *display) { GtkWidget *widget = GTK_WIDGET(display); SpiceDisplayPrivate *d; + GtkTargetEntry targets = {"text/plain", 0, 0}; d = display->priv = SPICE_DISPLAY_GET_PRIVATE(display); g_signal_connect(display, "grab-broken-event", G_CALLBACK(grab_broken), NULL); + gtk_drag_dest_set(widget, GTK_DEST_DEFAULT_ALL, &targets, 1, GDK_ACTION_COPY); + g_signal_connect(display, "drag-data-received", G_CALLBACK(dnd_receive), NULL); gtk_widget_add_events(widget, GDK_STRUCTURE_MASK | GDK_POINTER_MOTION_MASK | -- 1.7.12.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel