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.
This commit is contained in:
Eric Anholt 2006-07-11 13:29:57 -07:00
parent 5a2e04bd1b
commit b65f18b05a
4 changed files with 77 additions and 9 deletions

View File

@ -45,6 +45,7 @@
#include "vbe.h"
#include "vbeModes.h"
#include "i830.h"
#include "i830_xf86Modes.h"
#include <math.h>
@ -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);
}

View File

@ -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)
{

View File

@ -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 <width>x<height>x<refresh> 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.
*

View File

@ -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);