From: Marc-André Lureau <marcandre.lur...@redhat.com> Note that for consistency, we use the same logic as MonitorsConfig to figure out the associated monitor. However, I can't find traces of the discussion/patches about the "new spice-server" behaviour: it still uses the multiple-configurations path in git master.
Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> --- include/ui/console.h | 4 ++++ ui/spice-display.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/include/ui/console.h b/include/ui/console.h index f35b4fc082..c334b92e70 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -133,6 +133,9 @@ typedef struct DisplaySurface { } DisplaySurface; typedef struct QemuUIInfo { + /* physical dimension */ + uint16_t width_mm; + uint16_t height_mm; /* geometry */ int xoff; int yoff; @@ -278,6 +281,7 @@ void update_displaychangelistener(DisplayChangeListener *dcl, void unregister_displaychangelistener(DisplayChangeListener *dcl); bool dpy_ui_info_supported(QemuConsole *con); +const QemuUIInfo *dpy_get_ui_info(const QemuConsole *con); int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info); void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h); diff --git a/ui/spice-display.c b/ui/spice-display.c index 625d9232b9..93d4e1c0a4 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -657,6 +657,53 @@ static void interface_set_client_capabilities(QXLInstance *sin, /* nothing to do */ } +#if SPICE_INTERFACE_QXL_MAJOR >= 3 && SPICE_INTERFACE_QXL_MINOR >= 4 +static int interface_client_monitors_mm(QXLInstance *sin, VDAgentMonitorsMM *mm) +{ + SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl); + QemuUIInfo info; + int head; + + if (!dpy_ui_info_supported(ssd->dcl.con)) { + return 0; /* == not supported by guest */ + } + + if (!mm) { + return 1; + } + + info = *dpy_get_ui_info(ssd->dcl.con); + /* Note: this code doesn't handle Spice multi-head support, where multiple + * monitor configuration for a single QXL device means multiple head. */ + if (mm->num_of_monitors == 1) { + /* + * New spice-server version which filters the list of monitors + * to only include those that belong to our display channel. + * + * single-head configuration (where filtering doesn't matter) + * takes this code path too. + */ + info.width_mm = mm->monitors[0].width; + info.height_mm = mm->monitors[0].height; + } else { + /* + * Old spice-server which gives us all monitors, so we have to + * figure ourself which entry we need. Array index is the + * channel_id, which is the qemu console index, see + * qemu_spice_add_display_interface(). + */ + head = qemu_console_get_index(ssd->dcl.con); + if (mm->num_of_monitors > head) { + info.width_mm = mm->monitors[head].width; + info.height_mm = mm->monitors[head].height; + } + } + + dpy_set_ui_info(ssd->dcl.con, &info); + return 1; +} +#endif + static int interface_client_monitors_config(QXLInstance *sin, VDAgentMonitorsConfig *mc) { @@ -674,6 +721,8 @@ static int interface_client_monitors_config(QXLInstance *sin, info = *dpy_get_ui_info(ssd->dcl.con); + /* Note: this code doesn't handle Spice multi-head support, where multiple + * monitor configuration for a single QXL device means multiple head. */ if (mc->num_of_monitors == 1) { /* * New spice-server version which filters the list of monitors @@ -728,6 +777,9 @@ static const QXLInterface dpy_interface = { .update_area_complete = interface_update_area_complete, .set_client_capabilities = interface_set_client_capabilities, .client_monitors_config = interface_client_monitors_config, +#if SPICE_INTERFACE_QXL_MAJOR >= 3 && SPICE_INTERFACE_QXL_MINOR >= 4 + .client_monitors_mm = interface_client_monitors_mm, +#endif }; static void display_update(DisplayChangeListener *dcl, -- 2.26.2