diff options
| author | Hans de Goede <hdegoede@redhat.com> | 2013-01-30 11:12:26 +0100 |
|---|---|---|
| committer | Hans de Goede <hdegoede@redhat.com> | 2013-01-30 17:04:56 +0100 |
| commit | 0dea1073d52bec13045fbb70bc9221a5fbca4e9c (patch) | |
| tree | 123ab0d0fb772302e616bc6415e707e87a640992 /src | |
| parent | 1fc816764b6db66c671ffa936ee024a481d88bb4 (diff) | |
| download | vd_agent-0dea1073d52bec13045fbb70bc9221a5fbca4e9c.tar.gz vd_agent-0dea1073d52bec13045fbb70bc9221a5fbca4e9c.tar.xz vd_agent-0dea1073d52bec13045fbb70bc9221a5fbca4e9c.zip | |
randr: Add a get get_current_mon_config function
And use it in same_monitor_configs, this is a preparation patch for
restoring the current settings when changing the settings fails due to
having not enough video-memory.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/vdagent-x11-randr.c | 126 |
1 files changed, 71 insertions, 55 deletions
diff --git a/src/vdagent-x11-randr.c b/src/vdagent-x11-randr.c index 7745a6e..8b1cc2d 100644 --- a/src/vdagent-x11-randr.c +++ b/src/vdagent-x11-randr.c @@ -603,78 +603,91 @@ static int enabled_monitors(VDAgentMonitorsConfig *mon) } static int same_monitor_configs(struct vdagent_x11 *x11, + VDAgentMonitorsConfig *curr, VDAgentMonitorsConfig *mon, int primary_w, int primary_h) { - int i; - XRRModeInfo *mode; - XRRCrtcInfo *crtc; - VDAgentMonConfig *client_mode; - XRRScreenResources *res; - - update_randr_res(x11, 0); - res = x11->randr.res; + XRRScreenResources *res = x11->randr.res; + int i, real_num_of_monitors = 0; - if (res->noutput > res->ncrtc) { - syslog(LOG_ERR, "error: unexpected noutput > ncrtc in driver"); - return 0; + for (i = 0; i < mon->num_of_monitors; i++) { + if (monitor_enabled(&mon->monitors[i])) + real_num_of_monitors = i + 1; } + mon->num_of_monitors = real_num_of_monitors; if (mon->num_of_monitors > res->noutput) { - for (i = res->noutput; i < mon->num_of_monitors; i++) { - if (monitor_enabled(&mon->monitors[i])) { - syslog(LOG_WARNING, - "warning: unexpected client request: #mon %d > driver output %d", - mon->num_of_monitors, res->noutput); - break; - } - } + syslog(LOG_WARNING, + "warning unexpected client request: #mon %d > driver output %d", + mon->num_of_monitors, res->noutput); mon->num_of_monitors = res->noutput; } if (x11->width != primary_w || x11->height != primary_h) return 0; - if (x11->randr.num_monitors != enabled_monitors(mon)) + if (curr == NULL || mon->num_of_monitors != curr->num_of_monitors) 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; - } - if (x11->randr.outputs[i]->ncrtc != 1) { - syslog(LOG_ERR, "error: unexpected driver config, ncrtc %d != 1", - x11->randr.outputs[i]->ncrtc); - return 0; - } - crtc = crtc_from_id(x11, x11->randr.outputs[i]->crtcs[0]); - if (!crtc) { - syslog(LOG_ERR, "error: inconsistent or stale data from X"); - return 0; - } - client_mode = &mon->monitors[i]; - mode = mode_from_id(x11, crtc->mode); - if (!mode) { - return 0; - } + for (i = 0; i < mon->num_of_monitors; i++) { + VDAgentMonConfig *mon1 = &mon->monitors[i]; + VDAgentMonConfig *mon2 = &curr->monitors[i]; /* NOTE: we don't compare depth. */ - /* NOTE 2: width set by X is a multiple of 8, so ignore lower 3 bits */ - if ((mode->width & ~7) != (client_mode->width & ~7) || - mode->height != client_mode->height || - (crtc->x & ~7) != (client_mode->x & ~7) || - crtc->y != client_mode->y) { + if (mon1->x != mon2->x || mon1->y != mon2->y || + mon1->width != mon2->width || mon1->height != mon2->height) return 0; - } } return 1; } +static VDAgentMonitorsConfig *get_current_mon_config(struct vdagent_x11 *x11) +{ + int i, num_of_monitors = 0; + XRRModeInfo *mode; + XRRCrtcInfo *crtc; + XRRScreenResources *res; + VDAgentMonitorsConfig *mon_config; + + update_randr_res(x11, 0); + res = x11->randr.res; + + mon_config = calloc(1, sizeof(VDAgentMonitorsConfig) + + res->noutput * sizeof(VDAgentMonConfig)); + if (!mon_config) { + syslog(LOG_ERR, "out of memory allocating current monitor config"); + return NULL; + } + + for (i = 0 ; i < res->noutput; i++) { + if (x11->randr.outputs[i]->ncrtc == 0) + continue; /* Monitor disabled, already zero-ed by calloc */ + if (x11->randr.outputs[i]->ncrtc != 1) + goto error; + + crtc = crtc_from_id(x11, x11->randr.outputs[i]->crtcs[0]); + if (!crtc) + goto error; + + mode = mode_from_id(x11, crtc->mode); + if (!mode) + continue; /* Monitor disabled, already zero-ed by calloc */ + + mon_config->monitors[i].x = crtc->x; + mon_config->monitors[i].y = crtc->y; + mon_config->monitors[i].width = mode->width; + mon_config->monitors[i].height = mode->height; + num_of_monitors = i + 1; + } + mon_config->num_of_monitors = num_of_monitors; + mon_config->flags = VD_AGENT_CONFIG_MONITORS_FLAG_USE_POS; + return mon_config; + +error: + syslog(LOG_ERR, "error: inconsistent or stale data from X"); + free(mon_config); + return NULL; +} + static void dump_monitors_config(struct vdagent_x11 *x11, VDAgentMonitorsConfig *mon_config, const char *prefix) @@ -710,6 +723,7 @@ void vdagent_x11_set_monitor_config(struct vdagent_x11 *x11, int width, height; int x, y; int primary_w, primary_h; + VDAgentMonitorsConfig *curr = NULL; if (!x11->has_xrandr) goto exit; @@ -734,14 +748,15 @@ void vdagent_x11_set_monitor_config(struct vdagent_x11 *x11, constrain_to_screen(x11, &primary_w, &primary_h); - if (same_monitor_configs(x11, mon_config, primary_w, primary_h)) { - goto exit; - } - if (x11->debug) { dump_monitors_config(x11, mon_config, "after zeroing"); } + curr = get_current_mon_config(x11); + if (same_monitor_configs(x11, curr, mon_config, primary_w, primary_h)) { + goto exit; + } + for (i = mon_config->num_of_monitors; i < x11->randr.res->noutput; i++) xrandr_disable_output(x11, i); @@ -793,6 +808,7 @@ exit: /* Flush output buffers and consume any pending events */ vdagent_x11_do_read(x11); + free(curr); } void vdagent_x11_send_daemon_guest_xorg_res(struct vdagent_x11 *x11) |
