Blob Blame History Raw
--- xf86-video-vesa-1.3.0/src/vesa.c.validmode	2007-01-24 19:29:16.000000000 -0500
+++ xf86-video-vesa-1.3.0/src/vesa.c	2007-01-24 19:34:16.000000000 -0500
@@ -273,6 +273,85 @@
     xf86PrintChipsets(VESA_NAME, "driver for VESA chipsets", VESAChipsets);
 }
 
+static VESAPtr
+VESAGetRec(ScrnInfoPtr pScrn)
+{
+    if (!pScrn->driverPrivate)
+	pScrn->driverPrivate = xcalloc(sizeof(VESARec), 1);
+
+    return ((VESAPtr)pScrn->driverPrivate);
+}
+
+static ModeStatus
+VESAValidMode(int scrn, DisplayModePtr p, Bool flag, int pass)
+{
+    static int warned = 0;
+    int found = 0;
+    ScrnInfoPtr pScrn = xf86Screens[scrn];
+    VESAPtr pVesa = VESAGetRec(pScrn);
+    MonPtr mon = pScrn->monitor, vesamon = pVesa->monitor;
+    ModeStatus ret;
+    DisplayModePtr mode;
+    float v;
+
+    pVesa = VESAGetRec(pScrn);
+
+    if (pass != MODECHECK_FINAL) {
+	if (!warned) {
+	    xf86DrvMsg(scrn, X_WARNING, "VESAValidMode called unexpectedly\n");
+	    warned = 1;
+	}
+	return MODE_OK;
+    }
+
+    /*
+     * This is suboptimal.  We pass in just the barest description of a mode
+     * we can get away with to VBEValidateModes, so it can't really throw
+     * out anything we give it.  But we need to filter the list so that we
+     * don't populate the mode list with things the monitor can't do.
+     *
+     * So first off, if this isn't a mode we handed to the server (ie,
+     * M_T_BUILTIN), then we know we can't do it.
+     */
+    if (!(p->type & M_T_BUILTIN))
+	return MODE_NOMODE;
+
+    /*
+     * Next, walk through the mode list from DDC (if any) and look for a
+     * matching resolution.
+     */
+    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) {
+		found = 1;
+		break;
+	    }
+	    if (mode == pScrn->monitor->Last)
+		break;
+	}
+	if (!found)
+	    return MODE_NOMODE;
+    }
+
+    /*
+     * Finally, walk through the vsync rates 1Hz at a time looking for a mode
+     * that will fit.  This is assuredly a terrible way to do this, but
+     * there's no obvious method for computing a mode of a given size that
+     * will pass xf86CheckModeForMonitor.
+     */
+    for (v = mon->vrefresh[0].lo; v <= mon->vrefresh[0].hi; v++) {
+	mode = xf86CVTMode(p->HDisplay, p->VDisplay, v, 0, 0);
+	ret = xf86CheckModeForMonitor(mode, mon);
+	xfree(mode);
+	if (ret == MODE_OK)
+	    break;
+    }
+
+    return ret;
+}
+
 /*
  * This function is called once, at the start of the first server generation to
  * do a minimal probe for supported hardware.
@@ -318,6 +397,7 @@
 			pScrn->PreInit       = VESAPreInit;
 			pScrn->ScreenInit    = VESAScreenInit;
 			pScrn->SwitchMode    = VESASwitchMode;
+			pScrn->ValidMode     = VESAValidMode;
 			pScrn->AdjustFrame   = VESAAdjustFrame;
 			pScrn->EnterVT       = VESAEnterVT;
 			pScrn->LeaveVT       = VESALeaveVT;
@@ -391,15 +471,6 @@
     return (int)CHIP_VESA_GENERIC;
 }
 
-static VESAPtr
-VESAGetRec(ScrnInfoPtr pScrn)
-{
-    if (!pScrn->driverPrivate)
-	pScrn->driverPrivate = xcalloc(sizeof(VESARec), 1);
-
-    return ((VESAPtr)pScrn->driverPrivate);
-}
-
 static void
 VESAFreeRec(ScrnInfoPtr pScrn)
 {