summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <anholt@FreeBSD.org>2006-07-11 13:29:57 -0700
committerEric Anholt <anholt@FreeBSD.org>2006-07-11 13:30:24 -0700
commitb65f18b05a5fba506b71293b495cab95197037ac (patch)
treefdb0d5387477809ec17fec3d1de55c0013a790a9 /src
parent5a2e04bd1b700a8a6e26136b8831ef5e4d11b565 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/i830_gtf.c5
-rw-r--r--src/i830_modes.c19
-rw-r--r--src/i830_xf86Modes.c56
-rw-r--r--src/i830_xf86Modes.h6
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 <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);
}
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 <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
*
@@ -386,6 +403,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.
*
* \param modeList pointer to a doubly-linked or circular list of modes.
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
@@ -32,6 +32,9 @@ double
i830xf86ModeVRefresh(DisplayModePtr mode);
void
+i830xf86SetModeDefaultName(DisplayModePtr mode);
+
+void
I830xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
Bool
@@ -62,6 +65,9 @@ i830xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
int flags);
void
+i830xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList);
+
+void
PrintModeline(int scrnIndex,DisplayModePtr mode);
extern DisplayModeRec I830xf86DefaultModes[];