From b65f18b05a5fba506b71293b495cab95197037ac Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 11 Jul 2006 13:29:57 -0700 Subject: [PATCH] Bug #7443: Respect the user's Modes configuration, and make it more useful. Now, mode names generated by DDC get names of the form "WIDTHxHEIGHTxREFRESH". The matching for user Modes lines takes the user Modes as the prefix that needs to match, rather than an exact string match or "WIDTHxHEIGHT" match. So one can, for example, specify "1024x768" to get any old 1024x768, or 1024x768x60 to get one of the modes named 1024x768x60. --- src/i830_gtf.c | 5 ++-- src/i830_modes.c | 19 ++++++++++----- src/i830_xf86Modes.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ src/i830_xf86Modes.h | 6 +++++ 4 files changed, 77 insertions(+), 9 deletions(-) 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);