diff options
Diffstat (limited to 'hw/xfree86/modes/xf86Crtc.c')
-rw-r--r-- | hw/xfree86/modes/xf86Crtc.c | 137 |
1 files changed, 129 insertions, 8 deletions
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 127e5431b..38bc58cbc 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -1124,6 +1124,15 @@ xf86InitialOutputPositions(ScrnInfoPtr scrn, DisplayModePtr * modes) int o; int min_x, min_y; + /* check for initial right-of heuristic */ + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + if (output->initial_x || output->initial_y) + return TRUE; + } + for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; @@ -2103,6 +2112,118 @@ bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect) return match; } +static int +numEnabledOutputs(xf86CrtcConfigPtr config, Bool *enabled) +{ + int i = 0, p; + + for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ; + + return i; +} + +static Bool +xf86TargetRightOf(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, + DisplayModePtr *modes, Bool *enabled, + int width, int height) +{ + int o; + int w = 0; + Bool has_tile = FALSE; + uint32_t configured_outputs; + + if (scrn->preferClone) + return FALSE; + + if (numEnabledOutputs(config, enabled) < 2) + return FALSE; + + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + DisplayModePtr mode = + xf86OutputHasPreferredMode(config->output[o], width, height); + + if (!mode) + return FALSE; + + w += mode->HDisplay; + } + + if (w > width) + return FALSE; + + w = 0; + configured_outputs = 0; + + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + DisplayModePtr mode = + xf86OutputHasPreferredMode(config->output[o], width, height); + + if (configured_outputs & (1 << o)) + continue; + + if (config->output[o]->tile_info.group_id) { + has_tile = TRUE; + continue; + } + + config->output[o]->initial_x = w; + w += mode->HDisplay; + + configured_outputs |= (1 << o); + modes[o] = mode; + } + + if (has_tile) { + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + int ht, vt, ot; + int add_x, cur_x = w; + struct xf86CrtcTileInfo *tile_info = &config->output[o]->tile_info, *this_tile; + if (configured_outputs & (1 << o)) + continue; + if (!tile_info->group_id) + continue; + + if (tile_info->tile_h_loc != 0 && tile_info->tile_v_loc != 0) + continue; + + for (ht = 0; ht < tile_info->num_h_tile; ht++) { + int cur_y = 0; + add_x = 0; + for (vt = 0; vt < tile_info->num_v_tile; vt++) { + + for (ot = -1; nextEnabledOutput(config, enabled, &ot); ) { + + DisplayModePtr mode = + xf86OutputHasPreferredMode(config->output[ot], width, height); + if (!config->output[ot]->tile_info.group_id) + continue; + + this_tile = &config->output[ot]->tile_info; + if (this_tile->group_id != tile_info->group_id) + continue; + + if (this_tile->tile_h_loc != ht || + this_tile->tile_v_loc != vt) + continue; + + config->output[ot]->initial_x = cur_x; + config->output[ot]->initial_y = cur_y; + + if (vt == 0) + add_x = this_tile->tile_h_size; + cur_y += this_tile->tile_v_size; + configured_outputs |= (1 << ot); + modes[ot] = mode; + } + } + cur_x += add_x; + } + w = cur_x; + } + } + return TRUE; +} + static Bool xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, DisplayModePtr * modes, Bool *enabled, @@ -2179,14 +2300,10 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, */ if (!ret) do { - int i = 0; float aspect = 0.0; DisplayModePtr a = NULL, b = NULL; - /* count the number of enabled outputs */ - for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++); - - if (i != 1) + if (numEnabledOutputs(config, enabled) != 1) break; p = -1; @@ -2492,6 +2609,8 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow) else { if (xf86TargetUserpref(scrn, config, modes, enabled, width, height)) xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n"); + else if (xf86TargetRightOf(scrn, config, modes, enabled, width, height)) + xf86DrvMsg(i, X_INFO, "Using spanning desktop for initial modes\n"); else if (xf86TargetPreferred (scrn, config, modes, enabled, width, height)) xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n"); @@ -2511,9 +2630,11 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow) "Output %s enabled but has no modes\n", config->output[o]->name); else - xf86DrvMsg(scrn->scrnIndex, X_INFO, - "Output %s using initial mode %s\n", - config->output[o]->name, modes[o]->name); + xf86DrvMsg (scrn->scrnIndex, X_INFO, + "Output %s using initial mode %s +%d+%d\n", + config->output[o]->name, modes[o]->name, + config->output[o]->initial_x, + config->output[o]->initial_y); } /* |