summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2011-02-14 11:44:02 -0500
committerAdam Jackson <ajax@redhat.com>2011-02-14 17:11:33 -0500
commit0b02c68581f48c3239bc150df137623053794a3e (patch)
tree9363978106cd2e041fae33ec493a76058a802d1d
parent8e32d9d23c64ed700d3e9c5e6709a4b3c46b204a (diff)
Be forgiving of character-cell size mismatches in mode sizes
Reviewed-by: Julien Cristau <jcristau@debian.org> Reviewed-by: Matt Turner <mattst88@gmail.com> Signed-off-by: Adam Jackson <ajax@redhat.com>
-rw-r--r--src/vesa.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/vesa.c b/src/vesa.c
index ef01881..61d3550 100644
--- a/src/vesa.c
+++ b/src/vesa.c
@@ -317,6 +317,30 @@ VESASetModeParameters(vbeInfoPtr pVbe, DisplayModePtr vbemode,
(double)(ddcmode->HTotal * ddcmode->VTotal));
}
+/*
+ * Despite that VBE gives you pixel granularity for mode sizes, some BIOSes
+ * think they can only give sizes in multiples of character cells; and
+ * indeed, the reference CVT and GTF formulae only give results where
+ * (h % 8) == 0. Whatever, let's just try to cope. What we're looking for
+ * here is cases where the display says 1366x768 and the BIOS says 1360x768.
+ */
+static Bool
+vesaModesCloseEnough(DisplayModePtr edid, DisplayModePtr vbe)
+{
+ if (!(edid->type & M_T_DRIVER))
+ return FALSE;
+
+ /* never seen a height granularity... */
+ if (edid->VDisplay != vbe->VDisplay)
+ return FALSE;
+
+ if (edid->HDisplay >= vbe->HDisplay &&
+ (edid->HDisplay & ~7) == (vbe->HDisplay & ~7))
+ return TRUE;
+
+ return FALSE;
+}
+
static ModeStatus
VESAValidMode(int scrn, DisplayModePtr p, Bool flag, int pass)
{
@@ -358,9 +382,7 @@ VESAValidMode(int scrn, DisplayModePtr p, Bool flag, int pass)
*/
if (pScrn->monitor->DDC) {
for (mode = pScrn->monitor->Modes; mode; mode = mode->next) {
- if (mode->type & M_T_DRIVER &&
- mode->HDisplay == p->HDisplay &&
- mode->VDisplay == p->VDisplay) {
+ if (vesaModesCloseEnough(mode, p)) {
if (xf86CheckModeForMonitor(mode, mon) == MODE_OK) {
found = 1;
break;