From 232e2094321dbcdd6a67ef230eb50494a1c7d6df Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 3 Jan 2007 00:38:34 -0800 Subject: Allow initial position to be set in config file. Increase 965 max size. Add relative and absolute position configuration code, using per-output monitor sections. Options include: PreferredMode selects a preferred mode for this output by name Position absolute position, x and y in a single string. Below relative positions; argument names other monitor. RightOf Above LeftOf Enable force the monitor to be disabled by setting Disable enable to no or disable to yes. MinClock Set valid clock ranges MaxClock Monitor sections can also include sync ranges, physical size and mode lines as documented in xorg.conf(5). Monitors are associated with outputs through options in the Device section: Option "monitor-VGA" "My VGA Monitor" Output named 'VGA' will use monitor section "My VGA Monitor". --- src/i830_driver.c | 25 ++-- src/i830_randr.c | 4 +- src/i830_sdvo.c | 7 +- src/i830_xf86Crtc.c | 410 +++++++++++++++++++++++++++++++++++++++++++--------- src/i830_xf86Crtc.h | 20 ++- 5 files changed, 375 insertions(+), 91 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 52647676..694c96f3 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -912,7 +912,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) Bool enable; const char *chipname; int num_pipe; - int max_width; + int max_width, max_height; #ifdef XF86DRI unsigned long savedMMSize; #endif @@ -1183,10 +1183,16 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); if (IS_I965G(pI830)) + { max_width = 16384; + max_height = 4096; + } else - max_width = 8192 / pI830->cpp; - xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, 2048); + { + max_width = 2048; + max_height = 2048; + } + xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height); /* Some of the probing needs MMIO access, so map it here. */ I830MapMMIO(pScrn); @@ -1830,14 +1836,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, "VideoRam: %d KB\n", pScrn->videoRam); - if (!IS_I965G(pI830) && pScrn->displayWidth * pI830->cpp > 8192) { + if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Cannot support DRI with frame buffer stride > 8K.\n"); + "Cannot support DRI with frame buffer width > 2048.\n"); pI830->disableTiling = TRUE; pI830->directRenderingDisabled = TRUE; } - if (pScrn->virtualY > 2048) { + if (!IS_I965G(pI830) && pScrn->virtualY > 2048) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support > 2048 vertical lines. disabling acceleration.\n"); pI830->noAccel = TRUE; } @@ -3047,7 +3053,8 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcPtr crtc = config->output[config->compat_output]->crtc; + xf86OutputPtr output = config->output[config->compat_output]; + xf86CrtcPtr crtc = output->crtc; DPRINTF(PFX, "i830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n", x, pI830->xoffset, y, pI830->yoffset); @@ -3059,7 +3066,7 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags) (*pI830->AccelInfoRec->Sync)(pScrn); pI830->AccelInfoRec->NeedToSync = FALSE; } - i830PipeSetBase(crtc, x, y); + i830PipeSetBase(crtc, output->initial_x + x, output->initial_y + y); } } @@ -3596,7 +3603,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) * is this. */ - xf86ProbeOutputModes (pScrn); + xf86ProbeOutputModes (pScrn, 0, 0); xf86SetScrnInfoModes (pScrn); I830DGAReInit (pScrn->pScreen); xf86SwitchMode(pScrn->pScreen, pScrn->currentMode); diff --git a/src/i830_randr.c b/src/i830_randr.c index d5ccce37..83cf0238 100644 --- a/src/i830_randr.c +++ b/src/i830_randr.c @@ -95,7 +95,7 @@ xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations) } /* Re-probe the outputs for new monitors or modes */ - xf86ProbeOutputModes (scrp); + xf86ProbeOutputModes (scrp, 0, 0); xf86SetScrnInfoModes (scrp); I830DGAReInit (pScreen); @@ -818,7 +818,7 @@ xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86ProbeOutputModes (pScrn); + xf86ProbeOutputModes (pScrn, 0, 0); xf86SetScrnInfoModes (pScrn); I830DGAReInit (pScreen); return xf86RandR12SetInfo12 (pScreen); diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index b5116be0..19b4b934 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -1207,7 +1207,12 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) } strcpy (name, name_prefix); strcat (name, name_suffix); - xf86OutputRename (output, name); + if (!xf86OutputRename (output, name)) + { + xf86OutputDestroy (output); + return; + } + /* Set the input timing to the screen. Assume always input 0. */ i830_sdvo_set_target_input(output, TRUE, FALSE); diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c index a0f44df5..ceb8f2ef 100644 --- a/src/i830_xf86Crtc.c +++ b/src/i830_xf86Crtc.c @@ -127,6 +127,33 @@ xf86CrtcDestroy (xf86CrtcPtr crtc) extern XF86ConfigPtr xf86configptr; +typedef enum { + OPTION_PREFERRED_MODE, + OPTION_POSITION, + OPTION_BELOW, + OPTION_RIGHT_OF, + OPTION_ABOVE, + OPTION_LEFT_OF, + OPTION_ENABLE, + OPTION_DISABLE, + OPTION_MIN_CLOCK, + OPTION_MAX_CLOCK, +} OutputOpts; + +static OptionInfoRec xf86OutputOptions[] = { + {OPTION_PREFERRED_MODE, "PreferredMode", OPTV_STRING, {0}, FALSE }, + {OPTION_POSITION, "Position", OPTV_STRING, {0}, FALSE }, + {OPTION_BELOW, "Below", OPTV_STRING, {0}, FALSE }, + {OPTION_RIGHT_OF, "RightOf", OPTV_STRING, {0}, FALSE }, + {OPTION_ABOVE, "Above", OPTV_STRING, {0}, FALSE }, + {OPTION_LEFT_OF, "LeftOf", OPTV_STRING, {0}, FALSE }, + {OPTION_ENABLE, "Enable", OPTV_BOOLEAN, {0}, FALSE }, + {OPTION_DISABLE, "Disable", OPTV_BOOLEAN, {0}, FALSE }, + {OPTION_MIN_CLOCK, "MinClock", OPTV_FREQ, {0}, FALSE }, + {OPTION_MAX_CLOCK, "MaxClock", OPTV_FREQ, {0}, FALSE }, + {-1, NULL, OPTV_NONE, {0}, FALSE }, +}; + static void xf86OutputSetMonitor (xf86OutputPtr output) { @@ -134,6 +161,12 @@ xf86OutputSetMonitor (xf86OutputPtr output) static const char monitor_prefix[] = "monitor-"; char *monitor; + if (output->options) + xfree (output->options); + + output->options = xnfalloc (sizeof (xf86OutputOptions)); + memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions)); + option_name = xnfalloc (strlen (monitor_prefix) + strlen (output->name) + 1); strcpy (option_name, monitor_prefix); @@ -144,7 +177,24 @@ xf86OutputSetMonitor (xf86OutputPtr output) else xf86MarkOptionUsedByName (output->scrn->options, option_name); xfree (option_name); - output->conf_monitor = xf86findMonitor (monitor, xf86configptr->conf_monitor_lst); + output->conf_monitor = xf86findMonitor (monitor, + xf86configptr->conf_monitor_lst); + if (output->conf_monitor) + xf86ProcessOptions (output->scrn->scrnIndex, + output->conf_monitor->mon_option_lst, + output->options); +} + +static Bool +xf86OutputEnabled (xf86OutputPtr output) +{ + /* Check to see if this output was disabled in the config file */ + if (xf86ReturnOptValBool (output->options, OPTION_ENABLE, TRUE) == FALSE || + xf86ReturnOptValBool (output->options, OPTION_DISABLE, FALSE) == TRUE) + { + return FALSE; + } + return TRUE; } xf86OutputPtr @@ -167,6 +217,8 @@ xf86OutputCreate (ScrnInfoPtr scrn, #ifdef RANDR_12_INTERFACE output->randr_output = NULL; #endif + xf86OutputSetMonitor (output); + if (xf86_config->output) outputs = xrealloc (xf86_config->output, (xf86_config->num_output + 1) * sizeof (xf86OutputPtr)); @@ -181,24 +233,24 @@ xf86OutputCreate (ScrnInfoPtr scrn, xf86_config->output = outputs; xf86_config->output[xf86_config->num_output++] = output; - xf86OutputSetMonitor (output); return output; } -void +Bool xf86OutputRename (xf86OutputPtr output, const char *name) { int len = strlen(name); char *newname = xalloc (len + 1); if (!newname) - return; /* so sorry... */ + return FALSE; /* so sorry... */ strcpy (newname, name); if (output->name != (char *) (output + 1)) xfree (output->name); output->name = newname; xf86OutputSetMonitor (output); + return TRUE; } void @@ -375,7 +427,9 @@ xf86PickCrtcs (ScrnInfoPtr pScrn, * If the two outputs desire the same mode, * see if they can be cloned */ - if (xf86ModesEqual (modes[o], modes[n])) + if (xf86ModesEqual (modes[o], modes[n]) && + config->output[o]->initial_x == config->output[n]->initial_x && + config->output[o]->initial_y == config->output[n]->initial_y) { for (l = 0; l < config->num_output; l++) if (output->possible_clones & (1 << l)) @@ -403,7 +457,8 @@ xf86PickCrtcs (ScrnInfoPtr pScrn, /* * Compute the virtual size necessary to place all of the available - * crtcs in a panorama configuration + * crtcs in the specified configuration and also large enough to + * resize any crtc to the largest available mode */ static void @@ -418,7 +473,13 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp) for (c = 0; c < config->num_crtc; c++) { int crtc_width = 0, crtc_height = 0; + xf86CrtcPtr crtc = config->crtc[c]; + if (crtc->enabled) + { + crtc_width = crtc->x + crtc->desiredMode.HDisplay; + crtc_height = crtc->y + crtc->desiredMode.VDisplay; + } for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; @@ -436,7 +497,8 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp) } } } - width += crtc_width; + if (crtc_width > width) + width = crtc_width; if (crtc_height > height) height = crtc_height; } @@ -448,6 +510,186 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp) *heightp = height; } +#define POSITION_UNSET -100000 + +static Bool +xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int o; + int min_x, min_y; + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + output->initial_x = output->initial_y = POSITION_UNSET; + } + + /* + * Loop until all outputs are set + */ + for (;;) + { + Bool any_set = FALSE; + Bool keep_going = FALSE; + + for (o = 0; o < config->num_output; o++) + { + static const OutputOpts relations[] = { + OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF + }; + xf86OutputPtr output = config->output[o]; + xf86OutputPtr relative; + char *relative_name; + char *position; + OutputOpts relation; + int r; + + if (output->initial_x != POSITION_UNSET) + continue; + position = xf86GetOptValString (output->options, + OPTION_POSITION); + /* + * Absolute position wins + */ + if (position) + { + int x, y; + if (sscanf (position, "%d %d", &x, &y) == 2) + { + output->initial_x = x; + output->initial_y = y; + } + else + { + xf86DrvMsg (pScrn->scrnIndex, X_ERROR, + "Output %s position not of form \"x y\"\n", + output->name); + output->initial_x = output->initial_y = 0; + } + any_set = TRUE; + continue; + } + /* + * Next comes relative positions + */ + relation = 0; + relative_name = NULL; + for (r = 0; r < 4; r++) + { + relation = relations[r]; + relative_name = xf86GetOptValString (output->options, + relation); + if (relative_name) + break; + } + if (relative_name) + { + int or; + relative = NULL; + for (or = 0; or < config->num_output; or++) + { + xf86OutputPtr out_rel = config->output[or]; + XF86ConfMonitorPtr rel_mon = out_rel->conf_monitor; + char *name; + + if (rel_mon) + name = rel_mon->mon_identifier; + else + name = out_rel->name; + if (!strcmp (relative_name, name)) + { + relative = config->output[or]; + break; + } + } + if (!relative) + { + xf86DrvMsg (pScrn->scrnIndex, X_ERROR, + "Cannot position output %s relative to unknown output %s\n", + output->name, relative_name); + output->initial_x = 0; + output->initial_y = 0; + any_set = TRUE; + continue; + } + if (relative->initial_x == POSITION_UNSET) + { + keep_going = TRUE; + continue; + } + output->initial_x = relative->initial_x; + output->initial_y = relative->initial_y; + switch (relation) { + case OPTION_BELOW: + output->initial_y += modes[or]->VDisplay; + break; + case OPTION_RIGHT_OF: + output->initial_x += modes[or]->HDisplay; + break; + case OPTION_ABOVE: + output->initial_y -= modes[o]->VDisplay; + break; + case OPTION_LEFT_OF: + output->initial_x -= modes[o]->HDisplay; + break; + default: + break; + } + any_set = TRUE; + continue; + } + + /* Nothing set, just stick them at 0,0 */ + output->initial_x = 0; + output->initial_y = 0; + any_set = TRUE; + } + if (!keep_going) + break; + if (!any_set) + { + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + if (output->initial_x == POSITION_UNSET) + { + xf86DrvMsg (pScrn->scrnIndex, X_ERROR, + "Output position loop. Moving %s to 0,0\n", + output->name); + output->initial_x = output->initial_y = 0; + break; + } + } + } + } + + /* + * normalize positions + */ + min_x = 1000000; + min_y = 1000000; + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + if (output->initial_x < min_x) + min_x = output->initial_x; + if (output->initial_y < min_y) + min_y = output->initial_y; + } + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + output->initial_x -= min_x; + output->initial_y -= min_y; + } + return TRUE; +} + /* * XXX walk the monitor mode list and prune out duplicates that * are inserted by xf86DDCMonitorSet. In an ideal world, that @@ -536,13 +778,13 @@ i830xf86SortModes (DisplayModePtr input) #define DEBUG_REPROBE 1 void -xf86ProbeOutputModes (ScrnInfoPtr pScrn) +xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); int o; - int virtualX, virtualY; - xf86RandR12GetOriginalVirtualSize (pScrn, &virtualX, &virtualY); + if (maxX == 0 || maxY == 0) + xf86RandR12GetOriginalVirtualSize (pScrn, &maxX, &maxY); /* Elide duplicate modes before defaulting code uses them */ xf86PruneDuplicateMonitorModes (pScrn->monitor); @@ -553,11 +795,13 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn) xf86OutputPtr output = config->output[o]; DisplayModePtr mode; DisplayModePtr config_modes = NULL, output_modes, default_modes; - XF86ConfMonitorPtr conf_monitor; + char *preferred_mode; xf86MonPtr edid_monitor; + XF86ConfMonitorPtr conf_monitor; MonRec mon_rec; int min_clock = 0; int max_clock = 0; + double clock; enum { sync_config, sync_edid, sync_default } sync_source = sync_default; while (output->probed_modes != NULL) @@ -632,6 +876,14 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn) } } } + + if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK, + OPTUNITS_KHZ, &clock)) + min_clock = (int) clock; + if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK, + OPTUNITS_KHZ, &clock)) + max_clock = (int) clock; + /* * These limits will end up setting a 1024x768@60Hz mode by default, * which seems like a fairly good mode to use when nothing else is @@ -677,9 +929,11 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn) output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes); /* - * Check all modes against virtual size + * Check all modes against max size */ - i830xf86ValidateModesSize (pScrn, output->probed_modes, virtualX, virtualY, 0); + if (maxX && maxY) + i830xf86ValidateModesSize (pScrn, output->probed_modes, + maxX, maxY, 0); /* * Check all modes against output @@ -693,27 +947,28 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn) output->probed_modes = i830xf86SortModes (output->probed_modes); /* Check for a configured preference for a particular mode */ - if (conf_monitor) - { - char *preferred_mode = xf86findOptionValue (conf_monitor->mon_option_lst, - "Preferred Mode"); + preferred_mode = xf86GetOptValString (output->options, + OPTION_PREFERRED_MODE); - if (preferred_mode) + if (preferred_mode) + { + for (mode = output->probed_modes; mode; mode = mode->next) { - for (mode = output->probed_modes; mode; mode = mode->next) - if (!strcmp (preferred_mode, mode->name)) - break; - if (mode && mode != output->probed_modes) + if (!strcmp (preferred_mode, mode->name)) { - if (mode->prev) - mode->prev->next = mode->next; - if (mode->next) - mode->next->prev = mode->prev; - mode->next = output->probed_modes; - output->probed_modes->prev = mode; - mode->prev = NULL; - output->probed_modes = mode; + if (mode != output->probed_modes) + { + if (mode->prev) + mode->prev->next = mode->next; + if (mode->next) + mode->next->prev = mode->prev; + mode->next = output->probed_modes; + output->probed_modes->prev = mode; + mode->prev = NULL; + output->probed_modes = mode; + } mode->type |= M_T_PREFERRED; + break; } } } @@ -760,7 +1015,6 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn) xf86OutputPtr output; xf86CrtcPtr crtc; DisplayModePtr last, mode; - int originalVirtualX, originalVirtualY; output = config->output[config->compat_output]; if (!output->crtc) @@ -788,18 +1042,6 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn) /* Set pScrn->modes to the mode list for the 'compat' output */ pScrn->modes = xf86DuplicateModes(pScrn, output->probed_modes); - xf86RandR12GetOriginalVirtualSize(pScrn, &originalVirtualX, &originalVirtualY); - - /* Disable modes in the XFree86 DDX list that are larger than the current - * virtual size. - */ - i830xf86ValidateModesSize(pScrn, pScrn->modes, - originalVirtualX, originalVirtualY, - pScrn->displayWidth); - - /* Strip out anything that we threw out for virtualX/Y. */ - i830xf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE); - for (mode = pScrn->modes; mode; mode = mode->next) if (xf86ModesEqual (mode, &crtc->desiredMode)) break; @@ -835,35 +1077,33 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) DisplayModePtr target_mode = NULL; xf86CrtcPtr *crtcs; DisplayModePtr *modes; - int width, height; - - xf86ProbeOutputModes (pScrn); + Bool *enabled; + int width; + int height; - if (pScrn->display->virtualX == 0) - { - /* - * Expand virtual size to cover potential mode switches - */ - xf86DefaultScreenLimits (pScrn, &width, &height); - - pScrn->display->virtualX = width; - pScrn->display->virtualY = height; - } - else - { + if (pScrn->display->virtualX) width = pScrn->display->virtualX; + else + width = config->maxWidth; + if (pScrn->display->virtualY) height = pScrn->display->virtualY; - } - if (width > pScrn->virtualX) - pScrn->virtualX = width; - if (height > pScrn->virtualY) - pScrn->virtualY = height; - + else + height = config->maxHeight; + + xf86ProbeOutputModes (pScrn, width, height); + crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr)); modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr)); + enabled = xnfcalloc (config->num_output, sizeof (Bool)); for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + modes[o] = NULL; + enabled[o] = (xf86OutputEnabled (output) && + output->status != XF86OutputStatusDisconnected); + } /* * Let outputs with preferred modes drive screen size @@ -872,7 +1112,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) { xf86OutputPtr output = config->output[o]; - if (output->status != XF86OutputStatusDisconnected && + if (enabled[o] && xf86OutputHasPreferredMode (output, width, height)) { target_mode = xf86DefaultMode (output, width, height); @@ -889,7 +1129,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; - if (output->status != XF86OutputStatusDisconnected) + if (enabled[o]) { target_mode = xf86DefaultMode (output, width, height); if (target_mode) @@ -905,10 +1145,23 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) { xf86OutputPtr output = config->output[o]; - if (output->status != XF86OutputStatusDisconnected && !modes[o]) + if (enabled[o] && !modes[o]) modes[o] = xf86ClosestMode (output, target_mode, width, height); } + /* + * Set the position of each output + */ + if (!xf86InitialOutputPositions (pScrn, modes)) + { + xfree (crtcs); + xfree (modes); + return FALSE; + } + + /* + * Assign CRTCs to fit output configuration + */ if (!xf86PickCrtcs (pScrn, crtcs, modes, 0, width, height)) { xfree (crtcs); @@ -928,7 +1181,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) crtc->enabled = FALSE; memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode)); } - + /* * Set initial configuration */ @@ -942,13 +1195,28 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) { crtc->desiredMode = *mode; crtc->enabled = TRUE; - crtc->x = 0; - crtc->y = 0; + crtc->x = output->initial_x; + crtc->y = output->initial_y; output->crtc = crtc; - /* XXX set position; for now, we clone */ } } + if (pScrn->display->virtualX == 0) + { + /* + * Expand virtual size to cover potential mode switches + */ + xf86DefaultScreenLimits (pScrn, &width, &height); + + pScrn->display->virtualX = width; + pScrn->display->virtualY = height; + } + + if (width > pScrn->virtualX) + pScrn->virtualX = width; + if (height > pScrn->virtualY) + pScrn->virtualY = height; + /* Mirror output modes to pScrn mode list */ xf86SetScrnInfoModes (pScrn); diff --git a/src/i830_xf86Crtc.h b/src/i830_xf86Crtc.h index b30003e7..2555c55d 100644 --- a/src/i830_xf86Crtc.h +++ b/src/i830_xf86Crtc.h @@ -288,6 +288,16 @@ struct _xf86Output { */ DisplayModePtr probed_modes; + /** + * Options parsed from the related monitor section + */ + OptionInfoPtr options; + + /** + * Configured monitor section + */ + XF86ConfMonitorPtr conf_monitor; + /** * Desired initial position */ @@ -313,12 +323,6 @@ struct _xf86Output { /** Output name */ char *name; - /** Configured monitor name */ - char *monitor_name; - - /** Monitor information from config file */ - XF86ConfMonitorPtr conf_monitor; - /** output-specific functions */ const xf86OutputFuncsRec *funcs; @@ -410,14 +414,14 @@ xf86OutputCreate (ScrnInfoPtr scrn, const xf86OutputFuncsRec *funcs, const char *name); -void +Bool xf86OutputRename (xf86OutputPtr output, const char *name); void xf86OutputDestroy (xf86OutputPtr output); void -xf86ProbeOutputModes (ScrnInfoPtr pScrn); +xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY); void xf86SetScrnInfoModes (ScrnInfoPtr pScrn); -- cgit v1.2.3