xserver: Branch 'glucose-2' - 10 commits

Alan Hourihane alanh at kemper.freedesktop.org
Fri Oct 19 03:08:51 PDT 2007


 GL/glx/Makefile.am                   |    1 
 GL/glx/glxcmds.c                     |  492 +++++++++++++--------------------
 GL/glx/glxdrawable.h                 |    4 
 GL/glx/glxdri.c                      |   66 ----
 GL/glx/glxglcore.c                   |    4 
 GL/glx/glxscreens.c                  |  252 ++++++++++++++++
 GL/glx/glxscreens.h                  |   11 
 GL/glx/glxserver.h                   |   10 
 GL/glx/glxvisuals.c                  |  520 -----------------------------------
 configure.ac                         |    4 
 exa/exa_accel.c                      |    3 
 exa/exa_migration.c                  |    3 
 exa/exa_render.c                     |   17 +
 hw/kdrive/fbdev/Makefile.am          |    2 
 hw/xfree86/common/xf86Config.c       |   29 +
 hw/xfree86/common/xf86Privstr.h      |    9 
 hw/xfree86/common/xf86str.h          |    1 
 hw/xfree86/dixmods/glxmodule.c       |   34 +-
 hw/xfree86/doc/man/xorg.conf.man.pre |   11 
 hw/xfree86/dri/dri.c                 |   40 --
 hw/xfree86/dri/xf86dri.c             |   12 
 hw/xfree86/modes/xf86Crtc.c          |   55 +--
 hw/xfree86/modes/xf86Crtc.h          |    3 
 hw/xfree86/modes/xf86EdidModes.c     |   29 +
 hw/xnest/Screen.c                    |   15 -
 mi/miinitext.c                       |    5 
 26 files changed, 606 insertions(+), 1026 deletions(-)

New commits:
commit 69f5760aec6f2eccc639f00bd32c5a4059eb3013
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Thu Oct 18 21:01:51 2007 -0400

    Introduce a new "GlxVisuals" option that controls which visuals are added.
    
    Right now we default to "all" which gives us a situation much like before,
    but when the "typical" option is implemented, we can change the default and
    reduce the number of visuals the GLX module bloats the X server with.

diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h
index 858bbb3..f62d1ee 100644
--- a/GL/glx/glxdrawable.h
+++ b/GL/glx/glxdrawable.h
@@ -42,10 +42,6 @@
 
 #include <damage.h>
 
-#ifdef XF86DRI
-#include <GL/internal/dri_interface.h>
-#endif
-
 /* We just need to avoid clashing with DRAWABLE_{WINDOW,PIXMAP} */
 enum {
     GLX_DRAWABLE_WINDOW,
diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c
index 8338880..5c2e024 100644
--- a/GL/glx/glxscreens.c
+++ b/GL/glx/glxscreens.c
@@ -396,10 +396,7 @@ findFirstSet(unsigned int v)
 static void
 initGlxVisual(VisualPtr visual, __GLcontextModes *config)
 {
-    ErrorF("Adding visual 0x%02lx for fbconfig %d\n",
-	   visual->vid, config->fbconfigID);
-
-    config->visualID = visual[0].vid;
+    config->visualID = visual->vid;
     visual->class = _gl_convert_to_x_visual_type(config->visualType);
     visual->bitsPerRGBValue = config->redBits;
     visual->ColormapEntries = 1 << config->redBits;
@@ -414,37 +411,84 @@ initGlxVisual(VisualPtr visual, __GLcontextModes *config)
 }
 
 static void
-addGlxVisuals(__GLXscreen *pGlxScreen)
+addMinimalSet(__GLXscreen *pGlxScreen)
 {
     __GLcontextModes *config;
-    VisualPtr visual;
+    VisualPtr visuals;
+    int depth;
 
-    /* Select a subset of fbconfigs that we send to the client when it
-     * asks for the glx visuals.  All the fbconfigs here have a valid
-     * value for visual ID and each visual ID is only present once.
-     * This runs before composite adds its extra visual so we have to
-     * remember the number of visuals here.*/
-
-    /* For now, just add the first double buffer fbconfig. */
-    for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next)
-	if (config->doubleBufferMode)
+    for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
+	if (config->visualRating != GLX_NONE)
+	    continue;
+	if (config->doubleBufferMode && config->depthBits > 0)
 	    break;
+    }
     if (config == NULL)
 	config = pGlxScreen->fbconfigs;
 
     pGlxScreen->visuals = xcalloc(1, sizeof (__GLcontextModes *));
-    visual = AddScreenVisuals(pGlxScreen->pScreen, 1, config->rgbBits);
-    if (visual == NULL) {
+    if (pGlxScreen->visuals == NULL) {
+	ErrorF("Failed to allocate for minimal set of GLX visuals\n");
+	return;
+    }
+
+    depth = config->redBits + config->greenBits + config->blueBits;
+    visuals = AddScreenVisuals(pGlxScreen->pScreen, 1, depth);
+    if (visuals == NULL) {
 	xfree(pGlxScreen->visuals);
 	return;
     }
 
     pGlxScreen->numVisuals = 1;
     pGlxScreen->visuals[0] = config;
-    initGlxVisual(&visual[0], config);
+    initGlxVisual(&visuals[0], config);
+}
+
+static void
+addTypicalSet(__GLXscreen *pGlxScreen)
+{
+    addMinimalSet(pGlxScreen);
+}
+
+static void
+addFullSet(__GLXscreen *pGlxScreen)
+{
+    __GLcontextModes *config;
+    VisualPtr visuals;
+    int i, depth;
+
+    pGlxScreen->visuals =
+	xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLcontextModes *));
+    if (pGlxScreen->visuals == NULL) {
+	ErrorF("Failed to allocate for full set of GLX visuals\n");
+	return;
+    }
+
+    config = pGlxScreen->fbconfigs;
+    depth = config->redBits + config->greenBits + config->blueBits;
+    visuals = AddScreenVisuals(pGlxScreen->pScreen, pGlxScreen->numFBConfigs, depth);
+    if (visuals == NULL) {
+	xfree(pGlxScreen->visuals);
+	return;
+    }
+
+    ErrorF("addFullSet, setting numVisuals to %d\n", pGlxScreen->numFBConfigs);
+
+    pGlxScreen->numVisuals = pGlxScreen->numFBConfigs;
+    for (i = 0, config = pGlxScreen->fbconfigs; config; config = config->next, i++) {
+	pGlxScreen->visuals[i] = config;
+	initGlxVisual(&visuals[i], config);
+    }
 }
 
-void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen)
+static int glxVisualConfig = GLX_ALL_VISUALS;
+
+void GlxSetVisualConfig(int config)
+{
+    glxVisualConfig = config;
+}
+
+void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
 {
     static int glxGeneration;
     __GLcontextModes *m;
@@ -460,28 +504,44 @@ void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen)
     }
 
     i = 0;
-    for (m = glxScreen->fbconfigs; m != NULL; m = m->next) {
+    for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
 	m->fbconfigID = FakeClientID(0);
 	m->visualID = findVisualForConfig(pScreen, m);
 	i++;
     }
-    glxScreen->numFBConfigs = i;
+    pGlxScreen->numFBConfigs = i;
+
+    /* Select a subset of fbconfigs that we send to the client when it
+     * asks for the glx visuals.  All the fbconfigs here have a valid
+     * value for visual ID and each visual ID is only present once.
+     * This runs before composite adds its extra visual so we have to
+     * remember the number of visuals here.*/
 
-    addGlxVisuals(glxScreen);
+    switch (glxVisualConfig) {
+    case GLX_MINIMAL_VISUALS:
+	addMinimalSet(pGlxScreen);
+	break;
+    case GLX_TYPICAL_VISUALS:
+	addTypicalSet(pGlxScreen);
+	break;
+    case GLX_ALL_VISUALS:
+	addFullSet(pGlxScreen);
+	break;
+    }
 
-    glxScreen->pScreen       = pScreen;
-    glxScreen->GLextensions  = xstrdup(GLServerExtensions);
-    glxScreen->GLXvendor     = xstrdup(GLXServerVendorName);
-    glxScreen->GLXversion    = xstrdup(GLXServerVersion);
-    glxScreen->GLXextensions = xstrdup(GLXServerExtensions);
+    pGlxScreen->pScreen       = pScreen;
+    pGlxScreen->GLextensions  = xstrdup(GLServerExtensions);
+    pGlxScreen->GLXvendor     = xstrdup(GLXServerVendorName);
+    pGlxScreen->GLXversion    = xstrdup(GLXServerVersion);
+    pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions);
 
-    glxScreen->PositionWindow = pScreen->PositionWindow;
+    pGlxScreen->PositionWindow = pScreen->PositionWindow;
     pScreen->PositionWindow = glxPositionWindow;
  
-    glxScreen->CloseScreen = pScreen->CloseScreen;
+    pGlxScreen->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = glxCloseScreen;
 
-    pScreen->devPrivates[glxScreenPrivateIndex].ptr = (pointer) glxScreen;
+    pScreen->devPrivates[glxScreenPrivateIndex].ptr = (pointer) pGlxScreen;
 }
  
 void __glXScreenDestroy(__GLXscreen *screen)
diff --git a/GL/glx/glxserver.h b/GL/glx/glxserver.h
index 45de8e7..5188689 100644
--- a/GL/glx/glxserver.h
+++ b/GL/glx/glxserver.h
@@ -95,6 +95,8 @@ extern __GLXclientState *glxGetClient(ClientPtr pClient);
 
 /************************************************************************/
 
+void GlxExtensionInit(void);
+
 void GlxSetVisualConfigs(int nconfigs, 
                          __GLXvisualConfig *configs, void **privates);
 
@@ -132,6 +134,14 @@ struct __GLXprovider {
 
 void GlxPushProvider(__GLXprovider *provider);
 
+enum {
+    GLX_MINIMAL_VISUALS,
+    GLX_TYPICAL_VISUALS,
+    GLX_ALL_VISUALS
+};
+
+void GlxSetVisualConfig(int config);
+
 void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean),
 				   void (*leave)(GLboolean));
 void __glXenterServer(GLboolean rendering);
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 96fadc9..35b62a2 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -792,6 +792,7 @@ typedef enum {
     FLAG_USE_DEFAULT_FONT_PATH,
     FLAG_AUTO_ADD_DEVICES,
     FLAG_AUTO_ENABLE_DEVICES,
+    FLAG_GLX_VISUALS,
 } FlagValues;
    
 static OptionInfoRec FlagOptions[] = {
@@ -873,6 +874,8 @@ static OptionInfoRec FlagOptions[] = {
         {0}, TRUE },
   { FLAG_AUTO_ENABLE_DEVICES,    "AutoEnableDevices",                   OPTV_BOOLEAN,
         {0}, TRUE },
+  { FLAG_GLX_VISUALS,		"GlxVisuals",			OPTV_STRING,
+        {0}, FALSE },
   { -1,				NULL,				OPTV_NONE,
 	{0}, FALSE },
 };
@@ -904,6 +907,7 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
     Pix24Flags pix24 = Pix24DontCare;
     Bool value;
     MessageType from;
+    const char *s;
 
     /*
      * Merge the ServerLayout and ServerFlags options.  The former have
@@ -1021,7 +1025,6 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
     if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value)) 
 	xf86Info.pmFlag = !value;
     {
-	const char *s;
 	if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) {
 	    if (!xf86NameCmp(s,"flush")) {
 		xf86Msg(X_CONFIG, "Flushing logfile enabled\n");
@@ -1040,8 +1043,6 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
     
 #ifdef RENDER
     {
-	const char *s;
-
 	if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){
 	    int policy = PictureParseCmapPolicy (s);
 	    if (policy == PictureCmapPolicyInvalid)
@@ -1055,7 +1056,6 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
     }
 #endif
     {
-	const char *s;
 	if ((s = xf86GetOptValString(FlagOptions, FLAG_HANDLE_SPECIAL_KEYS))) {
 	    if (!xf86NameCmp(s,"always")) {
 		xf86Msg(X_CONFIG, "Always handling special keys in DDX\n");
@@ -1093,6 +1093,27 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
 	xf86Info.aiglxFrom = X_CONFIG;
     }
 
+#ifdef GLXEXT
+    xf86Info.glxVisuals = XF86_GlxVisualsAll;
+    xf86Info.glxVisualsFrom = X_DEFAULT;
+    if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
+	if (!xf86NameCmp(s, "minimal")) {
+	    xf86Info.glxVisuals = XF86_GlxVisualsMinimal;
+	} else if (!xf86NameCmp(s, "typical")) {
+	    xf86Info.glxVisuals = XF86_GlxVisualsTypical;
+	} else if (!xf86NameCmp(s, "all")) {
+	    xf86Info.glxVisuals = XF86_GlxVisualsAll;
+	} else {
+	    xf86Msg(X_WARNING,"Unknown HandleSpecialKeys option\n");
+	}
+    }
+
+    if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
+	xf86Info.aiglx = value;
+	xf86Info.aiglxFrom = X_CONFIG;
+    }
+#endif
+
     xf86Info.allowEmptyInput = FALSE;
     if (xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &value))
         xf86Info.allowEmptyInput = TRUE;
diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index 75d4974..92a6305 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -60,6 +60,12 @@ typedef enum {
     SKAlways
 } SpecialKeysInDDX;
 
+typedef enum {
+    XF86_GlxVisualsMinimal,
+    XF86_GlxVisualsTypical,
+    XF86_GlxVisualsAll,
+} XF86_GlxVisuals;
+
 /*
  * xf86InfoRec contains global parameters which the video drivers never
  * need to access.  Global parameters which the video drivers do need
@@ -120,6 +126,9 @@ typedef struct {
     MessageType		randRFrom;
     Bool		aiglx;
     MessageType		aiglxFrom;
+    XF86_GlxVisuals	glxVisuals;
+    MessageType		glxVisualsFrom;
+    
     Bool		useDefaultFontPath;
     MessageType		useDefaultFontPathFrom;
     Bool        ignoreABI;
diff --git a/hw/xfree86/dixmods/glxmodule.c b/hw/xfree86/dixmods/glxmodule.c
index f1c861b..847f0d4 100644
--- a/hw/xfree86/dixmods/glxmodule.c
+++ b/hw/xfree86/dixmods/glxmodule.c
@@ -41,17 +41,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "colormap.h"
 #include "micmap.h"
 #include "globals.h"
-
-typedef struct __GLXscreen __GLXscreen;
-typedef struct __GLXprovider __GLXprovider;
-struct __GLXprovider {
-    __GLXscreen *(*screenProbe)(ScreenPtr pScreen);
-    const char    *name;
-    __GLXprovider *next;
-};
-
-extern void GlxPushProvider(__GLXprovider *provider);
-extern void GlxExtensionInit(void);
+#include "glxserver.h"
 
 static MODULESETUPPROTO(glxSetup);
 
@@ -113,7 +103,6 @@ static __GLXprovider __glXMesaProxyProvider = {
     NULL
 };
 
-
 static pointer
 glxSetup(pointer module, pointer opts, int *errmaj, int *errmin)
 {
@@ -138,8 +127,22 @@ glxSetup(pointer module, pointer opts, int *errmaj, int *errmin)
 	GlxPushProvider(provider);
     }
 
+    switch (xf86Info.glxVisuals) {
+    case XF86_GlxVisualsMinimal:
+	GlxSetVisualConfig(GLX_MINIMAL_VISUALS);
+	xf86Msg(xf86Info.aiglxFrom, "Exporting only minimal set of GLX visuals\n");
+	break;
+    case XF86_GlxVisualsTypical:
+	GlxSetVisualConfig(GLX_TYPICAL_VISUALS);
+	xf86Msg(xf86Info.aiglxFrom, "Exporting typical set of GLX visuals\n");
+	break;
+    case XF86_GlxVisualsAll:
+	GlxSetVisualConfig(GLX_ALL_VISUALS);
+	xf86Msg(xf86Info.aiglxFrom, "Exporting all GLX visuals\n");
+	break;
+    }
+
     LoadExtension(&GLXExt, FALSE);
 
- bail:
     return module;
 }
diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre
index 54d8eaa..4064ef6 100644
--- a/hw/xfree86/doc/man/xorg.conf.man.pre
+++ b/hw/xfree86/doc/man/xorg.conf.man.pre
@@ -700,6 +700,17 @@ the builtin handler will be used.
 .BI "Option \*qAIGLX\*q \*q" boolean \*q
 enable or disable AIGLX. AIGLX is enabled by default.
 .TP 7
+.BI "Option \*qGlxVisuals\*q \*q" string \*q
+This option controls how many GLX visuals the GLX modules sets up.
+The default value is
+.BR "typical" ,
+which will setup up a typical subset of
+the GLXFBConfigs provided by the driver as GLX visuals.  Other options are
+.BR "minimal" ,
+which will set up the minimal set allowed by the GLX specification and
+.BR "all"
+which will setup GLX visuals for all GLXFBConfigs.
+.TP 7
 .BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q
 Include the default font path even if other paths are specified in
 xorg.conf. If enabled, other font paths are included as well. Enabled by
commit 9a289a6e3e147bba7815e97097b73b558606d7ba
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Thu Oct 18 19:12:24 2007 -0400

    Add code to set up GLX visuals and add one for the first double buffered FBConfig.

diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c
index 8ab035d..8338880 100644
--- a/GL/glx/glxscreens.c
+++ b/GL/glx/glxscreens.c
@@ -40,6 +40,7 @@
 #include <string.h>
 #include <windowstr.h>
 #include <os.h>
+#include <colormapst.h>
 
 #include "glxserver.h"
 #include "glxutil.h"
@@ -305,6 +306,144 @@ findVisualForConfig(ScreenPtr pScreen, __GLcontextModes *m)
     return 0;
 }
 
+/* This code inspired by composite/compinit.c.  We could move this to
+ * mi/ and share it with composite.*/
+
+static VisualPtr
+AddScreenVisuals(ScreenPtr pScreen, int count, int d)
+{
+    XID		*installedCmaps, *vids, vid;
+    int		 numInstalledCmaps, numVisuals, i, j;
+    VisualPtr	 visuals;
+    ColormapPtr	 installedCmap;
+    DepthPtr	 depth;
+
+    depth = NULL;
+    for (i = 0; i < pScreen->numDepths; i++) {
+	if (pScreen->allowedDepths[i].depth == d) {
+	    depth = &pScreen->allowedDepths[i];
+	    break;
+	}
+    }
+    if (depth == NULL)
+	return NULL;
+
+    /* Find the installed colormaps */
+    installedCmaps = xalloc (pScreen->maxInstalledCmaps * sizeof (XID));
+    if (!installedCmaps)
+	return NULL;
+
+    numInstalledCmaps = pScreen->ListInstalledColormaps(pScreen, installedCmaps);
+
+    /* realloc the visual array to fit the new one in place */
+    numVisuals = pScreen->numVisuals;
+    visuals = xrealloc(pScreen->visuals, (numVisuals + count) * sizeof(VisualRec));
+    if (!visuals) {
+	xfree(installedCmaps);
+	return NULL;
+    }
+
+    vids = xrealloc(depth->vids, (depth->numVids + count) * sizeof(XID));
+    if (vids == NULL) {
+	xfree(installedCmaps);
+	xfree(visuals);
+	return NULL;
+    }
+
+    /*
+     * Fix up any existing installed colormaps -- we'll assume that
+     * the only ones created so far have been installed.  If this
+     * isn't true, we'll have to walk the resource database looking
+     * for all colormaps.
+     */
+    for (i = 0; i < numInstalledCmaps; i++) {
+	installedCmap = LookupIDByType (installedCmaps[i], RT_COLORMAP);
+	if (!installedCmap)
+	    continue;
+	j = installedCmap->pVisual - pScreen->visuals;
+	installedCmap->pVisual = &visuals[j];
+    }
+
+    xfree(installedCmaps);
+
+    for (i = 0; i < count; i++) {
+	vid = FakeClientID(0);
+	visuals[pScreen->numVisuals + i].vid = vid;
+	vids[depth->numVids + i] = vid;
+    }
+
+    pScreen->visuals = visuals;
+    pScreen->numVisuals += count;
+    depth->vids = vids;
+    depth->numVids += count;
+
+    /* Return a pointer to the first of the added visuals. */ 
+    return pScreen->visuals + pScreen->numVisuals - count;
+}
+
+static int
+findFirstSet(unsigned int v)
+{
+    int i;
+
+    for (i = 0; i < 32; i++)
+	if (v & (1 << i))
+	    return i;
+
+    return -1;
+}
+
+static void
+initGlxVisual(VisualPtr visual, __GLcontextModes *config)
+{
+    ErrorF("Adding visual 0x%02lx for fbconfig %d\n",
+	   visual->vid, config->fbconfigID);
+
+    config->visualID = visual[0].vid;
+    visual->class = _gl_convert_to_x_visual_type(config->visualType);
+    visual->bitsPerRGBValue = config->redBits;
+    visual->ColormapEntries = 1 << config->redBits;
+    visual->nplanes = config->redBits + config->greenBits + config->blueBits;
+
+    visual->redMask = config->redMask;
+    visual->greenMask = config->greenMask;
+    visual->blueMask = config->blueMask;
+    visual->offsetRed = findFirstSet(config->redMask);
+    visual->offsetGreen = findFirstSet(config->greenMask);
+    visual->offsetBlue = findFirstSet(config->blueMask);
+}
+
+static void
+addGlxVisuals(__GLXscreen *pGlxScreen)
+{
+    __GLcontextModes *config;
+    VisualPtr visual;
+
+    /* Select a subset of fbconfigs that we send to the client when it
+     * asks for the glx visuals.  All the fbconfigs here have a valid
+     * value for visual ID and each visual ID is only present once.
+     * This runs before composite adds its extra visual so we have to
+     * remember the number of visuals here.*/
+
+    /* For now, just add the first double buffer fbconfig. */
+    for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next)
+	if (config->doubleBufferMode)
+	    break;
+    if (config == NULL)
+	config = pGlxScreen->fbconfigs;
+
+    pGlxScreen->visuals = xcalloc(1, sizeof (__GLcontextModes *));
+    visual = AddScreenVisuals(pGlxScreen->pScreen, 1, config->rgbBits);
+    if (visual == NULL) {
+	xfree(pGlxScreen->visuals);
+	return;
+    }
+
+    pGlxScreen->numVisuals = 1;
+    pGlxScreen->visuals[0] = config;
+    initGlxVisual(&visual[0], config);
+}
+
 void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen)
 {
     static int glxGeneration;
@@ -322,20 +461,13 @@ void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen)
 
     i = 0;
     for (m = glxScreen->fbconfigs; m != NULL; m = m->next) {
-	m->fbconfigID = i++;
+	m->fbconfigID = FakeClientID(0);
 	m->visualID = findVisualForConfig(pScreen, m);
-	ErrorF("mapping fbconfig %d to visual 0x%02x\n",
-	       m->fbconfigID, m->visualID);
+	i++;
     }
     glxScreen->numFBConfigs = i;
 
-    /* Select a subset of fbconfigs that we send to the client when it
-     * asks for the glx visuals.  All the fbconfigs here have a valid
-     * value for visual ID and each visual ID is only present once.
-     * This runs before composite adds its extra visual so we have to
-     * remember the number of visuals here.*/
-    glxScreen->visuals = NULL;
-    glxScreen->numVisuals = 0;
+    addGlxVisuals(glxScreen);
 
     glxScreen->pScreen       = pScreen;
     glxScreen->GLextensions  = xstrdup(GLServerExtensions);
commit 994bec46750a04f52e901ea875540f6e113b98b4
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Thu Oct 18 15:51:11 2007 -0400

    Separate handling of GLX visuals and GLX FBConfigs.
    
    XIDs for GLX visuals and FBConfigs used to be interchangable and the list of
    GLX visuals was identical to the list for FBConfigs.  This patch splits handling
    of these two data types and allows the X server to pick and choose the FBConfigs
    that are exposed as visuals.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index f6e0321..ac2393c 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -59,16 +59,91 @@
 #include "indirect_table.h"
 #include "indirect_util.h"
 
-/************************************************************************/
-
 void
 GlxSetRenderTables (struct _glapi_table *table)
 {
     _glapi_set_dispatch (table);
 }
 
+static int
+validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err)
+{
+    /*
+    ** Check if screen exists.
+    */
+    if (screen >= screenInfo.numScreens) {
+	client->errorValue = screen;
+	*err = BadValue;
+	return FALSE;
+    }
+    *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
 
-/************************************************************************/
+    return TRUE;
+}
+
+static int
+validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
+		 __GLcontextModes **config, int *err)
+{
+    __GLcontextModes *m;
+
+    for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next)
+	if (m->fbconfigID == id) {
+	    *config = m;
+	    return TRUE;
+	}
+
+    client->errorValue = id;
+    *err = __glXError(GLXBadFBConfig);
+
+    return FALSE;
+}
+
+static int
+validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
+	       __GLcontextModes **config, int *err)
+{
+    int i;
+
+    for (i = 0; i < pGlxScreen->numVisuals; i++)
+ 	if (pGlxScreen->visuals[i]->visualID == id) {
+	    *config = pGlxScreen->visuals[i];
+	    return TRUE;
+	}
+
+    client->errorValue = id;
+    *err = BadValue;
+
+    return FALSE;
+}
+
+static int
+validGlxFBConfigForWindow(ClientPtr client, __GLcontextModes *config,
+			  DrawablePtr pDraw, int *err)
+{
+    ScreenPtr pScreen = pDraw->pScreen;
+    VisualPtr pVisual = NULL;
+    XID vid;
+    int i;
+
+    vid = wVisual((WindowPtr)pDraw);
+    for (i = 0; i < pScreen->numVisuals; i++) {
+	if (pScreen->visuals[i].vid == vid) {
+	    pVisual = &pScreen->visuals[i];
+	    break;
+	}
+    }
+
+    /* FIXME: What exactly should we check here... */
+    if (pVisual->class != _gl_convert_to_x_visual_type(config->visualType) ||
+	!(config->drawableType & GLX_WINDOW_BIT)) {
+	client->errorValue = pDraw->id;
+	*err = BadMatch;
+	return FALSE;
+    }
+
+    return TRUE;
+}
 
 void
 __glXContextDestroy(__GLXcontext *context)
@@ -111,58 +186,14 @@ static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen,
 
 static int
 DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
-		GLXContextID shareList, VisualID visual,
-		GLuint screen, GLboolean isDirect)
+		GLXContextID shareList, __GLcontextModes *config,
+		__GLXscreen *pGlxScreen, GLboolean isDirect)
 {
     ClientPtr client = cl->client;
     VisualPtr pVisual;
-    ScreenPtr pScreen;
     __GLXcontext *glxc, *shareglxc;
-    __GLcontextModes *modes;
-    __GLXscreen *pGlxScreen;
-    GLint i;
 
     LEGAL_NEW_RESOURCE(gcId, client);
-    
-    /*
-    ** Check if screen exists.
-    */
-    if (screen >= screenInfo.numScreens) {
-	client->errorValue = screen;
-	return BadValue;
-    }
-    pScreen = screenInfo.screens[screen];
-    pGlxScreen = glxGetScreen(pScreen);
-
-    /*
-    ** Check if the visual ID is valid for this screen.
-    */
-    pVisual = pScreen->visuals;
-    for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
-	if (pVisual->vid == visual) {
-	    break;
-	}
-    }
-    if (i == pScreen->numVisuals) {
-	client->errorValue = visual;
-	return BadValue;
-    }
-
-    /*
-    ** Get configuration of the visual.  This assumes that the
-    ** glxScreen structure contains visual configurations only for the
-    ** subset of Visuals that are supported by this implementation of the
-    ** OpenGL.
-    */
-
-    modes = _gl_context_modes_find_visual( pGlxScreen->modes, visual );
-    if (modes == NULL) {
-	/*
-	** Visual not support on this screen by this OpenGL implementation.
-	*/
-	client->errorValue = visual;
-	return BadValue;
-    }
 
     /*
     ** Find the display list space that we want to share.  
@@ -206,9 +237,9 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
     ** Allocate memory for the new context
     */
     if (!isDirect)
-	glxc = pGlxScreen->createContext(pGlxScreen, modes, shareglxc);
+	glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc);
     else
-	glxc = __glXdirectContextCreate(pGlxScreen, modes, shareglxc);
+	glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc);
     if (!glxc) {
 	return BadAlloc;
     }
@@ -217,10 +248,10 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
     ** Initially, setup the part of the context that could be used by
     ** a GL core that needs windowing information (e.g., Mesa).
     */
-    glxc->pScreen = pScreen;
+    glxc->pScreen = pGlxScreen->pScreen;
     glxc->pGlxScreen = pGlxScreen;
     glxc->pVisual = pVisual;
-    glxc->modes = modes;
+    glxc->modes = config;
 
     /*
     ** Register this context as a resource.
@@ -245,34 +276,54 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
     return Success;
 }
 
-
 int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
-    return DoCreateContext( cl, req->context, req->shareList, req->visual,
-			    req->screen, req->isDirect );
-}
+    __GLcontextModes *config;
+    __GLXscreen *pGlxScreen;
+    int err;
+
+    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+	return err;
+    if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
+	return err;
 
+    return DoCreateContext(cl, req->context, req->shareList,
+			   config, pGlxScreen, req->isDirect);
+}
 
 int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
-    return DoCreateContext( cl, req->context, req->shareList, req->fbconfig,
-			    req->screen, req->isDirect );
-}
+    __GLcontextModes *config;
+    __GLXscreen *pGlxScreen;
+    int err;
 
+    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+	return err;
+    if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
+	return err;
+
+    return DoCreateContext(cl, req->context, req->shareList,
+			   config, pGlxScreen, req->isDirect);
+}
 
 int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateContextWithConfigSGIXReq *req = 
 	(xGLXCreateContextWithConfigSGIXReq *) pc;
-    return DoCreateContext( cl, req->context, req->shareList, req->fbconfig,
-			    req->screen, req->isDirect );
-}
+    __GLcontextModes *config;
+    __GLXscreen *pGlxScreen;
+    int err;
 
-/*
-** Destroy a GL context as an X resource.
-*/
+    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+	return err;
+    if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
+	return err;
+
+    return DoCreateContext(cl, req->context, req->shareList,
+			   config, pGlxScreen, req->isDirect);
+}
 int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc)
 {
     ClientPtr client = cl->client;
@@ -407,9 +458,7 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
 		 int *error)
 {
     DrawablePtr pDraw;
-    __GLcontextModes *modes;
     __GLXdrawable *pGlxDraw;
-    VisualID vid;
     int rc;
 
     /* This is the GLX 1.3 case - the client passes in a GLXWindow or
@@ -446,21 +495,17 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
 	return NULL;
     }
 
-    vid = wVisual((WindowPtr)pDraw);
-    modes = _gl_context_modes_find_visual(glxc->pGlxScreen->modes, vid);
-
     /* We're binding an X Window for the first time and need to create
-     * a GLX drawable for it.  First check that the drawable screen
-     * and fbconfig matches the context ditto. */
-    if (pDraw->pScreen != glxc->pScreen || modes != glxc->modes) {
-	client->errorValue = drawId;
-	*error = BadMatch;
+     * a GLX drawable for it.  Check that the drawable screen matches
+     * the context screen and that the context fbconfig is compatible
+     * with the window visual. */
+    if (pDraw->pScreen != glxc->pScreen ||
+	!validGlxFBConfigForWindow(client, glxc->modes, pDraw, error))
 	return NULL;
-    }
 
     pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
 						pDraw, GLX_DRAWABLE_WINDOW,
-						drawId, modes);
+						drawId, glxc->modes);
 
     /* since we are creating the drawablePrivate, drawId should be new */
     if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
@@ -830,29 +875,24 @@ int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc)
 }
 
 
-static int
-DoGetVisualConfigs(__GLXclientState *cl, unsigned screen)
+int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
 {
+    xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
     ClientPtr client = cl->client;
     xGLXGetVisualConfigsReply reply;
     __GLXscreen *pGlxScreen;
     __GLcontextModes *modes;
     CARD32 buf[__GLX_TOTAL_CONFIG];
-    int p;
+    int p, i, err;
     __GLX_DECLARE_SWAP_VARIABLES;
     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 
-    if (screen >= screenInfo.numScreens) {
-	/* The client library must send a valid screen number. */
-	client->errorValue = screen;
-	return BadValue;
-    }
-    pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+	return err;
 
-    reply.numVisuals = pGlxScreen->numUsableVisuals;
+    reply.numVisuals = pGlxScreen->numVisuals;
     reply.numProps = __GLX_TOTAL_CONFIG;
-    reply.length = (pGlxScreen->numUsableVisuals * __GLX_SIZE_CARD32 *
-		    __GLX_TOTAL_CONFIG) >> 2;
+    reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG) >> 2;
     reply.type = X_Reply;
     reply.sequenceNumber = client->sequence;
 
@@ -865,11 +905,9 @@ DoGetVisualConfigs(__GLXclientState *cl, unsigned screen)
 
     WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
 
-    for ( modes = pGlxScreen->modes ; modes != NULL ; modes = modes->next ) {
-	if (modes->visualID == 0) {
-	    /* not a usable visual */
-	    continue;
-	}
+    for (i = 0; i < pGlxScreen->numVisuals; i++) {
+	modes = pGlxScreen->visuals[i];
+
 	p = 0;
 	buf[p++] = modes->visualID;
 	buf[p++] = _gl_convert_to_x_visual_type( modes->visualType );
@@ -919,93 +957,6 @@ DoGetVisualConfigs(__GLXclientState *cl, unsigned screen)
     return Success;
 }
 
-int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
-{
-    xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
-    return DoGetVisualConfigs(cl, req->screen);
-}
-
-
-/* Composite adds a 32 bit ARGB visual after glxvisuals.c have created
- * the context modes for the screens.  This visual is useful for GLX
- * pixmaps, so we create a single mode for this visual with no extra
- * buffers. */
-static void
-__glXCreateARGBConfig(__GLXscreen *screen)
-{
-    __GLcontextModes *modes;
-    VisualPtr visual;
-    int i;
-
-    /* search for a 32-bit visual */
-    visual = NULL;
-    for (i = 0; i < screen->pScreen->numVisuals; i++) 
-	if (screen->pScreen->visuals[i].nplanes == 32) {
-	    visual = &screen->pScreen->visuals[i];
-	    break;
-	}
-
-    if (visual == NULL || visual->class != TrueColor)
-	return;
-
-    /* Stop now if we already added the mode. */
-    if (_gl_context_modes_find_visual (screen->modes, visual->vid))
-	return;
-
-    modes = _gl_context_modes_create(1, sizeof(__GLcontextModes));
-    if (modes == NULL)
-	return;
-
-    /* Insert this new mode at the TAIL of the linked list.
-     * Previously, the mode was incorrectly inserted at the head of the
-     * list, causing find_mesa_visual() to be off by one.  This would
-     * GLX clients to blow up if they attempted to use the last mode
-     * in the list!
-     */
-    {
-        __GLcontextModes *prev = NULL, *m;
-        for (m = screen->modes; m; m = m->next)
-            prev = m;
-        if (prev)
-            prev->next = modes;
-        else
-            screen->modes = modes;
-    }
-
-    screen->numUsableVisuals++;
-    screen->numVisuals++;
-
-    modes->visualID = visual->vid;
-    modes->fbconfigID = visual->vid;
-    modes->visualType = GLX_TRUE_COLOR;
-    modes->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
-    modes->renderType = GLX_RGBA_BIT;
-    modes->xRenderable = GL_TRUE;
-    modes->rgbMode = TRUE;
-    modes->colorIndexMode = FALSE;
-    modes->doubleBufferMode = FALSE;
-    modes->stereoMode = FALSE;
-    modes->haveAccumBuffer = FALSE;
-
-    modes->redBits = visual->bitsPerRGBValue;;
-    modes->greenBits = visual->bitsPerRGBValue;
-    modes->blueBits = visual->bitsPerRGBValue;
-    modes->alphaBits = visual->bitsPerRGBValue;
-
-    modes->rgbBits = 4 * visual->bitsPerRGBValue;
-    modes->indexBits = 0;
-    modes->level = 0;
-    modes->numAuxBuffers = 0;
-
-    modes->haveDepthBuffer = FALSE;
-    modes->depthBits = 0;
-    modes->haveStencilBuffer = FALSE;
-    modes->stencilBits = 0;
-
-    modes->visualRating = GLX_NON_CONFORMANT_CONFIG;
-}
-
-
 #define __GLX_TOTAL_FBCONFIG_ATTRIBS (28)
 #define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2)
 /**
@@ -1025,25 +976,15 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
     xGLXGetFBConfigsReply reply;
     __GLXscreen *pGlxScreen;
     CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH];
-    int p;
+    int p, err;
     __GLcontextModes *modes;
     __GLX_DECLARE_SWAP_VARIABLES;
     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 
+    if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err))
+	return err;
 
-    if (screen >= screenInfo.numScreens) {
-	/* The client library must send a valid screen number. */
-	client->errorValue = screen;
-	return BadValue;
-    }
-    pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
-
-    /* Create the "extra" 32bpp ARGB visual, if not already added.
-     * XXX This is questionable place to do so!  Re-examine this someday.
-     */
-    __glXCreateARGBConfig(pGlxScreen);
-
-    reply.numFBConfigs = pGlxScreen->numUsableVisuals;
+    reply.numFBConfigs = pGlxScreen->numFBConfigs;
     reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS;
     reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs);
     reply.type = X_Reply;
@@ -1058,18 +999,14 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
 
     WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
 
-    for ( modes = pGlxScreen->modes ; modes != NULL ; modes = modes->next ) {
-	if (modes->visualID == 0) {
-	    /* not a usable visual */
-	    continue;
-	}
+    for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) {
 	p = 0;
 
 #define WRITE_PAIR(tag,value) \
     do { buf[p++] = tag ; buf[p++] = value ; } while( 0 )
 
 	WRITE_PAIR( GLX_VISUAL_ID,        modes->visualID );
-	WRITE_PAIR( GLX_FBCONFIG_ID,      modes->visualID );
+	WRITE_PAIR( GLX_FBCONFIG_ID,      modes->fbconfigID );
 	WRITE_PAIR( GLX_X_RENDERABLE,     GL_TRUE );
 
 	WRITE_PAIR( GLX_RGBA,             modes->rgbMode );
@@ -1089,12 +1026,7 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
 	WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits );
 	WRITE_PAIR( GLX_DEPTH_SIZE,       modes->depthBits );
 	WRITE_PAIR( GLX_STENCIL_SIZE,     modes->stencilBits );
-
 	WRITE_PAIR( GLX_X_VISUAL_TYPE,    modes->visualType );
-
-	/* 
-	** Add token/value pairs for extensions.
-	*/
 	WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating );
 	WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel );
 	WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed );
@@ -1127,44 +1059,18 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
 }
 
 static int 
-DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId,
+DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config,
 		    DrawablePtr pDraw, XID glxDrawableId, int type)
 {
-    ScreenPtr pScreen;
-    VisualPtr pVisual;
-    __GLXscreen *pGlxScreen;
     __GLXdrawable *pGlxDraw;
-    __GLcontextModes *modes;
-    int i;
 
     LEGAL_NEW_RESOURCE(glxDrawableId, client);
 
-    /* Check if screen of the fbconfig matches screen of drawable. */
-    pScreen = pDraw->pScreen;
-    if (screenNum != pScreen->myNum)
+    if (pGlxScreen->pScreen != pDraw->pScreen)
 	return BadMatch;
 
-    /* If this fbconfig has a corresponding VisualRec the number of
-     * planes must match the drawable depth. */
-    pVisual = pScreen->visuals;
-    for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
-	if (pVisual->vid == fbconfigId && pVisual->nplanes != pDraw->depth)
-	    return BadMatch;
-    }
-
-    /* Get configuration of the visual. */
-    pGlxScreen = glxGetScreen(pScreen);
-    modes = _gl_context_modes_find_visual(pGlxScreen->modes, fbconfigId);
-    if (modes == NULL) {
-	/* Visual not support on this screen by this OpenGL implementation. */
-	client->errorValue = fbconfigId;
-	return BadValue;
-    }
-
-    /* FIXME: We need to check that the window visual is compatible
-     * with the specified fbconfig. */
     pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type,
-					  glxDrawableId, modes);
+					  glxDrawableId, config);
     if (pGlxDraw == NULL)
 	return BadAlloc;
 
@@ -1177,7 +1083,7 @@ DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId,
 }
 
 static int
-DoCreateGLXPixmap(ClientPtr client, int screenNum, XID fbconfigId,
+DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config,
 		  XID drawableId, XID glxDrawableId)
 {
     DrawablePtr pDraw;
@@ -1189,7 +1095,7 @@ DoCreateGLXPixmap(ClientPtr client, int screenNum, XID fbconfigId,
 	return BadPixmap;
     }
 
-    err = DoCreateGLXDrawable(client, screenNum, fbconfigId, pDraw,
+    err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw,
 			      glxDrawableId, GLX_DRAWABLE_PIXMAP);
 
     if (err == Success)
@@ -1235,17 +1141,32 @@ determineTextureTarget(XID glxDrawableID, CARD32 *attribs, CARD32 numAttribs)
 int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
+    __GLcontextModes *config;
+    __GLXscreen *pGlxScreen;
+    int err;
+
+    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+	return err;
+    if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
+	return err;
 
-    return DoCreateGLXPixmap(cl->client, req->screen, req->visual,
+    return DoCreateGLXPixmap(cl->client, pGlxScreen, config,
 			     req->pixmap, req->glxpixmap);
 }
 
 int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
+    __GLcontextModes *config;
+    __GLXscreen *pGlxScreen;
     int err;
 
-    err = DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig,
+    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+	return err;
+    if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
+	return err;
+
+    err = DoCreateGLXPixmap(cl->client, pGlxScreen, config,
 			    req->pixmap, req->glxpixmap);
     if (err != Success)
 	return err;
@@ -1260,9 +1181,17 @@ int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateGLXPixmapWithConfigSGIXReq *req = 
 	(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
+    __GLcontextModes *config;
+    __GLXscreen *pGlxScreen;
+    int err;
 
-    return DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig,
-			     req->pixmap, req->glxpixmap);
+    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+	return err;
+    if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
+	return err;
+
+    return DoCreateGLXPixmap(cl->client, pGlxScreen,
+			     config, req->pixmap, req->glxpixmap);
 }
 
 
@@ -1309,29 +1238,23 @@ static int
 DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
 		int width, int height, XID glxDrawableId)
 {
-    ScreenPtr	 pScreen;
-    VisualPtr	 pVisual;
-    PixmapPtr	 pPixmap;
-    int		i;
-
-    pScreen = screenInfo.screens[screenNum];
+    __GLcontextModes	*config;
+    __GLXscreen		*pGlxScreen;
+    PixmapPtr		 pPixmap;
+    int			 err;
 
-    pVisual = pScreen->visuals;
-    for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
-	if (pVisual->vid == fbconfigId)
-	    break;
-    }
-    if (i == pScreen->numVisuals)
-	return __glXError(GLXBadFBConfig);
+    if (!validGlxScreen(client, screenNum, &pGlxScreen, &err))
+	return err;
+    if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err))
+	return err;
 
     __glXenterServer(GL_FALSE);
-    pPixmap = (*pScreen->CreatePixmap) (pScreen,
-					width, height, pVisual->nplanes);
+    pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen,
+						    width, height, config->rgbBits);
     __glXleaveServer(GL_FALSE);
 
-    return DoCreateGLXDrawable(client, screenNum, fbconfigId,
-			       &pPixmap->drawable, glxDrawableId,
-			       GLX_DRAWABLE_PBUFFER);
+    return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
+			       glxDrawableId, GLX_DRAWABLE_PBUFFER);
 }
 
 int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
@@ -1428,17 +1351,27 @@ int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
 int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateWindowReq	*req = (xGLXCreateWindowReq *) pc;
+    __GLcontextModes	*config;
+    __GLXscreen		*pGlxScreen;
     ClientPtr		 client = cl->client;
     DrawablePtr		 pDraw;
     int			 err;
 
+    if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
+	return err;
+    if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err))
+	return err;
+
     err = dixLookupDrawable(&pDraw, req->window, client, 0, DixUnknownAccess);
     if (err != Success || pDraw->type != DRAWABLE_WINDOW) {
 	client->errorValue = req->window;
 	return BadWindow;
     }
 
-    return DoCreateGLXDrawable(client, req->screen, req->fbconfig,
+    if (!validGlxFBConfigForWindow(client, config, pDraw, &err))
+	return err;
+
+    return DoCreateGLXDrawable(client, pGlxScreen, config,
 			       pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW);
 }
 
@@ -2338,23 +2271,15 @@ int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
     ClientPtr client = cl->client;
     xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
     xGLXQueryExtensionsStringReply reply;
-    GLuint screen;
+    __GLXscreen *pGlxScreen;
     size_t n, length;
-    const char *ptr;
     char *buf;
+    int err;
 
-    screen = req->screen;
-    /*
-    ** Check if screen exists.
-    */
-    if (screen >= screenInfo.numScreens) {
-	client->errorValue = screen;
-	return BadValue;
-    }
-
-    ptr = glxGetScreen(screenInfo.screens[screen])->GLXextensions;
+    if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
+	return err;
 
-    n = strlen(ptr) + 1;
+    n = strlen(pGlxScreen->GLXextensions) + 1;
     length = __GLX_PAD(n) >> 2;
     reply.type = X_Reply;
     reply.sequenceNumber = client->sequence;
@@ -2365,7 +2290,7 @@ int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
     buf = (char *) xalloc(length << 2);
     if (buf == NULL)
         return BadAlloc;
-    memcpy(buf, ptr, n);
+    memcpy(buf, pGlxScreen->GLXextensions, n);
 
     if (client->swapped) {
         glxSwapQueryExtensionsStringReply(client, &reply, buf);
@@ -2383,25 +2308,16 @@ int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc)
     ClientPtr client = cl->client;
     xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
     xGLXQueryServerStringReply reply;
-    int name;
-    GLuint screen;
     size_t n, length;
     const char *ptr;
     char *buf;
     __GLXscreen *pGlxScreen;
+    int err;
 
-    name = req->name;
-    screen = req->screen;
-    /*
-    ** Check if screen exists.
-    */
-    if (screen >= screenInfo.numScreens) {
-	client->errorValue = screen;
-	return BadValue;
-    }
-    pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+    if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
+	return err;
 
-    switch(name) {
+    switch(req->name) {
 	case GLX_VENDOR:
 	    ptr = pGlxScreen->GLXvendor;
 	    break;
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index f11051b..3688d50 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -1025,7 +1025,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 			   fd,
 			   api_ver,
 			   &interface_methods,
-			   &screen->base.modes);
+			   &screen->base.fbconfigs);
 
     if (screen->driScreen.private == NULL) {
 	LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed");
diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c
index fd4e57d..b50967a 100644
--- a/GL/glx/glxglcore.c
+++ b/GL/glx/glxglcore.c
@@ -280,7 +280,7 @@ find_mesa_visual(__GLXscreen *screen, VisualID vid)
     const __GLcontextModes *modes;
     unsigned i = 0;
 
-    for ( modes = screen->modes ; modes != NULL ; modes = modes->next ) {
+    for ( modes = screen->fbconfigs ; modes != NULL ; modes = modes->next ) {
 	if ( modes->visualID == vid ) {
 	    break;
 	}
@@ -314,7 +314,7 @@ static void init_screen_visuals(__GLXMESAscreen *screen)
     memset(used, 0, pScreen->numVisuals * sizeof(int));
 
     num_vis = 0;
-    for ( modes = screen->base.modes; modes != NULL; modes = modes->next ) {
+    for ( modes = screen->base.fbconfigs; modes != NULL; modes = modes->next ) {
 	const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
 	const int nplanes = (modes->rgbBits - modes->alphaBits);
 	const VisualPtr pVis = pScreen->visuals;
diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c
index d063ad7..8ab035d 100644
--- a/GL/glx/glxscreens.c
+++ b/GL/glx/glxscreens.c
@@ -44,6 +44,7 @@
 #include "glxserver.h"
 #include "glxutil.h"
 #include "glxext.h"
+#include "glcontextmodes.h"
 
 static int glxScreenPrivateIndex;
 
@@ -287,13 +288,28 @@ glxGetScreen(ScreenPtr pScreen)
 void GlxSetVisualConfigs(int nconfigs, 
                          __GLXvisualConfig *configs, void **privates)
 {
-	/* We keep this stub around for the DDX drivers that still
-	 * call it. */
+    /* We keep this stub around for the DDX drivers that still
+     * call it. */
+}
+
+static XID
+findVisualForConfig(ScreenPtr pScreen, __GLcontextModes *m)
+{
+    int i;
+
+    for (i = 0; i < pScreen->numVisuals; i++) {
+	if (_gl_convert_to_x_visual_type(m->visualType) == pScreen->visuals[i].class)
+	    return pScreen->visuals[i].vid;
+    }
+
+    return 0;
 }
 
 void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen)
 {
     static int glxGeneration;
+    __GLcontextModes *m;
+    int i;
 
     if (glxGeneration != serverGeneration)
     {
@@ -304,6 +320,23 @@ void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen)
 	glxGeneration = serverGeneration;
     }
 
+    i = 0;
+    for (m = glxScreen->fbconfigs; m != NULL; m = m->next) {
+	m->fbconfigID = i++;
+	m->visualID = findVisualForConfig(pScreen, m);
+	ErrorF("mapping fbconfig %d to visual 0x%02x\n",
+	       m->fbconfigID, m->visualID);
+    }
+    glxScreen->numFBConfigs = i;
+
+    /* Select a subset of fbconfigs that we send to the client when it
+     * asks for the glx visuals.  All the fbconfigs here have a valid
+     * value for visual ID and each visual ID is only present once.
+     * This runs before composite adds its extra visual so we have to
+     * remember the number of visuals here.*/
+    glxScreen->visuals = NULL;
+    glxScreen->numVisuals = 0;
+
     glxScreen->pScreen       = pScreen;
     glxScreen->GLextensions  = xstrdup(GLServerExtensions);
     glxScreen->GLXvendor     = xstrdup(GLXServerVendorName);
diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h
index 7b1bbcd..f1eef91 100644
--- a/GL/glx/glxscreens.h
+++ b/GL/glx/glxscreens.h
@@ -83,14 +83,13 @@ struct __GLXscreen {
 
     ScreenPtr pScreen;
 
-    /**
-     * Linked list of valid context modes for this screen.
-     */
-    __GLcontextModes *modes;
+    /* Linked list of valid fbconfigs for this screen. */
+    __GLcontextModes *fbconfigs;
+    int numFBConfigs;
 
-    void **pVisualPriv;
+    /* Subset of fbconfigs that are exposed as GLX visuals. */
+    __GLcontextModes **visuals;
     GLint numVisuals;
-    GLint numUsableVisuals;
 
     char *GLextensions;
 
commit 6a310bf763315edbebc76da337050ac778adf080
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Wed Oct 17 17:18:47 2007 -0400

    Drop VisualConfigPriv support from the DRI module.
    
    No DDX driver uses this, and this patch stops the DRI module from
    poking around GLX module data structures.

diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index e828fbb..ce75af5 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -67,7 +67,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "dristruct.h"
 #include "xf86.h"
 #include "xf86drm.h"
-#include "glxserver.h"
 #include "mi.h"
 #include "mipointer.h"
 #include "xf86_OSproc.h"
@@ -981,24 +980,8 @@ static Bool
 DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv)
 {
     DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-    __GLXscreen *pGLXScreen = glxGetScreen(pScreen);
-    __GLcontextModes *modes = pGLXScreen->modes;
-    void **pVisualConfigPriv = pGLXScreen->pVisualPriv;
     DRIContextPrivPtr pDRIContextPriv;
     void *contextStore;
-    VisualPtr visual;
-    int visNum;
-
-    visual = pScreen->visuals;
-
-    /* Find the X visual that corresponds the the first GLX visual */
-    for (visNum = 0;
-	 visNum < pScreen->numVisuals;
-	 visNum++, visual++) {
-	if (modes->visualID == visual->vid)
-	    break;
-    }
-    if (visNum == pScreen->numVisuals) return FALSE;
 
     if (!(pDRIContextPriv =
 	  DRICreateContextPriv(pScreen,
@@ -1008,9 +991,9 @@ DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv)
 
     contextStore = DRIGetContextStore(pDRIContextPriv);
     if (pDRIPriv->pDriverInfo->CreateContext && needCtxPriv) {
-	if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, visual,
+	if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, NULL,
 						  pDRIPriv->pSAREA->dummy_context,
-						  *pVisualConfigPriv,
+						  NULL,
 						  (DRIContextType)(long)contextStore)) {
 	    DRIDestroyContextPriv(pDRIContextPriv);
 	    return FALSE;
@@ -1045,9 +1028,6 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
                  XID context, drm_context_t * pHWContext)
 {
     DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-    __GLXscreen *pGLXScreen = glxGetScreen(pScreen);
-    __GLcontextModes *modes = pGLXScreen->modes;
-    void **pVisualConfigPriv = pGLXScreen->pVisualPriv;
     DRIContextPrivPtr pDRIContextPriv;
     void *contextStore;
 
@@ -1059,26 +1039,14 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
 	}
     }
 
-    /* Find the GLX visual associated with the one requested */
-    for (modes = pGLXScreen->modes; modes != NULL; modes = modes->next) {
-	if (modes->visualID == visual->vid)
-	    break;
-	pVisualConfigPriv++;
-    }
-
-    if (modes == NULL) {
-	/* No matching GLX visual found */
-	return FALSE;
-    }
-
     if (!(pDRIContextPriv = DRICreateContextPriv(pScreen, pHWContext, 0))) {
 	return FALSE;
     }
 
     contextStore = DRIGetContextStore(pDRIContextPriv);
     if (pDRIPriv->pDriverInfo->CreateContext) {
-	if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, visual,
-		*pHWContext, *pVisualConfigPriv,
+	if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, NULL,
+		*pHWContext, NULL,
 		(DRIContextType)(long)contextStore))) {
 	    DRIDestroyContextPriv(pDRIContextPriv);
 	    return FALSE;
diff --git a/hw/xfree86/dri/xf86dri.c b/hw/xfree86/dri/xf86dri.c
index fdf0e99..130afdf 100644
--- a/hw/xfree86/dri/xf86dri.c
+++ b/hw/xfree86/dri/xf86dri.c
@@ -337,19 +337,9 @@ ProcXF86DRICreateContext(
     rep.sequenceNumber = client->sequence;
 
     pScreen = screenInfo.screens[stuff->screen];
-    visual = pScreen->visuals;
-
-    /* Find the requested X visual */
-    for (i = 0; i < pScreen->numVisuals; i++, visual++)
-	if (visual->vid == stuff->visual)
-	    break;
-    if (i == pScreen->numVisuals) {
-	/* No visual found */
-	return BadValue;
-    }
 
     if (!DRICreateContext( pScreen,
-			   visual,
+			   NULL,
 			   stuff->context,
 			   (drm_context_t *)&rep.hHWContext)) {
 	return BadValue;
commit 2a5c2bdfd587663c5da27411533e4011e097129b
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Sun Oct 14 15:39:21 2007 -0400

    Simplify and clean up GLX visual initialization.
    
    Instead of the fragile setup where we filter the modes common between the
    DDX generated GLX visuals and the DRI driver generated fbconfigs, we now
    just take the fbconfigs returned by the DRI driver to be our supported set.

diff --git a/GL/glx/Makefile.am b/GL/glx/Makefile.am
index 7c1730e..8eda153 100644
--- a/GL/glx/Makefile.am
+++ b/GL/glx/Makefile.am
@@ -53,7 +53,6 @@ libglx_la_SOURCES = \
         glxserver.h \
         glxutil.c \
         glxutil.h \
-        glxvisuals.c \
         indirect_dispatch.c \
         indirect_dispatch.h \
         indirect_dispatch_swap.c \
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index 2ded6aa..f11051b 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -658,64 +658,6 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
     return &private->base;
 }
 
-
-static unsigned
-filter_modes(__GLcontextModes **server_modes,
-	     const __GLcontextModes *driver_modes)
-{
-    __GLcontextModes * m;
-    __GLcontextModes ** prev_next;
-    const __GLcontextModes * check;
-    unsigned modes_count = 0;
-
-    if ( driver_modes == NULL ) {
-	LogMessage(X_WARNING,
-		   "AIGLX: 3D driver returned no fbconfigs.\n");
-	return 0;
-    }
-
-    /* For each mode in server_modes, check to see if a matching mode exists
-     * in driver_modes.  If not, then the mode is not available.
-     */
-
-    prev_next = server_modes;
-    for ( m = *prev_next ; m != NULL ; m = *prev_next ) {
-	GLboolean do_delete = GL_TRUE;
-
-	for ( check = driver_modes ; check != NULL ; check = check->next ) {
-	    if ( _gl_context_modes_are_same( m, check ) ) {
-		do_delete = GL_FALSE;
-		break;
-	    }
-	}
-
-	/* The 3D has to support all the modes that match the GLX visuals
-	 * sent from the X server.
-	 */
-	if ( do_delete && (m->visualID != 0) ) {
-	    do_delete = GL_FALSE;
-
-	    LogMessage(X_WARNING,
-		       "AIGLX: 3D driver claims to not support "
-		       "visual 0x%02x\n", m->visualID);
-	}
-
-	if ( do_delete ) {
-	    *prev_next = m->next;
-
-	    m->next = NULL;
-	    _gl_context_modes_destroy( m );
-	}
-	else {
-	    modes_count++;
-	    prev_next = & m->next;
-	}
-    }
-
-    return modes_count;
-}
-
-
 static GLboolean
 getDrawableInfo(__DRIdrawable *driDrawable,
 		unsigned int *index, unsigned int *stamp,
@@ -923,7 +865,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     char *driverName;
     drm_handle_t  hFB;
     int        junk;
-    __GLcontextModes * driver_modes;
     __GLXDRIscreen *screen;
     void *dev_priv = NULL;
     char filename[128];
@@ -1073,7 +1014,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 	goto handle_error;
     }
     
-    driver_modes = NULL;
     screen->driScreen.private =
 	(*createNewScreen)(pScreen->myNum,
 			   &screen->driScreen,
@@ -1085,7 +1025,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 			   fd,
 			   api_ver,
 			   &interface_methods,
-			   &driver_modes);
+			   &screen->base.modes);
 
     if (screen->driScreen.private == NULL) {
 	LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed");
@@ -1110,10 +1050,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 				       screen->base.GLXextensions);
     }
 
-
-    filter_modes(&screen->base.modes, driver_modes);
-    _gl_context_modes_destroy(driver_modes);
-
     __glXsetEnterLeaveServerFuncs(__glXDRIenterServer, __glXDRIleaveServer);
 
     screen->enterVT = pScrn->EnterVT;
diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c
index 9757874..d063ad7 100644
--- a/GL/glx/glxscreens.c
+++ b/GL/glx/glxscreens.c
@@ -284,6 +284,13 @@ glxGetScreen(ScreenPtr pScreen)
     return (__GLXscreen *) pScreen->devPrivates[glxScreenPrivateIndex].ptr;
 }
 
+void GlxSetVisualConfigs(int nconfigs, 
+                         __GLXvisualConfig *configs, void **privates)
+{
+	/* We keep this stub around for the DDX drivers that still
+	 * call it. */
+}
+
 void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen)
 {
     static int glxGeneration;
@@ -309,8 +316,6 @@ void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen)
     glxScreen->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = glxCloseScreen;
 
-    __glXScreenInitVisuals(glxScreen);
-
     pScreen->devPrivates[glxScreenPrivateIndex].ptr = (pointer) glxScreen;
 }
  
diff --git a/GL/glx/glxvisuals.c b/GL/glx/glxvisuals.c
deleted file mode 100644
index 46b380b..0000000
--- a/GL/glx/glxvisuals.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Copyright © 2006  Red Hat, Inc.
- * (C) Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sub license,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
- * RED HAT, INC, OR PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
- * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
- * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * Authors:
- *   Kevin E. Martin <kevin at precisioninsight.com>
- *   Brian Paul <brian at precisioninsight.com>
- *   Kristian Høgsberg <krh at redhat.com>
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <assert.h>
-#include <string.h>
-#include <regionstr.h>
-#include <resource.h>
-#include <GL/gl.h>
-#include <GL/glxint.h>
-#include <GL/glxtokens.h>
-#include <GL/internal/glcore.h>
-#include <scrnintstr.h>
-#include <config.h>
-#include <glxserver.h>
-#include <glxscreens.h>
-#include <glxdrawable.h>
-#include <glxcontext.h>
-#include <glxext.h>
-#include <glxutil.h>
-#include <micmap.h>
-
-void GlxWrapInitVisuals(miInitVisualsProcPtr *);
-
-extern Bool noGlxVisualInit;
-#include "glcontextmodes.h"
-
-struct ScreenVisualsRec {
-    int num_vis;
-    void *private;
-    __GLcontextModes *modes;
-};
-typedef struct ScreenVisualsRec ScreenVisuals;
-
-static ScreenVisuals screenVisuals[MAXSCREENS];
-
-static int                 numConfigs     = 0;
-static __GLXvisualConfig  *visualConfigs  = NULL;
-static void              **visualPrivates = NULL;
-
-static int count_bits(unsigned int n)
-{
-   int bits = 0;
-
-   while (n > 0) {
-      if (n & 1) bits++;
-      n >>= 1;
-   }
-   return bits;
-}
-
-/*
- * In the case the driver defines no GLX visuals we'll use these.
- * Note that for TrueColor and DirectColor visuals, bufferSize is the 
- * sum of redSize, greenSize, blueSize and alphaSize, which may be larger 
- * than the nplanes/rootDepth of the server's X11 visuals
- */
-#define NUM_FALLBACK_CONFIGS 5
-static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = {
-  /* [0] = RGB, double buffered, Z */
-  {
-    -1,                 /* vid */
-    -1,                 /* class */
-    True,               /* rgba */
-    -1, -1, -1, 0,      /* rgba sizes */
-    -1, -1, -1, 0,      /* rgba masks */
-     0,  0,  0, 0,      /* rgba accum sizes */
-    True,               /* doubleBuffer */
-    False,              /* stereo */
-    -1,                 /* bufferSize */
-    16,                 /* depthSize */
-    0,                  /* stencilSize */
-    0,                  /* auxBuffers */
-    0,                  /* level */
-    GLX_NONE,           /* visualRating */
-    GLX_NONE,           /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-  },
-  /* [1] = RGB, double buffered, Z, stencil, accum */
-  {
-    -1,                 /* vid */
-    -1,                 /* class */
-    True,               /* rgba */
-    -1, -1, -1, 0,      /* rgba sizes */
-    -1, -1, -1, 0,      /* rgba masks */
-    16, 16, 16, 0,      /* rgba accum sizes */
-    True,               /* doubleBuffer */
-    False,              /* stereo */
-    -1,                 /* bufferSize */
-    16,                 /* depthSize */
-    8,                  /* stencilSize */
-    0,                  /* auxBuffers */
-    0,                  /* level */
-    GLX_NONE,           /* visualRating */
-    GLX_NONE,           /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-  },
-  /* [2] = RGB+Alpha, double buffered, Z, stencil, accum */
-  {
-    -1,                 /* vid */
-    -1,                 /* class */
-    True,               /* rgba */
-    -1, -1, -1, 8,      /* rgba sizes */
-    -1, -1, -1, -1,     /* rgba masks */
-    16, 16, 16, 16,     /* rgba accum sizes */
-    True,               /* doubleBuffer */
-    False,              /* stereo */
-    -1,                 /* bufferSize */
-    16,                 /* depthSize */
-    8,                  /* stencilSize */
-    0,                  /* auxBuffers */
-    0,                  /* level */
-    GLX_NONE,           /* visualRating */
-    GLX_NONE,           /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-  },
-  /* [3] = RGB+Alpha, single buffered, Z, stencil, accum */
-  {
-    -1,                 /* vid */
-    -1,                 /* class */
-    True,               /* rgba */
-    -1, -1, -1, 8,      /* rgba sizes */
-    -1, -1, -1, -1,     /* rgba masks */
-    16, 16, 16, 16,     /* rgba accum sizes */
-    False,              /* doubleBuffer */
-    False,              /* stereo */
-    -1,                 /* bufferSize */
-    16,                 /* depthSize */
-    8,                  /* stencilSize */
-    0,                  /* auxBuffers */
-    0,                  /* level */
-    GLX_NONE,           /* visualRating */
-    GLX_NONE,           /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-  },
-  /* [4] = CI, double buffered, Z */
-  {
-    -1,                 /* vid */
-    -1,                 /* class */
-    False,              /* rgba? (false = color index) */
-    -1, -1, -1, 0,      /* rgba sizes */
-    -1, -1, -1, 0,      /* rgba masks */
-     0,  0,  0, 0,      /* rgba accum sizes */
-    True,               /* doubleBuffer */
-    False,              /* stereo */
-    -1,                 /* bufferSize */
-    16,                 /* depthSize */
-    0,                  /* stencilSize */
-    0,                  /* auxBuffers */
-    0,                  /* level */
-    GLX_NONE,           /* visualRating */
-    GLX_NONE,           /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-  },
-};
-
-
-static Bool init_visuals(int *nvisualp, VisualPtr *visualp,
-			 VisualID *defaultVisp,
-			 int ndepth, DepthPtr pdepth,
-			 int rootDepth)
-{
-    int numRGBconfigs;
-    int numCIconfigs;
-    int numVisuals = *nvisualp;
-    int numNewVisuals;
-    int numNewConfigs;
-    VisualPtr pVisual = *visualp;
-    VisualPtr pVisualNew = NULL;
-    VisualID *orig_vid = NULL;
-    __GLcontextModes *modes;
-    __GLXvisualConfig *pNewVisualConfigs = NULL;
-    void **glXVisualPriv;
-    void **pNewVisualPriv;
-    int found_default;
-    int i, j, k;
-
-    if (numConfigs > 0)
-        numNewConfigs = numConfigs;
-    else
-        numNewConfigs = NUM_FALLBACK_CONFIGS;
-
-    /* Alloc space for the list of new GLX visuals */
-    pNewVisualConfigs = (__GLXvisualConfig *)
-	xalloc(numNewConfigs * sizeof(__GLXvisualConfig));
-    if (!pNewVisualConfigs) {
-	return FALSE;
-    }
-
-    /* Alloc space for the list of new GLX visual privates */
-    pNewVisualPriv = (void **) xalloc(numNewConfigs * sizeof(void *));
-    if (!pNewVisualPriv) {
-	xfree(pNewVisualConfigs);
-	return FALSE;
-    }
-
-    /*
-    ** If SetVisualConfigs was not called, then use default GLX
-    ** visual configs.
-    */
-    if (numConfigs == 0) {
-	memcpy(pNewVisualConfigs, FallbackConfigs,
-               NUM_FALLBACK_CONFIGS * sizeof(__GLXvisualConfig));
-	memset(pNewVisualPriv, 0, NUM_FALLBACK_CONFIGS * sizeof(void *));
-    }
-    else {
-        /* copy driver's visual config info */
-        for (i = 0; i < numConfigs; i++) {
-            pNewVisualConfigs[i] = visualConfigs[i];
-            pNewVisualPriv[i] = visualPrivates[i];
-        }
-    }
-
-    /* Count the number of RGB and CI visual configs */
-    numRGBconfigs = 0;
-    numCIconfigs = 0;
-    for (i = 0; i < numNewConfigs; i++) {
-	if (pNewVisualConfigs[i].rgba)
-	    numRGBconfigs++;
-	else
-	    numCIconfigs++;
-    }
-
-    /* Count the total number of visuals to compute */
-    numNewVisuals = 0;
-    for (i = 0; i < numVisuals; i++) {
-        numNewVisuals +=
-	    (pVisual[i].class == TrueColor || pVisual[i].class == DirectColor)
-	    ? numRGBconfigs : numCIconfigs;
-    }
-
-    /* Reset variables for use with the next screen/driver's visual configs */
-    visualConfigs = NULL;
-    numConfigs = 0;
-
-    /* Alloc temp space for the list of orig VisualIDs for each new visual */
-    orig_vid = (VisualID *) xalloc(numNewVisuals * sizeof(VisualID));
-    if (!orig_vid) {
-	xfree(pNewVisualPriv);
-	xfree(pNewVisualConfigs);
-	return FALSE;
-    }
-
-    /* Alloc space for the list of glXVisuals */
-    modes = _gl_context_modes_create(numNewVisuals, sizeof(__GLcontextModes));
-    if (modes == NULL) {
-	xfree(orig_vid);
-	xfree(pNewVisualPriv);
-	xfree(pNewVisualConfigs);
-	return FALSE;
-    }
-
-    /* Alloc space for the list of glXVisualPrivates */
-    glXVisualPriv = (void **)xalloc(numNewVisuals * sizeof(void *));
-    if (!glXVisualPriv) {
-	_gl_context_modes_destroy( modes );
-	xfree(orig_vid);
-	xfree(pNewVisualPriv);
-	xfree(pNewVisualConfigs);
-	return FALSE;
-    }
-
-    /* Alloc space for the new list of the X server's visuals */
-    pVisualNew = (VisualPtr)xalloc(numNewVisuals * sizeof(VisualRec));
-    if (!pVisualNew) {
-	xfree(glXVisualPriv);
-	_gl_context_modes_destroy( modes );
-	xfree(orig_vid);
-	xfree(pNewVisualPriv);
-	xfree(pNewVisualConfigs);
-	return FALSE;
-    }
-
-    /* Initialize the new visuals */
-    found_default = FALSE;
-    screenVisuals[screenInfo.numScreens-1].modes = modes;
-    for (i = j = 0; i < numVisuals; i++) {
-        int is_rgb = (pVisual[i].class == TrueColor ||
-		      pVisual[i].class == DirectColor);
-
-	for (k = 0; k < numNewConfigs; k++) {
-	    if (pNewVisualConfigs[k].rgba != is_rgb)
-		continue;
-
-	    assert( modes != NULL );
-
-	    /* Initialize the new visual */
-	    pVisualNew[j] = pVisual[i];
-	    pVisualNew[j].vid = FakeClientID(0);
-
-	    /* Check for the default visual */
-	    if (!found_default && pVisual[i].vid == *defaultVisp) {
-		*defaultVisp = pVisualNew[j].vid;
-		found_default = TRUE;
-	    }
-
-	    /* Save the old VisualID */
-	    orig_vid[j] = pVisual[i].vid;
-
-	    /* Initialize the glXVisual */
-	    _gl_copy_visual_to_context_mode( modes, & pNewVisualConfigs[k] );
-	    modes->visualID = pVisualNew[j].vid;
-	    if (modes->fbconfigID == GLX_DONT_CARE)
-		modes->fbconfigID = modes->visualID;
-
-	    /*
-	     * If the class is -1, then assume the X visual information
-	     * is identical to what GLX needs, and take them from the X
-	     * visual.  NOTE: if class != -1, then all other fields MUST
-	     * be initialized.
-	     */
-	    if (modes->visualType == GLX_NONE) {
-		modes->visualType = _gl_convert_from_x_visual_type( pVisual[i].class );
-		modes->redBits    = count_bits(pVisual[i].redMask);
-		modes->greenBits  = count_bits(pVisual[i].greenMask);
-		modes->blueBits   = count_bits(pVisual[i].blueMask);
-		modes->alphaBits  = modes->alphaBits;
-		modes->redMask    = pVisual[i].redMask;
-		modes->greenMask  = pVisual[i].greenMask;
-		modes->blueMask   = pVisual[i].blueMask;
-		modes->alphaMask  = modes->alphaMask;
-		modes->rgbBits = (is_rgb)
-		    ? (modes->redBits + modes->greenBits +
-		       modes->blueBits + modes->alphaBits)
-		    : rootDepth;
-	    }
-
-	    /* Save the device-dependent private for this visual */
-	    glXVisualPriv[j] = pNewVisualPriv[k];
-
-	    j++;
-	    modes = modes->next;
-	}
-    }
-
-    assert(j <= numNewVisuals);
-
-    /* Save the GLX visuals in the screen structure */
-    screenVisuals[screenInfo.numScreens-1].num_vis = numNewVisuals;
-    screenVisuals[screenInfo.numScreens-1].private = glXVisualPriv;
-
-    /* Set up depth's VisualIDs */
-    for (i = 0; i < ndepth; i++) {
-	int numVids = 0;
-	VisualID *pVids = NULL;
-	int k, n = 0;
-
-	/* Count the new number of VisualIDs at this depth */
-	for (j = 0; j < pdepth[i].numVids; j++)
-	    for (k = 0; k < numNewVisuals; k++)
-		if (pdepth[i].vids[j] == orig_vid[k])
-		    numVids++;
-
-	/* Allocate a new list of VisualIDs for this depth */
-	pVids = (VisualID *)xalloc(numVids * sizeof(VisualID));
-
-	/* Initialize the new list of VisualIDs for this depth */
-	for (j = 0; j < pdepth[i].numVids; j++)
-	    for (k = 0; k < numNewVisuals; k++)
-		if (pdepth[i].vids[j] == orig_vid[k])
-		    pVids[n++] = pVisualNew[k].vid;
-
-	/* Update this depth's list of VisualIDs */
-	xfree(pdepth[i].vids);
-	pdepth[i].vids = pVids;
-	pdepth[i].numVids = numVids;
-    }
-
-    /* Update the X server's visuals */
-    *nvisualp = numNewVisuals;
-    *visualp = pVisualNew;
-
-    /* Free the old list of the X server's visuals */
-    xfree(pVisual);
-
-    /* Clean up temporary allocations */
-    xfree(orig_vid);
-    xfree(pNewVisualPriv);
-    xfree(pNewVisualConfigs);
-
-    /* Free the private list created by DDX HW driver */
-    if (visualPrivates)
-        xfree(visualPrivates);
-    visualPrivates = NULL;
-
-    return TRUE;
-}
-
-void GlxSetVisualConfigs(int nconfigs, 
-                         __GLXvisualConfig *configs, void **privates)
-{
-    numConfigs = nconfigs;
-    visualConfigs = configs;
-    visualPrivates = privates;
-}
-
-static miInitVisualsProcPtr saveInitVisualsProc;
-
-Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
-		    int *nvisualp, int *ndepthp,
-		    int *rootDepthp, VisualID *defaultVisp,
-		    unsigned long sizes, int bitsPerRGB,
-		    int preferredVis)
-{
-    Bool ret;
-
-    if (saveInitVisualsProc) {
-        ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
-                                  rootDepthp, defaultVisp, sizes, bitsPerRGB,
-                                  preferredVis);
-        if (!ret)
-            return False;
-    }
-
-    /*
-     * Setup the visuals supported by this particular screen.
-     */
-    if (!noGlxVisualInit) {
-        init_visuals(nvisualp, visualp, defaultVisp,
-                     *ndepthp, *depthp, *rootDepthp);
-    }
-
-
-    return True;
-}
-
-/************************************************************************/
-
-
-void
-GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
-{
-    saveInitVisualsProc = *initVisProc;
-    *initVisProc = GlxInitVisuals;
-}
-
-static void fixup_visuals(int screen)
-{
-    ScreenPtr pScreen = screenInfo.screens[screen];
-    ScreenVisuals *psv = &screenVisuals[screen];
-    int j;
-    __GLcontextModes *modes;
-
-    for ( modes = psv->modes ; modes != NULL ; modes = modes->next ) {
-	const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
-	const int nplanes = (modes->rgbBits - modes->alphaBits);
-	const VisualPtr pVis = pScreen->visuals;
-
-	/* Find a visual that matches the GLX visual's class and size */
-	for (j = 0; j < pScreen->numVisuals; j++) {
-	    if (pVis[j].class == vis_class &&
-		pVis[j].nplanes == nplanes) {
-
-		/* Fixup the masks */
-		modes->redMask   = pVis[j].redMask;
-		modes->greenMask = pVis[j].greenMask;
-		modes->blueMask  = pVis[j].blueMask;
-
-		/* Recalc the sizes */
-		modes->redBits   = count_bits(modes->redMask);
-		modes->greenBits = count_bits(modes->greenMask);
-		modes->blueBits  = count_bits(modes->blueMask);
-	    }
-	}
-    }
-}
-
-void __glXScreenInitVisuals(__GLXscreen *screen)
-{
-    int index = screen->pScreen->myNum;
-
-    screen->modes = screenVisuals[index].modes;
-    screen->pVisualPriv = screenVisuals[index].private;
-    screen->numVisuals = screenVisuals[index].num_vis;
-    screen->numUsableVisuals = screenVisuals[index].num_vis;
-
-    /*
-     * The ordering of the rgb compenents might have been changed by the
-     * driver after mi initialized them.
-     */
-    fixup_visuals(index);
-}
diff --git a/hw/xfree86/dixmods/glxmodule.c b/hw/xfree86/dixmods/glxmodule.c
index 5384f43..f1c861b 100644
--- a/hw/xfree86/dixmods/glxmodule.c
+++ b/hw/xfree86/dixmods/glxmodule.c
@@ -52,7 +52,6 @@ struct __GLXprovider {
 
 extern void GlxPushProvider(__GLXprovider *provider);
 extern void GlxExtensionInit(void);
-extern void GlxWrapInitVisuals(miInitVisualsProcPtr *);
 
 static MODULESETUPPROTO(glxSetup);
 
@@ -140,10 +139,6 @@ glxSetup(pointer module, pointer opts, int *errmaj, int *errmin)
     }
 
     LoadExtension(&GLXExt, FALSE);
-    /* Wrap the init visuals routine in micmap.c */
-    GlxWrapInitVisuals(&miInitVisualsProc);
-    /* Make sure this gets wrapped each time InitVisualWrap is called */
-    miHookInitVisuals(NULL, GlxWrapInitVisuals);
 
  bail:
     return module;
diff --git a/hw/xnest/Screen.c b/hw/xnest/Screen.c
index 86f856e..02e82d1 100644
--- a/hw/xnest/Screen.c
+++ b/hw/xnest/Screen.c
@@ -45,10 +45,6 @@ is" without express or implied warranty.
 Window xnestDefaultWindows[MAXSCREENS];
 Window xnestScreenSaverWindows[MAXSCREENS];
 
-#ifdef GLXEXT
-extern void GlxWrapInitVisuals(miInitVisualsProcPtr *);
-#endif
-
 static int xnestScreenGeneration = -1;
 
 ScreenPtr
@@ -230,17 +226,6 @@ xnestOpenScreen(int index, ScreenPtr pScreen, int argc, char *argv[])
   defaultVisual = visuals[xnestDefaultVisualIndex].vid;
   rootDepth = visuals[xnestDefaultVisualIndex].nplanes;
 
-#ifdef GLXEXT
-  {
-    miInitVisualsProcPtr proc = NULL;
-
-    GlxWrapInitVisuals(&proc);
-    /* GlxInitVisuals ignores the last three arguments. */
-    proc(&visuals, &depths, &numVisuals, &numDepths,
-	 &rootDepth, &defaultVisual, 0, 0, 0);
-  }
-#endif
-
   if (xnestParentWindow != 0) {
     XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes);
     xnestWidth = gattributes.width;
diff --git a/mi/miinitext.c b/mi/miinitext.c
index 5d7f163..c449e27 100644
--- a/mi/miinitext.c
+++ b/mi/miinitext.c
@@ -347,7 +347,6 @@ extern void DarwinGlxWrapInitVisuals(miInitVisualsProcPtr *);
 extern __GLXprovider __glXMesaProvider;
 extern void GlxPushProvider(__GLXprovider *impl);
 extern void GlxExtensionInit(INITARGS);
-extern void GlxWrapInitVisuals(miInitVisualsProcPtr *);
 #endif // INXDARWINAPP
 #endif // GLXEXT
 #ifdef XF86DRI
@@ -675,9 +674,7 @@ InitVisualWrap()
 {
     miResetInitVisuals();
 #ifdef GLXEXT
-#ifndef __DARWIN__
-    GlxWrapInitVisuals(&miInitVisualsProc);
-#else
+#ifdef __DARWIN__
     DarwinGlxWrapInitVisuals(&miInitVisualsProc);
 #endif
 #endif
commit 08be77543441237f159693c2eb22bd3b4cb4b1ab
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Oct 18 15:22:42 2007 -0700

    Add a quirk for Philips 107P5 which lacks the preferred bit on detailed timing.
    
    Also fix the prefer-large-75 quirk if the prefer-first-detailed bit was set,
    though it's not the case for the existing prefer-large-75 consumer.

diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 9fa5fef..2f26a64 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -64,6 +64,8 @@ typedef enum {
      * maximum size and use that.
      */
     DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE = 1 << 5,
+    /* Monitor forgot to set the first detailed is preferred bit. */
+    DDC_QUIRK_FIRST_DETAILED_PREFERRED = 1 << 6,
 } ddc_quirk_t;
 
 static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
@@ -147,6 +149,16 @@ static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC)
     return FALSE;
 }
 
+static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC)
+{
+    /* Philips 107p5 CRT. Reported on xorg@ with pastebin. */
+    if (memcmp (DDC->vendor.name, "PHL", 4) == 0 &&
+	DDC->vendor.prod_id == 57364)
+	return TRUE;
+
+    return FALSE;
+}
+
 typedef struct {
     Bool	(*detect) (int scrnIndex, xf86MonPtr DDC);
     ddc_quirk_t	quirk;
@@ -178,6 +190,10 @@ static const ddc_quirk_map_t ddc_quirks[] = {
 	quirk_detailed_use_maximum_size,   DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE,
 	"Detailed timings give sizes in cm."
     },
+    {
+	quirk_first_detailed_preferred, DDC_QUIRK_FIRST_DETAILED_PREFERRED,
+	"First detailed timing was not marked as preferred."
+    },
     { 
 	NULL,		DDC_QUIRK_NONE,
 	"No known quirks"
@@ -257,7 +273,7 @@ DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing,
  */
 static DisplayModePtr
 DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
-			  int preferred, ddc_quirk_t quirks)
+			  Bool preferred, ddc_quirk_t quirks)
 {
     DisplayModePtr Mode;
 
@@ -470,9 +486,10 @@ xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes,
 _X_EXPORT DisplayModePtr
 xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
 {
-    int preferred, i;
+    int		    i;
     DisplayModePtr  Modes = NULL, Mode;
     ddc_quirk_t	    quirks;
+    Bool	    preferred;
 
     xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
 		DDC->vendor.name, DDC->vendor.prod_id);
@@ -480,8 +497,10 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
     quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE);
 
     preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
-    if (quirks & DDC_QUIRK_PREFER_LARGE_60)
-	preferred = 0;
+    if (quirks & DDC_QUIRK_FIRST_DETAILED_PREFERRED)
+	preferred = TRUE;
+    if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_LARGE_75))
+	preferred = FALSE;
 
     for (i = 0; i < DET_TIMINGS; i++) {
 	struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
@@ -492,7 +511,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
                                              &det_mon->section.d_timings,
 					     preferred,
 					     quirks);
-	    preferred = 0;
+	    preferred = FALSE;
             Modes = xf86ModesAdd(Modes, Mode);
             break;
         case DS_STD_TIMINGS:
commit c3f909c5d387e4faf3e222c4a59e94a7ec78f5f6
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Oct 18 17:44:48 2007 +0200

    EXA: Skip empty glyphs.

diff --git a/exa/exa_render.c b/exa/exa_render.c
index 65e67d8..cc2f59d 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -1246,6 +1246,7 @@ exaGlyphs (CARD8	op,
 	    y1 = y - glyph->info.y;
 
 	    if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height ||
+		glyph->info.width == 0 || glyph->info.height == 0 ||
 		(x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0)
 		goto nextglyph;
 
commit fe31564f10850718c663fab2826ddb91c97c1fa8
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Oct 18 17:44:14 2007 +0200

    EXA: Don't attempt to move in pixmaps that can't be accelerated.
    
    Fixes https://bugs.freedesktop.org/show_bug.cgi?id=12815 .

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 8bbf036..52cc5c4 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -152,6 +152,9 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
     int bpp = pDrawable->bitsPerPixel;
     Bool access_prepared = FALSE;
 
+    if (pExaPixmap->accel_blocked)
+	return FALSE;
+
     /* Don't bother with under 8bpp, XYPixmaps. */
     if (format != ZPixmap || bpp < 8)
 	return FALSE;
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index 7968521..d69526b 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -299,6 +299,9 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate)
     if (pPixmap->drawable.bitsPerPixel < 8)
 	return;
 
+    if (pExaPixmap->accel_blocked)
+	return;
+
     if (pExaPixmap->area == NULL) {
 	pExaPixmap->area =
 	    exaOffscreenAlloc (pScreen, pExaPixmap->fb_size,
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 2ad5304..65e67d8 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -247,10 +247,24 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
     int nbox;
     int dst_off_x, dst_off_y;
     PixmapPtr pSrcPix, pDstPix;
+    ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
     CARD32 pixel;
     CARD16 red, green, blue, alpha;
     ExaMigrationRec pixmaps[1];
 
+    pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
+    pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
+
+    pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+    pDstExaPix = ExaGetPixmapPriv(pDstPix);
+
+    /* Check whether the accelerator can use these pixmaps.
+     */
+    if (pSrcExaPix->accel_blocked || pDstExaPix->accel_blocked)
+    {
+	return -1;
+    }
+
     xDst += pDst->pDrawable->x;
     yDst += pDst->pDrawable->y;
     xSrc += pSrc->pDrawable->x;
@@ -261,12 +275,10 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
 				   width, height))
 	return 1;
 
-    pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
     exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
 
     REGION_TRANSLATE(pScreen, &region, dst_off_x, dst_off_y);
 
-    pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
     pixel = exaGetPixmapFirstPixel (pSrcPix);
 
     pixmaps[0].as_dst = TRUE;
commit 502c757e79a6794473dea8ae5a241e948279f128
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Wed Oct 17 11:42:28 2007 +0800

    Make config file preferred mode override monitor preferred mode.
    
    Add a new even-more-preferred bit to each mode which is used to make config
    file preferences selected instead of the monitor preferred mode.

diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 0365ddd..af98b4f 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -142,6 +142,7 @@ typedef enum {
 # define M_T_DEFAULT 0x10	/* (VESA) default modes */
 # define M_T_USERDEF 0x20	/* One of the modes from the config file */
 # define M_T_DRIVER  0x40	/* Supplied by the driver (EDID, etc) */
+# define M_T_USERPREF 0x80	/* mode preferred by the user config */
 
 /* Video mode */
 typedef struct _DisplayModeRec {
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index f589b5a..0a48d5b 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -711,7 +711,8 @@ xf86DefaultMode (xf86OutputPtr output, int width, int height)
     for (mode = output->probed_modes; mode; mode = mode->next)
     {
 	int	    dpi;
-	int	    preferred = (mode->type & M_T_PREFERRED) != 0;
+	int	    preferred = (((mode->type & M_T_PREFERRED) != 0) +
+				 ((mode->type & M_T_USERPREF) != 0));
 	int	    diff;
 
 	if (xf86ModeWidth (mode, output->initial_rotation) > width ||
@@ -1415,7 +1416,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
 			mode->prev = NULL;
 			output->probed_modes = mode;
 		    }
-		    mode->type |= M_T_PREFERRED;
+		    mode->type |= (M_T_PREFERRED|M_T_USERPREF);
 		}
 		else
 		    mode->type &= ~M_T_PREFERRED;
@@ -1532,6 +1533,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
     int			o, c;
     DisplayModePtr	target_mode = NULL;
+    int			target_preferred = 0;
     Rotation		target_rotation = RR_Rotate_0;
     xf86CrtcPtr		*crtcs;
     DisplayModePtr	*modes;
@@ -1572,43 +1574,34 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
     }
     
     /*
-     * Let outputs with preferred modes drive screen size
+     * User preferred > preferred > other modes
      */
     for (o = 0; o < config->num_output; o++)
     {
-	xf86OutputPtr output = config->output[o];
+	xf86OutputPtr	output = config->output[o];
+	DisplayModePtr	default_mode;
+	int		default_preferred;
 
-	if (enabled[o] &&
-	    xf86OutputHasPreferredMode (output, width, height))
+	if (!enabled[o])
+	    continue;
+	default_mode = xf86DefaultMode (output, width, height);
+	if (!default_mode)
+	    continue;
+	default_preferred = (((default_mode->type & M_T_PREFERRED) != 0) +
+			     ((default_mode->type & M_T_USERPREF) != 0));
+	if (default_preferred > target_preferred || !target_mode)
 	{
-	    target_mode = xf86DefaultMode (output, width, height);
+	    target_mode = default_mode;
+	    target_preferred = default_preferred;
 	    target_rotation = output->initial_rotation;
-	    if (target_mode)
-	    {
-		modes[o] = target_mode;
-		config->compat_output = o;
-		break;
-	    }
-	}
-    }
-    if (!target_mode)
-    {
-	for (o = 0; o < config->num_output; o++)
-	{
-	    xf86OutputPtr output = config->output[o];
-	    if (enabled[o])
-	    {
-		target_mode = xf86DefaultMode (output, width, height);
-		target_rotation = output->initial_rotation;
-		if (target_mode)
-		{
-		    modes[o] = target_mode;
-		    config->compat_output = o;
-		    break;
-		}
-	    }
+	    config->compat_output = o;
 	}
     }
+    if (target_mode)
+	modes[config->compat_output] = target_mode;
+    /*
+     * Fill in other output modes
+     */
     for (o = 0; o < config->num_output; o++)
     {
 	xf86OutputPtr output = config->output[o];
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 9693e12..4c843cd 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -39,6 +39,9 @@
 #ifndef M_T_DRIVER
 #define M_T_DRIVER	0x40
 #endif
+#ifndef M_T_USERPREF
+#define M_T_USERPREF	0x80
+#endif
 #ifndef HARDWARE_CURSOR_ARGB
 #define HARDWARE_CURSOR_ARGB				0x00004000
 #endif
commit 3b73eaf57759dc8e163b221e3eb892019604cca7
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Wed Oct 17 10:50:22 2007 +0800

    KDRIVE_LOCAL_LIBS includes some system libraries, not just internal x server libs

diff --git a/configure.ac b/configure.ac
index 574b0f2..bcaf21e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1887,7 +1887,7 @@ if test "$KDRIVE" = yes; then
     
     KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS $XV_CFLAGS"
 
-    KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $XV_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB"
+    KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB"
     KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.a'
     case $host_os in
 	*linux*)
@@ -1899,7 +1899,7 @@ if test "$KDRIVE" = yes; then
     KDRIVE_LOCAL_LIBS="$TSLIB_LIBS $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB"
     KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS"
     KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB"
-    KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVERLIBS_LIBS"
+    KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVERLIBS_LIBS $XV_LIBS"
 
     # check if we can build Xephyr
     PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"])
diff --git a/hw/kdrive/fbdev/Makefile.am b/hw/kdrive/fbdev/Makefile.am
index 1ce4833..420855b 100644
--- a/hw/kdrive/fbdev/Makefile.am
+++ b/hw/kdrive/fbdev/Makefile.am
@@ -20,7 +20,7 @@ Xfbdev_LDADD = 						\
 
 Xfbdev_DEPENDENCIES =	\
 	libfbdev.a					\
-	@KDRIVE_LOCAL_LIBS@
+	$(KDRIVE_PURE_LIBS)
 
 relink:
 	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)


More information about the xorg-commit mailing list