diff --git a/src/i830_gtf.c b/src/i830_gtf.c index 2eff46a9..663a2f45 100644 --- a/src/i830_gtf.c +++ b/src/i830_gtf.c @@ -45,6 +45,7 @@ #include "vbe.h" #include "vbeModes.h" #include "i830.h" +#include "i830_xf86Modes.h" #include @@ -97,7 +98,6 @@ i830GetGTF(int h_pixels, int v_lines, float freq, int interlaced, int margins) float h_sync; float h_front_porch; float v_odd_front_porch_lines; - char modename[20]; DisplayModePtr m; m = xnfcalloc(sizeof(DisplayModeRec), 1); @@ -349,8 +349,7 @@ i830GetGTF(int h_pixels, int v_lines, float freq, int interlaced, int margins) m->HSync = h_freq; m->VRefresh = v_frame_rate /* freq */; - snprintf(modename, sizeof(modename), "%dx%d", m->HDisplay,m->VDisplay); - m->name = xnfstrdup(modename); + i830xf86SetModeDefaultName(m); return (m); } diff --git a/src/i830_modes.c b/src/i830_modes.c index ac25864c..90bd0931 100644 --- a/src/i830_modes.c +++ b/src/i830_modes.c @@ -176,7 +176,11 @@ I830DuplicateMode(DisplayModePtr pMode) *pNew = *pMode; pNew->next = NULL; pNew->prev = NULL; - pNew->name = xnfstrdup(pMode->name); + if (pNew->name == NULL) { + i830xf86SetModeDefaultName(pMode); + } else { + pNew->name = xnfstrdup(pMode->name); + } return pNew; } @@ -242,6 +246,7 @@ I830GetVESAEstablishedMode(ScrnInfoPtr pScrn, int i) fabs(i830xf86ModeVRefresh(pMode) - est_timings[i].refresh) < 1.0) { DisplayModePtr pNew = I830DuplicateMode(pMode); + i830xf86SetModeDefaultName(pNew); pNew->VRefresh = i830xf86ModeVRefresh(pMode); return pNew; } @@ -257,7 +262,6 @@ i830GetDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc) DisplayModePtr first = NULL; int count = 0; int j, tmp; - char stmp[32]; if (ddc == NULL) return NULL; @@ -276,10 +280,6 @@ i830GetDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc) new->HDisplay = d_timings->h_active; new->VDisplay = d_timings->v_active; - sprintf(stmp, "%dx%d", new->HDisplay, new->VDisplay); - new->name = xnfalloc(strlen(stmp) + 1); - strcpy(new->name, stmp); - new->HTotal = new->HDisplay + d_timings->h_blanking; new->HSyncStart = new->HDisplay + d_timings->h_sync_off; new->HSyncEnd = new->HSyncStart + d_timings->h_sync_width; @@ -291,6 +291,8 @@ i830GetDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc) new->status = MODE_OK; new->type = M_T_DEFAULT; + i830xf86SetModeDefaultName(new); + if (d_timings->sync == 3) { switch (d_timings->misc) { case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break; @@ -806,6 +808,11 @@ I830ReprobePipeModeList(ScrnInfoPtr pScrn, int pipe) i830xf86PruneInvalidModes(pScrn, &pI830->pipeMon[pipe]->Modes, TRUE); + /* silently prune modes down to ones matching the user's configuration. + */ + i830xf86ValidateModesUserConfig(pScrn, pI830->pipeMon[pipe]->Modes); + i830xf86PruneInvalidModes(pScrn, &pI830->pipeMon[pipe]->Modes, FALSE); + for (pMode = pI830->pipeMon[pipe]->Modes; pMode != NULL; pMode = pMode->next) { diff --git a/src/i830_xf86Modes.c b/src/i830_xf86Modes.c index 4c5de4d9..8c34053c 100644 --- a/src/i830_xf86Modes.c +++ b/src/i830_xf86Modes.c @@ -1,3 +1,4 @@ +/* -*- c-basic-offset: 4 -*- */ /* $XdotOrg: xserver/xorg/hw/xfree86/common/xf86Mode.c,v 1.10 2006/03/07 16:00:57 libv Exp $ */ /* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Mode.c,v 1.69 2003/10/08 14:58:28 dawes Exp $ */ /* @@ -87,6 +88,22 @@ i830xf86ModeVRefresh(DisplayModePtr mode) return refresh; } +/** + * Sets a default mode name of xx on a mode. + * + * The refresh rate doesn't contain decimals, as that's expected to be + * unimportant from the user's perspective for non-custom modelines. + */ +void +i830xf86SetModeDefaultName(DisplayModePtr mode) +{ + if (mode->name != NULL) + xfree(mode->name); + + mode->name = XNFprintf("%dx%dx%.0f", mode->HDisplay, mode->VDisplay, + i830xf86ModeVRefresh(mode)); +} + /* * I830xf86SetModeCrtc * @@ -385,6 +402,45 @@ i830xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList, } } +/** + * If the user has specified a set of mode names to use, mark as bad any modes + * not listed. + * + * The user mode names specified are prefixes to names of modes, so "1024x768" + * will match modes named "1024x768", "1024x768x75", "1024x768-good", but + * "1024x768x75" would only match "1024x768x75" from that list. + * + * MODE_BAD is used as the rejection flag, for lack of a better flag. + * + * \param modeList doubly-linked or circular list of modes. + * + * This is not in xf86Modes.c, but would be part of the proposed new API. + */ +void +i830xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList) +{ + DisplayModePtr mode; + + if (pScrn->display->modes[0] == NULL) + return; + + for (mode = modeList; mode != NULL; mode = mode->next) { + int i; + Bool good = FALSE; + + for (i = 0; pScrn->display->modes[i] != NULL; i++) { + if (strncmp(pScrn->display->modes[i], mode->name, + strlen(pScrn->display->modes[i])) == 0) { + good = TRUE; + break; + } + } + if (!good) + mode->status = MODE_BAD; + } +} + + /** * Frees any modes from the list with a status other than MODE_OK. * diff --git a/src/i830_xf86Modes.h b/src/i830_xf86Modes.h index 855aa460..0cba8874 100644 --- a/src/i830_xf86Modes.h +++ b/src/i830_xf86Modes.h @@ -31,6 +31,9 @@ i830xf86ModeHSync(DisplayModePtr mode); double i830xf86ModeVRefresh(DisplayModePtr mode); +void +i830xf86SetModeDefaultName(DisplayModePtr mode); + void I830xf86SetModeCrtc(DisplayModePtr p, int adjustFlags); @@ -61,6 +64,9 @@ void i830xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, int flags); +void +i830xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList); + void PrintModeline(int scrnIndex,DisplayModePtr mode);