[Spice-commits] 2 commits - gtk/decode-glz.c gtk/spice-widget.c gtk/spicy.c

Hans de Goede jwrdegoede at kemper.freedesktop.org
Mon Oct 10 01:02:27 PDT 2011


 gtk/decode-glz.c   |   21 ++++++++++++---------
 gtk/spice-widget.c |   12 ++++++++++++
 gtk/spicy.c        |   20 ++++++++++++++++++++
 3 files changed, 44 insertions(+), 9 deletions(-)

New commits:
commit 1305f7a23d642ac73fc1d87ea5ddf84dd3bfcc89
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Thu Oct 6 16:41:16 2011 +0200

    decode-glz: Handle needing glz images before they have arrived
    
    With multi monitor guests, it is possible for a glz-image to refer to
    bits from another glz-image which has not arrived yet! This can happen
    because each monitor has its own display channel, and thus its own socket,
    but they share the glz dict. Thus things can arrive out of order, with a
    glz-image on display 1 arriving before the glz-image on display 2 which it
    refers too.
    
    This triggers the:
    g_return_val_if_fail(w->images[slot]->hdr.id == id - dist, NULL);
    
    In glz_decoder_window_bits(), which is what caused me to debug this, once
    the out order thing was clear, so was the fix.
    If w->images[slot]->hdr.id == id - dist is not true, we need to wait for the
    correct image to arrive.
    
    The out of order issue with multiple monitors can also trigger the
    g_warn_if_reached() in glz_decoder_window_resize(), so remove that.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/gtk/decode-glz.c b/gtk/decode-glz.c
index 8ddb9d8..317fa9e 100644
--- a/gtk/decode-glz.c
+++ b/gtk/decode-glz.c
@@ -95,8 +95,12 @@ static void glz_decoder_window_resize(SpiceGlzDecoderWindow *w)
     new_images = spice_new0(struct glz_image*, w->nimages * 2);
     for (i = 0; i < w->nimages; i++) {
         if (w->images[i] == NULL) {
-            /* FIXME: is this really an anormal condition? */
-            g_warn_if_reached();
+            /*
+             * We can have empty slots when images come in out of order, this
+             * can happen when a vm has multiple displays, since each display
+             * uses its own socket there is no guarantee that images
+             * originating from different displays are received in id order.
+             */
             continue;
         }
         new_slot = w->images[i]->hdr.id % (w->nimages * 2);
@@ -124,14 +128,14 @@ static void glz_decoder_window_add(SpiceGlzDecoderWindow *w,
 struct wait_for_image_data {
     SpiceGlzDecoderWindow     *window;
     uint64_t                   id;
-    uint32_t                   dist;
 };
 
 static gboolean wait_for_image(gpointer data)
 {
     struct wait_for_image_data *wait = data;
-    int slot = (wait->id - wait->dist) % wait->window->nimages;
-    gboolean ready = wait->window->images[slot] != NULL;
+    int slot = wait->id % wait->window->nimages;
+    struct glz_image *image = wait->window->images[slot];
+    gboolean ready = image && image->hdr.id == wait->id;
 
     SPICE_DEBUG("image with slot %d: %s", slot, ready ? "yes" : "no");
 
@@ -142,12 +146,11 @@ static void *glz_decoder_window_bits(SpiceGlzDecoderWindow *w, uint64_t id,
                                      uint32_t dist, uint32_t offset)
 {
     int slot = (id - dist) % w->nimages;
-    
-    if (!w->images[slot]) {
+
+    if (!w->images[slot] || w->images[slot]->hdr.id != id - dist) {
         struct wait_for_image_data data = {
             .window = w,
-            .id = id,
-            .dist = dist,
+            .id = id - dist,
         };
 
         g_condition_wait(wait_for_image, &data);
commit 387ebeebe978ef107da40b41df6f5f2d50625e57
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Wed Oct 5 11:08:15 2011 +0200

    SpiceDisplay: Pass on notify signal from GtkSession for GtkSession properties
    
    Since some SpiceDisplay properties are now just a pass through to the
    equivalent SpiceGtkSession property, we also need to pass on the notify
    signal for these, so interested users can get notified of them changing.
    
    Use this in spicy to ensure that changes to SpiceGtkSession (and thus per
    session rather then per window) properties get reflected in all windows for
    a multimonitor guest.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index 5b53caf..06e5113 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -226,6 +226,15 @@ static void spice_display_set_property(GObject      *object,
     }
 }
 
+static void gtk_session_property_changed(GObject    *gobject,
+                                         GParamSpec *pspec,
+                                         gpointer    user_data)
+{
+    SpiceDisplay *display = user_data;
+
+    g_object_notify(G_OBJECT(display), g_param_spec_get_name(pspec));
+}
+
 static void spice_display_dispose(GObject *obj)
 {
     SpiceDisplay *display = SPICE_DISPLAY(obj);
@@ -329,6 +338,9 @@ spice_display_constructor(GType                  gtype,
     }
     g_list_free(list);
 
+    g_signal_connect(d->gtk_session, "notify::auto-clipboard",
+                     G_CALLBACK(gtk_session_property_changed), display);
+
     return obj;
 }
 
diff --git a/gtk/spicy.c b/gtk/spicy.c
index 77f339c..533d7f7 100644
--- a/gtk/spicy.c
+++ b/gtk/spicy.c
@@ -427,6 +427,20 @@ static void menu_cb_bool_prop(GtkToggleAction *action, gpointer data)
     g_object_set(G_OBJECT(win->spice), name, state, NULL);
 }
 
+static void menu_cb_bool_prop_changed(GObject    *gobject,
+                                      GParamSpec *pspec,
+                                      gpointer    user_data)
+{
+    struct spice_window *win = user_data;
+    const gchar *property = g_param_spec_get_name(pspec);
+    GtkAction *toggle;
+    gboolean state;
+
+    toggle = gtk_action_group_get_action(win->ag, property);
+    g_object_get(win->spice, property, &state, NULL);
+    gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(toggle), state);
+}
+
 static void menu_cb_toolbar(GtkToggleAction *action, gpointer data)
 {
     struct spice_window *win = data;
@@ -1133,9 +1147,15 @@ static spice_window *create_spice_window(spice_connection *conn, int id, SpiceCh
 
     /* init toggle actions */
     for (i = 0; i < G_N_ELEMENTS(spice_properties); i++) {
+        char notify[64];
+
         toggle = gtk_action_group_get_action(win->ag, spice_properties[i]);
         g_object_get(win->spice, spice_properties[i], &state, NULL);
         gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(toggle), state);
+
+        snprintf(notify, sizeof(notify), "notify::%s", spice_properties[i]);
+        g_signal_connect(win->spice, notify,
+                         G_CALLBACK(menu_cb_bool_prop_changed), win);
     }
 
     toggle = gtk_action_group_get_action(win->ag, "Toolbar");


More information about the Spice-commits mailing list