[Spice-commits] 5 commits - gtk/channel-cursor.c gtk/decode-glz.c gtk/decode.h gtk/spice-channel.c gtk/spice-session.c gtk/spice-widget.c

Marc-André Lureau elmarco at kemper.freedesktop.org
Fri Jul 15 11:26:57 PDT 2011


 gtk/channel-cursor.c |   15 ++++++++++-----
 gtk/decode-glz.c     |   27 ++++++++++++++++++---------
 gtk/decode.h         |    1 +
 gtk/spice-channel.c  |    2 +-
 gtk/spice-session.c  |   11 ++++++++++-
 gtk/spice-widget.c   |   51 ++++++++++++++++++++++++++++-----------------------
 6 files changed, 68 insertions(+), 39 deletions(-)

New commits:
commit 67cbd00179a605930a1f4c127fa4aa2ef324ede9
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Fri Jul 15 20:23:33 2011 +0200

    gtk: avoid doing GdkWindow operations if widget is not realized

diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index 52f4773..2049321 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -442,6 +442,8 @@ static GdkGrabStatus do_pointer_grab(SpiceDisplay *display)
     GdkWindow *window = GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(display)));
     GdkGrabStatus status;
 
+    if (!gtk_widget_get_realized(GTK_WIDGET(display)))
+        return GDK_GRAB_BROKEN;
     try_keyboard_grab(display);
 
     /*
@@ -489,7 +491,7 @@ static void update_mouse_pointer(SpiceDisplay *display)
             gdk_window_set_cursor(window, NULL);
         } else {
             gdk_window_set_cursor(window, d->mouse_cursor);
-            do_pointer_grab(display);
+            try_mouse_grab(GTK_WIDGET(display));
         }
         break;
     default:
@@ -1510,7 +1512,7 @@ static void cursor_move(SpiceCursorChannel *channel, gint x, gint y, gpointer da
     d->mouse_guest_x = x;
     d->mouse_guest_y = y;
 
-    if (spicex_is_scaled(display)) {
+    if (spicex_is_scaled(display) && gtk_widget_get_realized(GTK_WIDGET(display))) {
         gint ww, wh;
 
         gdk_drawable_get_size(gtk_widget_get_window(GTK_WIDGET(display)), &ww, &wh);
@@ -1522,7 +1524,7 @@ static void cursor_move(SpiceCursorChannel *channel, gint x, gint y, gpointer da
         y += d->my;
     }
 
-    if (d->mouse_grab_active) {
+    if (d->mouse_grab_active && gtk_widget_get_realized(GTK_WIDGET(display))) {
         gdk_window_get_origin(GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(display))), &wx, &wy);
         gdk_display_warp_pointer(gtk_widget_get_display(GTK_WIDGET(display)), screen, x + wx, y + wy);
     }
@@ -1553,13 +1555,14 @@ static void cursor_reset(SpiceCursorChannel *channel, gpointer data)
 static void disconnect_main(SpiceDisplay *display)
 {
     spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display);
+    gint i;
 
     if (d->main == NULL)
         return;
     g_signal_handlers_disconnect_by_func(d->main, G_CALLBACK(mouse_update),
                                          display);
     d->main = NULL;
-    for (int i = 0; i < CLIPBOARD_LAST; ++i) {
+    for (i = 0; i < CLIPBOARD_LAST; ++i) {
         d->clipboard_by_guest[i] = FALSE;
         d->clip_grabbed[i] = FALSE;
         d->nclip_targets[i] = 0;
commit d42c6a8f502dd86805c20964f90008be6ec89b2f
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Fri Jul 15 15:34:31 2011 +0200

    gtk: honour CURSOR_FLAGS_NONE by hiding cursor

diff --git a/gtk/channel-cursor.c b/gtk/channel-cursor.c
index e93c0ac..a05ba87 100644
--- a/gtk/channel-cursor.c
+++ b/gtk/channel-cursor.c
@@ -463,10 +463,10 @@ static void cursor_handle_init(SpiceChannel *channel, spice_msg_in *in)
     c->init_done = TRUE;
     if (cursor)
         emit_cursor_set(channel, cursor);
-    if (!init->visible)
+    if (!init->visible || !cursor)
         emit_main_context(channel, SPICE_CURSOR_HIDE);
-
-    display_cursor_unref(cursor);
+    if (cursor)
+        display_cursor_unref(cursor);
 }
 
 /* coroutine context */
@@ -491,9 +491,14 @@ static void cursor_handle_set(SpiceChannel *channel, spice_msg_in *in)
     g_return_if_fail(c->init_done == TRUE);
 
     cursor = set_cursor(channel, &set->cursor);
-    emit_cursor_set(channel, cursor);
+    if (cursor)
+        emit_cursor_set(channel, cursor);
+    else
+        emit_main_context(channel, SPICE_CURSOR_HIDE);
 
-    display_cursor_unref(cursor);
+
+    if (cursor)
+        display_cursor_unref(cursor);
 }
 
 /* coroutine context */
commit db804ba08e9c7be73b57ff7f029e3ba0576ef9b4
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Fri Jul 15 02:12:58 2011 +0200

    gtk: comment channel_new() returns a weak reference
    
    And add a few sanity checks.

diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index bd005b1..c780189 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -1676,7 +1676,7 @@ const gchar* spice_channel_type_to_string(gint type)
  *
  * Create a new #SpiceChannel of type @type, and channel ID @id.
  *
- * Returns: a #SpiceChannel
+ * Returns: a weak reference to #SpiceChannel, the session owns the reference
  **/
 SpiceChannel *spice_channel_new(SpiceSession *s, int type, int id)
 {
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index bfc5e9b..38dad34 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -61,7 +61,7 @@ struct spice_session {
 
     int               connection_id;
     int               protocol;
-    SpiceChannel      *cmain;
+    SpiceChannel      *cmain; /* weak reference */
     Ring              channels;
     guint32           mm_time;
     gboolean          client_provided_sockets;
@@ -837,6 +837,8 @@ gboolean spice_session_connect(SpiceSession *session)
     s->disconnecting = FALSE;
 
     s->client_provided_sockets = FALSE;
+
+    g_warn_if_fail(s->cmain == NULL);
     s->cmain = spice_channel_new(session, SPICE_CHANNEL_MAIN, 0);
 
     glz_decoder_window_clear(s->glz_window);
@@ -864,6 +866,8 @@ gboolean spice_session_open_fd(SpiceSession *session, int fd)
     spice_session_disconnect(session);
 
     s->client_provided_sockets = TRUE;
+
+    g_warn_if_fail(s->cmain == NULL);
     s->cmain = spice_channel_new(session, SPICE_CHANNEL_MAIN, 0);
     return spice_channel_open_fd(s->cmain, fd);
 }
@@ -1192,6 +1196,10 @@ void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel)
          ring = next) {
         next = ring_next(&s->channels, ring);
         item = SPICE_CONTAINEROF(ring, struct channel, link);
+        if (item->channel == s->cmain) {
+            SPICE_DEBUG("the session lost the main channel");
+            s->cmain = NULL;
+        }
         if (item->channel == channel) {
             ring_remove(&item->link);
             free(item);
commit 77bca231e15d7a4d9145072e491a14591eb2c916
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Fri Jul 15 01:41:58 2011 +0200

    gtk: add glz_decoder_window_clear, to recycle decoder

diff --git a/gtk/decode-glz.c b/gtk/decode-glz.c
index f1dde6e..8ddb9d8 100644
--- a/gtk/decode-glz.c
+++ b/gtk/decode-glz.c
@@ -411,27 +411,36 @@ static SpiceGlzDecoderOps glz_decoder_ops = {
     .decode = decode,
 };
 
-SpiceGlzDecoderWindow *glz_decoder_window_new(void)
+void glz_decoder_window_clear(SpiceGlzDecoderWindow *w)
 {
-    SpiceGlzDecoderWindow *w = spice_new0(SpiceGlzDecoderWindow, 1);
+    int i;
+
+    g_return_if_fail(w->nimages == 0 || w->images != NULL);
+
+    for (i = 0; i < w->nimages; i++) {
+        if (w->images[i]) {
+            glz_image_destroy(w->images[i]);
+        }
+    }
 
     w->nimages = 16;
+    g_free(w->images);
     w->images = spice_new0(struct glz_image*, w->nimages);
+}
+
+SpiceGlzDecoderWindow *glz_decoder_window_new(void)
+{
+    SpiceGlzDecoderWindow *w = spice_new0(SpiceGlzDecoderWindow, 1);
+    glz_decoder_window_clear(w);
     return w;
 }
 
 void glz_decoder_window_destroy(SpiceGlzDecoderWindow *w)
 {
-    int i;
-
     if (w == NULL)
         return;
 
-    for (i = 0; i < w->nimages; i++) {
-        if (w->images[i]) {
-            glz_image_destroy(w->images[i]);
-        }
-    }
+    glz_decoder_window_clear(w);
     free(w->images);
     free(w);
 }
diff --git a/gtk/decode.h b/gtk/decode.h
index 8bef3f9..9fee749 100644
--- a/gtk/decode.h
+++ b/gtk/decode.h
@@ -26,6 +26,7 @@ G_BEGIN_DECLS
 typedef struct SpiceGlzDecoderWindow SpiceGlzDecoderWindow;
 
 SpiceGlzDecoderWindow *glz_decoder_window_new(void);
+void glz_decoder_window_clear(SpiceGlzDecoderWindow *w);
 void glz_decoder_window_destroy(SpiceGlzDecoderWindow *w);
 
 SpiceGlzDecoder *glz_decoder_new(SpiceGlzDecoderWindow *w);
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 824eff0..bfc5e9b 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -839,6 +839,7 @@ gboolean spice_session_connect(SpiceSession *session)
     s->client_provided_sockets = FALSE;
     s->cmain = spice_channel_new(session, SPICE_CHANNEL_MAIN, 0);
 
+    glz_decoder_window_clear(s->glz_window);
     return spice_channel_connect(s->cmain);
 }
 
commit 34f11a7d6b380e94effe486a136cdb086226e881
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Thu Jul 14 02:57:01 2011 +0200

    gtk: rework widget destroy/dispose()
    
    Make sure to remove handlers during dispose.
    Destroy is purely a gtk+ thing, so let the widget do the job.
    
    This solves a refcount/crash issue found with virt-manager.

diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index 0d92429..52f4773 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -201,32 +201,33 @@ static void spice_display_set_property(GObject      *object,
     }
 }
 
-static void spice_display_destroy(GtkObject *obj)
+static void spice_display_dispose(GObject *obj)
 {
     SpiceDisplay *display = SPICE_DISPLAY(obj);
     spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display);
 
-    g_signal_handlers_disconnect_by_func(d->session, G_CALLBACK(channel_new),
-                                         display);
-    g_signal_handlers_disconnect_by_func(d->session, G_CALLBACK(channel_destroy),
-                                         display);
-    g_signal_handlers_disconnect_by_func(d->clipboard, G_CALLBACK(clipboard_owner_change),
-                                         display);
-    g_signal_handlers_disconnect_by_func(d->clipboard_primary, G_CALLBACK(clipboard_owner_change),
-                                         display);
+    SPICE_DEBUG("spice display dispose");
 
     disconnect_main(display);
     disconnect_display(display);
     disconnect_cursor(display);
-    GTK_OBJECT_CLASS(spice_display_parent_class)->destroy(obj);
-}
 
-static void spice_display_dispose(GObject *obj)
-{
-    SpiceDisplay *display = SPICE_DISPLAY(obj);
-    spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display);
+    if (d->clipboard) {
+        g_signal_handlers_disconnect_by_func(d->clipboard, G_CALLBACK(clipboard_owner_change),
+                                             display);
+        d->clipboard = NULL;
+    }
 
+    if (d->clipboard_primary) {
+        g_signal_handlers_disconnect_by_func(d->clipboard_primary, G_CALLBACK(clipboard_owner_change),
+                                             display);
+        d->clipboard_primary = NULL;
+    }
     if (d->session) {
+        g_signal_handlers_disconnect_by_func(d->session, G_CALLBACK(channel_new),
+                                             display);
+        g_signal_handlers_disconnect_by_func(d->session, G_CALLBACK(channel_destroy),
+                                             display);
         g_object_unref(d->session);
         d->session = NULL;
     }
@@ -1018,7 +1019,9 @@ static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
     if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER)
         try_mouse_grab(widget);
     else /* allow to drag and drop between windows/displays:
-            FIXME: should be multiple widget grab, but how? */
+            FIXME: should be multiple widget grab, but how?
+            or should now the position of the other widgets?..
+         */
         gdk_pointer_ungrab(GDK_CURRENT_TIME);
 
     if (!d->inputs)
@@ -1227,7 +1230,6 @@ static void clipboard_owner_change(GtkClipboard        *clipboard,
 static void spice_display_class_init(SpiceDisplayClass *klass)
 {
     GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-    GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS(klass);
     GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS(klass);
 
 #if GTK_CHECK_VERSION (2, 91, 0)
@@ -1247,8 +1249,6 @@ static void spice_display_class_init(SpiceDisplayClass *klass)
     gtkwidget_class->configure_event = configure_event;
     gtkwidget_class->scroll_event = scroll_event;
 
-    gtkobject_class->destroy = spice_display_destroy;
-
     gobject_class->dispose = spice_display_dispose;
     gobject_class->finalize = spice_display_finalize;
     gobject_class->get_property = spice_display_get_property;
@@ -1367,6 +1367,8 @@ static void mouse_update(SpiceChannel *channel, gpointer data)
     spice_display *d = SPICE_DISPLAY_GET_PRIVATE(display);
 
     g_object_get(channel, "mouse-mode", &d->mouse_mode, NULL);
+    SPICE_DEBUG("mouse mode %d", d->mouse_mode);
+
     d->mouse_guest_x = -1;
     d->mouse_guest_y = -1;
     if (d->mouse_mode == SPICE_MOUSE_MODE_CLIENT) {


More information about the Spice-commits mailing list