[Spice-devel] [PATCH spice-gtk 20/25] widget: use display monitors configuration

Marc-André Lureau marcandre.lureau at gmail.com
Thu Jul 12 15:29:17 PDT 2012


Use display::monitors property to manage display area. Call
update_area_monitor() to update the widget area depending on monitor
configuration
---
 gtk/spice-widget.c |   65 ++++++++++++++++++++++++++++++++++++++++++++--------
 spice-common       |    2 +-
 2 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index 6b4ae96..75efa7e 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -130,6 +130,7 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data);
 static void channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer data);
 static void sync_keyboard_lock_modifiers(SpiceDisplay *display);
 static void cursor_invalidate(SpiceDisplay *display);
+static void update_area(SpiceDisplay *display, gint x, gint y, gint width, gint height);
 
 /* ---------------------------------------------------------------- */
 
@@ -226,6 +227,44 @@ static void update_keyboard_focus(SpiceDisplay *display, gboolean state)
     spice_gtk_session_request_auto_usbredir(d->gtk_session, state);
 }
 
+static void update_monitor_area(SpiceDisplay *display)
+{
+    SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+    SpiceDisplayMonitorConfig *c;
+    GArray *monitors = NULL;
+
+    SPICE_DEBUG("update monitor area %d:%d", d->channel_id, d->monitor_id);
+    if (d->monitor_id < 0)
+        goto whole;
+
+    g_object_get(d->display, "monitors", &monitors, NULL);
+    if (monitors == NULL || d->monitor_id >= monitors->len) {
+        SPICE_DEBUG("update monitor: no monitor %d", d->monitor_id);
+        if (spice_channel_test_capability(d->display, SPICE_DISPLAY_CAP_MONITORS_CONFIG)) {
+            SPICE_DEBUG("waiting until MonitorsConfig is received");
+            return;
+        }
+        /* FIXME: mark false */
+        goto whole;
+    }
+
+    c = &g_array_index(monitors, SpiceDisplayMonitorConfig, d->monitor_id);
+    g_return_if_fail(c != NULL);
+    if (c->surface_id != 0) {
+        g_warning("FIXME: only support monitor config with primary surface 0, "
+                  "but given config surface %d", c->surface_id);
+        goto whole;
+    }
+
+    update_area(display, c->x, c->y, c->width, c->height);
+    g_clear_pointer(&monitors, g_array_unref);
+    return;
+
+whole:
+    /* by display whole surface */
+    update_area(display, 0, 0, d->width, d->height);
+}
+
 static void spice_display_set_property(GObject      *object,
                                        guint         prop_id,
                                        const GValue *value,
@@ -245,6 +284,8 @@ static void spice_display_set_property(GObject      *object,
         break;
     case PROP_MONITOR_ID:
         d->monitor_id = g_value_get_int(value);
+        if (d->display) /* if constructed */
+            update_monitor_area(display);
         break;
     case PROP_KEYBOARD_GRAB:
         d->keyboard_grab_enable = g_value_get_boolean(value);
@@ -808,13 +849,13 @@ static void recalc_geometry(GtkWidget *widget)
     } else
         zoom = (gdouble)d->zoom_level / 100;
 
-    SPICE_DEBUG("monitors: id %d, guest +%d+%d:%dx%d, window %dx%d, zoom %g, offset +%d+%d",
-                d->channel_id, d->area.x, d->area.y, d->area.width, d->area.height,
+    SPICE_DEBUG("recalc geom monitor: %d:%d, guest +%d+%d:%dx%d, window %dx%d, zoom %g, offset +%d+%d",
+                d->channel_id, d->monitor_id, d->area.x, d->area.y, d->area.width, d->area.height,
                 d->ww, d->wh, zoom, d->mx, d->my);
 
     if (d->resize_guest_enable)
         spice_main_set_display(d->main, get_display_id(display),
-                               0, 0, d->ww / zoom, d->wh / zoom);
+                               d->area.x, d->area.y, d->ww / zoom, d->wh / zoom);
 }
 
 /* ---------------------------------------------------------------- */
@@ -1645,8 +1686,7 @@ static void primary_create(SpiceChannel *channel, gint format,
     d->height = height;
     d->data_origin = d->data = imgdata;
 
-    /* by default, display whole surface */
-    update_area(display, 0, 0, width, height);
+    update_monitor_area(display);
 }
 
 static void primary_destroy(SpiceChannel *channel, gpointer data)
@@ -1694,13 +1734,12 @@ static void invalidate(SpiceChannel *channel,
                                x, y, w, h);
 }
 
-static void mark(SpiceChannel *channel, gint mark, gpointer data)
+static void mark(SpiceDisplay *display, gint mark)
 {
-    SpiceDisplay *display = data;
     SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
     g_return_if_fail(d != NULL);
 
-    SPICE_DEBUG("widget mark: %d, channel %d", mark, d->channel_id);
+    SPICE_DEBUG("widget mark: %d, %d:%d %p", mark, d->channel_id, d->monitor_id, display);
     d->mark = mark;
     spice_main_set_display_enabled(d->main, get_display_id(display), d->mark != 0);
     if (mark != 0 && gtk_widget_get_window(GTK_WIDGET(display)))
@@ -1856,6 +1895,7 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
     }
 
     if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
+        SpiceDisplayPrimary primary;
         if (id != d->channel_id)
             return;
         d->display = channel;
@@ -1866,7 +1906,14 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
         spice_g_signal_connect_object(channel, "display-invalidate",
                                       G_CALLBACK(invalidate), display, 0);
         spice_g_signal_connect_object(channel, "display-mark",
-                                      G_CALLBACK(mark), display, 0);
+                                      G_CALLBACK(mark), display, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+        spice_g_signal_connect_object(channel, "notify::monitors",
+                                      G_CALLBACK(update_monitor_area), display, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+        if (spice_display_get_primary(channel, 0, &primary)) {
+            primary_create(channel, primary.format, primary.width, primary.height,
+                           primary.stride, primary.shmid, primary.data, display);
+            mark(display, primary.marked);
+        }
         spice_channel_connect(channel);
         return;
     }
diff --git a/spice-common b/spice-common
index 5f44094..6a9d40f 160000
--- a/spice-common
+++ b/spice-common
@@ -1 +1 @@
-Subproject commit 5f4409494066b5f59df58d6207fdbb0441aa9e90
+Subproject commit 6a9d40f7f03756599f4a3880c212a379be9e784e
-- 
1.7.10.4



More information about the Spice-devel mailing list