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