[Spice-commits] 2 commits - src/spice-gtk-session.c

Christophe Fergau teuf at kemper.freedesktop.org
Thu Sep 1 10:52:17 UTC 2016


 src/spice-gtk-session.c |  134 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 95 insertions(+), 39 deletions(-)

New commits:
commit 7b0de6217670e0f668aff2949fba174ed3cc0b50
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Wed Aug 10 12:04:30 2016 +0200

    clipboard: Use gtk_clipboard_request_text for text data
    
    Currently, when the agent asks us for VD_AGENT_CLIPBOARD_UTF8_TEXT data,
    spice-gtk looks up for the first X11 target which would provide it with
    UTF8_TEXT data, and uses that for the clipboard request. This means we
    will use UTF8_STRING as the target for gtk_clipboard_request_contents().
    
    However, some applications who can copy and paste text do not
    necessarily support the UTF8_STRING target. This is the case for Motif
    applications which support the STRING target however. It turns out gtk+
    also provides a gtk_clipboard_request_text() method which will try
    several targets (UTF8_TEXT, COMPOUND_TEXT, TEXT), and will ensure the
    returned string is UTF-8, so we can use that when the agent asks us for
    some text data.
    
    This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1348624

diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c
index fb7630d..7b75117 100644
--- a/src/spice-gtk-session.c
+++ b/src/spice-gtk-session.c
@@ -953,6 +953,40 @@ static char *fixup_clipboard_text(SpiceGtkSession *self, const char *text, int *
     return conv;
 }
 
+static void clipboard_received_text_cb(GtkClipboard *clipboard,
+                                       const gchar *text,
+                                       gpointer user_data)
+{
+    WeakRef *weakref = user_data;
+    SpiceGtkSession *self = (SpiceGtkSession*)weakref->object;
+    char *conv = NULL;
+    int len = 0;
+    int selection;
+
+    weak_unref(weakref);
+
+    if (self == NULL)
+        return;
+
+    g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+
+    selection = get_selection_from_clipboard(self->priv, clipboard);
+    g_return_if_fail(selection != -1);
+
+    len = strlen(text);
+    if (!check_clipboard_size_limits(self, len)) {
+        return;
+    }
+
+    /* gtk+ internal utf8 newline is always LF, even on windows */
+    conv = fixup_clipboard_text(self, text, &len);
+
+    spice_main_clipboard_selection_notify(self->priv->main, selection,
+                                          VD_AGENT_CLIPBOARD_UTF8_TEXT,
+                                          (guchar *)(conv ?: text), len);
+    g_free(conv);
+}
+
 static void clipboard_received_cb(GtkClipboard *clipboard,
                                   GtkSelectionData *selection_data,
                                   gpointer user_data)
@@ -998,16 +1032,14 @@ static void clipboard_received_cb(GtkClipboard *clipboard,
     }
 
     const guchar *data = gtk_selection_data_get_data(selection_data);
-    gpointer conv = NULL;
 
-    /* gtk+ internal utf8 newline is always LF, even on windows */
-    if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) {
-        conv = fixup_clipboard_text(self, (gchar *)data, &len);
-    }
+    /* text should be handled through clipboard_received_text_cb(), not
+     * clipboard_received_cb().
+     */
+    g_warn_if_fail(type != VD_AGENT_CLIPBOARD_UTF8_TEXT);
 
     spice_main_clipboard_selection_notify(s->main, selection, type,
-                                          conv ?: data, len);
-    g_free(conv);
+                                          data, len);
 }
 
 static gboolean clipboard_request(SpiceMainChannel *main, guint selection,
@@ -1030,16 +1062,21 @@ static gboolean clipboard_request(SpiceMainChannel *main, guint selection,
     cb = get_clipboard_from_selection(s, selection);
     g_return_val_if_fail(cb != NULL, FALSE);
 
-    for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) {
-        if (atom2agent[m].vdagent == type)
-            break;
-    }
+    if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) {
+        gtk_clipboard_request_text(cb, clipboard_received_text_cb,
+                                   weak_ref(G_OBJECT(self)));
+    } else {
+        for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) {
+            if (atom2agent[m].vdagent == type)
+                break;
+        }
 
-    g_return_val_if_fail(m < SPICE_N_ELEMENTS(atom2agent), FALSE);
+        g_return_val_if_fail(m < SPICE_N_ELEMENTS(atom2agent), FALSE);
 
-    atom = gdk_atom_intern_static_string(atom2agent[m].xatom);
-    gtk_clipboard_request_contents(cb, atom, clipboard_received_cb,
-                                   weak_ref(G_OBJECT(self)));
+        atom = gdk_atom_intern_static_string(atom2agent[m].xatom);
+        gtk_clipboard_request_contents(cb, atom, clipboard_received_cb,
+                                       weak_ref(G_OBJECT(self)));
+    }
 
     return TRUE;
 }
commit b0a2ff4f205e39f87e9b54d658a27d415ee3d055
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Wed Aug 10 11:17:35 2016 +0200

    clipboard: Add fixup_clipboard_text helper
    
    This makes clipboard_received_cb a bit shorter, and will be useful
    in the next commit.

diff --git a/src/spice-gtk-session.c b/src/spice-gtk-session.c
index 6cdae87..fb7630d 100644
--- a/src/spice-gtk-session.c
+++ b/src/spice-gtk-session.c
@@ -910,6 +910,49 @@ static gboolean check_clipboard_size_limits(SpiceGtkSession *session,
     return TRUE;
 }
 
+/* This will convert line endings if needed (between Windows/Unix conventions),
+ * and will make sure 'len' does not take into account any trailing \0 as this could
+ * cause some confusion guest side.
+ * The 'len' argument will be modified by this function to the length of the modified
+ * string
+ */
+static char *fixup_clipboard_text(SpiceGtkSession *self, const char *text, int *len)
+{
+    char *conv = NULL;
+    int new_len = *len;
+
+
+    if (spice_main_agent_test_capability(self->priv->main, VD_AGENT_CAP_GUEST_LINEEND_CRLF)) {
+        GError *err = NULL;
+
+        conv = spice_unix2dos(text, *len, &err);
+        if (err) {
+            g_warning("Failed to convert text line ending: %s", err->message);
+            g_clear_error(&err);
+            return NULL;
+        }
+
+        new_len = strlen(conv);
+    } else {
+        /* On Windows, with some versions of gtk+, GtkSelectionData::length
+         * will include the final '\0'. When a string with this trailing '\0'
+         * is pasted in some linux applications, it will be pasted as <NIL> or
+         * as an invisible character, which is unwanted. Ensure the length we
+         * send to the agent does not include any trailing '\0'
+         * This is gtk+ bug https://bugzilla.gnome.org/show_bug.cgi?id=734670
+         */
+        new_len = strlen(text);
+    }
+
+    if (!check_clipboard_size_limits(self, new_len)) {
+        g_free(conv);
+        return NULL;
+    }
+
+    *len = new_len;
+    return conv;
+}
+
 static void clipboard_received_cb(GtkClipboard *clipboard,
                                   GtkSelectionData *selection_data,
                                   gpointer user_data)
@@ -959,31 +1002,7 @@ static void clipboard_received_cb(GtkClipboard *clipboard,
 
     /* gtk+ internal utf8 newline is always LF, even on windows */
     if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) {
-        if (spice_main_agent_test_capability(s->main, VD_AGENT_CAP_GUEST_LINEEND_CRLF)) {
-            GError *err = NULL;
-
-            conv = spice_unix2dos((gchar*)data, len, &err);
-            if (err) {
-                g_warning("Failed to convert text line ending: %s", err->message);
-                g_clear_error(&err);
-                return;
-            }
-
-            len = strlen(conv);
-        } else {
-            /* On Windows, with some versions of gtk+, GtkSelectionData::length
-             * will include the final '\0'. When a string with this trailing '\0'
-             * is pasted in some linux applications, it will be pasted as <NIL> or
-             * as an invisible character, which is unwanted. Ensure the length we
-             * send to the agent does not include any trailing '\0'
-             * This is gtk+ bug https://bugzilla.gnome.org/show_bug.cgi?id=734670
-             */
-            len = strlen((const char *)data);
-        }
-        if (!check_clipboard_size_limits(self, len)) {
-            g_free(conv);
-            return;
-        }
+        conv = fixup_clipboard_text(self, (gchar *)data, &len);
     }
 
     spice_main_clipboard_selection_notify(s->main, selection, type,


More information about the Spice-commits mailing list