diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c index 6b73264d..76d6d039 100644 --- a/src/i830_xf86Crtc.c +++ b/src/i830_xf86Crtc.c @@ -196,7 +196,7 @@ xf86OutputDestroy (xf86OutputPtr output) } static DisplayModePtr -xf86DefaultMode (xf86OutputPtr output) +xf86DefaultMode (xf86OutputPtr output, int width, int height) { DisplayModePtr target_mode = NULL; DisplayModePtr mode; @@ -216,6 +216,7 @@ xf86DefaultMode (xf86OutputPtr output) int preferred = (mode->type & M_T_PREFERRED) != 0; int diff; + if (mode->HDisplay > width || mode->VDisplay > height) continue; dpi = (mode->HDisplay * 254) / (mm_height * 10); diff = dpi - 96; diff = diff < 0 ? -diff : diff; @@ -231,7 +232,8 @@ xf86DefaultMode (xf86OutputPtr output) } static DisplayModePtr -xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match) +xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match, + int width, int height) { DisplayModePtr target_mode = NULL; DisplayModePtr mode; @@ -245,6 +247,8 @@ xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match) int dx, dy; int diff; + if (mode->HDisplay > width || mode->VDisplay > height) continue; + /* exact matches are preferred */ if (xf86ModesEqual (mode, match)) return mode; @@ -262,13 +266,16 @@ xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match) } static Bool -xf86OutputHasPreferredMode (xf86OutputPtr output) +xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height) { DisplayModePtr mode; for (mode = output->probed_modes; mode; mode = mode->next) + { + if (mode->HDisplay > width || mode->VDisplay > height) continue; if (mode->type & M_T_PREFERRED) return TRUE; + } return FALSE; } @@ -276,7 +283,9 @@ static int xf86PickCrtcs (ScrnInfoPtr pScrn, xf86CrtcPtr *best_crtcs, DisplayModePtr *modes, - int n) + int n, + int width, + int height) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); int c, o, l; @@ -297,7 +306,7 @@ xf86PickCrtcs (ScrnInfoPtr pScrn, */ best_crtcs[n] = NULL; best_crtc = NULL; - best_score = xf86PickCrtcs (pScrn, best_crtcs, modes, n+1); + best_score = xf86PickCrtcs (pScrn, best_crtcs, modes, n+1, width, height); if (modes[n] == NULL) return best_score; @@ -310,7 +319,7 @@ xf86PickCrtcs (ScrnInfoPtr pScrn, if (output->status == XF86OutputStatusConnected) my_score++; /* Score outputs with preferred modes higher */ - if (xf86OutputHasPreferredMode (output)) + if (xf86OutputHasPreferredMode (output, width, height)) my_score++; /* * Select a crtc for this output and @@ -349,7 +358,7 @@ xf86PickCrtcs (ScrnInfoPtr pScrn, } crtcs[n] = crtc; memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr)); - score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1); + score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1, width, height); if (score >= best_score) { best_crtc = crtc; @@ -378,7 +387,7 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp) for (c = 0; c < config->num_crtc; c++) { - int crtc_width = 1600, crtc_height = 1200; + int crtc_width = 0, crtc_height = 0; for (o = 0; o < config->num_output; o++) { @@ -392,16 +401,19 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp) { if (mode->HDisplay > crtc_width) crtc_width = mode->HDisplay; - if (mode->VDisplay > crtc_width) + if (mode->VDisplay > crtc_height) crtc_height = mode->VDisplay; } } } - if (crtc_width > width) - width = crtc_width; + width += crtc_width; if (crtc_height > height) height = crtc_height; } + if (config->maxWidth && width > config->maxWidth) width = config->maxWidth; + if (config->maxHeight && height > config->maxHeight) height = config->maxHeight; + if (config->minWidth && width < config->minWidth) width = config->minWidth; + if (config->minHeight && height < config->minHeight) height = config->minHeight; *widthp = width; *heightp = height; } @@ -575,6 +587,26 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) xf86ProbeOutputModes (pScrn); + 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 + { + width = pScrn->display->virtualX; + height = pScrn->display->virtualY; + } + if (width > pScrn->virtualX) + pScrn->virtualX = width; + if (height > pScrn->virtualY) + pScrn->virtualY = height; + crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr)); modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr)); @@ -589,9 +621,9 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) xf86OutputPtr output = config->output[o]; if (output->status != XF86OutputStatusDisconnected && - xf86OutputHasPreferredMode (output)) + xf86OutputHasPreferredMode (output, width, height)) { - target_mode = xf86DefaultMode (output); + target_mode = xf86DefaultMode (output, width, height); if (target_mode) { modes[o] = target_mode; @@ -607,7 +639,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) xf86OutputPtr output = config->output[o]; if (output->status != XF86OutputStatusDisconnected) { - target_mode = xf86DefaultMode (output); + target_mode = xf86DefaultMode (output, width, height); if (target_mode) { modes[o] = target_mode; @@ -622,30 +654,16 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) xf86OutputPtr output = config->output[o]; if (output->status != XF86OutputStatusDisconnected && !modes[o]) - modes[o] = xf86ClosestMode (output, target_mode); + modes[o] = xf86ClosestMode (output, target_mode, width, height); } - if (!xf86PickCrtcs (pScrn, crtcs, modes, 0)) + if (!xf86PickCrtcs (pScrn, crtcs, modes, 0, width, height)) { xfree (crtcs); xfree (modes); return FALSE; } - xf86DefaultScreenLimits (pScrn, &width, &height); - - /* - * Expand virtual size to cover potential mode switches - */ - if (width > pScrn->virtualX) - pScrn->virtualX = width; - if (width > pScrn->display->virtualX) - pScrn->display->virtualX = width; - if (height > pScrn->virtualY) - pScrn->virtualY = height; - if (height > pScrn->display->virtualY) - pScrn->display->virtualY = height; - /* XXX override xf86 common frame computation code */ pScrn->display->frameX0 = 0;