[Spice-devel] [PATCH spice-gtk 1/2] channel-display: Make monitors array contain monitors in id order

Hans de Goede hdegoede at redhat.com
Thu Jan 10 14:52:50 PST 2013


Both the spice-widget code, as well as remote-viewer expect that
monitors[i]->id == i, but if ie only the qxl-0 and qxl-2 outputs are
enabled this is not true.

I've chosen to fix this by making this assumption true. This does mean
that the monitors array can now contain 0x0 sized (iow disabled) monitors,
remote-viewer already checks for this.

Thus this patch:
1) Makes the monitors[i]->id == i assumption be true
2) Makes spice-widget check for 0x0 sized monitors and treat them as disabled

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 gtk/channel-display.c | 18 ++++++++++++++----
 gtk/spice-widget.c    |  5 +++++
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/gtk/channel-display.c b/gtk/channel-display.c
index d07b65c..e7bb080 100644
--- a/gtk/channel-display.c
+++ b/gtk/channel-display.c
@@ -1524,7 +1524,8 @@ static void display_handle_monitors_config(SpiceChannel *channel, SpiceMsgIn *in
 {
     SpiceMsgDisplayMonitorsConfig *config = spice_msg_in_parsed(in);
     SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
-    guint i;
+    SpiceDisplayMonitorConfig *mc;
+    guint i, max_id = 0;
 
     g_return_if_fail(config != NULL);
     g_return_if_fail(config->count > 0);
@@ -1542,12 +1543,18 @@ static void display_handle_monitors_config(SpiceChannel *channel, SpiceMsgIn *in
         config->count = CLAMP(config->count, 1, c->monitors_max);
     }
 
-    c->monitors = g_array_set_size(c->monitors, config->count);
+    /* The received data does not necessarily contain a contineous id range */
+    c->monitors = g_array_set_size(c->monitors, 0);
+    c->monitors = g_array_set_size(c->monitors, c->monitors_max);
 
     for (i = 0; i < config->count; i++) {
-        SpiceDisplayMonitorConfig *mc = &g_array_index(c->monitors, SpiceDisplayMonitorConfig, i);
         SpiceHead *head = &config->heads[i];
-        CHANNEL_DEBUG(channel, "monitor id: %u, surface id: %u, +%u+%u-%ux%u",
+        if (head->id >= c->monitors_max) {
+            g_warning("MonitorConfig head->id >= c->monitors_max, skipping");
+            continue;
+        }
+        mc = &g_array_index(c->monitors, SpiceDisplayMonitorConfig, head->id);
+        printf("monitor id: %u, surface id: %u, +%u+%u-%ux%u\n",
                     head->id, head->surface_id,
                     head->x, head->y, head->width, head->height);
         mc->id = head->id;
@@ -1556,7 +1563,10 @@ static void display_handle_monitors_config(SpiceChannel *channel, SpiceMsgIn *in
         mc->y = head->y;
         mc->width = head->width;
         mc->height = head->height;
+        if (head->id > max_id)
+            max_id = head->id;
     }
+    c->monitors = g_array_set_size(c->monitors, max_id + 1);
 
     g_object_notify_main_context(G_OBJECT(channel), "monitors");
 }
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index a8d3ce9..5e6f61d 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -291,6 +291,11 @@ static void update_monitor_area(SpiceDisplay *display)
         goto whole;
     }
 
+    if (c->width == 0 || c->height == 0) {
+        set_monitor_ready(display, false);
+        return;
+    }
+
     update_area(display, c->x, c->y, c->width, c->height);
     g_clear_pointer(&monitors, g_array_unref);
     return;
-- 
1.8.0.2



More information about the Spice-devel mailing list