[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