summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/i830_driver.c25
-rw-r--r--src/i830_randr.c4
-rw-r--r--src/i830_sdvo.c7
-rw-r--r--src/i830_xf86Crtc.c410
-rw-r--r--src/i830_xf86Crtc.h20
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
@@ -289,6 +289,16 @@ struct _xf86Output {
DisplayModePtr probed_modes;
/**
+ * Options parsed from the related monitor section
+ */
+ OptionInfoPtr options;
+
+ /**
+ * Configured monitor section
+ */
+ XF86ConfMonitorPtr conf_monitor;
+
+ /**
* Desired initial position
*/
int initial_x, initial_y;
@@ -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);