[Spice-devel] [RFC] [PATCH spice-gtk 2/4] DND: Add spice-dnd.c

Dunrong Huang riegamaths at gmail.com
Mon Nov 5 01:01:16 PST 2012


The file provides a API spice_dnd_process for processing DND message,
e.g. sending DND start message.

After received "drag-data-received" signal, SpiceDisplay could call
this API to sending dnd message.

Signed-off-by: Dunrong Huang <riegamaths at gmail.com>
---
 gtk/Makefile.am         |   1 +
 gtk/map-file            |   1 +
 gtk/spice-dnd.c         | 100 ++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/spice-dnd.h         |  24 ++++++++++++
 gtk/spice-glib-sym-file |   1 +
 5 files changed, 127 insertions(+)
 create mode 100644 gtk/spice-dnd.c
 create mode 100644 gtk/spice-dnd.h

diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 06cc6e1..c8ae1b3 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -128,6 +128,7 @@ SPICE_GTK_SOURCES_COMMON =		\
 	desktop-integration.c		\
 	desktop-integration.h		\
 	usb-device-widget.c		\
+	spice-dnd.c				\
 	$(NULL)
 
 nodist_SPICE_GTK_SOURCES_COMMON =	\
diff --git a/gtk/map-file b/gtk/map-file
index 3b26d1d..2efeed8 100644
--- a/gtk/map-file
+++ b/gtk/map-file
@@ -55,6 +55,7 @@ spice_inputs_set_key_locks;
 spice_main_agent_test_capability;
 spice_main_dnd_start;
 spice_main_dnd_send_data;
+spice_dnd_process;
 spice_main_channel_get_type;
 spice_main_clipboard_grab;
 spice_main_clipboard_notify;
diff --git a/gtk/spice-dnd.c b/gtk/spice-dnd.c
new file mode 100644
index 0000000..3593c9d
--- /dev/null
+++ b/gtk/spice-dnd.c
@@ -0,0 +1,100 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+   Copyright (C) 2012 Dunrong Huang <riegamaths at gmail.com>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <spice/vd_agent.h>
+
+#include "spice-common.h"
+#include "channel-main.h"
+#include "spice-widget.h"
+#include "spice-widget-priv.h"
+#include "glib-compat.h"
+
+void spice_dnd_process(SpiceDisplay *display, const char *file_path)
+{
+#define DND_CHUNK_SIZE 1600
+    int fd;
+    struct stat st;
+    VDAgentDndMessage *msg;
+    const char *file_name;
+    int size;
+    SpiceDisplayPrivate *d;
+
+    d = SPICE_DISPLAY_GET_PRIVATE(display);
+    if (!d->main) {
+        g_warning("SpiceDisplay does not main channel");
+        return ;
+    }
+    g_print("DND start, file:%s\n", file_path);
+
+    /* TODO: use glib to open/read file */
+    fd = open(file_path, O_RDONLY);
+    if (fd == -1) {
+        g_warning("Open file %s error: %s\n", file_path, strerror(errno));
+        return ;
+    }
+
+    if (fstat(fd, &st) == -1) {
+        g_warning("Fetch file size error: %s\n", strerror(errno));
+        close(fd);
+        return ;
+    }
+
+    /* Get file basename */
+    file_name = strrchr(file_path, '/');
+    if (file_name) {
+        file_name++;
+    } else {
+        file_name = file_path;
+    }
+    size = sizeof(VDAgentDndMessage) + strlen(file_name) + 1;
+    msg = g_malloc0(size);
+    msg->file_size = st.st_size;
+    snprintf((char *)msg->file_name, strlen(file_name) + 1, "%s", file_name);
+
+    /* Send dnd start message to guest */
+    /* TODO: check whether guest has enough space to store file. */
+    spice_main_dnd_start(d->main, msg, size);
+    g_free(msg);
+
+    /* Start transfering file content */
+    for (;;) {
+        int len;
+        char buf[DND_CHUNK_SIZE];
+        len = read(fd, buf, sizeof(buf));
+        if (len == -1) {
+            if (errno == EINTR) {
+                continue;
+            } else {
+                g_warning("Read file error: %s\n", strerror(errno));
+                break;
+            }
+        } else if (len == 0) {
+            break;
+        }
+        spice_main_dnd_send_data(d->main, buf, len);
+    }
+
+    g_print("DND finish\n");
+    close(fd);
+}
diff --git a/gtk/spice-dnd.h b/gtk/spice-dnd.h
new file mode 100644
index 0000000..aea55c6
--- /dev/null
+++ b/gtk/spice-dnd.h
@@ -0,0 +1,24 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+   Copyright (C) 2012 Dunrong Huang <riegamaths at gmail.com>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __SPICE_DND_H__
+#define __SPICE_DND_H__
+
+void spice_dnd_process(SpiceDisplay *display, const char *file_path);
+
+#endif /* __SPICE_DND_H__ */
diff --git a/gtk/spice-glib-sym-file b/gtk/spice-glib-sym-file
index 35886c8..bb7e495 100644
--- a/gtk/spice-glib-sym-file
+++ b/gtk/spice-glib-sym-file
@@ -31,6 +31,7 @@ spice_inputs_set_key_locks
 spice_main_agent_test_capability
 spice_main_dnd_start
 spice_main_dnd_send_data
+spice_dnd_process
 spice_main_channel_get_type
 spice_main_clipboard_grab
 spice_main_clipboard_notify
-- 
1.7.12.4



More information about the Spice-devel mailing list