[Spice-devel] [PATCH linux vdagent v4 4/9] Use guest output map to determine xrandr output
Lukáš Hrázký
lhrazky at redhat.com
Fri Jan 18 12:49:52 UTC 2019
On Thu, 2019-01-17 at 16:14 -0600, Jonathon Jongsma wrote:
> instead of using the spice display id directly as the xrandr output,
> look it up using our new guest output map
> ---
> src/vdagent/x11-randr.c | 78 ++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 69 insertions(+), 9 deletions(-)
>
> diff --git a/src/vdagent/x11-randr.c b/src/vdagent/x11-randr.c
> index 10a1325..5eff225 100644
> --- a/src/vdagent/x11-randr.c
> +++ b/src/vdagent/x11-randr.c
> @@ -399,6 +399,28 @@ static int xrandr_add_and_set(struct vdagent_x11 *x11, int output_index, int x,
> return 1;
> }
>
> +// Looks up the xrandr output id associated with the given spice display id
> +static RROutput get_xrandr_output_for_display_id(struct vdagent_x11 *x11, int display_id)
> +{
> + guint map_size = g_hash_table_size(x11->guest_output_map);
> + if (map_size == 0) {
> + // we never got a device info message from the server, so just use old
> + // assumptions that the spice display id is equal to the index into the
> + // array of xrandr outputs
> + if (display_id < x11->randr.res->noutput) {
> + return x11->randr.res->outputs[display_id];
> + }
> + } else {
> + gpointer value;
> + if (g_hash_table_lookup_extended(x11->guest_output_map, GINT_TO_POINTER(display_id), NULL, &value)) {
Line too long.
> + return *(gint64*)value;
> + }
> + }
> +
> + // unable to find a valid output id
> + return -1;
> +}
> +
> static void xrandr_disable_nth_output(struct vdagent_x11 *x11, int output_index)
> {
> Status s;
> @@ -786,6 +808,16 @@ void vdagent_x11_handle_graphics_device_info(struct vdagent_x11 *x11, uint8_t *d
> }
> }
>
> +static int get_output_index_for_display_id(struct vdagent_x11 *x11, int display_id)
> +{
> + RROutput oid = get_xrandr_output_for_display_id(x11, display_id);
> + for (int i = 0; i < x11->randr.res->noutput; i++) {
> + if (oid == x11->randr.res->outputs[i]) {
> + return i;
> + }
> + }
> + return -1;
> +}
>
> /*
> * Set monitor configuration according to client request.
> @@ -862,13 +894,32 @@ void vdagent_x11_set_monitor_config(struct vdagent_x11 *x11,
> g_unlink(config);
> g_free(config);
>
> - for (i = mon_config->num_of_monitors; i < x11->randr.res->noutput; i++)
> - xrandr_disable_nth_output(x11, i);
> + // disable all outputs that don't have associated entries in the MonitorConfig
> + for (i = 0; i < x11->randr.res->noutput; i++) {
> + bool disable = true;
> + // check if this xrandr output is represented by an item in mon_config
> + for (int j = 0; j < mon_config->num_of_monitors; j++) {
> + // j represents the display id of an enabled monitor. Check whether
> + // an enabled xrandr output is represented by this id.
> + RROutput oid = get_xrandr_output_for_display_id(x11, j);
> + if (oid == x11->randr.res->outputs[i]) {
> + disable = false;
> + }
> + }
> + if (disable) {
> + xrandr_disable_nth_output(x11, i);
> + }
> + }
>
> - /* First, disable disabled CRTCs... */
> + /* disable CRTCs that are present but explicitly disabled in the
> + * MonitorConfig */
> for (i = 0; i < mon_config->num_of_monitors; ++i) {
> if (!monitor_enabled(&mon_config->monitors[i])) {
> - xrandr_disable_nth_output(x11, i);
> + int output_index = get_output_index_for_display_id(x11, i);
> + if (output_index != -1)
> + xrandr_disable_nth_output(x11, output_index);
> + else
> + syslog(LOG_WARNING, "Unable to find a guest output index for spice display %i", i);
Brackets missing.
> }
> }
>
> @@ -891,7 +942,11 @@ void vdagent_x11_set_monitor_config(struct vdagent_x11 *x11,
> syslog(LOG_DEBUG, "Disabling monitor %d: %dx%d+%d+%d > (%d,%d)",
> i, width, height, x, y, primary_w, primary_h);
>
> - xrandr_disable_nth_output(x11, i);
> + int output_index = get_output_index_for_display_id(x11, i);
> + if (output_index != -1)
> + xrandr_disable_nth_output(x11, output_index);
> + else
> + syslog(LOG_WARNING, "Unable to find a guest output index for spice display %i", i);
Brackets missing.
> }
> }
>
> @@ -943,11 +998,16 @@ void vdagent_x11_set_monitor_config(struct vdagent_x11 *x11,
> i, width, height, x, y);
> }
>
> - if (!xrandr_add_and_set(x11, i, x, y, width, height) &&
> + int output_index = get_output_index_for_display_id(x11, i);
> + if (output_index != -1) {
> + if (!xrandr_add_and_set(x11, output_index, x, y, width, height) &&
> enabled_monitors(mon_config) == 1) {
> - set_screen_to_best_size(x11, width, height,
> - &primary_w, &primary_h);
> - break;
> + set_screen_to_best_size(x11, width, height,
> + &primary_w, &primary_h);
> + break;
> + }
> + } else {
> + syslog(LOG_WARNING, "Unable to find a guest output index for spice display %i", i);
> }
> }
Reviewed-by: Lukáš Hrázký <lhrazky at redhat.com>
More information about the Spice-devel
mailing list