[Spice-devel] [linux-vdagent PATCH] randr: Add support for VD_AGENT_CAP_SPARSE_MONITORS_CONFIG (rhbz#881072)
Hans de Goede
hdegoede at redhat.com
Thu Jan 10 15:02:04 PST 2013
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
src/vdagent-x11-randr.c | 55 +++++++++++++++++++++++++++++++++++--------------
src/vdagentd.c | 1 +
2 files changed, 40 insertions(+), 16 deletions(-)
diff --git a/src/vdagent-x11-randr.c b/src/vdagent-x11-randr.c
index 59dfe38..7745a6e 100644
--- a/src/vdagent-x11-randr.c
+++ b/src/vdagent-x11-randr.c
@@ -24,6 +24,7 @@
#include <string.h>
#include <syslog.h>
#include <stdlib.h>
+#include <limits.h>
#include <X11/extensions/Xinerama.h>
@@ -537,6 +538,11 @@ static void constrain_to_screen(struct vdagent_x11 *x11, int *w, int *h)
}
}
+static int monitor_enabled(VDAgentMonConfig *mon)
+{
+ return mon->width != 0 && mon->height != 0;
+}
+
/*
* The agent config doesn't contain a primary size, just the monitors, but
* we need to total size as well, to make sure we have enough memory and
@@ -553,20 +559,12 @@ static void zero_base_monitors(struct vdagent_x11 *x11,
VDAgentMonitorsConfig *mon_config,
int *width, int *height)
{
- int i = 0;
- int min_x, min_y, max_x, max_y;
+ int i, min_x = INT_MAX, min_y = INT_MAX, max_x = INT_MIN, max_y = INT_MIN;
int *mon_height, *mon_width;
- mon_config->monitors[0].x &= ~7;
- mon_config->monitors[0].width &= ~7;
- mon_width = (int *)&mon_config->monitors[i].width;
- mon_height = (int *)&mon_config->monitors[i].height;
- constrain_to_screen(x11, mon_width, mon_height);
- min_x = mon_config->monitors[0].x;
- min_y = mon_config->monitors[0].y;
- max_x = mon_config->monitors[0].width + min_x;
- max_y = mon_config->monitors[0].height + min_y;
- for (++i ; i < mon_config->num_of_monitors; ++i) {
+ for (i = 0; i < mon_config->num_of_monitors; i++) {
+ if (!monitor_enabled(&mon_config->monitors[i]))
+ continue;
mon_config->monitors[i].x &= ~7;
mon_config->monitors[i].width &= ~7;
mon_width = (int *)&mon_config->monitors[i].width;
@@ -581,6 +579,8 @@ static void zero_base_monitors(struct vdagent_x11 *x11,
syslog(LOG_ERR, "%s: agent config %d,%d rooted, adjusting to 0,0.",
__FUNCTION__, min_x, min_y);
for (i = 0 ; i < mon_config->num_of_monitors; ++i) {
+ if (!monitor_enabled(&mon_config->monitors[i]))
+ continue;
mon_config->monitors[i].x -= min_x;
mon_config->monitors[i].y -= min_y;
}
@@ -591,6 +591,17 @@ static void zero_base_monitors(struct vdagent_x11 *x11,
*height = max_y;
}
+static int enabled_monitors(VDAgentMonitorsConfig *mon)
+{
+ int i, enabled = 0;
+
+ for (i = 0; i < mon->num_of_monitors; i++) {
+ if (monitor_enabled(&mon->monitors[i]))
+ enabled++;
+ }
+ return enabled;
+}
+
static int same_monitor_configs(struct vdagent_x11 *x11,
VDAgentMonitorsConfig *mon,
int primary_w, int primary_h)
@@ -611,7 +622,7 @@ static int same_monitor_configs(struct vdagent_x11 *x11,
if (mon->num_of_monitors > res->noutput) {
for (i = res->noutput; i < mon->num_of_monitors; i++) {
- if (mon->monitors[i].width || mon->monitors[i].height) {
+ if (monitor_enabled(&mon->monitors[i])) {
syslog(LOG_WARNING,
"warning: unexpected client request: #mon %d > driver output %d",
mon->num_of_monitors, res->noutput);
@@ -624,10 +635,16 @@ static int same_monitor_configs(struct vdagent_x11 *x11,
if (x11->width != primary_w || x11->height != primary_h)
return 0;
- if (x11->randr.num_monitors != mon->num_of_monitors)
+ if (x11->randr.num_monitors != enabled_monitors(mon))
return 0;
for (i = 0 ; i < mon->num_of_monitors; ++i) {
+ if (!monitor_enabled(&mon->monitors[i])) {
+ if (x11->randr.outputs[i]->ncrtc != 0) {
+ return 0;
+ }
+ continue;
+ }
if (x11->randr.outputs[i]->ncrtc == 0) {
return 0;
}
@@ -669,6 +686,8 @@ static void dump_monitors_config(struct vdagent_x11 *x11,
mon_config->flags);
for (i = 0 ; i < mon_config->num_of_monitors; ++i) {
m = &mon_config->monitors[i];
+ if (!monitor_enabled(m))
+ continue;
syslog(LOG_DEBUG, "received monitor %d config %dx%d+%d+%d", i,
m->width, m->height, m->x, m->y);
}
@@ -727,13 +746,17 @@ void vdagent_x11_set_monitor_config(struct vdagent_x11 *x11,
xrandr_disable_output(x11, i);
for (i = 0; i < mon_config->num_of_monitors; ++i) {
+ if (!monitor_enabled(&mon_config->monitors[i])) {
+ xrandr_disable_output(x11, i);
+ continue;
+ }
/* Try to create the requested resolution */
width = mon_config->monitors[i].width;
height = mon_config->monitors[i].height;
x = mon_config->monitors[i].x;
y = mon_config->monitors[i].y;
if (!xrandr_add_and_set(x11, i, x, y, width, height) &&
- mon_config->num_of_monitors == 1) {
+ enabled_monitors(mon_config) == 1) {
set_screen_to_best_size(x11, width, height,
&primary_w, &primary_h);
goto update;
@@ -756,7 +779,7 @@ void vdagent_x11_set_monitor_config(struct vdagent_x11 *x11,
update:
update_randr_res(x11,
- x11->randr.num_monitors != mon_config->num_of_monitors);
+ x11->randr.num_monitors != enabled_monitors(mon_config));
x11->width = primary_w;
x11->height = primary_h;
diff --git a/src/vdagentd.c b/src/vdagentd.c
index b5f6434..27925f5 100644
--- a/src/vdagentd.c
+++ b/src/vdagentd.c
@@ -96,6 +96,7 @@ static void send_capabilities(struct vdagent_virtio_port *vport,
VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_REPLY);
VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND);
VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_SELECTION);
+ VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_SPARSE_MONITORS_CONFIG);
vdagent_virtio_port_write(vport, VDP_CLIENT_PORT,
VD_AGENT_ANNOUNCE_CAPABILITIES, 0,
--
1.8.0.2
More information about the Spice-devel
mailing list