[Spice-commits] 3 commits - src/channel-main.c src/channel-main.h src/map-file src/spice-glib-sym-file src/spice-widget.c

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Sep 16 09:55:36 UTC 2020


 src/channel-main.c      |   88 ++++++++++++++++++++++++++++++++++++++++++------
 src/channel-main.h      |    3 +
 src/map-file            |    1 
 src/spice-glib-sym-file |    1 
 src/spice-widget.c      |   28 +++++++++++++--
 5 files changed, 107 insertions(+), 14 deletions(-)

New commits:
commit 2e4f5d98f44e184bdd79ff269144eda13ec6d4a2
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Mon Aug 17 14:37:59 2020 +0400

    widget: set physical display dimensions (with resize-guest=true)
    
    Note that Gtk+ doesn't provide a convenient & reliable API to get the
    dimensions of a widget. See the gitlab issue in the comment.
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>
    Acked-by: Frediano Ziglio <fziglio at redhat.com>

diff --git a/src/spice-widget.c b/src/spice-widget.c
index 9cb1273..eaf9e91 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -1358,23 +1358,43 @@ static void recalc_geometry(GtkWidget *widget)
     SpiceDisplay *display = SPICE_DISPLAY(widget);
     SpiceDisplayPrivate *d = display->priv;
     gdouble zoom = 1.0;
-    gint scale_factor;
+    gint scale_factor, height_mm = 0, width_mm = 0;
+    bool has_display_mm = false;
 
     if (spice_cairo_is_scaled(display))
         zoom = (gdouble)d->zoom_level / 100;
 
     scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(display));
 
+    if (gtk_widget_get_window(widget)) {
+        GdkRectangle geometry;
+        GdkMonitor *monitor =
+            gdk_display_get_monitor_at_window(gtk_widget_get_display(widget),
+                                              gtk_widget_get_window(widget));
+        height_mm = gdk_monitor_get_height_mm(monitor);
+        width_mm = gdk_monitor_get_width_mm(monitor);
+        gdk_monitor_get_geometry(monitor, &geometry);
+        /* FIXME: gives wrong results atm: https://gitlab.gnome.org/GNOME/gtk/-/issues/3066 */
+        width_mm = (width_mm * d->ww / geometry.width) / zoom * scale_factor;
+        height_mm = (height_mm * d->wh / geometry.height) / zoom * scale_factor;
+        has_display_mm = true;
+    }
+
     DISPLAY_DEBUG(display,
-                  "recalc geom: guest +%d+%d:%dx%d, window %dx%d, zoom %g, scale %d",
+                  "recalc geom: guest +%d+%d:%dx%d, window %dx%d, zoom %g, scale %d, dim %dx%dmm",
                   d->area.x, d->area.y, d->area.width, d->area.height,
-                  d->ww, d->wh, zoom, scale_factor);
+                  d->ww, d->wh, zoom, scale_factor, width_mm, height_mm);
 
-    if (d->resize_guest_enable)
+    if (d->resize_guest_enable) {
+        if (has_display_mm) {
+            spice_main_channel_update_display_mm(d->main, get_display_id(display),
+                                                 width_mm, height_mm, TRUE);
+        }
         spice_main_channel_update_display(d->main, get_display_id(display),
                                           d->area.x, d->area.y,
                                           d->ww * scale_factor / zoom,
                                           d->wh * scale_factor / zoom, TRUE);
+    }
 }
 
 /* ---------------------------------------------------------------- */
commit b9754be1663adcbb217e73baa131f279f612685f
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Tue Sep 15 14:01:48 2020 +0400

    main: add display physical size support
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>
    Acked-by: Frediano Ziglio <fziglio at redhat.com>

diff --git a/src/channel-main.c b/src/channel-main.c
index 5fcf8e8..79fe63c 100644
--- a/src/channel-main.c
+++ b/src/channel-main.c
@@ -62,6 +62,8 @@ typedef struct {
     int                     y;
     int                     width;
     int                     height;
+    int                     width_mm;
+    int                     height_mm;
     SpiceDisplayState       display_state;
 } SpiceDisplayConfig;
 
@@ -1129,7 +1131,8 @@ gboolean spice_main_channel_send_monitor_config(SpiceMainChannel *channel)
         }
     }
 
-    size = sizeof(VDAgentMonitorsConfig) + sizeof(VDAgentMonConfig) * monitors;
+    size = sizeof(VDAgentMonitorsConfig) +
+        (sizeof(VDAgentMonConfig) + sizeof(VDAgentMonitorMM)) * monitors;
     mon = g_malloc0(size);
 
     mon->num_of_monitors = monitors;
@@ -1137,6 +1140,8 @@ gboolean spice_main_channel_send_monitor_config(SpiceMainChannel *channel)
         c->disable_display_align == FALSE)
         mon->flags |= VD_AGENT_CONFIG_MONITORS_FLAG_USE_POS;
 
+    mon->flags |= VD_AGENT_CONFIG_MONITORS_FLAG_PHYSICAL_SIZE;
+
     CHANNEL_DEBUG(channel, "sending new monitors config to guest");
     j = 0;
     for (i = 0; i < SPICE_N_ELEMENTS(c->display); i++) {
@@ -1158,6 +1163,20 @@ gboolean spice_main_channel_send_monitor_config(SpiceMainChannel *channel)
         j++;
     }
 
+    VDAgentMonitorMM *mm = (void *)&mon->monitors[monitors];
+    for (i = 0, j = 0; i < SPICE_N_ELEMENTS(c->display); i++) {
+        if (c->display[i].display_state != DISPLAY_ENABLED) {
+            if (spice_main_channel_agent_test_capability(channel,
+                                                         VD_AGENT_CAP_SPARSE_MONITORS_CONFIG)) {
+                j++;
+            }
+            continue;
+        }
+        mm[j].width = c->display[i].width_mm;
+        mm[j].height = c->display[i].height_mm;
+        j++;
+    }
+
     if (c->disable_display_align == FALSE)
         monitors_align(mon->monitors, mon->num_of_monitors);
 
@@ -2690,6 +2709,22 @@ void spice_main_update_display(SpiceMainChannel *channel, int id,
     spice_main_channel_update_display(channel, id, x, y, width, height, update);
 }
 
+static void
+update_display_config(SpiceMainChannel *channel, int id, SpiceDisplayConfig *config, gboolean update)
+{
+    SpiceMainChannelPrivate *c = channel->priv;
+
+    if (memcmp(config, &c->display[id], sizeof(SpiceDisplayConfig)) == 0) {
+        return;
+    }
+
+    c->display[id] = *config;
+
+    if (update) {
+        update_display_timer(channel, 1);
+    }
+}
+
 /**
  * spice_main_channel_update_display:
  * @channel: a #SpiceMainChannel
@@ -2725,18 +2760,51 @@ void spice_main_channel_update_display(SpiceMainChannel *channel, int id, int x,
 
     g_return_if_fail(id >= 0 && id < SPICE_N_ELEMENTS(c->display));
 
-    SpiceDisplayConfig display = {
+    SpiceDisplayConfig config = {
         .x = x, .y = y, .width = width, .height = height,
-        .display_state = c->display[id].display_state
+        .width_mm = c->display[id].width_mm,
+        .height_mm = c->display[id].height_mm,
+        .display_state = c->display[id].display_state,
     };
 
-    if (memcmp(&display, &c->display[id], sizeof(SpiceDisplayConfig)) == 0)
-        return;
+    update_display_config(channel, id, &config, update);
+}
 
-    c->display[id] = display;
+/**
+ * spice_main_channel_update_display_mm:
+ * @channel: a #SpiceMainChannel
+ * @id: display ID
+ * @width_mm: physical display width in millimeters
+ * @height_mm: physical display height in millimeters
+ * @update: if %TRUE, update guest resolution after 1sec.
+ *
+ * Update the display @id physical size.
+ *
+ * If @update is %TRUE, the remote configuration will be updated too
+ * after 1 second without further changes. You can send when you want
+ * without delay the new configuration to the remote with
+ * spice_main_send_monitor_config()
+ *
+ * Since: 0.39
+ **/
+void spice_main_channel_update_display_mm(SpiceMainChannel *channel, int id,
+                                          int width_mm, int height_mm, gboolean update)
+{
+    SpiceMainChannelPrivate *c;
 
-    if (update)
-        update_display_timer(channel, 1);
+    g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
+    g_return_if_fail(width_mm >= 0);
+    g_return_if_fail(height_mm >= 0);
+
+    c = channel->priv;
+
+    g_return_if_fail(id >= 0 && id < SPICE_N_ELEMENTS(c->display));
+
+    SpiceDisplayConfig config = c->display[id];
+    config.width_mm = width_mm;
+    config.height_mm = height_mm;
+
+    update_display_config(channel, id, &config, update);
 }
 
 /**
diff --git a/src/channel-main.h b/src/channel-main.h
index 379805b..2f8da62 100644
--- a/src/channel-main.h
+++ b/src/channel-main.h
@@ -70,6 +70,9 @@ struct _SpiceMainChannelClass {
 
 GType spice_main_channel_get_type(void);
 
+void spice_main_channel_update_display_mm(SpiceMainChannel *channel, int id,
+                                          int width_mm, int height_mm, gboolean update);
+
 void spice_main_channel_update_display(SpiceMainChannel *channel, int id, int x, int y, int width,
                                        int height, gboolean update);
 void spice_main_channel_update_display_enabled(SpiceMainChannel *channel, int id, gboolean enabled,
diff --git a/src/map-file b/src/map-file
index acdd38f..8ceaeb1 100644
--- a/src/map-file
+++ b/src/map-file
@@ -94,6 +94,7 @@ spice_main_channel_request_mouse_mode;
 spice_main_channel_send_monitor_config;
 spice_main_channel_update_display;
 spice_main_channel_update_display_enabled;
+spice_main_channel_update_display_mm;
 spice_main_clipboard_grab;
 spice_main_clipboard_notify;
 spice_main_clipboard_release;
diff --git a/src/spice-glib-sym-file b/src/spice-glib-sym-file
index 72e6ef0..a8bfe1d 100644
--- a/src/spice-glib-sym-file
+++ b/src/spice-glib-sym-file
@@ -73,6 +73,7 @@ spice_main_channel_request_mouse_mode
 spice_main_channel_send_monitor_config
 spice_main_channel_update_display
 spice_main_channel_update_display_enabled
+spice_main_channel_update_display_mm
 spice_main_clipboard_grab
 spice_main_clipboard_notify
 spice_main_clipboard_release
commit e521ddee98961bb30a7a3d93c6c01dddb7da3662
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Tue Sep 15 13:09:46 2020 +0400

    main: add stricter pre-condition on display id value
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>
    Acked-by: Frediano Ziglio <fziglio at redhat.com>

diff --git a/src/channel-main.c b/src/channel-main.c
index 671716a..5fcf8e8 100644
--- a/src/channel-main.c
+++ b/src/channel-main.c
@@ -2723,7 +2723,7 @@ void spice_main_channel_update_display(SpiceMainChannel *channel, int id, int x,
 
     c = SPICE_MAIN_CHANNEL(channel)->priv;
 
-    g_return_if_fail(id < SPICE_N_ELEMENTS(c->display));
+    g_return_if_fail(id >= 0 && id < SPICE_N_ELEMENTS(c->display));
 
     SpiceDisplayConfig display = {
         .x = x, .y = y, .width = width, .height = height,
@@ -3040,7 +3040,7 @@ void spice_main_channel_update_display_enabled(SpiceMainChannel *channel, int id
             c->display[i].display_state = display_state;
         }
     } else {
-        g_return_if_fail(id < G_N_ELEMENTS(c->display));
+        g_return_if_fail(id >= 0 && id < G_N_ELEMENTS(c->display));
         if (c->display[id].display_state == display_state)
             return;
         c->display[id].display_state = display_state;


More information about the Spice-commits mailing list