[Xquartz-changes] xserver: Branch 'server-1.9-apple' - 9 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Fri Apr 30 12:52:24 PDT 2010


Rebased ref, commits from common ancestor:
commit 0e62bdebdff28aa1f7b151eff3ff1230fc9fb121
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sat Mar 27 18:02:14 2010 -0700

    OS: Add some noreturn and printflike compiler attributes where appropriate
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/include/os.h b/include/os.h
index 453ab82..957fc74 100644
--- a/include/os.h
+++ b/include/os.h
@@ -83,6 +83,15 @@ typedef struct _NewClientRec *NewClientPtr;
 #include <stdio.h>
 #include <stdarg.h>
 
+/* XXX Need to check which GCC versions have the format(printf) attribute. */
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#define _printf_attribute(a,b) __attribute((format(__printf__,a,b)))
+#define _noreturn_attribute __attribute((noreturn))
+#else
+#define _printf_attribute(a,b) /**/
+#define _noreturn_attribute /**/
+#endif
+
 #ifdef DDXBEFORERESET
 extern void ddxBeforeReset (void);
 #endif
@@ -226,9 +235,9 @@ extern _X_EXPORT pointer XNFrealloc(pointer /*ptr*/, unsigned long /*amount*/);
 
 extern _X_EXPORT char *Xstrdup(const char *s);
 extern _X_EXPORT char *XNFstrdup(const char *s);
-extern _X_EXPORT char *Xprintf(const char *fmt, ...);
+extern _X_EXPORT char *Xprintf(const char *fmt, ...) _printf_attribute(1,2);
 extern _X_EXPORT char *Xvprintf(const char *fmt, va_list va);
-extern _X_EXPORT char *XNFprintf(const char *fmt, ...);
+extern _X_EXPORT char *XNFprintf(const char *fmt, ...) _printf_attribute(1,2);
 extern _X_EXPORT char *XNFvprintf(const char *fmt, va_list va);
 
 typedef void (*OsSigHandlerPtr)(int /* sig */);
@@ -262,7 +271,7 @@ extern _X_EXPORT void OsBlockSignals (void);
 
 extern _X_EXPORT void OsReleaseSignals (void);
 
-extern _X_EXPORT void OsAbort (void);
+extern _X_EXPORT void OsAbort (void) _noreturn_attribute;
 
 #if !defined(WIN32)
 extern _X_EXPORT int System(char *);
@@ -488,13 +497,6 @@ typedef enum {
     X_UNKNOWN = -1		/* unknown -- this must always be last */
 } MessageType;
 
-/* XXX Need to check which GCC versions have the format(printf) attribute. */
-#if defined(__GNUC__) && (__GNUC__ > 2)
-#define _printf_attribute(a,b) __attribute((format(__printf__,a,b)))
-#else
-#define _printf_attribute(a,b) /**/
-#endif
-
 extern _X_EXPORT const char *LogInit(const char *fname, const char *backup);
 extern _X_EXPORT void LogClose(void);
 extern _X_EXPORT Bool LogSetParameter(LogParameter param, int value);
@@ -509,11 +511,7 @@ extern _X_EXPORT void LogMessage(MessageType type, const char *format, ...)
 extern _X_EXPORT void FreeAuditTimer(void);
 extern _X_EXPORT void AuditF(const char *f, ...) _printf_attribute(1,2);
 extern _X_EXPORT void VAuditF(const char *f, va_list args);
-extern _X_EXPORT void FatalError(const char *f, ...) _printf_attribute(1,2)
-#if defined(__GNUC__) && (__GNUC__ > 2)
-__attribute((noreturn))
-#endif
-;
+extern _X_EXPORT void FatalError(const char *f, ...) _printf_attribute(1,2) _noreturn_attribute;
 
 #ifdef DEBUG
 #define DebugF ErrorF
diff --git a/os/log.c b/os/log.c
index 3773315..99f3528 100644
--- a/os/log.c
+++ b/os/log.c
@@ -402,9 +402,7 @@ LogMessage(MessageType type, const char *format, ...)
     va_end(ap);
 }
 
-#ifdef __GNUC__
-void AbortServer(void) __attribute__((noreturn));
-#endif
+void AbortServer(void) _noreturn_attribute;
 
 void
 AbortServer(void)
commit 2ca12428b6f8a92f114ec83c116c0e371c346929
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Fri Feb 12 19:48:52 2010 -0800

    fb: Revert fb changes that broke XQuartz
    
    http://bugs.freedesktop.org/show_bug.cgi?id=26124
    
    Revert "Fix source pictures getting random transforms after 2d6a8f668342a5190cdf43b5."
    Revert "fb: Adjust transform or composite coordinates for pixman operations"
    
    http://bugs.freedesktop.org/26124
    
    This reverts commit a72c65e9176c51de95db2fdbf4c5d946a4911695.
    This reverts commit a6bd5d2e482a5aa84acb3d4932e2a166d8670ef1.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/fb/fb.h b/fb/fb.h
index 91c91ee..6d15b79 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -2078,11 +2078,8 @@ fbFillRegionSolid (DrawablePtr	pDrawable,
 		   FbBits	xor);
 
 extern _X_EXPORT pixman_image_t *
-image_from_pict (PicturePtr	pict,
-		 Bool		has_clip,
-		 int		*xoff,
-		 int		*yoff);
-
+image_from_pict (PicturePtr pict,
+		 Bool       has_clip);
 extern _X_EXPORT void free_pixman_pict (PicturePtr, pixman_image_t *);
 
 #endif /* _FB_H_ */
diff --git a/fb/fbpict.c b/fb/fbpict.c
index 896d33e..00f9ada 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -156,24 +156,19 @@ fbComposite (CARD8      op,
 	     CARD16     height)
 {
     pixman_image_t *src, *mask, *dest;
-    int src_xoff, src_yoff;
-    int msk_xoff, msk_yoff;
-    int dst_xoff, dst_yoff;
     
     miCompositeSourceValidate (pSrc, xSrc - xDst, ySrc - yDst, width, height);
     if (pMask)
 	miCompositeSourceValidate (pMask, xMask - xDst, yMask - yDst, width, height);
     
-    src = image_from_pict (pSrc, FALSE, &src_xoff, &src_yoff);
-    mask = image_from_pict (pMask, FALSE, &msk_xoff, &msk_yoff);
-    dest = image_from_pict (pDst, TRUE, &dst_xoff, &dst_yoff);
+    src = image_from_pict (pSrc, TRUE);
+    mask = image_from_pict (pMask, TRUE);
+    dest = image_from_pict (pDst, TRUE);
 
     if (src && dest && !(pMask && !mask))
     {
 	pixman_image_composite (op, src, mask, dest,
-				xSrc + src_xoff, ySrc + src_yoff,
-				xMask + msk_xoff, yMask + msk_yoff,
-				xDst + dst_xoff, yDst + dst_yoff,
+				xSrc, ySrc, xMask, yMask, xDst, yDst,
 				width, height);
     }
 
@@ -271,22 +266,22 @@ create_conical_gradient_image (PictGradient *gradient)
 
 static pixman_image_t *
 create_bits_picture (PicturePtr pict,
-		     Bool       has_clip,
-		     int	*xoff,
-		     int	*yoff)
+		     Bool       has_clip)
 {
-    PixmapPtr pixmap;
     FbBits *bits;
     FbStride stride;
-    int bpp;
+    int bpp, xoff, yoff;
     pixman_image_t *image;
     
-    fbGetDrawablePixmap (pict->pDrawable, pixmap, *xoff, *yoff);
-    fbGetPixmapBitsData(pixmap, bits, stride, bpp);
+    fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
+
+    bits = (FbBits*)((CARD8*)bits +
+		     (pict->pDrawable->y + yoff) * stride * sizeof(FbBits) +
+		     (pict->pDrawable->x + xoff) * (bpp / 8));
 
     image = pixman_image_create_bits (
 	pict->format,
-	pixmap->drawable.width, pixmap->drawable.height,
+	pict->pDrawable->width, pict->pDrawable->height,
 	(uint32_t *)bits, stride * sizeof (FbStride));
     
     
@@ -312,52 +307,30 @@ create_bits_picture (PicturePtr pict,
 	if (pict->clientClipType != CT_NONE)
 	    pixman_image_set_has_client_clip (image, TRUE);
 
-	if (*xoff || *yoff)
-	    pixman_region_translate (pict->pCompositeClip, *xoff, *yoff);
+	pixman_region_translate (pict->pCompositeClip, - pict->pDrawable->x, - pict->pDrawable->y);
 
 	pixman_image_set_clip_region (image, pict->pCompositeClip);
 
-	if (*xoff || *yoff)
-	    pixman_region_translate (pict->pCompositeClip, -*xoff, -*yoff);
+	pixman_region_translate (pict->pCompositeClip, pict->pDrawable->x, pict->pDrawable->y);
     }
     
     /* Indexed table */
     if (pict->pFormat->index.devPrivate)
 	pixman_image_set_indexed (image, pict->pFormat->index.devPrivate);
 
-    /* Add in drawable origin to position within the image */
-    *xoff += pict->pDrawable->x;
-    *yoff += pict->pDrawable->y;
-
     return image;
 }
 
 static void
-set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+set_image_properties (pixman_image_t *image, PicturePtr pict)
 {
     pixman_repeat_t repeat;
     pixman_filter_t filter;
     
     if (pict->transform)
     {
-	/* For source images, adjust the transform to account
-	 * for the drawable offset within the pixman image,
-	 * then set the offset to 0 as it will be used
-	 * to compute positions within the transformed image.
-	 */
-	if (!has_clip) {
-	    struct pixman_transform	adjusted;
-
-	    adjusted = *pict->transform;
-	    pixman_transform_translate(&adjusted,
-				       NULL,
-				       pixman_int_to_fixed(*xoff),
-				       pixman_int_to_fixed(*yoff));
-	    pixman_image_set_transform (image, &adjusted);
-	    *xoff = 0;
-	    *yoff = 0;
-	} else
-	    pixman_image_set_transform (image, pict->transform);
+	pixman_image_set_transform (
+	    image, (pixman_transform_t *)pict->transform);
     }
     
     switch (pict->repeatType)
@@ -384,8 +357,7 @@ set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int
     
     if (pict->alphaMap)
     {
-	int alpha_xoff, alpha_yoff;
-	pixman_image_t *alpha_map = image_from_pict (pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff);
+	pixman_image_t *alpha_map = image_from_pict (pict->alphaMap, TRUE);
 	
 	pixman_image_set_alpha_map (
 	    image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
@@ -418,7 +390,8 @@ set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int
 }
 
 pixman_image_t *
-image_from_pict (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+image_from_pict (PicturePtr pict,
+		 Bool has_clip)
 {
     pixman_image_t *image = NULL;
 
@@ -427,7 +400,7 @@ image_from_pict (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
 
     if (pict->pDrawable)
     {
-	image = create_bits_picture (pict, has_clip, xoff, yoff);
+	image = create_bits_picture (pict, has_clip);
     }
     else if (pict->pSourcePict)
     {
@@ -448,11 +421,10 @@ image_from_pict (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
 	    else if (sp->type == SourcePictTypeConical)
 		image = create_conical_gradient_image (gradient);
 	}
-	*xoff = *yoff = 0;
     }
     
     if (image)
-	set_image_properties (image, pict, has_clip, xoff, yoff);
+	set_image_properties (image, pict);
     
     return image;
 }
diff --git a/fb/fbtrap.c b/fb/fbtrap.c
index 9f5c39f..9c55236 100644
--- a/fb/fbtrap.c
+++ b/fb/fbtrap.c
@@ -38,8 +38,7 @@ fbAddTraps (PicturePtr	pPicture,
 	    int		ntrap,
 	    xTrap	*traps)
 {
-    int image_xoff, image_yoff;
-    pixman_image_t *image = image_from_pict (pPicture, FALSE, &image_xoff, &image_yoff);
+    pixman_image_t *image = image_from_pict (pPicture, FALSE);
 
     if (!image)
 	return;
@@ -55,8 +54,7 @@ fbRasterizeTrapezoid (PicturePtr    pPicture,
 		      int	    x_off,
 		      int	    y_off)
 {
-    int	mask_xoff, mask_yoff;
-    pixman_image_t *image = image_from_pict (pPicture, FALSE, &mask_xoff, &mask_yoff);
+    pixman_image_t *image = image_from_pict (pPicture, FALSE);
 
     if (!image)
 	return;
commit de7e2d456d584681a86672144facdb536e11d9d9
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sun Apr 18 01:32:09 2010 -0700

    Fixes it, but not sure what the real fix is...
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/mi/miexpose.c b/mi/miexpose.c
index 6776064..45a4b1e 100644
--- a/mi/miexpose.c
+++ b/mi/miexpose.c
@@ -524,6 +524,7 @@ void RootlessSetPixmapOfAncestors(WindowPtr pWin);
 void RootlessStartDrawing(WindowPtr pWin);
 void RootlessDamageRegion(WindowPtr pWin, RegionPtr prgn);
 Bool IsFramedWindow(WindowPtr pWin);
+#include "../fb/fb.h"
 #endif 
 
 void
@@ -551,6 +552,19 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     Bool	solid = TRUE;
     DrawablePtr	drawable = &pWin->drawable;
 
+#ifdef XQUARTZ_CLIP_DEBUG
+    ErrorF("START %d BS %d (pR = %ld)\n", what, pWin->backgroundState, ParentRelative);
+    ErrorF("      Rgn: %d %d %d %d\n", prgn->extents.x1, prgn->extents.y1,
+	                               prgn->extents.x2 - prgn->extents.x1,
+	                               prgn->extents.y2 - prgn->extents.y1);
+    ErrorF("      Win: %d %d (%d %d) %d %d\n", pWin->origin.x, pWin->origin.y,
+	                                       pWin->winSize.extents.x1, pWin->winSize.extents.y1,
+	                                       pWin->winSize.extents.x2 - pWin->winSize.extents.x1,
+					       pWin->winSize.extents.y2 - pWin->winSize.extents.y1);
+    ErrorF("     Draw: %d %d %d %d\n", pWin->drawable.x, pWin->drawable.y,
+				       pWin->drawable.width, pWin->drawable.height);
+#endif
+
     if(!drawable || drawable->type == UNDRAWABLE_WINDOW)
 	return;
 
@@ -608,6 +622,12 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
 	    return;
 	pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable);
 	drawable = &pixmap->drawable;
+
+#ifdef XQUARTZ_CLIP_DEBUG
+	ErrorF("     Draw: %d %d %d %d\n",
+	       drawable->x, drawable->y, drawable->width, drawable->height);    
+#endif
+	
 #ifdef COMPOSITE
 	draw_x_off = pixmap->screen_x;
 	draw_y_off = pixmap->screen_y;
@@ -670,6 +690,57 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     dixChangeGC (NullClient, pGC, gcmask, NULL, gcval);
     ValidateGC (drawable, pGC);
 
+#ifdef XQUARTZ_CLIP_DEBUG
+    ErrorF("       GC: %d %d %d %d\n",
+	   pGC->pCompositeClip->extents.x1, pGC->pCompositeClip->extents.y1,
+	   pGC->pCompositeClip->extents.x2 - pGC->pCompositeClip->extents.x1,
+	   pGC->pCompositeClip->extents.y2 - pGC->pCompositeClip->extents.y1);
+#endif
+    
+#ifdef XQUARTZ
+    /* Looks like our clipping isn't set right for some reason:
+     * http://xquartz.macosforge.org/trac/ticket/290
+     */
+    if(what == PW_BORDER) {
+
+#if 0
+	if(solid) {
+#if 1
+	    fbFillRegionSolid(&pWin->drawable,
+			      prgn,
+			      0,
+			      fbReplicatePixel(fill.pixel,
+					       pWin->drawable.bitsPerPixel));
+#else
+	    fbFillRegionSolid(drawable,
+			      prgn,
+			      0,
+			      fbReplicatePixel(fill.pixel,
+					       drawable->bitsPerPixel));
+#endif
+	    return;
+	}
+#endif
+    
+	pGC->pCompositeClip->extents.x1 += prgn->extents.x1;
+	pGC->pCompositeClip->extents.y1 += prgn->extents.y1;
+	pGC->pCompositeClip->extents.x2 += prgn->extents.x1;
+	pGC->pCompositeClip->extents.y2 += prgn->extents.y1;
+	
+	if(pGC->pCompositeClip->extents.x2 > drawable->pScreen->width)
+	    pGC->pCompositeClip->extents.x2 = drawable->pScreen->width;
+	if(pGC->pCompositeClip->extents.y2 > drawable->pScreen->height)
+	    pGC->pCompositeClip->extents.y2 = drawable->pScreen->height;
+    }
+#endif
+
+#ifdef XQUARTZ_CLIP_DEBUG
+    ErrorF("       GC: %d %d %d %d\n",
+	   pGC->pCompositeClip->extents.x1, pGC->pCompositeClip->extents.y1,
+	   pGC->pCompositeClip->extents.x2 - pGC->pCompositeClip->extents.x1,
+	   pGC->pCompositeClip->extents.y2 - pGC->pCompositeClip->extents.y1);    
+#endif
+
     numRects = REGION_NUM_RECTS(prgn);
     pbox = REGION_RECTS(prgn);
     for (i= numRects; --i >= 0; pbox++, prect++)
commit ad7788e575a1061957e882c4ae8aa418d0261bb4
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Wed Apr 21 08:40:57 2010 -0700

    mi: move ROOTLESS hunks
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/mi/miexpose.c b/mi/miexpose.c
index 1a7cd0c..6776064 100644
--- a/mi/miexpose.c
+++ b/mi/miexpose.c
@@ -554,21 +554,19 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     if(!drawable || drawable->type == UNDRAWABLE_WINDOW)
 	return;
 
-#ifdef ROOTLESS
-    if(IsFramedWindow(pWin)) {
-        RootlessStartDrawing(pWin);
-        RootlessDamageRegion(pWin, prgn);
-    
-        if(pWin->backgroundState == ParentRelative) {
-            if((what == PW_BACKGROUND) || 
-               (what == PW_BORDER && !pWin->borderIsPixel))
-                RootlessSetPixmapOfAncestors(pWin);
-        }
-    }
-#endif
-    
     if (what == PW_BACKGROUND)
     {
+#ifdef ROOTLESS
+	if(IsFramedWindow(pWin)) {
+	    RootlessStartDrawing(pWin);
+	    RootlessDamageRegion(pWin, prgn);
+	    
+	    if(pWin->backgroundState == ParentRelative) {
+		RootlessSetPixmapOfAncestors(pWin);
+	    }
+	}
+#endif
+
 	while (pWin->backgroundState == ParentRelative)
 	    pWin = pWin->parent;
 
@@ -590,6 +588,18 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     {
 	PixmapPtr   pixmap;
 
+#ifdef ROOTLESS
+	if(IsFramedWindow(pWin)) {
+	    RootlessStartDrawing(pWin);
+	    RootlessDamageRegion(pWin, prgn);
+	    
+	    if(!pWin->borderIsPixel &&
+	       pWin->backgroundState == ParentRelative) {
+		RootlessSetPixmapOfAncestors(pWin);
+	    }
+	}
+#endif
+
 	tile_x_off = drawable->x;
 	tile_y_off = drawable->y;
 	
commit f7753c302e29ea866968e91d339e4b3e7e1a0e1f
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Tue Apr 27 13:14:47 2010 -0700

    XQuartz GLX: Change around includes for better compatability with different OS versions
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index 70558ed..ad9ebbd 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -42,6 +42,8 @@
 #define GL_GLEXT_WUNDEF_SUPPORT
 
 #include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
 #include <OpenGL/CGLContext.h>
 
 /* These next few GL_EXT pre-processing blocks are to explicitly define 
diff --git a/hw/xquartz/GL/visualConfigs.c b/hw/xquartz/GL/visualConfigs.c
index bef27f0..cecc902 100644
--- a/hw/xquartz/GL/visualConfigs.c
+++ b/hw/xquartz/GL/visualConfigs.c
@@ -35,9 +35,10 @@
 #include "dri.h"
 
 #include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
 #include <OpenGL/CGLContext.h>
 
-#include <GL/gl.h>
 #include <GL/glxproto.h>
 #include <windowstr.h>
 #include <resource.h>
commit 1483cd4af89a636b3cb472851307db887a34c5d3
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Wed Apr 21 08:38:53 2010 -0700

    mi: Add some sanity checking to miPaintWindow
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/mi/miexpose.c b/mi/miexpose.c
index 1c9c3a4..1a7cd0c 100644
--- a/mi/miexpose.c
+++ b/mi/miexpose.c
@@ -551,6 +551,9 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     Bool	solid = TRUE;
     DrawablePtr	drawable = &pWin->drawable;
 
+    if(!drawable || drawable->type == UNDRAWABLE_WINDOW)
+	return;
+
 #ifdef ROOTLESS
     if(IsFramedWindow(pWin)) {
         RootlessStartDrawing(pWin);
commit 08526064426cc0b37d25ca7fc036026e70b7ab08
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sun Apr 18 01:22:27 2010 -0700

    rootless: Remove an unneeded comment
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c
index e78e2c8..55c7b96 100644
--- a/miext/rootless/rootlessWindow.c
+++ b/miext/rootless/rootlessWindow.c
@@ -1553,10 +1553,6 @@ RootlessDisableRoot (ScreenPtr pScreen)
 	return;
            
     RootlessDestroyFrame (pRoot, winRec);
-    /* 
-     * gstaplin: I fixed the usage of this DeleteProperty so that it would compile.
-     * QUESTION: Where is this xa_native_window_id set?
-     */
     DeleteProperty (serverClient, pRoot, xa_native_window_id ());
 }
 
commit 70e09f27ff4d8c9b221473bfa0bef602466a55ac
Author: Oliver McFadden <oliver.mcfadden at nokia.com>
Date:   Thu Apr 22 10:29:44 2010 +0300

    x-list.c: null-returning function malloc() was called without checking
    
    Signed-off-by: Oliver McFadden <oliver.mcfadden at nokia.com>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/xpr/x-list.c b/hw/xquartz/xpr/x-list.c
index 3596dd3..77c9309 100644
--- a/hw/xquartz/xpr/x-list.c
+++ b/hw/xquartz/xpr/x-list.c
@@ -97,6 +97,7 @@ X_PFX (list_prepend) (x_list *lst, void *data)
         int i;
 
         b = malloc (sizeof (x_list_block));
+        assert(b != NULL);
 
         for (i = 0; i < NODES_PER_BLOCK - 1; i++)
             b->l[i].next = &(b->l[i+1]);
commit 81a081c1f0cb55df94cb10495aa7ad71cd5a9afb
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Sat Nov 7 19:28:18 2009 +0000

    Cygwin/X: AIGLX using native WGL
    
    A rewrite of the XWin DDX AIGLX code to actually make it do something useful again
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/configure.ac b/configure.ac
index b48d3a9..65d18c4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2220,6 +2220,7 @@ hw/dmx/Makefile
 hw/vfb/Makefile
 hw/xnest/Makefile
 hw/xwin/Makefile
+hw/xwin/glx/Makefile
 hw/xquartz/Makefile
 hw/xquartz/GL/Makefile
 hw/xquartz/bundle/Makefile
diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index fd286de..ce3e7ee 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -99,8 +99,8 @@ extern HMODULE			g_hmodCommonControls;
 extern FARPROC			g_fpTrackMouseEvent;
 extern Bool			g_fNoHelpMessageBox;                     
 extern Bool			g_fSilentDupError;                     
-  
-  
+extern Bool                     g_fNativeGl;
+
 /*
  * Function prototypes
  */
@@ -187,6 +187,17 @@ winClipboardShutdown (void)
 }
 #endif
 
+void
+ddxPushProviders(void)
+{
+#ifdef XWIN_GLX_WINDOWS
+  if (g_fNativeGl)
+    {
+      /* install the native GL provider */
+      glxWinPushNativeProvider();
+    }
+#endif
+}
 
 #if defined(DDXBEFORERESET)
 /*
@@ -890,6 +901,11 @@ winUseMsg (void)
   ErrorF ("-[no]unixkill\n"
           "\tCtrl+Alt+Backspace exits the X Server.\n");
 
+#ifdef XWIN_GLX_WINDOWS
+  ErrorF ("-[no]wgl\n"
+	  "\tEnable the GLX extension to use the native Windows WGL interface for accelerated OpenGL\n");
+#endif
+
   ErrorF ("-[no]winkill\n"
           "\tAlt+F4 exits the X Server.\n");
 
diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am
index 89b021b..7544cd3 100644
--- a/hw/xwin/Makefile.am
+++ b/hw/xwin/Makefile.am
@@ -13,9 +13,10 @@ DEFS_CLIPBOARD = -DXWIN_CLIPBOARD
 endif
 
 if XWIN_GLX_WINDOWS
-SRCS_GLX_WINDOWS = \
-	winpriv.c
+GLX_DIR = glx
 DEFS_GLX_WINDOWS = -DXWIN_GLX_WINDOWS
+XWIN_GLX_LIBS = $(top_builddir)/hw/xwin/glx/libXwinGLX.la
+XWIN_GLX_LINK_FLAGS = -lopengl32
 endif
 
 if XWIN_MULTIWINDOW
@@ -125,7 +126,6 @@ SRCS =	InitInput.c \
 	$(top_srcdir)/mi/miinitext.c \
 	$(top_srcdir)/fb/fbcmap_mi.c \
 	$(SRCS_CLIPBOARD) \
-	$(SRCS_GLX_WINDOWS) \
 	$(SRCS_MULTIWINDOW) \
 	$(SRCS_MULTIWINDOWEXTWM) \
 	$(SRCS_NATIVEGDI) \
@@ -146,14 +146,13 @@ XWin_SOURCES = $(SRCS)
 
 INCLUDES = -I$(top_srcdir)/miext/rootless
 
-XWin_DEPENDENCIES = $(XWIN_LIBS)
-XWin_LDADD = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS)
+XWin_DEPENDENCIES = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS)
+XWin_LDADD = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS)
+XWin_LDFLAGS = -mwindows -static
 
 .rc.o:
 	$(AM_V_GEN)$(WINDRES) --use-temp-file -i $< --input-format=rc -o $@ -O coff -I $(top_builddir)/include
 
-XWin_LDFLAGS = -mwindows -static
-
 winprefsyacc.h: winprefsyacc.c
 winprefslex.c: winprefslex.l winprefsyacc.c winprefsyacc.h
 
@@ -164,12 +163,8 @@ AM_YFLAGS = -d
 AM_LFLAGS = -i
 AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \
             $(XWINMODULES_CFLAGS) \
-            -DXFree86Server
-
-GLX_EXTRAS = \
-	glx/glwindows.h \
-	glx/glwrap.c \
-	glx/indirect.c
+            -DXFree86Server \
+            -I$(top_srcdir)
 
 MAN_SRCS = XWin.man.pre XWinrc.man.pre
 
@@ -198,7 +193,6 @@ install-exec-hook:
 	(cd $(DESTDIR)$(bindir) && rm -f X && $(LN_S) XWin$(EXEEXT) X)
 
 EXTRA_DIST = \
-	$(GLX_EXTRAS) \
 	$(MAN_SRCS) \
 	$(xwinconfig_DATA) \
 	X.ico \
@@ -226,3 +220,6 @@ EXTRA_DIST = \
 
 relink:
 	$(AM_V_at)rm -f XWin$(EXEEXT) && $(MAKE) XWin$(EXEEXT)
+
+SUBDIRS = $(GLX_DIR) .
+DIST_SUBDIRS = glx .
diff --git a/hw/xwin/glx/.gitignore b/hw/xwin/glx/.gitignore
new file mode 100644
index 0000000..e7c7617
--- /dev/null
+++ b/hw/xwin/glx/.gitignore
@@ -0,0 +1,8 @@
+# ignore downloaded and generated files
+generated_gl_wrappers.c
+generated_wgl_wrappers.c
+gl.spec
+gl.tm
+wgl.tm
+wglext.spec
+wglext.h
diff --git a/hw/xwin/glx/Makefile.am b/hw/xwin/glx/Makefile.am
new file mode 100644
index 0000000..aadd442
--- /dev/null
+++ b/hw/xwin/glx/Makefile.am
@@ -0,0 +1,59 @@
+noinst_LTLIBRARIES = libXwinGLX.la
+
+libXwinGLX_la_SOURCES = \
+	winpriv.c \
+	glwindows.h \
+	glwrap.c \
+	indirect.c \
+	wgl_ext_api.c
+
+if XWIN_MULTIWINDOW
+DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW
+endif
+
+if XWIN_MULTIWINDOWEXTWM
+DEFS_MULTIWINDOWEXTWM = -DXWIN_MULTIWINDOWEXTWM
+endif
+
+DEFS =  $(DEFS_MULTIWINDOW) $(DEFS_MULTIWINDOWEXTWM)
+
+INCLUDES = -I$(top_srcdir)/miext/rootless
+
+AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \
+            $(XWINMODULES_CFLAGS) \
+            -I$(top_srcdir) \
+            -I$(top_srcdir)/hw/xwin/
+
+glwrap.c: generated_gl_wrappers.c
+wgl_ext_api.c: generated_wgl_wrappers.c wglext.h
+wgl_ext_api.h: wglext.h
+indirect.c: wgl_ext_api.h
+
+SPEC_FILES = gl.spec gl.tm wglext.spec wgl.tm
+
+gl.spec:
+	wget http://www.opengl.org/registry/api/gl.spec
+
+gl.tm:
+	wget http://www.opengl.org/registry/api/gl.tm
+
+wglext.spec:
+	wget http://www.opengl.org/registry/api/wglext.spec
+
+wgl.tm:
+	wget http://www.opengl.org/registry/api/wgl.tm
+
+generated_gl_wrappers.c: gen_gl_wrappers.py gl.spec gl.tm
+	./gen_gl_wrappers.py --spec=gl.spec --typemap=gl.tm --dispatch-header=$(top_srcdir)/glx/dispatch.h --staticwrappers >generated_gl_wrappers.c
+
+generated_wgl_wrappers.c: gen_gl_wrappers.py wglext.spec wgl.tm
+	./gen_gl_wrappers.py --spec=wglext.spec --typemap=wgl.tm --prefix=wgl --preresolve >generated_wgl_wrappers.c
+
+wglext.h:
+	wget http://www.opengl.org/registry/api/wglext.h
+
+BUILT_SOURCES = generated_gl_wrappers.c generated_wgl_wrappers.c
+CLEANFILES = $(BUILT_SOURCES)
+DISTCLEANFILES = $(SPEC_FILES) wglext.h
+
+EXTRA_DIST = gen_gl_wrappers.py $(SPEC_FILES) wglext.h
diff --git a/hw/xwin/glx/gen_gl_wrappers.py b/hw/xwin/glx/gen_gl_wrappers.py
new file mode 100755
index 0000000..d7fe98d
--- /dev/null
+++ b/hw/xwin/glx/gen_gl_wrappers.py
@@ -0,0 +1,319 @@
+#!/usr/bin/python
+#
+# Comedy python script to generate cdecl to stdcall wrappers for GL functions
+#
+# This is designed to operate on OpenGL spec files from
+# http://www.opengl.org/registry/api/
+#
+#
+# Copyright (c) Jon TURNEY 2009
+#
+# 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, sublicense,
+# 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
+# THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+#
+# Except as contained in this notice, the name(s) of the above copyright
+# holders shall not be used in advertising or otherwise to promote the sale,
+# use or other dealings in this Software without prior written authorization.
+#
+
+import sys
+import re
+import getopt
+
+dispatchheader = ''
+prefix = 'gl'
+preresolve = False
+staticwrappers = False
+
+opts, args = getopt.getopt(sys.argv[1:], "", ['spec=', 'typemap=', 'dispatch-header=', 'prefix=', 'preresolve', 'staticwrappers' ])
+
+for o,a in opts:
+        if o == '--typemap' :
+                typemapfile = a
+        elif o == '--dispatch-header' :
+                dispatchheader = a
+        elif o == '--spec' :
+                specfile = a
+        elif o == '--prefix' :
+                prefix = a
+        elif o == '--preresolve' :
+                preresolve = True
+        elif o == '--staticwrappers' :
+                staticwrappers = True
+
+#
+# look for all the SET_ macros in dispatch.h, this is the set of functions
+# we need to generate
+#
+
+dispatch = {}
+
+if dispatchheader :
+        fh = open(dispatchheader)
+        dispatchh = fh.readlines()
+
+        dispatch_regex = re.compile(r'#define\sSET_(\S*)\(')
+
+        for line in dispatchh :
+                line = line.strip()
+                m1 = dispatch_regex.search(line)
+
+                if m1 :
+                        dispatch[m1.group(1)] = 1
+
+        del dispatch['by_offset']
+
+#
+# read the typemap .tm file
+#
+
+typemap = {}
+
+fh = open(typemapfile)
+tm = fh.readlines()
+
+typemap_regex = re.compile(r'#define\sSET_(\S*)\(')
+
+for line in tm :
+        # ignore everything after a '#' as a comment
+        hash = line.find('#')
+        if hash != -1 :
+                line = line[:hash-1]
+
+        # ignore blank lines
+        if line.startswith('#') or len(line) == 0 :
+                continue
+
+        l = line.split(',')
+        typemap[l[0]] = l[3].strip()
+
+# interestingly, * is not a C type
+if typemap['void'] == '*' :
+        typemap['void'] = 'void'
+
+#
+# crudely parse the .spec file
+#
+
+r1 = re.compile(r'\t(\S*)\s+(\S*.*)')
+r2 = re.compile(r'(.*)\((.*)\)')
+r3 = re.compile(r'glWindowPos.*MESA')
+r4 = re.compile(r'gl.*Program(s|)NV')
+r5 = re.compile(r'glGetVertexAttribfvNV')
+
+wrappers = {}
+
+fh = open(specfile)
+glspec = fh.readlines()
+param_count = 0
+
+for line in glspec :
+        line = line.rstrip()
+
+        # ignore everything after a '#' as a comment
+        hash = line.find('#')
+        if hash != -1 :
+                line = line[:hash-1]
+
+        # ignore blank lines
+        if line.startswith('#') or len(line) == 0 :
+                continue
+
+        # lines containing ':' aren't intersting to us
+        if line.count(':') != 0 :
+                continue
+
+        # attributes of each function follow the name, indented by a tab
+        if not line.startswith('\t') :
+                m1 = r2.search(line)
+                if m1 :
+                        function = m1.group(1)
+                        arglist_use = m1.group(2)
+                        wrappers[function] = {}
+
+                        # near and far might be reserved words or macros so can't be used as formal parameter names
+                        arglist_use = arglist_use.replace('near','zNear')
+                        arglist_use = arglist_use.replace('far','zFar')
+
+                        wrappers[function]['arglist_use'] = arglist_use
+                        param_count = 0
+        else :
+                m1 = r1.search(line)
+                if m1 :
+                        attribute = m1.group(1)
+                        value = m1.group(2)
+
+                        # make param attributes unique and ordered
+                        if attribute == 'param' :
+                                attribute = 'param' + '%02d' % param_count
+                                param_count += 1
+
+                        wrappers[function][attribute] = value
+
+#
+# now emit code
+#
+
+print '/* Automatically generated by ' + sys.argv[0] + ' DO NOT EDIT */'
+print '/* from ' + specfile + ' and typemap ' + typemapfile + ' */'
+print ''
+
+#
+# if required, emit code for non-lazy function resolving
+#
+
+if preresolve :
+        for w in sorted(wrappers.keys()) :
+                funcname = prefix + w
+                print 'RESOLVE_DECL(PFN' + funcname.upper() + 'PROC);'
+
+        print ''
+        print 'void ' + prefix + 'ResolveExtensionProcs(void)'
+        print '{'
+
+        for w in sorted(wrappers.keys()) :
+                funcname = prefix + w
+                print '  PRERESOLVE(PFN' + funcname.upper() + 'PROC, "' + funcname + '");'
+
+        print '}\n'
+
+#
+# now emit the wrappers
+# for GL 1.0 and 1.1 functions, generate stdcall wrappers which call the function directly
+# for GL 1.2+ functions, generate wrappers which use wglGetProcAddress()
+#
+
+for w in sorted(wrappers.keys()) :
+
+        funcname = prefix + w
+        returntype = wrappers[w]['return']
+        if returntype != 'void' :
+                returntype = typemap[returntype]
+
+        # Avoid generating wrappers which aren't referenced by the dispatch table
+        if dispatchheader and not dispatch.has_key(w) :
+                print '/* No wrapper for ' + funcname + ', not in dispatch table */'
+                continue
+
+        # manufacture arglist
+        # if no param attributes were found, it should be 'void'
+        al = []
+        for k in sorted(wrappers[w].keys()) :
+                if k.startswith('param') :
+                        l = wrappers[w][k].split()
+
+                        # near and far might be reserved words or macros so can't be used as formal parameter names
+                        l[0] = l[0].replace('near','zNear')
+                        l[0] = l[0].replace('far','zFar')
+
+                        if l[2] == 'in' :
+                                if l[3] == 'array' :
+                                        arg = 'const ' + typemap[l[1]] + ' *' + l[0]
+                                else :
+                                        arg = typemap[l[1]] + ' ' + l[0]
+                        elif l[2] == 'out' :
+                                arg = typemap[l[1]] + ' *' + l[0]
+
+                        al.append(arg)
+
+        if len(al) == 0 :
+                arglist = 'void'
+        else:
+                arglist  = ', '.join(al)
+
+        if wrappers[w]['category'].startswith('VERSION_1_0') or wrappers[w]['category'].startswith('VERSION_1_1') :
+                if staticwrappers :
+                        print 'static',
+                print returntype + ' ' + funcname + 'Wrapper(' + arglist + ')'
+                print '{'
+                print '  if (glxWinDebugSettings.enable' + prefix.upper() + 'callTrace) ErrorF("'+ funcname + '\\n");'
+                print '  glWinDirectProcCalls++;'
+                if returntype.lower() == 'void' :
+                        print '  ' +  funcname + '(',
+                else :
+                        print ' /* returntype was ' + returntype.lower() + '*/'
+                        print '  return ' +  funcname + '(',
+
+                if arglist != 'void' :
+                        print wrappers[w]['arglist_use'],
+
+                print ');'
+                print "}\n"
+        else:
+                if staticwrappers :
+                        print 'static',
+                print returntype + ' ' + funcname + 'Wrapper(' + arglist + ')'
+                print '{'
+
+                stringname = funcname
+
+#
+# special case: Windows OpenGL implementations are far more likely to have GL_ARB_window_pos than GL_MESA_window_pos,
+# so arrange for the wrapper to use the ARB strings to find functions...
+#
+
+                m2 = r3.search(funcname)
+                if m2 :
+                        stringname = stringname.replace('MESA','ARB')
+
+#
+# special case: likewise, implementations are more likely to have GL_ARB_vertex_program than GL_NV_vertex_program,
+# especially if they are not NV implementations, so arrange for the wrapper to use ARB strings to find functions
+#
+
+                m3 = r4.search(funcname)
+                if m3 :
+                        stringname = stringname.replace('NV','ARB')
+                m4 = r5.search(funcname)
+                if m4 :
+                        stringname = stringname.replace('NV','ARB')
+
+                pfntypename = 'PFN' + funcname.upper() + 'PROC'
+
+                if returntype.lower() == 'void' :
+                        print '  RESOLVE(' + pfntypename + ', "' + stringname + '");'
+                        print '  if (glxWinDebugSettings.enable' + prefix.upper() + 'callTrace) ErrorF("'+ funcname + '\\n");'
+                        print '  RESOLVED_PROC(' + pfntypename + ')(',
+                else :
+                        print '  RESOLVE_RET(' + pfntypename + ', "' + stringname + '", FALSE);'
+                        print '  if (glxWinDebugSettings.enable' + prefix.upper() + 'callTrace) ErrorF("'+ funcname + '\\n");'
+                        print '  return RESOLVED_PROC(' + pfntypename + ')(',
+
+                if arglist != 'void' :
+                        print wrappers[w]['arglist_use'],
+
+                print ');'
+                print "}\n"
+
+
+# generate function to setup the dispatch table, which sets each
+# dispatch table entry to point to it's wrapper function
+# (assuming we were able to make one)
+
+if dispatchheader :
+        print 'void glWinSetupDispatchTable(void)'
+        print '{'
+        print '  struct _glapi_table *disp = _glapi_get_dispatch();'
+
+        for d in sorted(dispatch.keys()) :
+                if wrappers.has_key(d) :
+                        print '  SET_'+ d + '(disp, ' + prefix + d + 'Wrapper);'
+                else :
+                        print '#warning  No wrapper for ' + prefix + d + ' !'
+
+        print '}'
diff --git a/hw/xwin/glx/glwindows.h b/hw/xwin/glx/glwindows.h
index 74e81f2..cc3f2e6 100644
--- a/hw/xwin/glx/glwindows.h
+++ b/hw/xwin/glx/glwindows.h
@@ -1,64 +1,58 @@
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/Xwindows.h>
-#include <GL/gl.h>
-#include <GL/glext.h>
+/*
+ * File: glwindows.h
+ * Purpose: Header for GLX implementation using native Windows OpenGL library
+ *
+ * Authors: Alexander Gottwald
+ *          Jon TURNEY
+ *
+ * Copyright (c) Jon TURNEY 2009
+ * Copyright (c) Alexander Gottwald 2004
+ *
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+ */
 
-#include <glxserver.h>
-#include <glxext.h>
 
-#include <windowstr.h>
-#include <resource.h>
-#include <GL/glxint.h>
-#include <GL/glxtokens.h>
-#include <scrnintstr.h>
-#include <glxserver.h>
-#include <glxscreens.h>
-#include <glxdrawable.h>
-#include <glxcontext.h>
-#include <glxext.h>
-#include <glxutil.h>
-#include <glxscreens.h>
-#include <GL/internal/glcore.h>
-#include <stdlib.h>
-
-
-typedef struct {
-    unsigned enableDebug : 1;
-    unsigned enableTrace : 1;
-    unsigned dumpPFD : 1;
-    unsigned dumpHWND : 1;
-    unsigned dumpDC : 1;
-} glWinDebugSettingsRec, *glWinDebugSettingsPtr;
-extern glWinDebugSettingsRec glWinDebugSettings;
+#include <GL/gl.h>
 
 typedef struct {
-    int num_vis;
-    __GLcontextModes *modes;
-    void **priv;
-
-    /* wrapped screen functions */
-    RealizeWindowProcPtr RealizeWindow;
-    UnrealizeWindowProcPtr UnrealizeWindow;
-    CopyWindowProcPtr CopyWindow;
-} glWinScreenRec;
-
-extern glWinScreenRec glWinScreens[MAXSCREENS];
-
-#define glWinGetScreenPriv(pScreen)  &glWinScreens[pScreen->myNum]
-#define glWinScreenPriv(pScreen) glWinScreenRec *pScreenPriv = glWinGetScreenPriv(pScreen);
+    unsigned int enableDebug : 1;
+    unsigned int enableTrace : 1;
+    unsigned int dumpPFD : 1;
+    unsigned int dumpHWND : 1;
+    unsigned int dumpDC : 1;
+    unsigned int enableGLcallTrace : 1;
+    unsigned int enableWGLcallTrace :1;
+} glxWinDebugSettingsRec;
+
+extern glxWinDebugSettingsRec glxWinDebugSettings;
+
+void glWinCallDelta(void);
+void glxWinPushNativeProvider(void);
+const GLubyte* glGetStringWrapperNonstatic(GLenum name);
+void glAddSwapHintRectWINWrapperNonstatic(GLint x, GLint y, GLsizei width, GLsizei height);
+void glWinSetupDispatchTable(void);
 
 #if 1
-#define GLWIN_TRACE() if (glWinDebugSettings.enableTrace) ErrorF("%s:%d: Trace\n", __FUNCTION__, __LINE__ )
-#define GLWIN_TRACE_MSG(msg, args...) if (glWinDebugSettings.enableTrace) ErrorF("%s:%d: " msg, __FUNCTION__, __LINE__, ##args )
-#define GLWIN_DEBUG_MSG(msg, args...) if (glWinDebugSettings.enableDebug) ErrorF("%s:%d: " msg, __FUNCTION__, __LINE__, ##args )
-#define GLWIN_DEBUG_MSG2(msg, args...) if (glWinDebugSettings.enableDebug) ErrorF(msg, ##args )
+#define GLWIN_TRACE_MSG(msg, args...) if (glxWinDebugSettings.enableTrace) ErrorF(msg " [%s:%d]\n" , ##args , __FUNCTION__, __LINE__ )
+#define GLWIN_DEBUG_MSG(msg, args...) if (glxWinDebugSettings.enableDebug) ErrorF(msg " [%s:%d]\n" , ##args , __FUNCTION__, __LINE__ )
 #else
-#define GLWIN_TRACE()
 #define GLWIN_TRACE_MSG(a, ...)
 #define GLWIN_DEBUG_MSG(a, ...)
-#define GLWIN_DEBUG_MSG2(a, ...)
 #endif
-
diff --git a/hw/xwin/glx/glwrap.c b/hw/xwin/glx/glwrap.c
index f0b38b2..5190d36 100755
--- a/hw/xwin/glx/glwrap.c
+++ b/hw/xwin/glx/glwrap.c
@@ -1,583 +1,148 @@
 /*
- * GLX implementation that uses Win32's OpenGL
- * Wrapper functions for Win32's OpenGL
+ * File: glwrap.c
+ * Purpose: Wrapper functions for Win32 OpenGL functions
  *
  * Authors: Alexander Gottwald
+ *          Jon TURNEY
+ *
+ * Copyright (c) Jon TURNEY 2009
+ * Copyright (c) Alexander Gottwald 2004
+ *
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
  */
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
+// define USE_OPENGL32 makes gl.h declare gl*() function prototypes with stdcall linkage,
+// so our generated wrappers will correctly link with the functions in opengl32.dll
+#define USE_OPENGL32
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
 #endif
 
 #include <X11/Xwindows.h>
 #include <GL/gl.h>
 #include <GL/glext.h>
-#include <glxserver.h>
-#include <glxext.h>
-
-#define RESOLVE_RET(procname, symbol, retval) \
-    static Bool init = TRUE; \
-    static procname proc = NULL; \
-    if (init) { \
-        proc = (procname)wglGetProcAddress(symbol); \
-        init = FALSE; \
-        if (proc == NULL) { \
-            ErrorF("glwrap: Can't resolve \"%s\"\n", symbol); \
-        } else \
-            ErrorF("glwrap: resolved \"%s\"\n", symbol); \
-    } \
-    if (proc == NULL) { \
-        __glXErrorCallBack(NULL, 0); \
-        return retval; \
+#include <glx/glxserver.h>
+#include <glx/glxext.h>
+#include <glx/glapi.h>
+#include <glx/dispatch.h>
+#include <glwindows.h>
+
+static unsigned int glWinIndirectProcCalls = 0;
+static unsigned int glWinDirectProcCalls = 0;
+
+void
+glWinCallDelta(void)
+{
+  static unsigned int glWinIndirectProcCallsLast = 0;
+  static unsigned int glWinDirectProcCallsLast = 0;
+  if ((glWinIndirectProcCalls != glWinIndirectProcCallsLast) ||
+      (glWinDirectProcCalls != glWinDirectProcCallsLast))
+    {
+      if (glxWinDebugSettings.enableTrace)
+        {
+          ErrorF("after %d direct and %d indirect GL calls\n",
+                 glWinDirectProcCalls - glWinDirectProcCallsLast,
+                 glWinIndirectProcCalls - glWinIndirectProcCallsLast);
+        }
+      glWinDirectProcCallsLast = glWinDirectProcCalls;
+      glWinIndirectProcCallsLast = glWinIndirectProcCalls;
     }
-#define RESOLVE(procname, symbol) RESOLVE_RET(procname, symbol,)
-        
-        
-/*
- * GL_ARB_imaging
- */
-
-
-GLAPI void GLAPIENTRY glColorTable( GLenum target, GLenum internalformat,
-                                    GLsizei width, GLenum format,
-                                    GLenum type, const GLvoid *table )
-{
-    RESOLVE(PFNGLCOLORTABLEPROC, "glColorTable");
-    proc(target, internalformat, width, format, type, table);
-}
-
-GLAPI void GLAPIENTRY glColorSubTable( GLenum target,
-                                       GLsizei start, GLsizei count,
-                                       GLenum format, GLenum type,
-                                       const GLvoid *data )
-{
-    RESOLVE(PFNGLCOLORSUBTABLEPROC, "glColorSubTable");
-    proc(target, start, count, format, type, data);
-}
-
-GLAPI void GLAPIENTRY glColorTableParameteriv(GLenum target, GLenum pname,
-                                              const GLint *params)
-{
-    RESOLVE(PFNGLCOLORTABLEPARAMETERIVPROC, "glColorTableParameteriv");
-    proc(target, pname, params);
-}
-
-GLAPI void GLAPIENTRY glColorTableParameterfv(GLenum target, GLenum pname,
-                                              const GLfloat *params)
-{
-    RESOLVE(PFNGLCOLORTABLEPARAMETERFVPROC, "glColorTableParameterfv");
-    proc(target, pname, params);
-}
-
-GLAPI void GLAPIENTRY glCopyColorSubTable( GLenum target, GLsizei start,
-                                           GLint x, GLint y, GLsizei width )
-{
-    RESOLVE(PFNGLCOPYCOLORSUBTABLEPROC, "glCopyColorSubTable");
-    proc(target, start, x, y, width);
-}
-
-GLAPI void GLAPIENTRY glCopyColorTable( GLenum target, GLenum internalformat,
-                                        GLint x, GLint y, GLsizei width )
-{
-    RESOLVE(PFNGLCOPYCOLORTABLEPROC, "glCopyColorTable");
-    proc(target, internalformat, x, y, width);
-}
-
-
-GLAPI void GLAPIENTRY glGetColorTable( GLenum target, GLenum format,
-                                       GLenum type, GLvoid *table )
-{
-    RESOLVE(PFNGLGETCOLORTABLEPROC, "glGetColorTable");
-    proc(target, format, type, table);
-}
-
-GLAPI void GLAPIENTRY glGetColorTableParameterfv( GLenum target, GLenum pname,
-                                                  GLfloat *params )
-{
-    RESOLVE(PFNGLGETCOLORTABLEPARAMETERFVPROC, "glGetColorTableParameterfv");
-    proc(target, pname, params);
-}
-
-GLAPI void GLAPIENTRY glGetColorTableParameteriv( GLenum target, GLenum pname,
-                                                  GLint *params )
-{
-    RESOLVE(PFNGLGETCOLORTABLEPARAMETERIVPROC, "glGetColorTableParameteriv");
-    proc(target, pname, params);
-}
-
-GLAPI void GLAPIENTRY glBlendEquation( GLenum mode )
-{
-    RESOLVE(PFNGLBLENDEQUATIONPROC, "glBlendEquation");
-    proc(mode);
-}
-
-GLAPI void GLAPIENTRY glBlendColor( GLclampf red, GLclampf green,
-                                    GLclampf blue, GLclampf alpha )
-{
-    RESOLVE(PFNGLBLENDCOLORPROC, "glBlendColor");
-    proc(red, green, blue, alpha);
-}
-
-GLAPI void GLAPIENTRY glHistogram( GLenum target, GLsizei width,
-				   GLenum internalformat, GLboolean sink )
-{
-    RESOLVE(PFNGLHISTOGRAMPROC, "glHistogram");
-    proc(target, width, internalformat, sink);
-}
-
-GLAPI void GLAPIENTRY glResetHistogram( GLenum target )
-{
-    RESOLVE(PFNGLRESETHISTOGRAMPROC, "glResetHistogram");
-    proc(target);
-}
-
-GLAPI void GLAPIENTRY glGetHistogram( GLenum target, GLboolean reset,
-				      GLenum format, GLenum type,
-				      GLvoid *values )
-{
-    RESOLVE(PFNGLGETHISTOGRAMPROC, "glGetHistogram");
-    proc(target, reset, format, type, values);
-};
-
-GLAPI void GLAPIENTRY glGetHistogramParameterfv( GLenum target, GLenum pname,
-						 GLfloat *params )
-{
-    RESOLVE(PFNGLGETHISTOGRAMPARAMETERFVPROC, "glGetHistogramParameterfv");
-    proc(target, pname, params);
-}
-
-GLAPI void GLAPIENTRY glGetHistogramParameteriv( GLenum target, GLenum pname,
-						 GLint *params )
-{
-    RESOLVE(PFNGLGETHISTOGRAMPARAMETERIVPROC, "glGetHistogramParameteriv");
-    proc(target, pname, params);
-}
-
-GLAPI void GLAPIENTRY glMinmax( GLenum target, GLenum internalformat,
-				GLboolean sink )
-{
-    RESOLVE(PFNGLMINMAXPROC, "glMinmax");
-    proc(target, internalformat, sink);
-}
-
-GLAPI void GLAPIENTRY glResetMinmax( GLenum target )
-{
-    RESOLVE(PFNGLRESETMINMAXPROC, "glResetMinmax");
-    proc(target);
-}
-
-GLAPI void GLAPIENTRY glGetMinmax( GLenum target, GLboolean reset,
-                                   GLenum format, GLenum types,
-                                   GLvoid *values )
-{
-    RESOLVE(PFNGLGETMINMAXPROC, "glGetMinmax");
-    proc(target, reset, format, types, values);
-}
-
-GLAPI void GLAPIENTRY glGetMinmaxParameterfv( GLenum target, GLenum pname,
-					      GLfloat *params )
-{
-    RESOLVE(PFNGLGETMINMAXPARAMETERFVPROC, "glGetMinmaxParameterfv");
-    proc(target, pname, params);
-}
-
-GLAPI void GLAPIENTRY glGetMinmaxParameteriv( GLenum target, GLenum pname,
-					      GLint *params )
-{
-    RESOLVE(PFNGLGETMINMAXPARAMETERIVPROC, "glGetMinmaxParameteriv");
-    proc(target, pname, params);
-}
-
-GLAPI void GLAPIENTRY glConvolutionFilter1D( GLenum target,
-	GLenum internalformat, GLsizei width, GLenum format, GLenum type,
-	const GLvoid *image )
-{
-    RESOLVE(PFNGLCONVOLUTIONFILTER1DPROC, "glConvolutionFilter1D");
-    proc(target, internalformat, width, format, type, image);
 }
 
-GLAPI void GLAPIENTRY glConvolutionFilter2D( GLenum target,
-	GLenum internalformat, GLsizei width, GLsizei height, GLenum format,
-	GLenum type, const GLvoid *image )
-{
-    RESOLVE(PFNGLCONVOLUTIONFILTER2DPROC, "glConvolutionFilter2D");
-    proc(target, internalformat, width, height, format, type, image);
-}
-
-GLAPI void GLAPIENTRY glConvolutionParameterf( GLenum target, GLenum pname,
-	GLfloat params )
-{
-    RESOLVE(PFNGLCONVOLUTIONPARAMETERFPROC, "glConvolutionParameterf");
-    proc(target, pname, params); 
-}
-
-GLAPI void GLAPIENTRY glConvolutionParameterfv( GLenum target, GLenum pname,
-	const GLfloat *params )
-{
-    RESOLVE(PFNGLCONVOLUTIONPARAMETERFVPROC, "glConvolutionParameterfv");
-    proc(target, pname, params);
-}
-
-GLAPI void GLAPIENTRY glConvolutionParameteri( GLenum target, GLenum pname,
-	GLint params )
-{
-    RESOLVE(PFNGLCONVOLUTIONPARAMETERIPROC, "glConvolutionParameteri");
-    proc(target, pname, params);
-}
-
-GLAPI void GLAPIENTRY glConvolutionParameteriv( GLenum target, GLenum pname,
-	const GLint *params )
-{
-    RESOLVE(PFNGLCONVOLUTIONPARAMETERIVPROC, "glConvolutionParameteriv");
-    proc(target, pname, params);
-}
-
-GLAPI void GLAPIENTRY glCopyConvolutionFilter1D( GLenum target,
-	GLenum internalformat, GLint x, GLint y, GLsizei width )
-{
-    RESOLVE(PFNGLCOPYCONVOLUTIONFILTER1DPROC, "glCopyConvolutionFilter1D");
-    proc(target, internalformat, x, y, width);
-}
-
-GLAPI void GLAPIENTRY glCopyConvolutionFilter2D( GLenum target,
-	GLenum internalformat, GLint x, GLint y, GLsizei width,
-	GLsizei height)
-{
-    RESOLVE(PFNGLCOPYCONVOLUTIONFILTER2DPROC, "glCopyConvolutionFilter2D");
-    proc(target, internalformat, x, y, width, height);
-}
+static PROC
+glWinResolveHelper(PROC *cache, char *symbol)
+{
+  PROC proc = NULL;
+
+  /* If not yet cached, call wglGetProcAddress */
+  if ((*cache) == NULL)
+    {
+      proc = wglGetProcAddress(symbol);
+      if (proc == NULL)
+        {
+          ErrorF("glwrap: Can't resolve \"%s\"\n", symbol);
+          (*cache) = (PROC)-1;
+        }
+      else
+        {
+          ErrorF("glwrap: Resolved \"%s\"\n", symbol);
+          (*cache) = proc;
+        }
+    }
+  /* Cached wglGetProcAddress failure */
+  else if ((*cache) == (PROC)-1)
+    {
+      proc = 0;
+    }
+  /* Cached wglGetProcAddress result */
+  else
+    {
+      proc = (*cache);
+    }
 
-GLAPI void GLAPIENTRY glGetConvolutionFilter( GLenum target, GLenum format,
-	GLenum type, GLvoid *image )
-{
-    RESOLVE(PFNGLGETCONVOLUTIONFILTERPROC, "glGetConvolutionFilter");
-    proc(target, format, type, image);
+  return proc;
 }
 
-GLAPI void GLAPIENTRY glGetConvolutionParameterfv( GLenum target, GLenum pname,
-	GLfloat *params )
-{
-    RESOLVE(PFNGLGETCONVOLUTIONPARAMETERFVPROC, "glGetConvolutionParameterfv");
-    proc(target, pname, params);
-}
-
-GLAPI void GLAPIENTRY glGetConvolutionParameteriv( GLenum target, GLenum pname,
-	GLint *params )
-{
-    RESOLVE(PFNGLGETCONVOLUTIONPARAMETERIVPROC, "glGetConvolutionParameteriv");
-    proc(target, pname, params);
-}
+#define RESOLVE_RET(proctype, symbol, retval) \
+    static PROC cache = NULL; \
+    __stdcall proctype proc = (proctype)glWinResolveHelper(&cache, symbol); \
+    if (proc == NULL) { \
+        __glXErrorCallBack(0); \
+        return retval; \
+    } \
+    glWinIndirectProcCalls++;
 
-GLAPI void GLAPIENTRY glSeparableFilter2D( GLenum target,
-	GLenum internalformat, GLsizei width, GLsizei height, GLenum format,
-	GLenum type, const GLvoid *row, const GLvoid *column )
-{
-    RESOLVE(PFNGLSEPARABLEFILTER2DPROC, "glSeparableFilter2D");
-    proc(target, internalformat, width, height, format, type, row, column);
-}
+#define RESOLVE(proctype, symbol) RESOLVE_RET(proctype, symbol,)
 
-GLAPI void GLAPIENTRY glGetSeparableFilter( GLenum target, GLenum format,
-	GLenum type, GLvoid *row, GLvoid *column, GLvoid *span )
-{
-    RESOLVE(PFNGLGETSEPARABLEFILTERPROC, "glGetSeparableFilter");
-    proc(target, format, type, row, column, span);
-}
+#define RESOLVED_PROC(proctype) proc
 
 /*
- * OpenGL 1.2
- */
+  Include generated cdecl wrappers for stdcall gl*() functions in opengl32.dll
 
-GLAPI void GLAPIENTRY glTexImage3D( GLenum target, GLint level,
-                                      GLint internalFormat,
-                                      GLsizei width, GLsizei height,
-                                      GLsizei depth, GLint border,
-                                      GLenum format, GLenum type,
-                                      const GLvoid *pixels )
-{
-    RESOLVE(PFNGLTEXIMAGE3DPROC, "glTexImage3D");
-    proc(target, level, internalFormat, width, height, depth, border, format, type, pixels);
-}
+  OpenGL 1.2 and upward is treated as extensions, function address must
+  found using wglGetProcAddress(), but also stdcall so still need wrappers...
 
-GLAPI void GLAPIENTRY glTexSubImage3D( GLenum target, GLint level,
-                                         GLint xoffset, GLint yoffset,
-                                         GLint zoffset, GLsizei width,
-                                         GLsizei height, GLsizei depth,
-                                         GLenum format,
-                                         GLenum type, const GLvoid *pixels)
-{
-    RESOLVE(PFNGLTEXSUBIMAGE3DPROC, "glTexSubImage3D");
-    proc(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
-}
-
-GLAPI void GLAPIENTRY glCopyTexSubImage3D( GLenum target, GLint level,
-                                             GLint xoffset, GLint yoffset,
-                                             GLint zoffset, GLint x,
-                                             GLint y, GLsizei width,
-                                             GLsizei height )
-{
-    RESOLVE(PFNGLCOPYTEXSUBIMAGE3DPROC, "glCopyTexSubImage3D");
-    proc(target, level, xoffset, yoffset, zoffset, x, y, width, height);
-}
+  Include generated dispatch table setup function
+*/
 
+#include "generated_gl_wrappers.c"
 
 /*
- * 20. GL_EXT_texture_object
- */
-GLAPI void GLAPIENTRY glGenTexturesEXT( GLsizei n, GLuint *textures )
-{
-    glGenTextures(n, textures);
-}
-
-GLAPI void GLAPIENTRY glDeleteTexturesEXT( GLsizei n, const GLuint *textures)
-{
-    glDeleteTextures(n, textures);
-}
-
-GLAPI void GLAPIENTRY glBindTextureEXT( GLenum target, GLuint texture )
-{
-    glBindTexture(target, target);
-}
-
-GLAPI void GLAPIENTRY glPrioritizeTexturesEXT( GLsizei n, const GLuint *textures, const GLclampf *priorities )
-{
-    glPrioritizeTextures(n, textures, priorities);
-}
-
-GLAPI GLboolean GLAPIENTRY glAreTexturesResidentEXT( GLsizei n, const GLuint *textures, GLboolean *residences )
-{
-    return glAreTexturesResident(n, textures, residences);
-}
+  Special non-static wrapper for glGetString for debug output
+*/
 
-GLAPI GLboolean GLAPIENTRY glIsTextureEXT( GLuint texture )
+const GLubyte* glGetStringWrapperNonstatic(GLenum name)
 {
-    return glIsTexture(texture); 
+  return glGetString(name);
 }
 
 /*
- * GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1)
- */
-
-GLAPI void GLAPIENTRY glActiveTextureARB(GLenum texture)
-{
-    RESOLVE(PFNGLACTIVETEXTUREARBPROC, "glActiveTextureARB");
-    proc(texture);
-}
-
-GLAPI void GLAPIENTRY glMultiTexCoord1dvARB(GLenum target, const GLdouble *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD1DVARBPROC, "glMultiTexCoord1dvARB");
-    proc(target, v);
-}
-
-GLAPI void GLAPIENTRY glMultiTexCoord1fvARB(GLenum target, const GLfloat *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD1FVARBPROC, "glMultiTexCoord1fvARB");
-    proc(target, v);
-}
-
-GLAPI void GLAPIENTRY glMultiTexCoord1ivARB(GLenum target, const GLint *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD1IVARBPROC, "glMultiTexCoord1ivARB");
-    proc(target, v);
-}
-
-GLAPI void GLAPIENTRY glMultiTexCoord1svARB(GLenum target, const GLshort *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD1SVARBPROC, "glMultiTexCoord1svARB");
-    proc(target, v);
-}
-GLAPI void GLAPIENTRY glMultiTexCoord2dvARB(GLenum target, const GLdouble *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD2DVARBPROC, "glMultiTexCoord2dvARB");
-    proc(target, v);
-}
-GLAPI void GLAPIENTRY glMultiTexCoord2fvARB(GLenum target, const GLfloat *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD2FVARBPROC, "glMultiTexCoord2fvARB");
-    proc(target, v);
-}
-GLAPI void GLAPIENTRY glMultiTexCoord2ivARB(GLenum target, const GLint *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD2IVARBPROC, "glMultiTexCoord2ivARB");
-    proc(target, v);
-}
-GLAPI void GLAPIENTRY glMultiTexCoord2svARB(GLenum target, const GLshort *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD1SVARBPROC, "glMultiTexCoord1svARB");
-    proc(target, v);
-}
-GLAPI void GLAPIENTRY glMultiTexCoord3dvARB(GLenum target, const GLdouble *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD3DVARBPROC, "glMultiTexCoord3dvARB");
-    proc(target, v);
-}
-GLAPI void GLAPIENTRY glMultiTexCoord3fvARB(GLenum target, const GLfloat *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD3FVARBPROC, "glMultiTexCoord3fvARB");
-    proc(target, v);
-}
-GLAPI void GLAPIENTRY glMultiTexCoord3ivARB(GLenum target, const GLint *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD3IVARBPROC, "glMultiTexCoord3ivARB");
-    proc(target, v);
-}
-GLAPI void GLAPIENTRY glMultiTexCoord3svARB(GLenum target, const GLshort *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD1SVARBPROC, "glMultiTexCoord1svARB");
-    proc(target, v);
-}
-GLAPI void GLAPIENTRY glMultiTexCoord4dvARB(GLenum target, const GLdouble *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD4DVARBPROC, "glMultiTexCoord4dvARB");
-    proc(target, v);
-}
-GLAPI void GLAPIENTRY glMultiTexCoord4fvARB(GLenum target, const GLfloat *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD4FVARBPROC, "glMultiTexCoord4fvARB");
-    proc(target, v);
-}
-GLAPI void GLAPIENTRY glMultiTexCoord4ivARB(GLenum target, const GLint *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD4IVARBPROC, "glMultiTexCoord4ivARB");
-    proc(target, v);
-}
-GLAPI void GLAPIENTRY glMultiTexCoord4svARB(GLenum target, const GLshort *v)
-{
-    RESOLVE(PFNGLMULTITEXCOORD1SVARBPROC, "glMultiTexCoord1svARB");
-    proc(target, v);
-}
+  Special non-static wrapper for glAddSwapHintRectWIN for copySubBuffers
+*/
 
+typedef void (__stdcall *PFNGLADDSWAPHINTRECTWIN)(GLint x, GLint y, GLsizei width, GLsizei height);
 
-GLAPI void GLAPIENTRY glActiveStencilFaceEXT(GLenum face)
+void glAddSwapHintRectWINWrapperNonstatic(GLint x, GLint y, GLsizei width, GLsizei height)
 {
-    RESOLVE(PFNGLACTIVESTENCILFACEEXTPROC, "glActiveStencilFaceEXT");
-    proc(face);
+  RESOLVE(PFNGLADDSWAPHINTRECTWIN, "glAddSwapHintRectWIN");
+  proc(x, y, width, height);
 }
 
-GLAPI void APIENTRY glPointParameterfARB(GLenum pname, GLfloat param)
-{
-    RESOLVE(PFNGLPOINTPARAMETERFARBPROC, "glPointParameterfARB");
-    proc(pname, param);
-}
-
-GLAPI void APIENTRY glPointParameterfvARB(GLenum pname, const GLfloat *params)
-{
-    RESOLVE(PFNGLPOINTPARAMETERFVARBPROC, "glPointParameterfvARB");
-    proc(pname, params);
-}
-
-
-GLAPI void APIENTRY glWindowPos3fARB(GLfloat x, GLfloat y, GLfloat z)
-{
-    RESOLVE(PFNGLWINDOWPOS3FARBPROC, "glWindowPos3fARB");
-    proc(x, y, z);
-}
-
-GLAPI void APIENTRY glPointParameteri(GLenum pname, GLint param)
-{
-    RESOLVE(PFNGLPOINTPARAMETERIPROC, "glPointParameteri");
-    proc(pname, param);
-}
-
-GLAPI void APIENTRY glPointParameteriv(GLenum pname, const GLint *params)
-{
-    RESOLVE(PFNGLPOINTPARAMETERIVPROC, "glPointParameteriv");
-    proc(pname, params);
-}
-
-GLAPI void APIENTRY glPointParameteriNV(GLenum pname, GLint param)
-{
-    RESOLVE(PFNGLPOINTPARAMETERINVPROC, "glPointParameteriNV");
-    proc(pname, param);
-}
-
-GLAPI void APIENTRY glPointParameterivNV(GLenum pname, const GLint *params)
-{
-    RESOLVE(PFNGLPOINTPARAMETERIVNVPROC, "glPointParameterivNV");
-    proc(pname, params);
-}
-
-GLAPI void APIENTRY glSecondaryColor3bv(const GLbyte *v)
-{
-    RESOLVE(PFNGLSECONDARYCOLOR3BVPROC, "glSecondaryColor3bv");
-    proc(v);
-}
-GLAPI void APIENTRY glSecondaryColor3dv(const GLdouble *v)
-{
-    RESOLVE(PFNGLSECONDARYCOLOR3DVPROC, "glSecondaryColor3dv");
-    proc(v);
-}
-GLAPI void APIENTRY glSecondaryColor3fv(const GLfloat *v)
-{
-    RESOLVE(PFNGLSECONDARYCOLOR3FVPROC, "glSecondaryColor3fv");
-    proc(v);
-}
-GLAPI void APIENTRY glSecondaryColor3iv(const GLint *v)
-{
-    RESOLVE(PFNGLSECONDARYCOLOR3IVPROC, "glSecondaryColor3iv");
-    proc(v);
-}
-GLAPI void APIENTRY glSecondaryColor3sv(const GLshort *v)
-{
-    RESOLVE(PFNGLSECONDARYCOLOR3SVPROC, "glSecondaryColor3sv");
-    proc(v);
-}
-GLAPI void APIENTRY glSecondaryColor3ubv(const GLubyte *v)
-{
-    RESOLVE(PFNGLSECONDARYCOLOR3UBVPROC, "glSecondaryColor3ubv");
-    proc(v);
-}
-GLAPI void APIENTRY glSecondaryColor3uiv(const GLuint *v)
-{
-    RESOLVE(PFNGLSECONDARYCOLOR3UIVPROC, "glSecondaryColor3uiv");
-    proc(v);
-}
-GLAPI void APIENTRY glSecondaryColor3usv(const GLushort *v)
-{
-    RESOLVE(PFNGLSECONDARYCOLOR3USVPROC, "glSecondaryColor3usv");
-    proc(v);
-}
-GLAPI void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
-{
-    RESOLVE(PFNGLSECONDARYCOLORPOINTERPROC, "glSecondaryColorPointer");
-    proc(size, type, stride, pointer);
-}
-
-
-GLAPI void APIENTRY glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)
-{
-    RESOLVE(PFNGLBLENDFUNCSEPARATEPROC, "glBlendFuncSeparate");
-    proc(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
-}
-GLAPI void APIENTRY glFogCoordfv(const GLfloat *coord)
-{
-    RESOLVE(PFNGLFOGCOORDFVPROC, "glFogCoordfv");
-    proc(coord);
-}
-GLAPI void APIENTRY glFogCoorddv(const GLdouble *coord)
-{
-    RESOLVE(PFNGLFOGCOORDDVPROC, "glFogCoorddv");
-    proc(coord);
-}
-GLAPI void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
-{
-    RESOLVE(PFNGLFOGCOORDPOINTERPROC, "glFogCoordPointer");
-    proc(type, stride, pointer);
-}
-
-
-GLAPI void APIENTRY glSampleCoverageARB(GLclampf value, GLboolean invert)
-{
-    RESOLVE(PFNGLSAMPLECOVERAGEARBPROC, "glSampleCoverageARB");
-    proc(value, invert);
-}
-GLAPI void APIENTRY glSampleMaskSGIS(GLclampf value, GLboolean invert)
-{
-    RESOLVE(PFNGLSAMPLEMASKSGISPROC, "glSampleMaskSGIS");
-    proc(value, invert);
-}
-GLAPI void APIENTRY glSamplePatternSGIS(GLenum pattern)
-{
-    RESOLVE(PFNGLSAMPLEPATTERNSGISPROC, "glSamplePatternSGIS");
-    proc(pattern);
-}
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index 5e12022..c12cd1f 100755
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -1,22 +1,27 @@
 /*
- * GLX implementation that uses Windows OpenGL library
- * (Indirect rendering path)
+ * File: indirect.c
+ * Purpose: A GLX implementation that uses Windows OpenGL library
+ *
+ * Authors: Alexander Gottwald
+ *          Jon TURNEY
+ *
+ * Copyright (c) Jon TURNEY 2009
+ * Copyright (c) Alexander Gottwald 2004
  *
- * Authors: Alexander Gottwald 
- */
-/* 
  * Portions of this file are copied from GL/apple/indirect.c,
  * which contains the following copyright:
- *  
+ *
+ * Copyright (c) 2007, 2008, 2009 Apple Inc.
+ * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved.
  * Copyright (c) 2002 Greg Parker. All Rights Reserved.
- * Copyright (c) 2002 Apple Computer, Inc.
  *
- * Portions of this file are copied from xf86glx.c,
+ * Portions of this file are copied from Mesa's xf86glx.c,
  * which contains the following copyright:
  *
  * 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
@@ -34,636 +39,1539 @@
  * 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.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
  */
 
+/*
+  TODO:
+  - hook up remaining unimplemented extensions
+  - research what guarantees glXWaitX, glXWaitGL are supposed to offer, and implement then
+    using GdiFlush and/or glFinish
+  - pbuffer clobbering: we don't get async notification, but can we arrange to emit the
+    event when we notice it's been clobbered? at the very least, check if it's been clobbered
+    before using it?
+  - are the __GLXConfig * we get handed back ones we are made (so we can extend the structure
+    with privates?) Or are they created inside the GLX core as well?
+*/
+
+/*
+  MSDN clarifications:
 
+  It says SetPixelFormat()'s PIXELFORMATDESCRIPTOR pointer argument has no effect
+  except on metafiles, this seems to mean that as it's ok to supply NULL if the DC
+  is not for a metafile
 
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
+  wglMakeCurrent ignores the hdc if hglrc is NULL, so wglMakeCurrent(NULL, NULL)
+  is used to make no context current
+
+*/
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
 #endif
 
 #include "glwindows.h"
-#include <glcontextmodes.h>
-#include <stdint.h>
+#include <glx/glxserver.h>
+#include <glx/glxutil.h>
+#include <glx/extension_string.h>
+#include <GL/glxtokens.h>
 
 #include <winpriv.h>
+#include <wgl_ext_api.h>
+
+#define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1]))
+
+/* ---------------------------------------------------------------------- */
+/*
+ *   structure definitions
+ */
+
+typedef struct __GLXWinContext  __GLXWinContext;
+typedef struct __GLXWinDrawable __GLXWinDrawable;
+typedef struct __GLXWinScreen glxWinScreen;
+typedef struct __GLXWinConfig GLXWinConfig;
+
+struct __GLXWinContext {
+  __GLXcontext base;
+  HGLRC ctx;                         /* Windows GL Context */
+  __GLXWinContext *shareContext;     /* Context with which we will share display lists and textures */
+  HWND hwnd;                         /* For detecting when HWND has changed */
+};
+
+struct __GLXWinDrawable
+{
+  __GLXdrawable base;
+  __GLXWinContext *drawContext;
+  __GLXWinContext *readContext;
+
+  /* If this drawable is GLX_DRAWABLE_PBUFFER */
+  HPBUFFERARB hPbuffer;
+
+  /* If this drawable is GLX_DRAWABLE_PIXMAP */
+  HDC dibDC;
+  HBITMAP hDIB;
+  HBITMAP hOldDIB; /* original DIB for DC */
+  void *pOldBits; /* original pBits for this drawable's pixmap */
+};
+
+struct __GLXWinScreen
+{
+  __GLXscreen base;
+
+  /* Supported GLX extensions */
+  unsigned char glx_enable_bits[__GLX_EXT_BYTES];
+
+  Bool has_WGL_ARB_multisample;
+  Bool has_WGL_ARB_pixel_format;
+  Bool has_WGL_ARB_pbuffer;
+  Bool has_WGL_ARB_render_texture;
+
+  /* wrapped screen functions */
+  RealizeWindowProcPtr RealizeWindow;
+  UnrealizeWindowProcPtr UnrealizeWindow;
+  CopyWindowProcPtr CopyWindow;
+};
+
+struct __GLXWinConfig
+{
+  __GLXconfig base;
+  int pixelFormatIndex;
+};
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Various debug helpers
+ */
 
 #define GLWIN_DEBUG_HWND(hwnd)  \
-    if (glWinDebugSettings.dumpHWND) { \
+    if (glxWinDebugSettings.dumpHWND) { \
         char buffer[1024]; \
         if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0; \
-        GLWIN_DEBUG_MSG("Got HWND %s (%p)\n", buffer, hwnd); \
+        GLWIN_DEBUG_MSG("Got HWND %p for window '%s'", hwnd, buffer); \
     }
 
+glxWinDebugSettingsRec glxWinDebugSettings = { 0, 0, 0, 0, 0, 0};
 
-/* ggs: needed to call back to glx with visual configs */
-extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, void **configprivs);
-
-glWinDebugSettingsRec glWinDebugSettings = { 1, 0, 0, 0, 0};
-
-static void glWinInitDebugSettings(void) 
+static void glxWinInitDebugSettings(void)
 {
     char *envptr;
 
     envptr = getenv("GLWIN_ENABLE_DEBUG");
     if (envptr != NULL)
-        glWinDebugSettings.enableDebug = (atoi(envptr) == 1);
+        glxWinDebugSettings.enableDebug = (atoi(envptr) == 1);
 
     envptr = getenv("GLWIN_ENABLE_TRACE");
     if (envptr != NULL)
-        glWinDebugSettings.enableTrace = (atoi(envptr) == 1);
+        glxWinDebugSettings.enableTrace = (atoi(envptr) == 1);
 
     envptr = getenv("GLWIN_DUMP_PFD");
     if (envptr != NULL)
-        glWinDebugSettings.dumpPFD = (atoi(envptr) == 1);
-        
+        glxWinDebugSettings.dumpPFD = (atoi(envptr) == 1);
+
     envptr = getenv("GLWIN_DUMP_HWND");
     if (envptr != NULL)
-        glWinDebugSettings.dumpHWND = (atoi(envptr) == 1);
+        glxWinDebugSettings.dumpHWND = (atoi(envptr) == 1);
 
     envptr = getenv("GLWIN_DUMP_DC");
     if (envptr != NULL)
-        glWinDebugSettings.dumpDC = (atoi(envptr) == 1);
+        glxWinDebugSettings.dumpDC = (atoi(envptr) == 1);
+
+    envptr = getenv("GLWIN_ENABLE_GLCALL_TRACE");
+    if (envptr != NULL)
+        glxWinDebugSettings.enableGLcallTrace = (atoi(envptr) == 1);
+
+    envptr = getenv("GLWIN_ENABLE_WGLCALL_TRACE");
+    if (envptr != NULL)
+        glxWinDebugSettings.enableWGLcallTrace = (atoi(envptr) == 1);
+
+    envptr = getenv("GLWIN_DEBUG_ALL");
+    if (envptr != NULL)
+      {
+        glxWinDebugSettings.enableDebug = 1;
+        glxWinDebugSettings.enableTrace = 1;
+        glxWinDebugSettings.dumpPFD = 1;
+        glxWinDebugSettings.dumpHWND = 1;
+        glxWinDebugSettings.dumpDC = 1;
+        glxWinDebugSettings.enableGLcallTrace = 1;
+        glxWinDebugSettings.enableWGLcallTrace = 1;
+      }
+}
+
+static
+const char *glxWinErrorMessage(void)
+{
+  static char errorbuffer[1024];
+
+  if (!FormatMessage(
+                     FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+                     NULL,
+                     GetLastError(),
+                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                     (LPTSTR) &errorbuffer,
+                     sizeof(errorbuffer),
+                     NULL ))
+    {
+      snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error in FormatMessage: %08x!", (unsigned)GetLastError());
+    }
+
+  if (errorbuffer[strlen(errorbuffer)-1] == '\n')
+    errorbuffer[strlen(errorbuffer)-1] = 0;
+
+  return errorbuffer;
+}
+
+static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd);
+
+#define DUMP_PFD_FLAG(flag) \
+    if (pfd->dwFlags & flag) { \
+        ErrorF("%s%s", pipesym, #flag); \
+        pipesym = " | "; \
+    }
+
+static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd)
+{
+    const char *pipesym = ""; /* will be set after first flag dump */
+    ErrorF("PIXELFORMATDESCRIPTOR:\n");
+    ErrorF("nSize = %u\n", pfd->nSize);
+    ErrorF("nVersion = %u\n", pfd->nVersion);
+    ErrorF("dwFlags = %lu = {", pfd->dwFlags);
+        DUMP_PFD_FLAG(PFD_DOUBLEBUFFER);
+        DUMP_PFD_FLAG(PFD_STEREO);
+        DUMP_PFD_FLAG(PFD_DRAW_TO_WINDOW);
+        DUMP_PFD_FLAG(PFD_DRAW_TO_BITMAP);
+        DUMP_PFD_FLAG(PFD_SUPPORT_GDI);
+        DUMP_PFD_FLAG(PFD_SUPPORT_OPENGL);
+        DUMP_PFD_FLAG(PFD_GENERIC_FORMAT);
+        DUMP_PFD_FLAG(PFD_NEED_PALETTE);
+        DUMP_PFD_FLAG(PFD_NEED_SYSTEM_PALETTE);
+        DUMP_PFD_FLAG(PFD_SWAP_EXCHANGE);
+        DUMP_PFD_FLAG(PFD_SWAP_COPY);
+        DUMP_PFD_FLAG(PFD_SWAP_LAYER_BUFFERS);
+        DUMP_PFD_FLAG(PFD_GENERIC_ACCELERATED);
+        DUMP_PFD_FLAG(PFD_DEPTH_DONTCARE);
+        DUMP_PFD_FLAG(PFD_DOUBLEBUFFER_DONTCARE);
+        DUMP_PFD_FLAG(PFD_STEREO_DONTCARE);
+    ErrorF("}\n");
+
+    ErrorF("iPixelType = %hu = %s\n", pfd->iPixelType,
+            (pfd->iPixelType == PFD_TYPE_RGBA ? "PFD_TYPE_RGBA" : "PFD_TYPE_COLORINDEX"));
+    ErrorF("cColorBits = %hhu\n", pfd->cColorBits);
+    ErrorF("cRedBits = %hhu\n", pfd->cRedBits);
+    ErrorF("cRedShift = %hhu\n", pfd->cRedShift);
+    ErrorF("cGreenBits = %hhu\n", pfd->cGreenBits);
+    ErrorF("cGreenShift = %hhu\n", pfd->cGreenShift);
+    ErrorF("cBlueBits = %hhu\n", pfd->cBlueBits);
+    ErrorF("cBlueShift = %hhu\n", pfd->cBlueShift);
+    ErrorF("cAlphaBits = %hhu\n", pfd->cAlphaBits);
+    ErrorF("cAlphaShift = %hhu\n", pfd->cAlphaShift);
+    ErrorF("cAccumBits = %hhu\n", pfd->cAccumBits);
+    ErrorF("cAccumRedBits = %hhu\n", pfd->cAccumRedBits);
+    ErrorF("cAccumGreenBits = %hhu\n", pfd->cAccumGreenBits);
+    ErrorF("cAccumBlueBits = %hhu\n", pfd->cAccumBlueBits);
+    ErrorF("cAccumAlphaBits = %hhu\n", pfd->cAccumAlphaBits);
+    ErrorF("cDepthBits = %hhu\n", pfd->cDepthBits);
+    ErrorF("cStencilBits = %hhu\n", pfd->cStencilBits);
+    ErrorF("cAuxBuffers = %hhu\n", pfd->cAuxBuffers);
+    ErrorF("iLayerType = %hhu\n", pfd->iLayerType);
+    ErrorF("bReserved = %hhu\n", pfd->bReserved);
+    ErrorF("dwLayerMask = %lu\n", pfd->dwLayerMask);
+    ErrorF("dwVisibleMask = %lu\n", pfd->dwVisibleMask);
+    ErrorF("dwDamageMask = %lu\n", pfd->dwDamageMask);
+    ErrorF("\n");
+}
+
+static const char *
+visual_class_name(int cls)
+{
+  switch (cls) {
+  case GLX_STATIC_COLOR:
+    return "StaticColor";
+  case GLX_PSEUDO_COLOR:
+    return "PseudoColor";
+  case GLX_STATIC_GRAY:
+    return "StaticGray";
+  case GLX_GRAY_SCALE:
+    return "GrayScale";
+  case GLX_TRUE_COLOR:
+     return "TrueColor";
+  case GLX_DIRECT_COLOR:
+     return "DirectColor";
+  default:
+    return "-none-";
+  }
 }
 
-static char errorbuffer[1024];
-const char *glWinErrorMessage(void)
+static const char *
+swap_method_name(int mthd)
+{
+  switch (mthd)
+    {
+    case GLX_SWAP_EXCHANGE_OML:
+      return "xchg";
+    case GLX_SWAP_COPY_OML:
+      return "copy";
+    case GLX_SWAP_UNDEFINED_OML:
+      return "    ";
+    default:
+      return "????";
+    }
+}
+
+static void
+fbConfigsDump(unsigned int n, __GLXconfig *c)
 {
-    if (!FormatMessage( 
-                FORMAT_MESSAGE_FROM_SYSTEM | 
-                FORMAT_MESSAGE_IGNORE_INSERTS,
-                NULL,
-                GetLastError(),
-                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                (LPTSTR) &errorbuffer,
-                sizeof(errorbuffer),
-                NULL ))
+  ErrorF("%d fbConfigs\n", n);
+  ErrorF("pxf vis  fb                      render         Ste                     aux    accum        MS    drawable             Group/\n");
+  ErrorF("idx  ID  ID VisualType Depth Lvl RGB CI DB Swap reo  R  G  B  A   Z  S  buf AR AG AB AA  bufs num  W P Pb  Float Trans Caveat\n");
+  ErrorF("-----------------------------------------------------------------------------------------------------------------------------\n");
+
+  while (c != NULL)
     {
-        snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error in FormatMessage: %08x!\n", (unsigned)GetLastError()); 
+      unsigned int i = ((GLXWinConfig *)c)->pixelFormatIndex;
+
+      ErrorF("%3d  %2x  %2x "
+             "%-11s"
+             " %3d %3d   %s   %s  %s %s  %s  "
+             "%2d %2d %2d %2d  "
+             "%2d %2d  "
+             "%2d  "
+             "%2d %2d %2d %2d"
+             "   %2d   %2d"
+             "  %s %s %s "
+             "    %s   "
+             "  %s   "
+             "  %d %s"
+             "\n",
+             i, c->visualID, c->fbconfigID,
+             visual_class_name(c->visualType),
+             c->rgbBits ? c->rgbBits : c->indexBits,
+             c->level,
+	     (c->renderType & GLX_RGBA_BIT) ? "y" : ".",
+	     (c->renderType & GLX_COLOR_INDEX_BIT) ? "y" : ".",
+	     c->doubleBufferMode ? "y" : ".",
+             swap_method_name(c->swapMethod),
+	     c->stereoMode ? "y" : ".",
+             c->redBits, c->greenBits, c->blueBits, c->alphaBits,
+             c->depthBits, c->stencilBits,
+             c->numAuxBuffers,
+             c->accumRedBits, c->accumGreenBits, c->accumBlueBits, c->accumAlphaBits,
+             c->sampleBuffers, c->samples,
+             (c->drawableType & GLX_WINDOW_BIT) ? "y" : ".",
+             (c->drawableType & GLX_PIXMAP_BIT) ? "y" : ".",
+             (c->drawableType & GLX_PBUFFER_BIT) ? "y" : ".",
+             ".",
+             (c->transparentPixel != GLX_NONE_EXT) ? "y" : ".",
+             c->visualSelectGroup, (c->visualRating == GLX_SLOW_VISUAL_EXT) ? "*" : " ");
+
+      c = c->next;
     }
-    return errorbuffer; 
 }
 
+/* ---------------------------------------------------------------------- */
 /*
- * GLX implementation that uses Win32's OpenGL
+ * Forward declarations
  */
 
+static __GLXscreen *glxWinScreenProbe(ScreenPtr pScreen);
+static __GLXcontext *glxWinCreateContext(__GLXscreen *screen,
+                                        __GLXconfig *modes,
+                                        __GLXcontext *baseShareContext);
+static __GLXdrawable *glxWinCreateDrawable(__GLXscreen *screen,
+                                          DrawablePtr pDraw,
+                                          int type,
+                                          XID drawId,
+                                          __GLXconfig *conf);
+
+static Bool glxWinRealizeWindow(WindowPtr pWin);
+static Bool glxWinUnrealizeWindow(WindowPtr pWin);
+static void glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+
+static HDC glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd);
+static void glxWinReleaseDC(HWND hwnd, HDC hdc, __GLXWinDrawable *draw);
+
+static void glxWinCreateConfigs(HDC dc, glxWinScreen *screen);
+static void glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen);
+static int fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride);
+static int fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen);
+
+/* ---------------------------------------------------------------------- */
 /*
- * Server-side GLX uses these functions which are normally defined
- * in the OpenGL SI.
+ * The GLX provider
  */
 
-GLuint __glFloorLog2(GLuint val)
+__GLXprovider __glXWGLProvider = {
+    glxWinScreenProbe,
+    "Win32 native WGL",
+    NULL
+};
+
+void
+glxWinPushNativeProvider(void)
 {
-    int c = 0;
+  GlxPushProvider(&__glXWGLProvider);
+}
 
-    while (val > 1) {
-        c++;
-        val >>= 1;
-    }
-    return c;
+/* ---------------------------------------------------------------------- */
+/*
+ * Screen functions
+ */
+
+static void
+glxWinScreenDestroy(__GLXscreen *screen)
+{
+    GLWIN_DEBUG_MSG("glxWinScreenDestroy(%p)", screen);
+    __glXScreenDestroy(screen);
+    xfree(screen);
 }
 
-/* some prototypes */
-static Bool glWinScreenProbe(int screen);
-static Bool glWinInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
-                              int *nvisualp, int *ndepthp,
-                              int *rootDepthp, VisualID *defaultVisp,
-                              unsigned long sizes, int bitsPerRGB);
-static void glWinSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
-                                   void **privates);
-static __GLinterface *glWinCreateContext(__GLimports *imports,
-                                          __GLcontextModes *mode,
-                                          __GLinterface *shareGC);
-static void glWinCreateBuffer(__GLXdrawablePrivate *glxPriv);
-static void glWinResetExtension(void);
+static int
+glxWinScreenSwapInterval(__GLXdrawable *drawable, int interval)
+{
+  BOOL ret = wglSwapIntervalEXTWrapper(interval);
+  if (!ret)
+    {
+      ErrorF("wglSwapIntervalEXT interval %d failed:%s\n", interval, glxWinErrorMessage());
+    }
+  return ret;
+}
 
 /*
- * This structure is statically allocated in the __glXScreens[]
- * structure.  This struct is not used anywhere other than in
- * __glXScreenInit to initialize each of the active screens
- * (__glXActiveScreens[]).  Several of the fields must be initialized by
- * the screenProbe routine before they are copied to the active screens
- * struct.  In particular, the contextCreate, pGlxVisual, numVisuals,
- * and numUsableVisuals fields must be initialized.
+  Report the extensions split and formatted to avoid overflowing a line
  */
-static __GLXscreenInfo __glDDXScreenInfo = {
-    glWinScreenProbe,   /* Must be generic and handle all screens */
-    glWinCreateContext, /* Substitute screen's createContext routine */
-    glWinCreateBuffer,  /* Substitute screen's createBuffer routine */
-    NULL,                 /* Set up pGlxVisual in probe */
-    NULL,                 /* Set up pVisualPriv in probe */
-    0,                    /* Set up numVisuals in probe */
-    0,                    /* Set up numUsableVisuals in probe */
-    "Vendor String",      /* GLXvendor is overwritten by __glXScreenInit */
-    "Version String",     /* GLXversion is overwritten by __glXScreenInit */
-    "Extensions String",  /* GLXextensions is overwritten by __glXScreenInit */
-    NULL                  /* WrappedPositionWindow is overwritten */
-};
+static void
+glxLogExtensions(const char *prefix, const char *extensions)
+{
+  int length = 0;
+  char *strl;
+  char *str = xalloc(strlen(extensions) + 1);
+
+  if (str == NULL)
+    {
+      ErrorF("glxLogExtensions: xalloc error\n");
+      return;
+    }
+
+  str[strlen(extensions)] = '\0';
+  strncpy (str, extensions, strlen(extensions));
+
+  strl = strtok(str, " ");
+  ErrorF("%s%s", prefix, strl);
+  length = strlen(prefix) + strlen(strl);
+
+  while (1)
+    {
+      strl = strtok(NULL, " ");
+      if (strl == NULL) break;
 
-void *__glXglDDXScreenInfo(void) {
-    return &__glDDXScreenInfo;
+      if (length + strlen(strl) + 1 > 120)
+        {
+          ErrorF("\n");
+          ErrorF("%s",prefix);
+          length = strlen(prefix);
+        }
+      else
+        {
+          ErrorF(" ");
+          length++;
+        }
+
+      ErrorF("%s", strl);
+      length = length + strlen(strl);
+    }
+
+  ErrorF("\n");
+
+  xfree(str);
 }
 
-static __GLXextensionInfo __glDDXExtensionInfo = {
-    GL_CORE_WINDOWS,
-    glWinResetExtension,
-    glWinInitVisuals,
-    glWinSetVisualConfigs
-};
+/* This is called by GlxExtensionInit() asking the GLX provider if it can handle the screen... */
+static __GLXscreen *
+glxWinScreenProbe(ScreenPtr pScreen)
+{
+    glxWinScreen *screen;
+    const char *gl_extensions;
+    const char *wgl_extensions;
+    HWND hwnd;
+    HDC hdc;
+    HGLRC hglrc;
+
+    GLWIN_DEBUG_MSG("glxWinScreenProbe");
+
+    glxWinInitDebugSettings();
+
+    if (pScreen == NULL)
+	return NULL;
+
+    if (!winCheckScreenAiglxIsSupported(pScreen))
+      {
+        LogMessage(X_ERROR,"AIGLX: No native OpenGL in modes with a root window\n");
+        return NULL;
+      }
+
+    screen = xcalloc(1, sizeof(glxWinScreen));
+
+    if (NULL == screen)
+	return NULL;
+
+    /* Wrap RealizeWindow, UnrealizeWindow and CopyWindow on this screen */
+    screen->RealizeWindow = pScreen->RealizeWindow;
+    pScreen->RealizeWindow = glxWinRealizeWindow;
+    screen->UnrealizeWindow = pScreen->UnrealizeWindow;
+    pScreen->UnrealizeWindow = glxWinUnrealizeWindow;
+    screen->CopyWindow = pScreen->CopyWindow;
+    pScreen->CopyWindow = glxWinCopyWindow;
+
+    /* Dump out some useful information about the native renderer */
+
+    // create window class
+#define WIN_GL_TEST_WINDOW_CLASS "XWinGLTest"
+    {
+      static wATOM glTestWndClass = 0;
+      if (glTestWndClass == 0)
+        {
+          WNDCLASSEX wc;
+          wc.cbSize = sizeof(WNDCLASSEX);
+          wc.style = CS_HREDRAW | CS_VREDRAW;
+          wc.lpfnWndProc = DefWindowProc;
+          wc.cbClsExtra = 0;
+          wc.cbWndExtra = 0;
+          wc.hInstance = GetModuleHandle(NULL);
+          wc.hIcon = 0;
+          wc.hCursor = 0;
+          wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+          wc.lpszMenuName = NULL;
+          wc.lpszClassName = WIN_GL_TEST_WINDOW_CLASS;
+          wc.hIconSm = 0;
+          RegisterClassEx (&wc);
+      }
+    }
+
+    // create an invisible window for a scratch DC
+    hwnd = CreateWindowExA(0,
+                           WIN_GL_TEST_WINDOW_CLASS,
+                           "XWin GL Renderer Capabilities Test Window",
+                           0, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
+    if (hwnd == NULL)
+      LogMessage(X_ERROR,"AIGLX: Couldn't create a window for render capabilities testing\n");
+
+    hdc = GetDC(hwnd);
+
+    // we must set a pixel format before we can create a context, just use the first one...
+    SetPixelFormat(hdc, 1, NULL);
+    hglrc = wglCreateContext(hdc);
+    wglMakeCurrent(hdc, hglrc);
+
+    // initialize wgl extension proc pointers (don't call them before here...)
+    // (but we need to have a current context for them to be resolvable)
+    wglResolveExtensionProcs();
+
+    ErrorF("GL_VERSION:     %s\n", glGetStringWrapperNonstatic(GL_VERSION));
+    ErrorF("GL_VENDOR:      %s\n", glGetStringWrapperNonstatic(GL_VENDOR));
+    ErrorF("GL_RENDERER:    %s\n", glGetStringWrapperNonstatic(GL_RENDERER));
+    gl_extensions = (const char *)glGetStringWrapperNonstatic(GL_EXTENSIONS);
+    glxLogExtensions("GL_EXTENSIONS:  ", gl_extensions);
+    wgl_extensions = wglGetExtensionsStringARBWrapper(hdc);
+    if (!wgl_extensions) wgl_extensions = "";
+    glxLogExtensions("WGL_EXTENSIONS: ", wgl_extensions);
+
+    // Can you see the problem here?  The extensions string is DC specific
+    // Different DCs for windows on a multimonitor system driven by multiple cards
+    // might have completely different capabilities.  Of course, good luck getting
+    // those screens to be accelerated in XP and earlier...
 
-void *__glXglDDXExtensionInfo(void) {
-    return &__glDDXExtensionInfo;
+    {
+      // testing facility to not use any WGL extensions
+      char *envptr = getenv("GLWIN_NO_WGL_EXTENSIONS");
+      if ((envptr != NULL) && (atoi(envptr) != 0))
+        {
+          ErrorF("GLWIN_NO_WGL_EXTENSIONS is set, ignoring WGL_EXTENSIONS\n");
+          wgl_extensions = "";
+        }
+    }
+
+    {
+      Bool glx_sgi_make_current_read = FALSE;
+
+      //
+      // Based on the WGL extensions available, enable various GLX extensions
+      // XXX: make this table-driven ?
+      //
+      memset(screen->glx_enable_bits, 0, __GLX_EXT_BYTES);
+
+      __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_info");
+      __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_rating");
+      __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_import_context");
+      __glXEnableExtension(screen->glx_enable_bits, "GLX_OML_swap_method");
+      __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_fbconfig");
+
+      if (strstr(wgl_extensions, "WGL_ARB_make_current_read"))
+        {
+          __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_make_current_read");
+          LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n");
+          glx_sgi_make_current_read = TRUE;
+        }
+
+      if (strstr(gl_extensions, "GL_WIN_swap_hint"))
+        {
+          __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
+          LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
+        }
+
+      if (strstr(wgl_extensions, "WGL_EXT_swap_control"))
+        {
+          __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control");
+          __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_swap_control");
+          LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
+        }
+
+/*       // Hmm?  screen->texOffset */
+/*       if (strstr(wgl_extensions, "WGL_ARB_render_texture")) */
+/*         { */
+/*           __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_texture_from_pixmap"); */
+/*           LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); */
+/*           screen->has_WGL_ARB_render_texture = TRUE; */
+/*         } */
+
+      if (strstr(wgl_extensions, "WGL_ARB_pbuffer"))
+        {
+          __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_pbuffer");
+          LogMessage(X_INFO, "AIGLX: enabled GLX_SGIX_pbuffer\n");
+          screen->has_WGL_ARB_pbuffer = TRUE;
+        }
+
+      if (strstr(wgl_extensions, "WGL_ARB_multisample"))
+        {
+          __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_multisample");
+          __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIS_multisample");
+          LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_multisample and GLX_SGIS_multisample\n");
+          screen->has_WGL_ARB_multisample = TRUE;
+        }
+
+      screen->base.destroy = glxWinScreenDestroy;
+      screen->base.createContext = glxWinCreateContext;
+      screen->base.createDrawable = glxWinCreateDrawable;
+      screen->base.swapInterval = glxWinScreenSwapInterval;
+      screen->base.hyperpipeFuncs = NULL;
+      screen->base.swapBarrierFuncs = NULL;
+      screen->base.pScreen = pScreen;
+
+      if (strstr(wgl_extensions, "WGL_ARB_pixel_format"))
+        {
+          glxWinCreateConfigsExt(hdc, screen);
+          screen->has_WGL_ARB_pixel_format = TRUE;
+        }
+      else
+        {
+          glxWinCreateConfigs(hdc, screen);
+          screen->has_WGL_ARB_pixel_format = FALSE;
+        }
+      // Initializes screen->base.fbconfigs and screen->base.numFBConfigs
+
+      /* These will be set by __glXScreenInit */
+      screen->base.visuals = NULL;
+      screen->base.numVisuals = 0;
+
+      __glXScreenInit(&screen->base, pScreen);
+
+      // dump out fbConfigs now fbConfigIds and visualIDs have been assigned
+      fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs);
+
+      // Override the GL extensions string set by __glXScreenInit()
+      screen->base.GLextensions = xstrdup(gl_extensions);
+
+      // Generate the GLX extensions string (overrides that set by __glXScreenInit())
+      {
+        unsigned int buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
+        if (buffer_size > 0)
+          {
+            if (screen->base.GLXextensions != NULL)
+              {
+                xfree(screen->base.GLXextensions);
+              }
+
+            screen->base.GLXextensions = xnfalloc(buffer_size);
+            __glXGetExtensionString(screen->glx_enable_bits, screen->base.GLXextensions);
+          }
+      }
+
+      //
+      // Override the GLX version (__glXScreenInit() sets it to "1.2")
+      // if we have all the needed extensionsto operate as a higher version
+      //
+      // SGIX_fbconfig && SGIX_pbuffer && SGI_make_current_read -> 1.3
+      // ARB_multisample -> 1.4
+      //
+      if (screen->has_WGL_ARB_pbuffer && glx_sgi_make_current_read)
+        {
+          xfree(screen->base.GLXversion);
+
+          if (screen->has_WGL_ARB_multisample)
+            {
+              screen->base.GLXversion = xstrdup("1.4");
+              screen->base.GLXmajor = 1;
+              screen->base.GLXminor = 4;
+            }
+          else
+            {
+              screen->base.GLXversion = xstrdup("1.3");
+              screen->base.GLXmajor = 1;
+              screen->base.GLXminor = 3;
+            }
+          LogMessage(X_INFO, "AIGLX: Set GLX version to %s\n", screen->base.GLXversion);
+        }
+    }
+
+    wglMakeCurrent(NULL, NULL);
+    wglDeleteContext(hglrc);
+    ReleaseDC(hwnd, hdc);
+    DestroyWindow(hwnd);
+
+    return &screen->base;
 }
 
-/* prototypes */
+/* ---------------------------------------------------------------------- */
+/*
+ * Window functions
+ */
+
+static Bool
+glxWinRealizeWindow(WindowPtr pWin)
+{
+    Bool result;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen);
+
+    GLWIN_DEBUG_MSG("glxWinRealizeWindow");
 
-static GLboolean glWinDestroyContext(__GLcontext *gc);
-static GLboolean glWinLoseCurrent(__GLcontext *gc);
-static GLboolean glWinMakeCurrent(__GLcontext *gc);
-static GLboolean glWinShareContext(__GLcontext *gc, __GLcontext *gcShare);
-static GLboolean glWinCopyContext(__GLcontext *dst, const __GLcontext *src,
-                            GLuint mask);
-static GLboolean glWinForceCurrent(__GLcontext *gc);
+    /* Allow the window to be created (RootlessRealizeWindow is inside our wrap) */
+    pScreen->RealizeWindow = screenPriv->RealizeWindow;
+    result = pScreen->RealizeWindow(pWin);
+    pScreen->RealizeWindow = glxWinRealizeWindow;
 
-/* Drawing surface notification callbacks */
-static GLboolean glWinNotifyResize(__GLcontext *gc);
-static void glWinNotifyDestroy(__GLcontext *gc);
-static void glWinNotifySwapBuffers(__GLcontext *gc);
+    return result;
+}
 
-/* Dispatch table override control for external agents like libGLS */
-static struct __GLdispatchStateRec* glWinDispatchExec(__GLcontext *gc);
-static void glWinBeginDispatchOverride(__GLcontext *gc);
-static void glWinEndDispatchOverride(__GLcontext *gc);
 
-/* Debug output */
-static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd);
+static void
+glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+    __GLXWinDrawable *pGlxDraw;
+    ScreenPtr pScreen = pWindow->drawable.pScreen;
+    glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen);
 
-static __GLexports glWinExports = {
-    glWinDestroyContext,
-    glWinLoseCurrent,
-    glWinMakeCurrent,
-    glWinShareContext,
-    glWinCopyContext,
-    glWinForceCurrent,
-
-    glWinNotifyResize,
-    glWinNotifyDestroy,
-    glWinNotifySwapBuffers,
-
-    glWinDispatchExec,
-    glWinBeginDispatchOverride,
-    glWinEndDispatchOverride
-};
+    GLWIN_TRACE_MSG("glxWinCopyWindow pWindow %p", pWindow);
 
-glWinScreenRec glWinScreens[MAXSCREENS];
+    dixLookupResourceByType((pointer) &pGlxDraw, pWindow->drawable.id, __glXDrawableRes,
+				NullClient, DixUnknownAccess);
 
-/* __GLdrawablePrivate->private */
-typedef struct {
-    DrawablePtr pDraw;
-  /*    xp_surface_id sid; */
-} GLWinDrawableRec;
 
-struct __GLcontextRec {
-  struct __GLinterfaceRec interface; /* required to be first */
+    /*
+       Discard any CopyWindow requests if a GL drawing context is pointing at the window
 
-  HGLRC ctx;                         /* Windows GL Context */
-  
-  HDC dc;                            /* Windows Device Context */
-  winWindowInfoRec winInfo;          /* Window info from XWin */
-  
-  PIXELFORMATDESCRIPTOR pfd;         /* Pixelformat flags */
-  int pixelFormat;                   /* Pixelformat index */
-
-  unsigned isAttached :1;            /* Flag to track if context is attached */
-};
+       For regions which are being drawn by GL, the shadow framebuffer doesn't have the
+       correct bits, so we wish to avoid shadow framebuffer damage occuring, which will
+       cause those incorrect bits to be transferred to the display....
+    */
+    if (pGlxDraw && pGlxDraw->drawContext)
+      {
+        GLWIN_DEBUG_MSG("glxWinCopyWindow: discarding");
+        return;
+      }
+
+    GLWIN_DEBUG_MSG("glxWinCopyWindow - passing to hw layer");
+
+    pScreen->CopyWindow = screenPriv->CopyWindow;
+    pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc);
+    pScreen->CopyWindow = glxWinCopyWindow;
+}
 
-static HDC glWinMakeDC(__GLcontext *gc)
+static Bool
+glxWinUnrealizeWindow(WindowPtr pWin)
+{
+    Bool result;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    glxWinScreen *screenPriv = (glxWinScreen *)glxGetScreen(pScreen);
+
+    GLWIN_DEBUG_MSG("glxWinUnrealizeWindow");
+
+    pScreen->UnrealizeWindow = screenPriv->UnrealizeWindow;
+    result = pScreen->UnrealizeWindow(pWin);
+    pScreen->UnrealizeWindow = glxWinUnrealizeWindow;
+
+    return result;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Drawable functions
+ */
+
+static GLboolean
+glxWinDrawableSwapBuffers(ClientPtr client, __GLXdrawable *base)
 {
     HDC dc;
+    HWND hwnd;
+    BOOL ret;
+    __GLXWinDrawable *draw = (__GLXWinDrawable *)base;
 
-    /*if (gc->winInfo.hrgn == NULL) 
-    {
-        GLWIN_DEBUG_MSG("Creating region from RECT(%ld,%ld,%ld,%ld):",
-                gc->winInfo.rect.left,
-                gc->winInfo.rect.top,
-                gc->winInfo.rect.right,
-                gc->winInfo.rect.bottom);
-        gc->winInfo.hrgn = CreateRectRgnIndirect(&gc->winInfo.rect);
-        GLWIN_DEBUG_MSG2("%p\n", gc->winInfo.hrgn);
-    }*/
-
-    if (glWinDebugSettings.enableTrace)
-        GLWIN_DEBUG_HWND(gc->winInfo.hwnd);
-
-    dc = GetDC(gc->winInfo.hwnd); 
-    /*dc = GetDCEx(gc->winInfo.hwnd, gc->winInfo.hrgn, 
-            DCX_WINDOW | DCX_NORESETATTRS ); */
+    /* Swap buffers on the last active context for drawing on the drawable */
+    if (draw->drawContext == NULL)
+      {
+        GLWIN_TRACE_MSG("glxWinSwapBuffers - no context for drawable");
+        return GL_FALSE;
+      }
+
+    GLWIN_TRACE_MSG("glxWinSwapBuffers on drawable %p, last context %p (native ctx %p)", base, draw->drawContext, draw->drawContext->ctx);
+
+    /*
+       draw->drawContext->base.drawPriv will not be set if the context is not current anymore,
+       but if it is, it should point to this drawable....
+    */
+    assert((draw->drawContext->base.drawPriv == NULL) || (draw->drawContext->base.drawPriv == base));
 
+    dc = glxWinMakeDC(draw->drawContext, draw, &dc, &hwnd);
     if (dc == NULL)
-        ErrorF("GetDC error: %s\n", glWinErrorMessage());
-    return dc;
+      return GL_FALSE;
+
+    ret = wglSwapLayerBuffers(dc, WGL_SWAP_MAIN_PLANE);
+
+    glxWinReleaseDC(hwnd, dc, draw);
+
+    if (!ret)
+      {
+        ErrorF("wglSwapBuffers failed: %s\n", glxWinErrorMessage());
+        return GL_FALSE;
+      }
+
+    return GL_TRUE;
 }
 
-static void unattach(__GLcontext *gc)
+static void
+glxWinDrawableCopySubBuffer(__GLXdrawable *drawable,
+                            int x, int y, int w, int h)
 {
-    BOOL ret;
-    GLWIN_DEBUG_MSG("unattach (ctx %p)\n", gc->ctx);
-    if (!gc->isAttached) 
+  glAddSwapHintRectWINWrapperNonstatic(x, y, w, h);
+  glxWinDrawableSwapBuffers(NULL, drawable);
+}
+
+static void
+glxWinDrawableDestroy(__GLXdrawable *base)
+{
+  __GLXWinDrawable *glxPriv = (__GLXWinDrawable *)base;
+
+  if (glxPriv->drawContext && (__glXLastContext == &((glxPriv->drawContext)->base)))
     {
-        ErrorF("called unattach on an unattached context\n");
-        return;
+      // if this context is current and has unflushed commands, say we have flushed them
+      // (don't actually flush them, the window is going away anyhow, and an implict flush occurs
+      // on the next context change)
+      // (GLX core considers it an error when we try to select a new current context if the old one
+      // has unflushed commands, but the window has disappeared..)
+      __GLX_NOTE_FLUSHED_CMDS(__glXLastContext);
+      __glXLastContext = NULL;
     }
 
-    if (gc->ctx) 
+  if (glxPriv->hPbuffer)
+    if (!wglDestroyPbufferARBWrapper(glxPriv->hPbuffer))
+      {
+        ErrorF("wglDestroyPbufferARB failed: %s\n", glxWinErrorMessage());
+      }
+
+  if (glxPriv->dibDC)
     {
-        ret = wglDeleteContext(gc->ctx);
-        if (!ret)
-            ErrorF("wglDeleteContext error: %s\n", glWinErrorMessage());
-        gc->ctx = NULL;
+      // restore the default DIB
+      SelectObject(glxPriv->dibDC, glxPriv->hOldDIB);
+
+      if (!DeleteDC(glxPriv->dibDC))
+        {
+          ErrorF("DeleteDC failed: %s\n", glxWinErrorMessage());
+        }
     }
 
-    if (gc->winInfo.hrgn)
+  if (glxPriv->hDIB)
     {
-        ret = DeleteObject(gc->winInfo.hrgn);
-        if (!ret)
-            ErrorF("DeleteObject error: %s\n", glWinErrorMessage());
-        gc->winInfo.hrgn = NULL;
+      if (!DeleteObject(glxPriv->hDIB))
+        {
+          ErrorF("DeleteObject failed: %s\n", glxWinErrorMessage());
+        }
+
+      ((PixmapPtr)glxPriv->base.pDraw)->devPrivate.ptr = glxPriv->pOldBits;
     }
 
-    gc->isAttached = 0;
+  GLWIN_DEBUG_MSG("glxWinDestroyDrawable");
+  xfree(glxPriv);
 }
 
-static BOOL glWinAdjustHWND(__GLcontext *gc, WindowPtr pWin)
+static __GLXdrawable *
+glxWinCreateDrawable(__GLXscreen *screen,
+                    DrawablePtr pDraw,
+                    int type,
+                    XID drawId,
+                    __GLXconfig *conf)
 {
-    HDC dc;
-    BOOL ret;
-    HGLRC newctx;
-    HWND oldhwnd;
+  __GLXWinDrawable *glxPriv;
 
-    GLWIN_DEBUG_MSG("glWinAdjustHWND (ctx %p, pWin %p)\n", gc->ctx, pWin);
+  glxPriv = xalloc(sizeof *glxPriv);
 
-    if (pWin == NULL)
-    {
-        GLWIN_DEBUG_MSG("Deferring until window is created\n");
-        return FALSE;
-    }
+  if (glxPriv == NULL)
+      return NULL;
+
+  memset(glxPriv, 0, sizeof *glxPriv);
+
+  if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, drawId, conf)) {
+    xfree(glxPriv);
+    return NULL;
+  }
 
-    oldhwnd = gc->winInfo.hwnd;
-    winGetWindowInfo(pWin, &gc->winInfo);
-    
-    GLWIN_DEBUG_HWND(gc->winInfo.hwnd);
-    if (gc->winInfo.hwnd == NULL)
+  glxPriv->base.destroy       = glxWinDrawableDestroy;
+  glxPriv->base.swapBuffers   = glxWinDrawableSwapBuffers;
+  glxPriv->base.copySubBuffer = glxWinDrawableCopySubBuffer;
+  // glxPriv->base.waitX  what are these for?
+  // glxPriv->base.waitGL
+
+  GLWIN_DEBUG_MSG("glxWinCreateDrawable %p", glxPriv);
+
+  return &glxPriv->base;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Texture functions
+ */
+
+static
+int glxWinBindTexImage(__GLXcontext  *baseContext,
+                      int            buffer,
+                      __GLXdrawable *pixmap)
+{
+  ErrorF("glxWinBindTexImage: not implemented\n");
+  return FALSE;
+}
+
+static
+int glxWinReleaseTexImage(__GLXcontext  *baseContext,
+                         int            buffer,
+                         __GLXdrawable *pixmap)
+{
+  ErrorF(" glxWinReleaseTexImage: not implemented\n");
+  return FALSE;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Lazy update context implementation
+ *
+ * WGL contexts are created for a specific HDC, so we cannot create the WGL
+ * context in glxWinCreateContext(), we must defer creation until the context
+ * is actually used on a specifc drawable which is connected to a native window,
+ * pbuffer or DIB
+ *
+ * The WGL context may be used on other, compatible HDCs, so we don't need to
+ * recreate it for every new native window
+ *
+ * XXX: I wonder why we can't create the WGL context on the screen HDC ?
+ * Basically we assume all HDCs are compatible at the moment: if they are not
+ * we are in a muddle, there was some code in the old implementation to attempt
+ * to transparently migrate a context to a new DC by copying state and sharing
+ * lists with the old one...
+ */
+
+static void
+glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawableTypeOverride)
+{
+  __GLXscreen *screen = gc->base.pGlxScreen;
+  glxWinScreen *winScreen = (glxWinScreen *)screen;
+
+  __GLXconfig *config = gc->base.config;
+  GLXWinConfig *winConfig = (GLXWinConfig *)config;
+
+  GLWIN_DEBUG_MSG("glxWinSetPixelFormat: pixelFormatIndex %d", winConfig->pixelFormatIndex);
+
+  /*
+    Normally, we can just use the the pixelFormatIndex corresponding
+    to the fbconfig which has been specified by the client
+  */
+
+  if (!((bppOverride && (bppOverride != (config->redBits + config->greenBits + config->blueBits) ))
+        || ((config->drawableType & drawableTypeOverride) == 0)))
     {
-        GLWIN_DEBUG_MSG("Deferring until window is created\n");
-        return FALSE;
+      if (!SetPixelFormat(hdc, winConfig->pixelFormatIndex, NULL))
+        {
+          ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
+          return;
+        }
+
+      return;
     }
 
-    dc = glWinMakeDC(gc);
-    
-    if (glWinDebugSettings.dumpDC)
-        GLWIN_DEBUG_MSG("Got HDC %p\n", dc);
-    
-    gc->pixelFormat = ChoosePixelFormat(dc, &gc->pfd);
-    if (gc->pixelFormat == 0)
+  /*
+    However, in certain special cases this pixel format will be incompatible with the
+    use we are going to put it to, so we need to re-evaluate the pixel format to use:
+
+    1) When PFD_DRAW_TO_BITMAP is set, ChoosePixelFormat() always returns a format with
+       the cColorBits we asked for, so we need to ensure it matches the bpp of the bitmap
+
+    2) Applications may assume that visuals selected with glXChooseVisual() work with
+       pixmap drawables (there is no attribute to explicitly query for pixmap drawable
+       support as there is for glXChooseFBConfig())
+       (it's arguable this is an error in the application, but we try to make it work)
+
+       pixmap rendering is always slow for us, so we don't want to choose those visuals
+       by default, but if the actual drawable type we're trying to select the context
+       on (drawableTypeOverride) isn't supported by the selected fbConfig, reconsider
+       and see if we can find a suitable one...
+   */
+  ErrorF("glxWinSetPixelFormat: having second thoughts: cColorbits %d, bppOveride %d; config->drawableType %d, drawableTypeOverride %d\n",
+         (config->redBits + config->greenBits + config->blueBits), bppOverride, config->drawableType, drawableTypeOverride);
+
+  if (!winScreen->has_WGL_ARB_pixel_format)
     {
-        ErrorF("ChoosePixelFormat error: %s\n", glWinErrorMessage());
-        ReleaseDC(gc->winInfo.hwnd, dc);
-        return FALSE;  
-    }
-    
-    ret = SetPixelFormat(dc, gc->pixelFormat, &gc->pfd);
-    if (!ret) {
-        ErrorF("SetPixelFormat error: %s\n", glWinErrorMessage());
-        ReleaseDC(gc->winInfo.hwnd, dc);
-        return FALSE;
+      PIXELFORMATDESCRIPTOR pfd;
+      int pixelFormat;
+
+      /* convert fbConfig to PFD */
+      if (fbConfigToPixelFormat(gc->base.config, &pfd, drawableTypeOverride))
+        {
+          ErrorF("glxWinSetPixelFormat: fbConfigToPixelFormat failed\n");
+          return;
+        }
+
+      if (glxWinDebugSettings.dumpPFD)
+        pfdOut(&pfd);
+
+      if (bppOverride)
+        {
+          GLWIN_DEBUG_MSG("glxWinSetPixelFormat: Forcing bpp from %d to %d\n", pfd.cColorBits, bppOverride);
+          pfd.cColorBits = bppOverride;
+        }
+
+      pixelFormat = ChoosePixelFormat(hdc, &pfd);
+      if (pixelFormat == 0)
+        {
+          ErrorF("ChoosePixelFormat error: %s\n", glxWinErrorMessage());
+          return;
+        }
+
+      GLWIN_DEBUG_MSG("ChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat);
+      ErrorF("ChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex);
+
+      if (!SetPixelFormat(hdc, pixelFormat, &pfd))
+        {
+          ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
+          return;
+        }
     }
-    
-    newctx = wglCreateContext(dc);
-    if (newctx == NULL) {
-        ErrorF("wglCreateContext error: %s\n", glWinErrorMessage());
-        ReleaseDC(gc->winInfo.hwnd, dc);
-        return FALSE;
+  else
+    {
+      int pixelFormat = fbConfigToPixelFormatIndex(hdc, gc->base.config, drawableTypeOverride, winScreen);
+      if (pixelFormat == 0)
+        {
+          ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
+          return;
+        }
+
+      GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat);
+      ErrorF("wglChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex);
+
+      if (!SetPixelFormat(hdc, pixelFormat, NULL))
+        {
+          ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
+          return;
+        }
     }
-    
-    GLWIN_DEBUG_MSG("wglCreateContext (ctx %p)\n", newctx);
+}
 
-    if (!wglShareLists(gc->ctx, newctx))
+static HDC
+glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd)
+{
+  *hdc = NULL;
+  *hwnd = NULL;
+
+  if (draw == NULL)
     {
-        ErrorF("wglShareLists error: %s\n", glWinErrorMessage());
-        ReleaseDC(gc->winInfo.hwnd, dc);
-        return FALSE;
+      GLWIN_TRACE_MSG("No drawable for context %p (native ctx %p)", gc, gc->ctx);
+      return NULL;
     }
-    
-    if (oldhwnd != gc->winInfo.hwnd)
+
+  switch (draw->base.type)
+  {
+    case GLX_DRAWABLE_WINDOW:
     {
-        GLWIN_DEBUG_MSG("Trying wglCopyContext\n");
-        if (!wglCopyContext(gc->ctx, newctx, GL_ALL_ATTRIB_BITS))
+      WindowPtr pWin;
+
+      pWin = (WindowPtr) draw->base.pDraw;
+      if (pWin == NULL)
+        {
+          GLWIN_TRACE_MSG("for drawable %p, no WindowPtr", pWin);
+          return NULL;
+        }
+
+      *hwnd = winGetWindowInfo(pWin);
+
+      if (*hwnd == NULL)
         {
-            ErrorF("wglCopyContext error: %s\n", glWinErrorMessage());
-            ReleaseDC(gc->winInfo.hwnd, dc);
-            return FALSE;
+          ErrorF("No HWND error: %s\n", glxWinErrorMessage());
+          return NULL;
+        }
+
+      *hdc = GetDC(*hwnd);
+
+      if (*hdc == NULL)
+        ErrorF("GetDC error: %s\n", glxWinErrorMessage());
+
+      /* Check if the hwnd has changed... */
+      if (*hwnd != gc->hwnd)
+        {
+          if (glxWinDebugSettings.enableTrace)
+            GLWIN_DEBUG_HWND(*hwnd);
+
+          GLWIN_TRACE_MSG("for context %p (native ctx %p), hWnd changed from %p to %p", gc, gc->ctx, gc->hwnd, *hwnd);
+          gc->hwnd = *hwnd;
+
+          /* We must select a pixelformat, but SetPixelFormat can only be called once for a window... */
+          glxWinSetPixelFormat(gc, *hdc, 0, GLX_WINDOW_BIT);
         }
     }
+    break;
 
-    if (!wglDeleteContext(gc->ctx))
+  case GLX_DRAWABLE_PBUFFER:
     {
-        ErrorF("wglDeleteContext error: %s\n", glWinErrorMessage());
+      *hdc = wglGetPbufferDCARBWrapper(draw->hPbuffer);
+
+      if (*hdc == NULL)
+        ErrorF("GetDC (pbuffer) error: %s\n", glxWinErrorMessage());
     }
+    break;
 
-    gc->ctx = newctx;
+  case GLX_DRAWABLE_PIXMAP:
+    {
+      *hdc = draw->dibDC;
+    }
+    break;
 
-    if (!wglMakeCurrent(dc, gc->ctx)) {
-        ErrorF("glMakeCurrent error: %s\n", glWinErrorMessage());
-        ReleaseDC(gc->winInfo.hwnd, dc);
-        return FALSE;
+  default:
+    {
+      ErrorF("glxWinMakeDC: tried to makeDC for unhandled drawable type %d\n", draw->base.type);
     }
+  }
 
-    ReleaseDC(gc->winInfo.hwnd, dc);
+  if (glxWinDebugSettings.dumpDC)
+    GLWIN_DEBUG_MSG("Got HDC %p", *hdc);
 
-    return TRUE;
+  return *hdc;
 }
 
-static BOOL glWinCreateContextReal(__GLcontext *gc, WindowPtr pWin)
+static void
+glxWinReleaseDC(HWND hwnd, HDC hdc,__GLXWinDrawable *draw)
 {
-    HDC dc;
-    BOOL ret;
+  switch (draw->base.type)
+  {
+    case GLX_DRAWABLE_WINDOW:
+    {
+      ReleaseDC(hwnd, hdc);
+    }
+    break;
 
-    GLWIN_DEBUG_MSG("glWinCreateContextReal (pWin %p)\n", pWin);
+  case GLX_DRAWABLE_PBUFFER:
+    {
+      if (!wglReleasePbufferDCARBWrapper(draw->hPbuffer, hdc))
+        {
+          ErrorF("wglReleasePbufferDCARB error: %s\n", glxWinErrorMessage());
+        }
+    }
+    break;
 
-    if (pWin == NULL)
+  case GLX_DRAWABLE_PIXMAP:
     {
-        GLWIN_DEBUG_MSG("Deferring until window is created\n");
-        return FALSE;
+      // don't release DC, the memory DC lives as long as the bitmap
+
+      // We must ensure that all GDI drawing into the bitmap has completed
+      // in case we subsequently access the bits from it
+      GdiFlush();
     }
+    break;
 
-    winGetWindowInfo(pWin, &gc->winInfo);
-    
-    GLWIN_DEBUG_HWND(gc->winInfo.hwnd);
-    if (gc->winInfo.hwnd == NULL)
+  default:
     {
-        GLWIN_DEBUG_MSG("Deferring until window is created\n");
-        return FALSE;
+      ErrorF("glxWinReleaseDC: tried to releaseDC for unhandled drawable type %d\n", draw->base.type);
     }
+  }
+}
 
-    
-    dc = glWinMakeDC(gc);
-    
-    if (glWinDebugSettings.dumpDC)
-        GLWIN_DEBUG_MSG("Got HDC %p\n", dc);
-    
-    gc->pixelFormat = ChoosePixelFormat(dc, &gc->pfd);
-    if (gc->pixelFormat == 0)
+static void
+glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw)
+{
+  HDC dc;
+  HWND hwnd;
+  GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attach context %p to drawable %p", gc, draw);
+
+  switch (draw->base.type)
+  {
+    case GLX_DRAWABLE_WINDOW:
     {
-        ErrorF("ChoosePixelFormat error: %s\n", glWinErrorMessage());
-        ReleaseDC(gc->winInfo.hwnd, dc);
-        return FALSE;  
+      WindowPtr pWin = (WindowPtr) draw->base.pDraw;
+
+      if (!(gc->base.config->drawableType & GLX_WINDOW_BIT))
+        {
+          ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_WINDOW_BIT to a GLX_DRAWABLE_WINDOW drawable\n");
+        }
+
+      if (pWin == NULL)
+        {
+          GLWIN_DEBUG_MSG("Deferring until X window is created");
+          return;
+        }
+
+      GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pWin %p", pWin);
+
+      if (winGetWindowInfo(pWin) == NULL)
+        {
+          GLWIN_DEBUG_MSG("Deferring until native window is created");
+          return;
+        }
+    }
+    break;
+
+    case GLX_DRAWABLE_PBUFFER:
+    {
+      if (draw->hPbuffer == NULL)
+        {
+          __GLXscreen *screen;
+          glxWinScreen *winScreen;
+          int pixelFormat;
+          // XXX: which DC are supposed to use???
+          HDC screenDC = GetDC(NULL);
+
+          if (!(gc->base.config->drawableType & GLX_PBUFFER_BIT))
+            {
+              ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PBUFFER_BIT to a GLX_DRAWABLE_PBUFFER drawable\n");
+            }
+
+          screen = gc->base.pGlxScreen;
+          winScreen = (glxWinScreen *)screen;
+
+          pixelFormat = fbConfigToPixelFormatIndex(screenDC, gc->base.config, GLX_DRAWABLE_PBUFFER, winScreen);
+          if (pixelFormat == 0)
+            {
+              ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
+              return;
+            }
+
+          draw->hPbuffer = wglCreatePbufferARBWrapper(screenDC, pixelFormat, draw->base.pDraw->width, draw->base.pDraw->height, NULL);
+          ReleaseDC(NULL, screenDC);
+
+          if (draw->hPbuffer == NULL)
+            {
+              ErrorF("wglCreatePbufferARBWrapper error: %s\n", glxWinErrorMessage());
+              return;
+            }
+
+          GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pBuffer %p created for drawable %p", draw->hPbuffer, draw);
+        }
     }
-    
-    ret = SetPixelFormat(dc, gc->pixelFormat, &gc->pfd);
-    if (!ret) {
-        ErrorF("SetPixelFormat error: %s\n", glWinErrorMessage());
-        ReleaseDC(gc->winInfo.hwnd, dc);
-        return FALSE;
+    break;
+
+    case GLX_DRAWABLE_PIXMAP:
+    {
+      if (draw->dibDC == NULL)
+        {
+          BITMAPINFOHEADER bmpHeader;
+          void *pBits;
+
+          memset (&bmpHeader, 0, sizeof(BITMAPINFOHEADER));
+          bmpHeader.biSize = sizeof(BITMAPINFOHEADER);
+          bmpHeader.biWidth = draw->base.pDraw->width;
+          bmpHeader.biHeight = draw->base.pDraw->height;
+          bmpHeader.biPlanes = 1;
+          bmpHeader.biBitCount = draw->base.pDraw->bitsPerPixel;
+          bmpHeader.biCompression = BI_RGB;
+
+          if (!(gc->base.config->drawableType & GLX_PIXMAP_BIT))
+            {
+              ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PIXMAP_BIT to a GLX_DRAWABLE_PIXMAP drawable\n");
+            }
+
+          draw->dibDC = CreateCompatibleDC(NULL);
+          if (draw->dibDC == NULL)
+            {
+              ErrorF("CreateCompatibleDC error: %s\n", glxWinErrorMessage());
+              return;
+            }
+
+          draw->hDIB = CreateDIBSection(draw->dibDC, (BITMAPINFO *)&bmpHeader, DIB_RGB_COLORS, &pBits, 0, 0);
+          if (draw->dibDC == NULL)
+            {
+              ErrorF("CreateDIBSection error: %s\n", glxWinErrorMessage());
+              return;
+            }
+
+          // XXX: CreateDIBSection insists on allocating the bitmap memory for us, so we're going to
+          // need some jiggery pokery to point the underlying X Drawable's bitmap at the same set of bits
+          // so that they can be read with XGetImage as well as glReadPixels, assuming the formats are
+          // even compatible ...
+          draw->pOldBits = ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr;
+          ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr = pBits;
+
+          // Select the DIB into the DC
+          draw->hOldDIB = SelectObject(draw->dibDC, draw->hDIB);
+          if (!draw->hOldDIB)
+            {
+              ErrorF("SelectObject error: %s\n", glxWinErrorMessage());
+            }
+
+          // Set the pixel format of the bitmap
+          glxWinSetPixelFormat(gc, draw->dibDC, draw->base.pDraw->bitsPerPixel, GLX_PIXMAP_BIT);
+
+          GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: DIB bitmap %p created for drawable %p", draw->hDIB, draw);
+        }
     }
-    
-    gc->ctx = wglCreateContext(dc);
-    if (gc->ctx == NULL) {
-        ErrorF("wglCreateContext error: %s\n", glWinErrorMessage());
-        ReleaseDC(gc->winInfo.hwnd, dc);
-        return FALSE;
+    break;
+
+    default:
+    {
+      ErrorF("glxWinDeferredCreateContext: tried to attach unhandled drawable type %d\n", draw->base.type);
+      return;
     }
+  }
 
-    GLWIN_DEBUG_MSG("glWinCreateContextReal (ctx %p)\n", gc->ctx);
+  dc = glxWinMakeDC(gc, draw, &dc, &hwnd);
+  gc->ctx = wglCreateContext(dc);
+  glxWinReleaseDC(hwnd, dc, draw);
 
-    if (!wglMakeCurrent(dc, gc->ctx)) {
-        ErrorF("glMakeCurrent error: %s\n", glWinErrorMessage());
-        ReleaseDC(gc->winInfo.hwnd, dc);
-        return FALSE;
+  if (gc->ctx == NULL)
+    {
+      ErrorF("wglCreateContext error: %s\n", glxWinErrorMessage());
+      return;
     }
 
-    ReleaseDC(gc->winInfo.hwnd, dc);
+  GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attached context %p to native context %p drawable %p", gc, gc->ctx, draw);
+
+  // if the native context was created successfully, shareLists if needed
+  if (gc->ctx && gc->shareContext)
+    {
+      GLWIN_DEBUG_MSG("glxWinCreateContextReal shareLists with context %p (native ctx %p)", gc->shareContext, gc->shareContext->ctx);
 
-    return TRUE;
+      if (!wglShareLists(gc->shareContext->ctx, gc->ctx))
+        {
+          ErrorF("wglShareLists error: %s\n", glxWinErrorMessage());
+        }
+    }
 }
 
-static void attach(__GLcontext *gc, __GLdrawablePrivate *glPriv)
+/* ---------------------------------------------------------------------- */
+/*
+ * Context functions
+ */
+
+
+/* Context manipulation routines should return TRUE on success, FALSE on failure */
+static int
+glxWinContextMakeCurrent(__GLXcontext *base)
 {
-    __GLXdrawablePrivate *glxPriv = (__GLXdrawablePrivate *)glPriv->other;
+  __GLXWinContext *gc = (__GLXWinContext *)base;
+  BOOL ret;
+  HDC drawDC;
+  HDC readDC = NULL;
+  __GLXdrawable *drawPriv;
+  __GLXdrawable *readPriv = NULL;
+  HWND hDrawWnd;
+  HWND hReadWnd;
+
+  GLWIN_TRACE_MSG("glxWinContextMakeCurrent context %p (native ctx %p)", gc, gc->ctx);
+  glWinCallDelta();
+
+  /* Keep a note of the last active context in the drawable */
+  drawPriv = gc->base.drawPriv;
+  ((__GLXWinDrawable *)drawPriv)->drawContext = gc;
+
+  if (gc->ctx == NULL)
+    {
+      glxWinDeferredCreateContext(gc, (__GLXWinDrawable *)drawPriv);
+    }
 
-    GLWIN_DEBUG_MSG("attach (ctx %p)\n", gc->ctx);
+  if (gc->ctx == NULL)
+    {
+      ErrorF("glxWinContextMakeCurrent: Native context is NULL\n");
+      return FALSE;
+    }
 
-    if (gc->isAttached)
+  drawDC = glxWinMakeDC(gc, (__GLXWinDrawable *)drawPriv, &drawDC, &hDrawWnd);
+  if (drawDC == NULL)
     {
-        ErrorF("called attach on an attached context\n");
-        return;
+      ErrorF("glxWinMakeDC failed for drawDC\n");
+      return FALSE;
     }
 
-    if (glxPriv->type == DRAWABLE_WINDOW)
+  if ((gc->base.readPriv != NULL) && (gc->base.readPriv != gc->base.drawPriv))
     {
-        WindowPtr pWin = (WindowPtr) glxPriv->pDraw;
-        if (pWin == NULL)
+      // XXX: should only occur with WGL_ARB_make_current_read
+      /*
+        If there is a separate read drawable, create a separate read DC, and
+        use the wglMakeContextCurrent extension to make the context current drawing
+        to one DC and reading from the other
+      */
+      readPriv = gc->base.readPriv;
+      readDC = glxWinMakeDC(gc, (__GLXWinDrawable *)readPriv, &readDC, &hReadWnd);
+      if (readDC == NULL)
         {
-            GLWIN_DEBUG_MSG("Deferring ChoosePixelFormat until window is created\n");
-        } else
+          ErrorF("glxWinMakeDC failed for readDC\n");
+          glxWinReleaseDC(hDrawWnd, drawDC, (__GLXWinDrawable *)drawPriv);
+          return FALSE;
+        }
+
+      ret = wglMakeContextCurrentARBWrapper(drawDC, readDC, gc->ctx);
+      if (!ret)
         {
-            if (glWinCreateContextReal(gc, pWin))
-            {
-                gc->isAttached = TRUE;
-                GLWIN_DEBUG_MSG("attached\n");
-            }
+          ErrorF("wglMakeContextCurrentARBWrapper error: %s\n", glxWinErrorMessage());
+        }
+    }
+  else
+    {
+      /* Otherwise, just use wglMakeCurrent */
+      ret = wglMakeCurrent(drawDC, gc->ctx);
+      if (!ret)
+        {
+          ErrorF("wglMakeCurrent error: %s\n", glxWinErrorMessage());
         }
     }
-}
 
-static GLboolean glWinLoseCurrent(__GLcontext *gc)
-{
-    GLWIN_TRACE_MSG("glWinLoseCurrent (ctx %p)\n", gc->ctx);
+  // apparently make current could fail if the context is current in a different thread,
+  // but that shouldn't be able to happen in the current server...
 
-    __glXLastContext = NULL; /* Mesa does this; why? */
+  glxWinReleaseDC(hDrawWnd, drawDC, (__GLXWinDrawable *)drawPriv);
+  if (readDC)
+    glxWinReleaseDC(hReadWnd, readDC, (__GLXWinDrawable *)readPriv);
 
-    return GL_TRUE;
+  return ret;
 }
 
-/* Context manipulation; return GL_FALSE on failure */
-static GLboolean glWinDestroyContext(__GLcontext *gc)
+static int
+glxWinContextLoseCurrent(__GLXcontext *base)
 {
-    GLWIN_DEBUG_MSG("glWinDestroyContext (ctx %p)\n", gc->ctx);
+  BOOL ret;
+  __GLXWinContext *gc = (__GLXWinContext *)base;
+
+  GLWIN_TRACE_MSG("glxWinContextLoseCurrent context %p (native ctx %p)", gc, gc->ctx);
+  glWinCallDelta();
 
-    if (gc != NULL)
+  /*
+     An error seems to be reported if we try to make no context current
+     if there is already no current context, so avoid doing that...
+  */
+  if (__glXLastContext != NULL)
     {
-        if (gc->isAttached)
-            unattach(gc);
-        if (gc->dc != NULL)
-            DeleteDC(gc->dc);
-        free(gc);
+      ret = wglMakeCurrent(NULL, NULL); /* We don't need a DC when setting no current context */
+      if (!ret)
+        ErrorF("glxWinContextLoseCurrent error: %s\n", glxWinErrorMessage());
     }
 
-    return GL_TRUE;
+  return TRUE;
 }
 
-static GLboolean glWinMakeCurrent(__GLcontext *gc)
+static int
+glxWinContextCopy(__GLXcontext *dst_base, __GLXcontext *src_base, unsigned long mask)
 {
-    __GLdrawablePrivate *glPriv = gc->interface.imports.getDrawablePrivate(gc);
-    BOOL ret;
-    HDC dc;
+  __GLXWinContext *dst = (__GLXWinContext *)dst_base;
+  __GLXWinContext *src = (__GLXWinContext *)src_base;
+  BOOL ret;
 
-    GLWIN_TRACE_MSG(" (ctx %p)\n", gc->ctx);
+  GLWIN_DEBUG_MSG("glxWinContextCopy");
 
-    if (!gc->isAttached)
-        attach(gc, glPriv);
-
-    if (gc->ctx == NULL) {
-        ErrorF("Context is NULL\n");
-        return GL_FALSE;
+  ret = wglCopyContext(src->ctx, dst->ctx, mask);
+  if (!ret)
+    {
+      ErrorF("wglCopyContext error: %s\n", glxWinErrorMessage());
     }
 
-    dc = glWinMakeDC(gc);
-    ret = wglMakeCurrent(dc, gc->ctx);
-    if (!ret)
-        ErrorF("glMakeCurrent error: %s\n", glWinErrorMessage());
-    ReleaseDC(gc->winInfo.hwnd, dc);
-
-    return ret?GL_TRUE:GL_FALSE;
+  return ret;
 }
 
-static GLboolean glWinShareContext(__GLcontext *gc, __GLcontext *gcShare)
+static int
+glxWinContextForceCurrent(__GLXcontext *base)
 {
-  GLWIN_DEBUG_MSG("glWinShareContext unimplemented\n");
-
-  return GL_TRUE;
+  /* wglMakeCurrent always flushes the previous context, so this is equivalent to glxWinContextMakeCurrent */
+  return glxWinContextMakeCurrent(base);
 }
 
-static GLboolean glWinCopyContext(__GLcontext *dst, const __GLcontext *src,
-                                   GLuint mask)
+static void
+glxWinContextDestroy(__GLXcontext *base)
 {
-    BOOL ret;
+  __GLXWinContext *gc = (__GLXWinContext *)base;
 
-    GLWIN_DEBUG_MSG("glWinCopyContext\n");
-    
-    ret = wglCopyContext(src->ctx, dst->ctx, mask);
-    if (!ret) 
+  if (gc != NULL)
     {
-        ErrorF("wglCopyContext error: %s\n", glWinErrorMessage());
-        return GL_FALSE;
-    }
+      GLWIN_DEBUG_MSG("GLXcontext %p destroyed (native ctx %p)", base, gc->ctx);
 
-    return GL_TRUE;
+      if (gc->ctx)
+        {
+          /* It's bad style to delete the context while it's still current */
+          if (wglGetCurrentContext() == gc->ctx)
+            {
+              wglMakeCurrent(NULL, NULL);
+            }
+
+          {
+            BOOL ret = wglDeleteContext(gc->ctx);
+            if (!ret)
+              ErrorF("wglDeleteContext error: %s\n", glxWinErrorMessage());
+          }
+
+          gc->ctx = NULL;
+        }
+
+      xfree(gc);
+    }
 }
 
-static GLboolean glWinForceCurrent(__GLcontext *gc)
+static __GLXcontext *
+glxWinCreateContext(__GLXscreen *screen,
+                   __GLXconfig *modes,
+                   __GLXcontext *baseShareContext)
 {
-    GLWIN_TRACE_MSG(" (ctx %p)\n", gc->ctx);
+    __GLXWinContext *context;
+    __GLXWinContext *shareContext = (__GLXWinContext *)baseShareContext;
 
-    return GL_TRUE;
-}
+    static __GLXtextureFromPixmap glxWinTextureFromPixmap =
+      {
+        glxWinBindTexImage,
+        glxWinReleaseTexImage
+      };
 
-/* Drawing surface notification callbacks */
+    context = (__GLXWinContext *)xcalloc(1, sizeof(__GLXWinContext));
 
-static GLboolean glWinNotifyResize(__GLcontext *gc)
-{
-    GLWIN_DEBUG_MSG("unimplemented glWinNotifyResize");
-    return GL_TRUE;
-}
+    if (!context)
+        return NULL;
 
-static void glWinNotifyDestroy(__GLcontext *gc)
-{
-    GLWIN_DEBUG_MSG("unimplemented glWinNotifyDestroy");
-}
+    memset(context, 0, sizeof *context);
+    context->base.destroy        = glxWinContextDestroy;
+    context->base.makeCurrent    = glxWinContextMakeCurrent;
+    context->base.loseCurrent    = glxWinContextLoseCurrent;
+    context->base.copy           = glxWinContextCopy;
+    context->base.forceCurrent   = glxWinContextForceCurrent;
+    context->base.textureFromPixmap = &glxWinTextureFromPixmap;
+    context->base.config = modes;
+    context->base.pGlxScreen = screen;
 
-static void glWinNotifySwapBuffers(__GLcontext *gc)
-{
-    GLWIN_DEBUG_MSG("unimplemented glWinNotifySwapBuffers");
-}
+    // actual native GL context creation is deferred until attach()
+    context->ctx = NULL;
+    context->shareContext = shareContext;
 
-/* Dispatch table override control for external agents like libGLS */
-static struct __GLdispatchStateRec* glWinDispatchExec(__GLcontext *gc)
-{
-    GLWIN_DEBUG_MSG("unimplemented glWinDispatchExec");
-    return NULL;
-}
+    glWinSetupDispatchTable();
 
-static void glWinBeginDispatchOverride(__GLcontext *gc)
-{
-    GLWIN_DEBUG_MSG("unimplemented glWinBeginDispatchOverride");
-}
+    GLWIN_DEBUG_MSG("GLXcontext %p created", context);
 
-static void glWinEndDispatchOverride(__GLcontext *gc)
-{
-    GLWIN_DEBUG_MSG("unimplemented glWinEndDispatchOverride");
+    return &(context->base);
 }
 
-#define DUMP_PFD_FLAG(flag) \
-    if (pfd->dwFlags & flag) { \
-        ErrorF("%s%s", pipesym, #flag); \
-        pipesym = " | "; \
-    }
-        
-static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd)
-{
-    const char *pipesym = ""; /* will be set after first flag dump */
-    ErrorF("PIXELFORMATDESCRIPTOR:\n");
-    ErrorF("nSize = %u\n", pfd->nSize);
-    ErrorF("nVersion = %u\n", pfd->nVersion);
-    ErrorF("dwFlags = %lu = {", pfd->dwFlags);
-        DUMP_PFD_FLAG(PFD_MAIN_PLANE);
-        DUMP_PFD_FLAG(PFD_OVERLAY_PLANE);
-        DUMP_PFD_FLAG(PFD_UNDERLAY_PLANE);
-        DUMP_PFD_FLAG(PFD_DOUBLEBUFFER);
-        DUMP_PFD_FLAG(PFD_STEREO);
-        DUMP_PFD_FLAG(PFD_DRAW_TO_WINDOW);
-        DUMP_PFD_FLAG(PFD_DRAW_TO_BITMAP);
-        DUMP_PFD_FLAG(PFD_SUPPORT_GDI);
-        DUMP_PFD_FLAG(PFD_SUPPORT_OPENGL);
-        DUMP_PFD_FLAG(PFD_GENERIC_FORMAT);
-        DUMP_PFD_FLAG(PFD_NEED_PALETTE);
-        DUMP_PFD_FLAG(PFD_NEED_SYSTEM_PALETTE);
-        DUMP_PFD_FLAG(PFD_SWAP_EXCHANGE);
-        DUMP_PFD_FLAG(PFD_SWAP_COPY);
-        DUMP_PFD_FLAG(PFD_SWAP_LAYER_BUFFERS);
-        DUMP_PFD_FLAG(PFD_GENERIC_ACCELERATED);
-        DUMP_PFD_FLAG(PFD_DEPTH_DONTCARE);
-        DUMP_PFD_FLAG(PFD_DOUBLEBUFFER_DONTCARE);
-        DUMP_PFD_FLAG(PFD_STEREO_DONTCARE);
-    ErrorF("}\n");
-    
-    ErrorF("iPixelType = %hu = %s\n", pfd->iPixelType, 
-            (pfd->iPixelType == PFD_TYPE_RGBA ? "PFD_TYPE_RGBA" : "PFD_TYPE_COLORINDEX"));
-    ErrorF("cColorBits = %hhu\n", pfd->cColorBits);
-    ErrorF("cRedBits = %hhu\n", pfd->cRedBits);
-    ErrorF("cRedShift = %hhu\n", pfd->cRedShift);
-    ErrorF("cGreenBits = %hhu\n", pfd->cGreenBits);
-    ErrorF("cGreenShift = %hhu\n", pfd->cGreenShift);
-    ErrorF("cBlueBits = %hhu\n", pfd->cBlueBits);
-    ErrorF("cBlueShift = %hhu\n", pfd->cBlueShift);
-    ErrorF("cAlphaBits = %hhu\n", pfd->cAlphaBits);
-    ErrorF("cAlphaShift = %hhu\n", pfd->cAlphaShift);
-    ErrorF("cAccumBits = %hhu\n", pfd->cAccumBits);
-    ErrorF("cAccumRedBits = %hhu\n", pfd->cAccumRedBits);
-    ErrorF("cAccumGreenBits = %hhu\n", pfd->cAccumGreenBits);
-    ErrorF("cAccumBlueBits = %hhu\n", pfd->cAccumBlueBits);
-    ErrorF("cAccumAlphaBits = %hhu\n", pfd->cAccumAlphaBits);
-    ErrorF("cDepthBits = %hhu\n", pfd->cDepthBits);
-    ErrorF("cStencilBits = %hhu\n", pfd->cStencilBits);
-    ErrorF("cAuxBuffers = %hhu\n", pfd->cAuxBuffers);
-    ErrorF("iLayerType = %hhu\n", pfd->iLayerType);
-    ErrorF("bReserved = %hhu\n", pfd->bReserved);
-    ErrorF("dwLayerMask = %lu\n", pfd->dwLayerMask);
-    ErrorF("dwVisibleMask = %lu\n", pfd->dwVisibleMask);
-    ErrorF("dwDamageMask = %lu\n", pfd->dwDamageMask);
-    ErrorF("\n");
-}    
+/* ---------------------------------------------------------------------- */
+/*
+ * Utility functions
+ */
 
-static int makeFormat(__GLcontextModes *mode, PIXELFORMATDESCRIPTOR *pfdret)
+static int
+fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride)
 {
     PIXELFORMATDESCRIPTOR pfd = {
       sizeof(PIXELFORMATDESCRIPTOR),   /* size of this pfd */
       1,                     /* version number */
-      PFD_DRAW_TO_WINDOW |   /* support window */
       PFD_SUPPORT_OPENGL,    /* support OpenGL */
       PFD_TYPE_RGBA,         /* RGBA type */
       24,                    /* 24-bit color depth */
@@ -672,934 +1580,737 @@ static int makeFormat(__GLcontextModes *mode, PIXELFORMATDESCRIPTOR *pfdret)
       0,                     /* shift bit ignored */
       0,                     /* no accumulation buffer */
       0, 0, 0, 0,            /* accum bits ignored */
-      0,                     /* 32-bit z-buffer */
+      32,                    /* 32-bit z-buffer */
       0,                     /* no stencil buffer */
       0,                     /* no auxiliary buffer */
       PFD_MAIN_PLANE,        /* main layer */
       0,                     /* reserved */
       0, 0, 0                /* layer masks ignored */
-    }, *result = &pfd;
+    };
+
+    if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT)
+      pfd.dwFlags |= PFD_DRAW_TO_WINDOW; /* support window */
+
+    if ((mode->drawableType | drawableTypeOverride) & GLX_PIXMAP_BIT)
+      pfd.dwFlags |= (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI); /* supports software rendering to bitmap */
 
-    /* disable anything but rgba. must get rgba to work first */
-    if (!mode->rgbMode) 
-        return -1; 
-    
     if (mode->stereoMode) {
-        result->dwFlags |= PFD_STEREO;
+        pfd.dwFlags |= PFD_STEREO;
     }
     if (mode->doubleBufferMode) {
-        result->dwFlags |= PFD_DOUBLEBUFFER;
+        pfd.dwFlags |= PFD_DOUBLEBUFFER;
     }
 
-    if (mode->colorIndexMode) {
-        /* ignored, see above */
-        result->iPixelType = PFD_TYPE_COLORINDEX; 
-        result->cColorBits = mode->redBits + mode->greenBits + mode->blueBits;
-        result->cRedBits = mode->redBits;
-        result->cRedShift = 0; /* FIXME */
-        result->cGreenBits = mode->greenBits;
-        result->cGreenShift = 0; /* FIXME  */
-        result->cBlueBits = mode->blueBits;
-        result->cBlueShift = 0; /* FIXME */
-        result->cAlphaBits = mode->alphaBits;
-        result->cAlphaShift = 0; /* FIXME */
-    }
+    pfd.iPixelType = PFD_TYPE_RGBA;
+    pfd.cColorBits = mode->redBits + mode->greenBits + mode->blueBits;
+    pfd.cRedBits = mode->redBits;
+    pfd.cRedShift = 0; /* FIXME */
+    pfd.cGreenBits = mode->greenBits;
+    pfd.cGreenShift = 0; /* FIXME  */
+    pfd.cBlueBits = mode->blueBits;
+    pfd.cBlueShift = 0; /* FIXME */
+    pfd.cAlphaBits = mode->alphaBits;
+    pfd.cAlphaShift = 0; /* FIXME */
+
+    pfd.cAccumBits = mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits + mode->accumAlphaBits;
+    pfd.cAccumRedBits = mode->accumRedBits;
+    pfd.cAccumGreenBits = mode->accumGreenBits;
+    pfd.cAccumBlueBits = mode->accumBlueBits;
+    pfd.cAccumAlphaBits = mode->accumAlphaBits;
+
+    pfd.cDepthBits = mode->depthBits;
+    pfd.cStencilBits = mode->stencilBits;
+    pfd.cAuxBuffers = mode->numAuxBuffers;
+
+    /* mode->level ? */
+    /* mode->pixmapMode ? */
 
-    if (mode->rgbMode) {
-        result->iPixelType = PFD_TYPE_RGBA;
-        result->cColorBits = mode->redBits + mode->greenBits + mode->blueBits;
-        result->cRedBits = mode->redBits;
-        result->cRedShift = 0; /* FIXME */
-        result->cGreenBits = mode->greenBits;
-        result->cGreenShift = 0; /* FIXME  */
-        result->cBlueBits = mode->blueBits;
-        result->cBlueShift = 0; /* FIXME */
-        result->cAlphaBits = mode->alphaBits;
-        result->cAlphaShift = 0; /* FIXME */
-    }
+    *pfdret = pfd;
 
-    if (mode->haveAccumBuffer) {
-        result->cAccumBits = mode->accumRedBits + mode->accumGreenBits
-            + mode->accumBlueBits + mode->accumAlphaBits;
-        result->cAccumRedBits = mode->accumRedBits;
-        result->cAccumGreenBits = mode->accumGreenBits;
-        result->cAccumBlueBits = mode->accumBlueBits;
-        result->cAccumAlphaBits = mode->accumAlphaBits;
-    }
-    
-    if (mode->haveDepthBuffer) {
-        result->cDepthBits = mode->depthBits;
-    }
-    if (mode->haveStencilBuffer) {
-        result->cStencilBits = mode->stencilBits;
+    return 0;
+}
+
+#define SET_ATTR_VALUE(attr, value) { attribList[i++] = attr; attribList[i++] = value; assert(i < NUM_ELEMENTS(attribList)); }
+
+static int
+fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen)
+{
+  UINT numFormats;
+  unsigned int i = 0;
+
+  /* convert fbConfig to attr-value list  */
+  int attribList[60];
+
+  SET_ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, TRUE);
+  SET_ATTR_VALUE(WGL_PIXEL_TYPE_ARB, (mode->visualType == GLX_TRUE_COLOR) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB);
+  SET_ATTR_VALUE(WGL_COLOR_BITS_ARB, (mode->visualType == GLX_TRUE_COLOR) ? mode->rgbBits : mode->indexBits);
+  SET_ATTR_VALUE(WGL_RED_BITS_ARB, mode->redBits);
+  SET_ATTR_VALUE(WGL_GREEN_BITS_ARB, mode->greenBits);
+  SET_ATTR_VALUE(WGL_BLUE_BITS_ARB, mode->blueBits);
+  SET_ATTR_VALUE(WGL_ALPHA_BITS_ARB, mode->alphaBits);
+  SET_ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, mode->accumRedBits);
+  SET_ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, mode->accumGreenBits);
+  SET_ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, mode->accumBlueBits);
+  SET_ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, mode->accumAlphaBits);
+  SET_ATTR_VALUE(WGL_DEPTH_BITS_ARB, mode->depthBits);
+  SET_ATTR_VALUE(WGL_STENCIL_BITS_ARB, mode->stencilBits);
+  SET_ATTR_VALUE(WGL_AUX_BUFFERS_ARB, mode->numAuxBuffers);
+
+  if (mode->doubleBufferMode)
+    SET_ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, TRUE);
+
+  if (mode->stereoMode)
+    SET_ATTR_VALUE(WGL_STEREO_ARB, TRUE);
+
+  // Some attributes are only added to the list if the value requested is not 'don't care', as exactly matching that is daft..
+  if (mode->swapMethod == GLX_SWAP_EXCHANGE_OML)
+    SET_ATTR_VALUE(WGL_SWAP_METHOD_ARB, WGL_SWAP_EXCHANGE_ARB);
+
+  if (mode->swapMethod == GLX_SWAP_COPY_OML)
+    SET_ATTR_VALUE(WGL_SWAP_COPY_ARB, TRUE);
+
+  // XXX: this should probably be the other way around, but that messes up drawableTypeOverride
+  if (mode->visualRating == GLX_SLOW_VISUAL_EXT)
+    SET_ATTR_VALUE(WGL_ACCELERATION_ARB, WGL_NO_ACCELERATION_ARB);
+
+  // must support all the drawable types the mode supports
+  if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT)
+    SET_ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB,TRUE);
+
+  // XXX: this is a horrible hacky heuristic, in fact this whole drawableTypeOverride thing is a bad idea
+  // try to avoid asking for formats which don't exist (by not asking for all when adjusting the config to include the drawableTypeOverride)
+  if (drawableTypeOverride == GLX_WINDOW_BIT)
+    {
+      if (mode->drawableType & GLX_PIXMAP_BIT)
+        SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE);
+
+      if (mode->drawableType & GLX_PBUFFER_BIT)
+        if (winScreen->has_WGL_ARB_pbuffer)
+          SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE);
     }
+  else
+    {
+      if (drawableTypeOverride & GLX_PIXMAP_BIT)
+        SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE);
 
-    /* result->cAuxBuffers = mode->numAuxBuffers; */
+      if (drawableTypeOverride & GLX_PBUFFER_BIT)
+        if (winScreen->has_WGL_ARB_pbuffer)
+          SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE);
+    }
 
-    /* mode->level ignored */
+  SET_ATTR_VALUE(0, 0); // terminator
 
-    /* mode->pixmapMode ? */
+  /* choose the first match */
+  {
+    int pixelFormatIndex;
 
-    *pfdret = pfd;
+    if (!wglChoosePixelFormatARBWrapper(hdc, attribList, NULL, 1, &pixelFormatIndex, &numFormats))
+      {
+        ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
+      }
+    else
+      {
+        if (numFormats > 0)
+          {
+            GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d)", pixelFormatIndex);
+            return pixelFormatIndex;
+          }
+        else
+          ErrorF("wglChoosePixelFormat couldn't decide\n");
+      }
+  }
 
-    return 0;
+  return 0;
 }
 
-static __GLinterface *glWinCreateContext(__GLimports *imports,
-                                          __GLcontextModes *mode,
-                                          __GLinterface *shareGC)
+/* ---------------------------------------------------------------------- */
+
+#define BITS_AND_SHIFT_TO_MASK(bits,mask) (((1<<(bits))-1) << (mask))
+
+//
+// Create the GLXconfigs using DescribePixelFormat()
+//
+static void
+glxWinCreateConfigs(HDC hdc, glxWinScreen *screen)
 {
-    __GLcontext *result;
+  GLXWinConfig *c, *result, *prev = NULL;
+  int numConfigs = 0;
+  int i = 0;
+  int n = 0;
+  PIXELFORMATDESCRIPTOR pfd;
 
-    GLWIN_DEBUG_MSG("glWinCreateContext\n");
+  GLWIN_DEBUG_MSG("glxWinCreateConfigs");
 
-    result = (__GLcontext *)calloc(1, sizeof(__GLcontext));
-    if (!result) 
-        return NULL;
+  screen->base.numFBConfigs = 0;
+  screen->base.fbconfigs = NULL;
+
+  // get the number of pixelformats
+  numConfigs = DescribePixelFormat(hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
+  GLWIN_DEBUG_MSG("DescribePixelFormat says %d possible pixel formats", numConfigs);
 
-    result->interface.imports = *imports;
-    result->interface.exports = glWinExports;
+  /* alloc */
+  result = xalloc(sizeof(GLXWinConfig) * numConfigs);
 
-    if (makeFormat(mode, &result->pfd))
+  if (NULL == result)
     {
-        ErrorF("makeFormat failed\n");
-        free(result);
-        return NULL;
+      return;
     }
 
-    if (glWinDebugSettings.dumpPFD)
-        pfdOut(&result->pfd);
+  memset(result, 0, sizeof(GLXWinConfig) * numConfigs);
+  n = 0;
 
-    GLWIN_DEBUG_MSG("glWinCreateContext done\n");
-    return (__GLinterface *)result;
-}
+  /* fill in configs */
+  for (i = 0;  i < numConfigs; i++)
+    {
+      int rc;
 
-Bool
-glWinRealizeWindow(WindowPtr pWin)
-{
-    /* If this window has GL contexts, tell them to reattach */
-    /* reattaching is bad: display lists and parameters get lost */
-    Bool result;
-    ScreenPtr pScreen = pWin->drawable.pScreen;
-    glWinScreenRec *screenPriv = &glWinScreens[pScreen->myNum];
-    __GLXdrawablePrivate *glxPriv;
+      c = &(result[i]);
+      c->base.next = NULL;
+      c->pixelFormatIndex = i+1;
 
-    GLWIN_DEBUG_MSG("glWinRealizeWindow\n");
+      rc = DescribePixelFormat(hdc, i+1, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
 
-    /* Allow the window to be created (RootlessRealizeWindow is inside our wrap) */
-    pScreen->RealizeWindow = screenPriv->RealizeWindow;
-    result = pScreen->RealizeWindow(pWin);
-    pScreen->RealizeWindow = glWinRealizeWindow;
-
-    /* Re-attach this window's GL contexts, if any. */
-    glxPriv = __glXFindDrawablePrivate(pWin->drawable.id);
-    if (glxPriv) {
-        __GLXcontext *gx;
-        __GLcontext *gc;
-        __GLdrawablePrivate *glPriv = &glxPriv->glPriv;
-        GLWIN_DEBUG_MSG("glWinRealizeWindow is GL drawable!\n");
-
-        /* GL contexts bound to this window for drawing */
-        for (gx = glxPriv->drawGlxc; gx != NULL; gx = gx->next) {
-            gc = (__GLcontext *)gx->gc;
-            if (gc->isAttached)
-#if 1
-            {
-                GLWIN_DEBUG_MSG("context is already bound! Adjusting HWND.\n");
-                glWinAdjustHWND(gc, pWin);
-                continue;
-            }
-#else
-                unattach(gc);
-#endif
-            attach(gc, glPriv);
+      if (!rc)
+        {
+          ErrorF("DescribePixelFormat failed for index %d, error %s\n", i+1, glxWinErrorMessage());
+          break;
         }
 
-        /* GL contexts bound to this window for reading */
-        for (gx = glxPriv->readGlxc; gx != NULL; gx = gx->next) {
-            gc = (__GLcontext *)gx->gc;
-            if (gc->isAttached)
-#if 1
-            {
-                GLWIN_DEBUG_MSG("context is already bound! Adjusting HWND.\n");
-                glWinAdjustHWND(gc, pWin);
-                continue;
-            }
-#else
-                unattach(gc);
-#endif
-            attach(gc, glPriv);
+      if (glxWinDebugSettings.dumpPFD)
+        pfdOut(&pfd);
+
+      if (!(pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP)) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL))
+        {
+          GLWIN_DEBUG_MSG("pixelFormat %d has unsuitable flags 0x%08lx, skipping", i+1, pfd.dwFlags);
+          continue;
         }
-    }
 
-    return result;
-}
+      c->base.doubleBufferMode = (pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE;
+      c->base.stereoMode = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE;
 
+      c->base.redBits = pfd.cRedBits;
+      c->base.greenBits = pfd.cGreenBits;
+      c->base.blueBits = pfd.cBlueBits;
+      c->base.alphaBits = pfd.cAlphaBits;
 
-void 
-glWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
-    ScreenPtr pScreen = pWindow->drawable.pScreen;
-    glWinScreenRec *screenPriv = &glWinScreens[pScreen->myNum];
-    __GLXdrawablePrivate *glxPriv;
-    
-    GLWIN_TRACE_MSG(" (pWindow %p)\n", pWindow);
-    
-    /* Check if the window is attached and discard any drawing request */
-    glxPriv = __glXFindDrawablePrivate(pWindow->drawable.id);
-    if (glxPriv) {
-        __GLXcontext *gx;
-
-        /* GL contexts bound to this window for drawing */
-        for (gx = glxPriv->drawGlxc; gx != NULL; gx = gx->next) {
-/*            
-            GLWIN_DEBUG_MSG("glWinCopyWindow - calling glDrawBuffer\n");
-            glDrawBuffer(GL_FRONT);
- */           
- 
-            return;
-        }
+      c->base.redMask = BITS_AND_SHIFT_TO_MASK(pfd.cRedBits, pfd.cRedShift);
+      c->base.greenMask =  BITS_AND_SHIFT_TO_MASK(pfd.cGreenBits, pfd.cGreenShift);
+      c->base.blueMask = BITS_AND_SHIFT_TO_MASK(pfd.cBlueBits, pfd.cBlueShift);
+      c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(pfd.cAlphaBits, pfd.cAlphaShift);
+
+      c->base.rgbBits = pfd.cColorBits;
 
-        /* GL contexts bound to this window for reading */
-        for (gx = glxPriv->readGlxc; gx != NULL; gx = gx->next) {
-            return;
+      if (pfd.iPixelType == PFD_TYPE_COLORINDEX)
+        {
+          c->base.indexBits = pfd.cColorBits;
+        }
+      else
+        {
+          c->base.indexBits = 0;
         }
-    }
 
-    GLWIN_DEBUG_MSG("glWinCopyWindow - passing to hw layer\n");
+      c->base.accumRedBits = pfd.cAccumRedBits;
+      c->base.accumGreenBits = pfd.cAccumGreenBits;
+      c->base.accumBlueBits = pfd.cAccumBlueBits;
+      c->base.accumAlphaBits = pfd.cAccumAlphaBits;
+      //  pfd.cAccumBits;
 
-    pScreen->CopyWindow = screenPriv->CopyWindow;
-    pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc);
-    pScreen->CopyWindow = glWinCopyWindow;
-}
+      c->base.depthBits = pfd.cDepthBits;
+      c->base.stencilBits = pfd.cStencilBits;
+      c->base.numAuxBuffers = pfd.cAuxBuffers;
 
-Bool
-glWinUnrealizeWindow(WindowPtr pWin)
-{
-    /* If this window has GL contexts, tell them to unattach */
-    Bool result;
-    ScreenPtr pScreen = pWin->drawable.pScreen;
-    glWinScreenRec *screenPriv = &glWinScreens[pScreen->myNum];
-    __GLXdrawablePrivate *glxPriv;
-
-    GLWIN_DEBUG_MSG("glWinUnrealizeWindow\n");
-
-    /* The Aqua window may have already been destroyed (windows
-     * are unrealized from top down)
-     */
-    
-    /* Unattach this window's GL contexts, if any. */
-    glxPriv = __glXFindDrawablePrivate(pWin->drawable.id);
-    if (glxPriv) {
-        __GLXcontext *gx;
-        __GLcontext *gc;
-        GLWIN_DEBUG_MSG("glWinUnealizeWindow is GL drawable!\n");
-
-        /* GL contexts bound to this window for drawing */
-        for (gx = glxPriv->drawGlxc; gx != NULL; gx = gx->next) {
-            gc = (__GLcontext *)gx->gc;
-            unattach(gc);
-        }
+      // pfd.iLayerType; // ignored
+      c->base.level = 0;
+      // pfd.dwLayerMask; // ignored
+      // pfd.dwDamageMask;  // ignored
+
+      c->base.pixmapMode = 0;
+      c->base.visualID = -1;  // will be set by __glXScreenInit()
 
-        /* GL contexts bound to this window for reading */
-        for (gx = glxPriv->readGlxc; gx != NULL; gx = gx->next) {
-            gc = (__GLcontext *)gx->gc;
-            unattach(gc);
+      /* EXT_visual_rating / GLX 1.2 */
+      if (pfd.dwFlags & PFD_GENERIC_FORMAT)
+        {
+          c->base.visualRating = GLX_SLOW_VISUAL_EXT;
+        }
+      else
+        {
+          // PFD_GENERIC_ACCELERATED is not considered, so this may be MCD or ICD acclerated...
+          c->base.visualRating = GLX_NONE_EXT;
         }
-    }
 
-    pScreen->UnrealizeWindow = screenPriv->UnrealizeWindow;
-    result = pScreen->UnrealizeWindow(pWin);
-    pScreen->UnrealizeWindow = glWinUnrealizeWindow;
+      /* EXT_visual_info / GLX 1.2 */
+      if (pfd.iPixelType == PFD_TYPE_COLORINDEX)
+        {
+          c->base.visualType = GLX_STATIC_COLOR;
 
-    return result;
-}
+          if (!getenv("GLWIN_ENABLE_COLORINDEX_FBCONFIGS"))
+            {
+              GLWIN_DEBUG_MSG("pixelFormat %d is PFD_TYPE_COLORINDEX, skipping", i+1);
+              continue;
+            }
+        }
+      else
+        {
+          c->base.visualType = GLX_TRUE_COLOR;
+        }
 
+      // pfd.dwVisibleMask; ???
+      c->base.transparentPixel = GLX_NONE;
+      c->base.transparentRed = GLX_NONE;
+      c->base.transparentGreen = GLX_NONE;
+      c->base.transparentBlue = GLX_NONE;
+      c->base.transparentAlpha = GLX_NONE;
+      c->base.transparentIndex = GLX_NONE;
 
-/*
- * In the case the driver has no GLX visuals we'll use these.
- * [0] = RGB, double buffered
- * [1] = RGB, double buffered, stencil, accum
- */
-/* Originally copied from Mesa */
+      /* ARB_multisample / SGIS_multisample */
+      c->base.sampleBuffers = 0;
+      c->base.samples = 0;
 
-static int                 numConfigs     = 0;
-static __GLXvisualConfig  *visualConfigs  = NULL;
-static void              **visualPrivates = NULL;
+      /* SGIX_fbconfig / GLX 1.3 */
+      c->base.drawableType = (((pfd.dwFlags & PFD_DRAW_TO_WINDOW) ? GLX_WINDOW_BIT : 0)
+                         | ((pfd.dwFlags & PFD_DRAW_TO_BITMAP) ? GLX_PIXMAP_BIT : 0));
 
-#define NUM_FALLBACK_CONFIGS 2
-static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = {
-  {
-    -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_EXT,       /* visualRating */
-    0,                  /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-  },
-  {
-    -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_EXT,       /* visualRating */
-    0,                  /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-  }
-};
+      if (pfd.iPixelType == PFD_TYPE_COLORINDEX)
+        {
+          c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT;
+        }
+      else
+        {
+          c->base.renderType = GLX_RGBA_BIT;
+        }
 
-static __GLXvisualConfig NullConfig = {
-    -1,                 /* vid */
-    -1,                 /* class */
-    False,              /* rgba */
-    -1, -1, -1, 0,      /* rgba sizes */
-    -1, -1, -1, 0,      /* rgba masks */
-     0,  0,  0, 0,      /* rgba accum sizes */
-    False,              /* doubleBuffer */
-    False,              /* stereo */
-    -1,                 /* bufferSize */
-    16,                 /* depthSize */
-    0,                  /* stencilSize */
-    0,                  /* auxBuffers */
-    0,                  /* level */
-    GLX_NONE_EXT,       /* visualRating */
-    0,                  /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-};
+      c->base.xRenderable = GL_TRUE;
+      c->base.fbconfigID = -1; // will be set by __glXScreenInit()
 
-static inline int count_bits(uint32_t x)
-{
-    x = x - ((x >> 1) & 0x55555555);
-    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
-    x = (x + (x >> 4)) & 0x0f0f0f0f;
-    x = x + (x >> 8);
-    x = x + (x >> 16);
-    return x & 63;
-}
+      /* SGIX_pbuffer / GLX 1.3 */
+      // XXX: How can we find these values out ???
+      c->base.maxPbufferWidth = -1;
+      c->base.maxPbufferHeight = -1;
+      c->base.maxPbufferPixels = -1;
+      c->base.optimalPbufferWidth = 0; // there is no optimal value
+      c->base.optimalPbufferHeight = 0;
 
-/* Mostly copied from Mesa's xf86glx.c */
-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 = NULL;
-    __GLXvisualConfig *pNewVisualConfigs = NULL;
-    void **glXVisualPriv;
-    void **pNewVisualPriv;
-    int found_default;
-    int i, j, k;
-
-    GLWIN_DEBUG_MSG("init_visuals\n");
-
-    if (numConfigs > 0)
-        numNewConfigs = numConfigs;
-    else
-        numNewConfigs = NUM_FALLBACK_CONFIGS;
+      /* SGIX_visual_select_group */
+      // arrange for visuals with the best acceleration to be preferred in selection
+      switch (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
+        {
+        case 0:
+          c->base.visualSelectGroup = 2;
+          break;
 
-    /* Alloc space for the list of new GLX visuals */
-    pNewVisualConfigs = (__GLXvisualConfig *)
-                     __glXMalloc(numNewConfigs * sizeof(__GLXvisualConfig));
-    if (!pNewVisualConfigs) {
-        return FALSE;
-    }
+        case PFD_GENERIC_ACCELERATED:
+          c->base.visualSelectGroup = 1;
+          break;
 
-    /* Alloc space for the list of new GLX visual privates */
-    pNewVisualPriv = (void **) __glXMalloc(numNewConfigs * sizeof(void *));
-    if (!pNewVisualPriv) {
-        __glXFree(pNewVisualConfigs);
-        return FALSE;
-    }
+        case PFD_GENERIC_FORMAT:
+          c->base.visualSelectGroup = 0;
+          break;
 
-    /*
-    ** 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];
+        default:
+          ;
+          // "can't happen"
         }
-    }
 
-    /* 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++;
-    }
+      /* OML_swap_method */
+      if (pfd.dwFlags & PFD_SWAP_EXCHANGE)
+        c->base.swapMethod = GLX_SWAP_EXCHANGE_OML;
+      else if (pfd.dwFlags & PFD_SWAP_COPY)
+        c->base.swapMethod = GLX_SWAP_COPY_OML;
+      else
+        c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
 
-    /* Count the total number of visuals to compute */
-    numNewVisuals = 0;
-    for (i = 0; i < numVisuals; i++) {
-        int count;
+      /* EXT_import_context */
+      c->base.screen = screen->base.pScreen->myNum;
 
-        count = ((pVisual[i].class == TrueColor
-                  || pVisual[i].class == DirectColor)
-                 ? numRGBconfigs : numCIconfigs);
-        if (count == 0)
-            count = 1;                  /* preserve the existing visual */
+      /* EXT_texture_from_pixmap */
+      c->base.bindToTextureRgb = -1;
+      c->base.bindToTextureRgba = -1;
+      c->base.bindToMipmapTexture = -1;
+      c->base.bindToTextureTargets = -1;
+      c->base.yInverted = -1;
 
-        numNewVisuals += count;
-    }
+      n++;
 
-    /* Reset variables for use with the next screen/driver's visual configs */
-    visualConfigs = NULL;
-    numConfigs = 0;
+      // update previous config to point to this config
+      if (prev)
+        prev->base.next = &(c->base);
 
-    /* Alloc temp space for the list of orig VisualIDs for each new visual */
-    orig_vid = (VisualID *)__glXMalloc(numNewVisuals * sizeof(VisualID));
-    if (!orig_vid) {
-        __glXFree(pNewVisualPriv);
-        __glXFree(pNewVisualConfigs);
-        return FALSE;
+      prev = c;
     }
 
-    /* Alloc space for the list of glXVisuals */
-    modes = _gl_context_modes_create(numNewVisuals, sizeof(__GLcontextModes));
-    if (modes == NULL) {
-        __glXFree(orig_vid);
-        __glXFree(pNewVisualPriv);
-        __glXFree(pNewVisualConfigs);
-        return FALSE;
-    }
-
-    /* Alloc space for the list of glXVisualPrivates */
-    glXVisualPriv = (void **)__glXMalloc(numNewVisuals * sizeof(void *));
-    if (!glXVisualPriv) {
-        _gl_context_modes_destroy( modes );
-        __glXFree(orig_vid);
-        __glXFree(pNewVisualPriv);
-        __glXFree(pNewVisualConfigs);
-        return FALSE;
-    }
+  GLWIN_DEBUG_MSG("found %d pixelFormats suitable for conversion to fbConfigs", n);
 
-    /* Alloc space for the new list of the X server's visuals */
-    pVisualNew = (VisualPtr)__glXMalloc(numNewVisuals * sizeof(VisualRec));
-    if (!pVisualNew) {
-        __glXFree(glXVisualPriv);
-        _gl_context_modes_destroy( modes );
-        __glXFree(orig_vid);
-        __glXFree(pNewVisualPriv);
-        __glXFree(pNewVisualConfigs);
-        return FALSE;
-    }
-
-    /* Initialize the new visuals */
-    found_default = FALSE;
-    glWinScreens[screenInfo.numScreens-1].modes = modes;
-    for (i = j = 0; i < numVisuals; i++) {
-        int is_rgb = (pVisual[i].class == TrueColor ||
-                      pVisual[i].class == DirectColor);
+  screen->base.numFBConfigs = n;
+  screen->base.fbconfigs = &(result->base);
+}
 
-        if (!is_rgb)
+// helper function to access an attribute value from an attribute value array by attribute
+static
+int getAttrValue(const int attrs[], int values[], unsigned int num, int attr, int fallback)
+{
+  unsigned int i;
+  for (i = 0; i < num; i++)
+    {
+      if (attrs[i] == attr)
         {
-            /* We don't support non-rgb visuals for GL. But we don't
-               want to remove them either, so just pass them through
-               with null glX configs */
-
-            pVisualNew[j] = pVisual[i];
-            pVisualNew[j].vid = FakeClientID(0);
+          GLWIN_TRACE_MSG("getAttrValue attr 0x%x, value %d", attr, values[i]);
+          return values[i];
+        }
+    }
 
-            /* Check for the default visual */
-            if (!found_default && pVisual[i].vid == *defaultVisp) {
-                *defaultVisp = pVisualNew[j].vid;
-                found_default = TRUE;
-            }
+  ErrorF("getAttrValue failed to find attr 0x%x, using default value %d\n", attr, fallback);
+  return fallback;
+}
 
-            /* Save the old VisualID */
-            orig_vid[j] = pVisual[i].vid;
+//
+// Create the GLXconfigs using wglGetPixelFormatAttribfvARB() extension
+//
+static void
+glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen)
+{
+  GLXWinConfig *c, *result, *prev = NULL;
+  int i = 0;
+  int n = 0;
 
-            /* Initialize the glXVisual */
-            _gl_copy_visual_to_context_mode( modes, & NullConfig );
-            modes->visualID = pVisualNew[j].vid;
+  const int attr = WGL_NUMBER_PIXEL_FORMATS_ARB;
+  int numConfigs;
 
-            j++;
+  int attrs[50];
+  unsigned int num_attrs = 0;
 
-            continue;
-        }
+  GLWIN_DEBUG_MSG("glxWinCreateConfigsExt");
 
-        for (k = 0; k < numNewConfigs; k++) {
-            if (pNewVisualConfigs[k].rgba != is_rgb)
-                continue;
+  screen->base.numFBConfigs = 0;
+  screen->base.fbconfigs = NULL;
 
-            assert( modes != NULL );
+  if (!wglGetPixelFormatAttribivARBWrapper(hdc, 0, 0, 1, &attr, &numConfigs))
+    {
+      ErrorF("wglGetPixelFormatAttribivARB failed for WGL_NUMBER_PIXEL_FORMATS_ARB: %s\n", glxWinErrorMessage());
+      return;
+    }
 
-            /* Initialize the new visual */
-            pVisualNew[j] = pVisual[i];
-            pVisualNew[j].vid = FakeClientID(0);
+  GLWIN_DEBUG_MSG("wglGetPixelFormatAttribivARB says %d possible pixel formats", numConfigs);
 
-            /* Check for the default visual */
-            if (!found_default && pVisual[i].vid == *defaultVisp) {
-                *defaultVisp = pVisualNew[j].vid;
-                found_default = TRUE;
-            }
+  /* alloc */
+  result = xalloc(sizeof(GLXWinConfig) * numConfigs);
 
-            /* 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 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;
-            }
+  if (NULL == result)
+    {
+      return;
+    }
 
-            /* Save the device-dependent private for this visual */
-            glXVisualPriv[j] = pNewVisualPriv[k];
+  memset(result, 0, sizeof(GLXWinConfig) * numConfigs);
+  n = 0;
+
+#define ADD_ATTR(a) { attrs[num_attrs++] = a; assert(num_attrs < NUM_ELEMENTS(attrs)); }
+
+  ADD_ATTR(WGL_DRAW_TO_WINDOW_ARB);
+  ADD_ATTR(WGL_DRAW_TO_BITMAP_ARB);
+  ADD_ATTR(WGL_ACCELERATION_ARB);
+  ADD_ATTR(WGL_SWAP_LAYER_BUFFERS_ARB);
+  ADD_ATTR(WGL_NUMBER_OVERLAYS_ARB);
+  ADD_ATTR(WGL_NUMBER_UNDERLAYS_ARB);
+  ADD_ATTR(WGL_TRANSPARENT_ARB);
+  ADD_ATTR(WGL_TRANSPARENT_RED_VALUE_ARB);
+  ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB);
+  ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB);
+  ADD_ATTR(WGL_TRANSPARENT_ALPHA_VALUE_ARB);
+  ADD_ATTR(WGL_SUPPORT_OPENGL_ARB);
+  ADD_ATTR(WGL_DOUBLE_BUFFER_ARB);
+  ADD_ATTR(WGL_STEREO_ARB);
+  ADD_ATTR(WGL_PIXEL_TYPE_ARB);
+  ADD_ATTR(WGL_COLOR_BITS_ARB);
+  ADD_ATTR(WGL_RED_BITS_ARB);
+  ADD_ATTR(WGL_RED_SHIFT_ARB);
+  ADD_ATTR(WGL_GREEN_BITS_ARB);
+  ADD_ATTR(WGL_GREEN_SHIFT_ARB);
+  ADD_ATTR(WGL_BLUE_BITS_ARB);
+  ADD_ATTR(WGL_BLUE_SHIFT_ARB);
+  ADD_ATTR(WGL_ALPHA_BITS_ARB);
+  ADD_ATTR(WGL_ALPHA_SHIFT_ARB);
+  ADD_ATTR(WGL_ACCUM_RED_BITS_ARB);
+  ADD_ATTR(WGL_ACCUM_GREEN_BITS_ARB);
+  ADD_ATTR(WGL_ACCUM_BLUE_BITS_ARB);
+  ADD_ATTR(WGL_ACCUM_ALPHA_BITS_ARB);
+  ADD_ATTR(WGL_DEPTH_BITS_ARB);
+  ADD_ATTR(WGL_STENCIL_BITS_ARB);
+  ADD_ATTR(WGL_AUX_BUFFERS_ARB);
+  ADD_ATTR(WGL_SWAP_METHOD_ARB);
+
+  if (screen->has_WGL_ARB_multisample)
+    {
+      // we may not query these attrs if WGL_ARB_multisample is not offered
+      ADD_ATTR(WGL_SAMPLE_BUFFERS_ARB);
+      ADD_ATTR(WGL_SAMPLES_ARB);
+    }
 
-            j++;
-            modes = modes->next;
-        }
+  if (screen->has_WGL_ARB_render_texture)
+    {
+      // we may not query these attrs if WGL_ARB_render_texture is not offered
+      ADD_ATTR(WGL_BIND_TO_TEXTURE_RGB_ARB);
+      ADD_ATTR(WGL_BIND_TO_TEXTURE_RGBA_ARB);
     }
 
-    assert(j <= numNewVisuals);
-
-    /* Save the GLX visuals in the screen structure */
-    glWinScreens[screenInfo.numScreens-1].num_vis = numNewVisuals;
-    glWinScreens[screenInfo.numScreens-1].priv = 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 *)__glXMalloc(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 */
-        __glXFree(pdepth[i].vids);
-        pdepth[i].vids = pVids;
-        pdepth[i].numVids = numVids;
+  if (screen->has_WGL_ARB_pbuffer)
+    {
+      // we may not query these attrs if WGL_ARB_pbuffer is not offered
+      ADD_ATTR(WGL_DRAW_TO_PBUFFER_ARB);
+      ADD_ATTR(WGL_MAX_PBUFFER_PIXELS_ARB);
+      ADD_ATTR(WGL_MAX_PBUFFER_WIDTH_ARB);
+      ADD_ATTR(WGL_MAX_PBUFFER_HEIGHT_ARB);
     }
 
-    /* Update the X server's visuals */
-    *nvisualp = numNewVisuals;
-    *visualp = pVisualNew;
+  /* fill in configs */
+  for (i = 0;  i < numConfigs; i++)
+    {
+      int values[num_attrs];
 
-    /* Free the old list of the X server's visuals */
-    __glXFree(pVisual);
+      c = &(result[i]);
+      c->base.next = NULL;
+      c->pixelFormatIndex = i+1;
 
-    /* Clean up temporary allocations */
-    __glXFree(orig_vid);
-    __glXFree(pNewVisualPriv);
-    __glXFree(pNewVisualConfigs);
+      if (!wglGetPixelFormatAttribivARBWrapper(hdc, i+1, 0, num_attrs, attrs, values))
+        {
+          ErrorF("wglGetPixelFormatAttribivARB failed for index %d, error %s\n", i+1, glxWinErrorMessage());
+          break;
+        }
 
-    /* Free the private list created by DDX HW driver */
-    if (visualPrivates)
-        xfree(visualPrivates);
-    visualPrivates = NULL;
+#define ATTR_VALUE(a, d) getAttrValue(attrs, values, num_attrs, (a), (d))
 
-    return TRUE;
-}
+      if (!ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, 0))
+        {
+          GLWIN_DEBUG_MSG("pixelFormat %d isn't WGL_SUPPORT_OPENGL_ARB, skipping", i+1);
+          continue;
+        }
 
+      c->base.doubleBufferMode = ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, 0) ? GL_TRUE : GL_FALSE;
+      c->base.stereoMode = ATTR_VALUE(WGL_STEREO_ARB, 0) ? GL_TRUE : GL_FALSE;
 
-static void fixup_visuals(int screen)
-{
-    ScreenPtr pScreen = screenInfo.screens[screen];
-    glWinScreenRec *pScr = &glWinScreens[screen];
-    __GLcontextModes *modes;
-    int j;
-
-    GLWIN_DEBUG_MSG("fixup_visuals\n");
-
-    for (modes = pScr->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);
-        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);
-            }
-        }
-    }
-}
+      c->base.redBits = ATTR_VALUE(WGL_RED_BITS_ARB, 0);
+      c->base.greenBits = ATTR_VALUE(WGL_GREEN_BITS_ARB, 0);
+      c->base.blueBits = ATTR_VALUE(WGL_BLUE_BITS_ARB, 0);
+      c->base.alphaBits = ATTR_VALUE(WGL_ALPHA_BITS_ARB, 0);
 
-static void init_screen_visuals(int screen)
-{
-    ScreenPtr pScreen = screenInfo.screens[screen];
-    __GLcontextModes *modes;
-    int *used;
-    int i, j;
-
-    GLWIN_DEBUG_MSG("init_screen_visuals\n");
-
-    used = (int *)__glXMalloc(pScreen->numVisuals * sizeof(int));
-    __glXMemset(used, 0, pScreen->numVisuals * sizeof(int));
-
-    i = 0;
-    for ( modes = glWinScreens[screen].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;
-
-        for (j = 0; j < pScreen->numVisuals; j++) {
-
-            if (pVis[j].class     == vis_class &&
-                pVis[j].nplanes   == nplanes &&
-                pVis[j].redMask   == modes->redMask &&
-                pVis[j].greenMask == modes->greenMask &&
-                pVis[j].blueMask  == modes->blueMask &&
-                !used[j]) {
-
-#if 0
-                /* Create the XMesa visual */
-                pXMesaVisual[i] =
-                    XMesaCreateVisual(pScreen,
-                                      pVis,
-                                      modes->rgbMode,
-                                      (modes->alphaBits > 0),
-                                      modes->doubleBufferMode,
-                                      modes->stereoMode,
-                                      GL_TRUE, /* ximage_flag */
-                                      modes->depthBits,
-                                      modes->stencilBits,
-                                      modes->accumRedBits,
-                                      modes->accumGreenBits,
-                                      modes->accumBlueBits,
-                                      modes->accumAlphaBits,
-                                      modes->samples,
-                                      modes->level,
-                                      modes->visualRating);
-#endif
-                
-                /* Set the VisualID */
-                modes->visualID = pVis[j].vid;
+      c->base.redMask = BITS_AND_SHIFT_TO_MASK(c->base.redBits, ATTR_VALUE(WGL_RED_SHIFT_ARB, 0));
+      c->base.greenMask = BITS_AND_SHIFT_TO_MASK(c->base.greenBits, ATTR_VALUE(WGL_GREEN_SHIFT_ARB, 0));
+      c->base.blueMask = BITS_AND_SHIFT_TO_MASK(c->base.blueBits, ATTR_VALUE(WGL_BLUE_SHIFT_ARB, 0));
+      c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(c->base.alphaBits, ATTR_VALUE(WGL_ALPHA_SHIFT_ARB, 0));
+
+      switch (ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0))
+        {
+        case WGL_TYPE_COLORINDEX_ARB:
+          c->base.indexBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0);
+          c->base.rgbBits = 0;
+          c->base.visualType = GLX_STATIC_COLOR;
 
-                /* Mark this visual used */
-                used[j] = 1;
-                break;
+          if (!getenv("GLWIN_ENABLE_COLORINDEX_FBCONFIGS"))
+            {
+              GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_COLORINDEX_ARB, skipping", i+1);
+              continue;
             }
-        }
 
-        if ( j == pScreen->numVisuals ) {
-            ErrorF("No matching visual for __GLcontextMode with "
-                   "visual class = %d (%d), nplanes = %u\n",
-                   vis_class, 
-                   modes->visualType,
-                   (modes->rgbBits - modes->alphaBits) );
-        }
-        else if ( modes->visualID == -1 ) {
-            FatalError( "Matching visual found, but visualID still -1!\n" );
-        }
+          break;
 
-        i++;
-        
-    }
+        case WGL_TYPE_RGBA_FLOAT_ARB:
+          GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_FLOAT_ARB, skipping", i+1);
+          continue;
 
-    __glXFree(used);
+        case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT:
+          GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT, skipping", i+1);
+          continue;
 
-    /* glWinScreens[screen].xm_vis = pXMesaVisual; */
-}
+        case WGL_TYPE_RGBA_ARB:
+          c->base.indexBits = 0;
+          c->base.rgbBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0);
+          c->base.visualType = GLX_TRUE_COLOR;
+          break;
 
-static Bool glWinScreenProbe(int screen)
-{
-    ScreenPtr pScreen;
-    glWinScreenRec *screenPriv;
+        default:
+          ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_PIXEL_TYPE_ARB\n", ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0));
+          continue;
+        }
 
-    GLWIN_DEBUG_MSG("glWinScreenProbe\n");
+      c->base.accumRedBits = ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, 0);
+      c->base.accumGreenBits = ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, 0);
+      c->base.accumBlueBits = ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, 0);
+      c->base.accumAlphaBits = ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, 0);
 
-    /*
-     * Set up the current screen's visuals.
-     */
-    __glDDXScreenInfo.modes = glWinScreens[screen].modes;
-    __glDDXScreenInfo.pVisualPriv = glWinScreens[screen].priv;
-    __glDDXScreenInfo.numVisuals =
-        __glDDXScreenInfo.numUsableVisuals = glWinScreens[screen].num_vis;
+      c->base.depthBits = ATTR_VALUE(WGL_DEPTH_BITS_ARB, 0);
+      c->base.stencilBits = ATTR_VALUE(WGL_STENCIL_BITS_ARB, 0);
+      c->base.numAuxBuffers = ATTR_VALUE(WGL_AUX_BUFFERS_ARB, 0);
 
-    /*
-     * Set the current screen's createContext routine.  This could be
-     * wrapped by a DDX GLX context creation routine.
-     */
-    __glDDXScreenInfo.createContext = glWinCreateContext;
+      {
+        int layers = ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0) + ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0);
 
-    /*
-     * The ordering of the rgb compenents might have been changed by the
-     * driver after mi initialized them.
-     */
-    fixup_visuals(screen);
+        if (layers > 0)
+          {
+            ErrorF("pixelFormat %d: has %d overlay, %d underlays which aren't currently handled", i, ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0), ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0));
+            // XXX: need to iterate over layers?
+          }
+      }
+      c->base.level = 0;
 
-    /*
-     * Find the GLX visuals that are supported by this screen and create
-     * XMesa's visuals.
-     */
-    init_screen_visuals(screen);
-
-    /* Wrap RealizeWindow and UnrealizeWindow on this screen */
-    pScreen = screenInfo.screens[screen];
-    screenPriv = &glWinScreens[screen];
-    screenPriv->RealizeWindow = pScreen->RealizeWindow;
-    pScreen->RealizeWindow = glWinRealizeWindow;
-    screenPriv->UnrealizeWindow = pScreen->UnrealizeWindow;
-    pScreen->UnrealizeWindow = glWinUnrealizeWindow;
-    screenPriv->CopyWindow = pScreen->CopyWindow;
-    pScreen->CopyWindow = glWinCopyWindow;
-
-    return TRUE;
-}
+      c->base.pixmapMode = 0; // ???
+      c->base.visualID = -1;  // will be set by __glXScreenInit()
 
-static GLboolean glWinSwapBuffers(__GLXdrawablePrivate *glxPriv)
-{
-  /* swap buffers on only *one* of the contexts
-   * (e.g. the last one for drawing)
-   */
-    __GLcontext *gc = (__GLcontext *)glxPriv->drawGlxc->gc;
-    HDC dc;
-    BOOL ret;
+      /* EXT_visual_rating / GLX 1.2 */
+      switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0))
+        {
+        default:
+          ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_ACCELERATION_ARB\n", ATTR_VALUE(WGL_ACCELERATION_ARB, 0));
 
-    GLWIN_TRACE_MSG("glWinSwapBuffers (ctx %p)\n", (gc!=NULL?gc->ctx:NULL));
+        case WGL_NO_ACCELERATION_ARB:
+          c->base.visualRating = GLX_SLOW_VISUAL_EXT;
+          break;
 
-    if (gc != NULL && gc->ctx != NULL)
-    {
-        dc = glWinMakeDC(gc);
-        if (dc == NULL)
-            return GL_FALSE;
-
-        ret = SwapBuffers(dc);
-        if (!ret)
-            ErrorF("SwapBuffers failed: %s\n", glWinErrorMessage());
-        
-        ReleaseDC(gc->winInfo.hwnd, dc);
-        if (!ret)
-            return GL_FALSE;
-    }
+        case WGL_GENERIC_ACCELERATION_ARB:
+        case WGL_FULL_ACCELERATION_ARB:
+          c->base.visualRating = GLX_NONE_EXT;
+          break;
+        }
 
-    return GL_TRUE;
-}
+      /* EXT_visual_info / GLX 1.2 */
+      // c->base.visualType is set above
+      if (ATTR_VALUE(WGL_TRANSPARENT_ARB, 0))
+        {
+          c->base.transparentPixel = (c->base.visualType == GLX_TRUE_COLOR) ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT;
+          c->base.transparentRed = ATTR_VALUE(WGL_TRANSPARENT_RED_VALUE_ARB, 0);
+          c->base.transparentGreen = ATTR_VALUE(WGL_TRANSPARENT_GREEN_VALUE_ARB, 0);
+          c->base.transparentBlue = ATTR_VALUE(WGL_TRANSPARENT_BLUE_VALUE_ARB, 0);
+          c->base.transparentAlpha = ATTR_VALUE(WGL_TRANSPARENT_ALPHA_VALUE_ARB, 0);
+          c->base.transparentIndex = ATTR_VALUE(WGL_TRANSPARENT_INDEX_VALUE_ARB, 0);
+        }
+      else
+        {
+          c->base.transparentPixel = GLX_NONE_EXT;
+          c->base.transparentRed = GLX_NONE;
+          c->base.transparentGreen = GLX_NONE;
+          c->base.transparentBlue = GLX_NONE;
+          c->base.transparentAlpha = GLX_NONE;
+          c->base.transparentIndex = GLX_NONE;
+        }
 
-static void glWinDestroyDrawablePrivate(__GLdrawablePrivate *glPriv)
-{
-    GLWIN_DEBUG_MSG("glWinDestroyDrawablePrivate\n");
+      /* ARB_multisample / SGIS_multisample */
+      if (screen->has_WGL_ARB_multisample)
+        {
+          c->base.sampleBuffers = ATTR_VALUE(WGL_SAMPLE_BUFFERS_ARB, 0);
+          c->base.samples = ATTR_VALUE(WGL_SAMPLES_ARB, 0);
+        }
+      else
+        {
+          c->base.sampleBuffers = 0;
+          c->base.samples = 0;
+        }
 
-    /* It doesn't work to call DRIDestroySurface here, the drawable's
-       already gone.. But dri.c notices the window destruction and
-       frees the surface itself. */
+      /* SGIX_fbconfig / GLX 1.3 */
+      c->base.drawableType = ((ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB, 0) ? GLX_WINDOW_BIT : 0)
+                         | (ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, 0) ? GLX_PIXMAP_BIT : 0)
+                         | (ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, 0) ? GLX_PBUFFER_BIT : 0));
 
-    free(glPriv->private);
-    glPriv->private = NULL;
-}
+      /*
+        Assume OpenGL RGBA rendering is available on all visuals
+        (it is specified to render to red component in single-channel visuals,
+        if supported, but there doesn't seem to be any mechanism to check if it
+        is supported)
 
+        Color index rendering is only supported on single-channel visuals
+      */
+      if (c->base.visualType == GLX_STATIC_COLOR)
+        {
+          c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT;
+        }
+      else
+        {
+          c->base.renderType = GLX_RGBA_BIT;
+        }
 
-static void glWinCreateBuffer(__GLXdrawablePrivate *glxPriv)
-{
-    GLWinDrawableRec *winPriv = malloc(sizeof(GLWinDrawableRec));
-    __GLdrawablePrivate *glPriv = &glxPriv->glPriv;
+      c->base.xRenderable = GL_TRUE;
+      c->base.fbconfigID = -1; // will be set by __glXScreenInit()
 
-    /*winPriv->sid = 0; */
-    winPriv->pDraw = NULL;
+      /* SGIX_pbuffer / GLX 1.3 */
+      if (screen->has_WGL_ARB_pbuffer)
+        {
+          c->base.maxPbufferWidth = ATTR_VALUE(WGL_MAX_PBUFFER_WIDTH_ARB, -1);
+          c->base.maxPbufferHeight = ATTR_VALUE(WGL_MAX_PBUFFER_HEIGHT_ARB, -1);
+          c->base.maxPbufferPixels =  ATTR_VALUE(WGL_MAX_PBUFFER_PIXELS_ARB, -1);
+        }
+      else
+        {
+          c->base.maxPbufferWidth = -1;
+          c->base.maxPbufferHeight = -1;
+          c->base.maxPbufferPixels =  -1;
+        }
+      c->base.optimalPbufferWidth = 0; // there is no optimal value
+      c->base.optimalPbufferHeight = 0;
 
-    GLWIN_DEBUG_MSG("glWinCreateBuffer\n");
+      /* SGIX_visual_select_group */
+      // arrange for visuals with the best acceleration to be preferred in selection
+      switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0))
+        {
+        case WGL_FULL_ACCELERATION_ARB:
+          c->base.visualSelectGroup = 2;
+          break;
+
+        case WGL_GENERIC_ACCELERATION_ARB:
+          c->base.visualSelectGroup = 1;
+          break;
+
+        default:
+        case WGL_NO_ACCELERATION_ARB:
+          c->base.visualSelectGroup = 0;
+          break;
+        }
 
-    /* replace swapBuffers (original is never called) */
-    glxPriv->swapBuffers = glWinSwapBuffers;
+      /* OML_swap_method */
+      switch (ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0))
+        {
+        case WGL_SWAP_EXCHANGE_ARB:
+          c->base.swapMethod = GLX_SWAP_EXCHANGE_OML;
+          break;
 
-    /* stash private data */
-    glPriv->private = winPriv;
-    glPriv->freePrivate = glWinDestroyDrawablePrivate;
-}
+        case WGL_SWAP_COPY_ARB:
+          c->base.swapMethod = GLX_SWAP_COPY_OML;
+          break;
 
-static void glWinResetExtension(void)
-{
-    GLWIN_DEBUG_MSG("glWinResetExtension\n");
-}
+        default:
+          ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_SWAP_METHOD_ARB\n", ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0));
 
-/* based on code in apples/indirect.c which is based on i830_dri.c */
-static void
-glWinInitVisualConfigs(void)
-{
-    int                 lclNumConfigs     = 0;
-    __GLXvisualConfig  *lclVisualConfigs  = NULL;
-    void              **lclVisualPrivates = NULL;
-
-    int depth, aux, buffers, stencil, accum;
-    int i = 0;
-
-    GLWIN_DEBUG_MSG("glWinInitVisualConfigs ");
-        
-    /* count num configs:
-        2 Z buffer (0, 24 bit)
-        2 AUX buffer (0, 2)
-        2 buffers (single, double)
-        2 stencil (0, 8 bit)
-        2 accum (0, 64 bit)
-        = 32 configs */
-
-    lclNumConfigs = 2 * 2 * 2 * 2 * 2; /* 32 */
-
-    /* alloc */
-    lclVisualConfigs = xcalloc(sizeof(__GLXvisualConfig), lclNumConfigs);
-    lclVisualPrivates = xcalloc(sizeof(void *), lclNumConfigs);
-
-    /* fill in configs */
-    if (NULL != lclVisualConfigs) {
-        i = 0; /* current buffer */
-        for (depth = 0; depth < 2; depth++) {
-            for (aux = 0; aux < 2; aux++) {
-                for (buffers = 0; buffers < 2; buffers++) {
-                    for (stencil = 0; stencil < 2; stencil++) {
-                        for (accum = 0; accum < 2; accum++) {
-                            lclVisualConfigs[i].vid = -1;
-                            lclVisualConfigs[i].class = -1;
-                            lclVisualConfigs[i].rgba = TRUE;
-                            lclVisualConfigs[i].redSize = -1;
-                            lclVisualConfigs[i].greenSize = -1;
-                            lclVisualConfigs[i].blueSize = -1;
-                            lclVisualConfigs[i].redMask = -1;
-                            lclVisualConfigs[i].greenMask = -1;
-                            lclVisualConfigs[i].blueMask = -1;
-                            lclVisualConfigs[i].alphaMask = 0;
-                            if (accum) {
-                                lclVisualConfigs[i].accumRedSize = 16;
-                                lclVisualConfigs[i].accumGreenSize = 16;
-                                lclVisualConfigs[i].accumBlueSize = 16;
-                                lclVisualConfigs[i].accumAlphaSize = 16;
-                            }
-                            else {
-                                lclVisualConfigs[i].accumRedSize = 0;
-                                lclVisualConfigs[i].accumGreenSize = 0;
-                                lclVisualConfigs[i].accumBlueSize = 0;
-                                lclVisualConfigs[i].accumAlphaSize = 0;
-                            }
-                            lclVisualConfigs[i].doubleBuffer = buffers ? TRUE : FALSE;
-                            lclVisualConfigs[i].stereo = FALSE;
-                            lclVisualConfigs[i].bufferSize = -1;
-                            
-                            lclVisualConfigs[i].depthSize = depth? 24 : 0;
-                            lclVisualConfigs[i].stencilSize = stencil ? 8 : 0;
-                            lclVisualConfigs[i].auxBuffers = aux ? 2 : 0;
-                            lclVisualConfigs[i].level = 0;
-                            lclVisualConfigs[i].visualRating = GLX_NONE_EXT;
-                            lclVisualConfigs[i].transparentPixel = 0;
-                            lclVisualConfigs[i].transparentRed = 0;
-                            lclVisualConfigs[i].transparentGreen = 0;
-                            lclVisualConfigs[i].transparentBlue = 0;
-                            lclVisualConfigs[i].transparentAlpha = 0;
-                            lclVisualConfigs[i].transparentIndex = 0;
-                            i++;
-                        }
-                    }
-                }
-            }
+        case WGL_SWAP_UNDEFINED_ARB:
+          c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
         }
-    }
-    if (i != lclNumConfigs)
-        GLWIN_DEBUG_MSG("glWinInitVisualConfigs failed to alloc visual configs");
 
-    GlxSetVisualConfigs(lclNumConfigs, lclVisualConfigs, lclVisualPrivates);
-}
-
-/* Copied from Mesa */
-static void glWinSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
-                                   void **privates)
-{
-    GLWIN_DEBUG_MSG("glWinSetVisualConfigs\n");
+      /* EXT_import_context */
+      c->base.screen = screen->base.pScreen->myNum;
 
-    numConfigs = nconfigs;
-    visualConfigs = configs;
-    visualPrivates = privates;
-}
+      /* EXT_texture_from_pixmap */
+      /*
+         Mesa's DRI configs always have bindToTextureRgb/Rgba TRUE (see driCreateConfigs(), so setting
+         bindToTextureRgb/bindToTextureRgba to FALSE means that swrast can't find any fbConfigs to use,
+         so setting these to 0, even if we know bindToTexture isn't available, isn't a good idea...
+       */
+      if (screen->has_WGL_ARB_render_texture)
+        {
+          c->base.bindToTextureRgb = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGB_ARB, -1);
+          c->base.bindToTextureRgba = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGBA_ARB, -1);
+        }
+      else
+        {
+          c->base.bindToTextureRgb = -1;
+          c->base.bindToTextureRgba = -1;
+        }
+      c->base.bindToMipmapTexture = -1;
+      c->base.bindToTextureTargets = GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | GLX_TEXTURE_RECTANGLE_BIT_EXT;
+      c->base.yInverted = -1;
 
-/* Copied from Mesa */
-static Bool glWinInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
-                              int *nvisualp, int *ndepthp,
-                              int *rootDepthp, VisualID *defaultVisp,
-                              unsigned long sizes, int bitsPerRGB)
-{
-    glWinInitDebugSettings();
+      n++;
 
-    GLWIN_DEBUG_MSG("glWinInitVisuals\n");
+      // update previous config to point to this config
+      if (prev)
+        prev->base.next = &(c->base);
 
-    if (0 == numConfigs) /* if no configs */
-        glWinInitVisualConfigs(); /* ensure the visula configs are setup */
+      prev = c;
+    }
 
-    /*
-     * Setup the visuals supported by this particular screen.
-     */
-    return init_visuals(nvisualp, visualp, defaultVisp,
-                        *ndepthp, *depthp, *rootDepthp);
+  screen->base.numFBConfigs = n;
+  screen->base.fbconfigs = &(result->base);
 }
diff --git a/hw/xwin/glx/wgl_ext_api.c b/hw/xwin/glx/wgl_ext_api.c
new file mode 100644
index 0000000..4b8359f
--- /dev/null
+++ b/hw/xwin/glx/wgl_ext_api.c
@@ -0,0 +1,75 @@
+/*
+ * File: wgl_ext_api.c
+ * Purpose: Wrapper functions for Win32 OpenGL wgl extension functions
+ *
+ * Authors: Jon TURNEY
+ *
+ * Copyright (c) Jon TURNEY 2009
+ *
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+
+#include <X11/Xwindows.h>
+#include <GL/gl.h>
+#include <GL/glext.h>
+#include <glx/glxserver.h>
+#include <glx/glxext.h>
+#include "wglext.h"
+#include <wgl_ext_api.h>
+#include "glwindows.h"
+
+#define RESOLVE_DECL(type) \
+    static type type##proc = NULL;
+
+#define PRERESOLVE(type, symbol) \
+    type##proc = (type)wglGetProcAddress(symbol); \
+    if (type##proc == NULL) \
+        ErrorF("wglwrap: Can't resolve \"%s\"\n", symbol); \
+    else \
+        ErrorF("wglwrap: Resolved \"%s\"\n", symbol);
+
+#define RESOLVE_RET(type, symbol, retval) \
+  if (type##proc == NULL) { \
+  __glXErrorCallBack(0); \
+  return retval; \
+      }
+
+#define RESOLVE(procname, symbol) RESOLVE_RET(procname, symbol,)
+
+#define RESOLVED_PROC(type) type##proc
+
+/*
+ * Include generated cdecl wrappers for stdcall WGL functions
+ *
+ * There are extensions to the wgl*() API as well; again we call
+ * these functions by using wglGetProcAddress() to get a pointer
+ * to the function, and wrapping it for cdecl/stdcall conversion
+ *
+ * We arrange to resolve the functions up front, as they need a
+ * context to work, as we like to use them to be able to select
+ * a context.  Again, this assumption fails badly on multimontor
+ * systems...
+ */
+
+#include "generated_wgl_wrappers.c"
diff --git a/hw/xwin/glx/wgl_ext_api.h b/hw/xwin/glx/wgl_ext_api.h
new file mode 100644
index 0000000..e4462ac
--- /dev/null
+++ b/hw/xwin/glx/wgl_ext_api.h
@@ -0,0 +1,87 @@
+/*
+ * File: wgl_ext_api.h
+ * Purpose: Wrapper functions for Win32 OpenGL wgl extension functions
+ *
+ * Authors: Jon TURNEY
+ *
+ * Copyright (c) Jon TURNEY 2009
+ *
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+ */
+
+#ifndef wgl_ext_api_h
+#define wgl_ext_api_h
+
+#include "wglext.h"
+
+void wglResolveExtensionProcs(void);
+
+/*
+  Prototypes for wrapper functions we actually use
+  XXX: should be automatically generated as well
+*/
+
+const char *wglGetExtensionsStringARBWrapper(HDC hdc);
+BOOL wglMakeContextCurrentARBWrapper(HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+HDC wglGetCurrentReadDCARBWrapper(VOID);
+
+BOOL wglGetPixelFormatAttribivARBWrapper(HDC hdc,
+                                          int iPixelFormat,
+                                          int iLayerPlane,
+                                          UINT nAttributes,
+                                          const int *piAttributes,
+                                          int *piValues);
+
+BOOL wglGetPixelFormatAttribfvARBWrapper(HDC hdc,
+                                          int iPixelFormat,
+                                          int iLayerPlane,
+                                          UINT nAttributes,
+                                          const int *piAttributes,
+                                          FLOAT *pfValues);
+
+BOOL wglChoosePixelFormatARBWrapper(HDC hdc,
+                                     const int *piAttribIList,
+                                     const FLOAT *pfAttribFList,
+                                     UINT nMaxFormats,
+                                     int *piFormats,
+                                     UINT *nNumFormats);
+
+HPBUFFERARB wglCreatePbufferARBWrapper(HDC hDC,
+                                       int iPixelFormat,
+                                       int iWidth,
+                                       int iHeight,
+                                       const int *piAttribList);
+
+HDC wglGetPbufferDCARBWrapper(HPBUFFERARB hPbuffer);
+
+int wglReleasePbufferDCARBWrapper(HPBUFFERARB hPbuffer,
+                                  HDC hDC);
+
+BOOL wglDestroyPbufferARBWrapper(HPBUFFERARB hPbuffer);
+
+BOOL wglQueryPbufferARBWrapper(HPBUFFERARB hPbuffer,
+                                int iAttribute,
+                                int *piValue);
+
+BOOL wglSwapIntervalEXTWrapper(int interval);
+
+int wglGetSwapIntervalEXTWrapper(void);
+
+#endif /* wgl_ext_api_h */
diff --git a/hw/xwin/glx/winpriv.c b/hw/xwin/glx/winpriv.c
new file mode 100644
index 0000000..a35392b
--- /dev/null
+++ b/hw/xwin/glx/winpriv.c
@@ -0,0 +1,126 @@
+/*
+ * Export window information for the Windows-OpenGL GLX implementation.
+ *
+ * Authors: Alexander Gottwald
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include "winpriv.h"
+#include "winwindow.h"
+
+void
+winCreateWindowsWindow (WindowPtr pWin);
+/**
+ * Return size and handles of a window.
+ * If pWin is NULL, then the information for the root window is requested.
+ */
+HWND winGetWindowInfo(WindowPtr pWin)
+{
+    winDebug("%s: pWin=%p\n", __FUNCTION__, pWin);
+
+    /* a real window was requested */
+    if (pWin != NULL)
+    {
+        /* Get the window and screen privates */
+        ScreenPtr pScreen = pWin->drawable.pScreen;
+        winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen);
+        winScreenInfoPtr pScreenInfo = NULL;
+        HWND hwnd = NULL;
+
+        if (pWinScreen == NULL)
+        {
+            ErrorF("winGetWindowInfo: screen has no privates\n");
+            return NULL;
+        }
+
+        hwnd = pWinScreen->hwndScreen;
+
+        pScreenInfo = pWinScreen->pScreenInfo;
+#ifdef XWIN_MULTIWINDOW
+        /* check for multiwindow mode */
+        if (pScreenInfo->fMultiWindow)
+        {
+            winWindowPriv(pWin);
+
+            if (pWinPriv == NULL)
+            {
+                ErrorF("winGetWindowInfo: window has no privates\n");
+                return hwnd;
+            }
+
+            if (pWinPriv->hWnd == NULL)
+            {
+              winCreateWindowsWindow(pWin);
+              ErrorF("winGetWindowInfo: forcing window to exist...\n");
+            }
+
+            if (pWinPriv->hWnd != NULL)
+              {
+                /* copy window handle */
+                hwnd = pWinPriv->hWnd;
+              }
+
+            return hwnd;
+        }
+#endif
+#ifdef XWIN_MULTIWINDOWEXTWM
+        /* check for multiwindow external wm mode */
+        if (pScreenInfo->fMWExtWM)
+        {
+            win32RootlessWindowPtr pRLWinPriv
+                = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
+
+            if (pRLWinPriv == NULL) {
+                ErrorF("winGetWindowInfo: window has no privates\n");
+                return hwnd;
+            }
+
+            if (pRLWinPriv->hWnd != NULL)
+            {
+                /* copy window handle */
+                hwnd = pRLWinPriv->hWnd;
+            }
+            return hwnd;
+        }
+#endif
+    }
+    else
+    {
+        ScreenPtr pScreen = g_ScreenInfo[0].pScreen;
+        winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen);
+
+        if (pWinScreen == NULL)
+        {
+            ErrorF("winGetWindowInfo: screen has no privates\n");
+            return NULL;
+        }
+
+        ErrorF("winGetWindowInfo: returning root window\n");
+
+        return pWinScreen->hwndScreen;
+    }
+
+    return NULL;
+}
+
+Bool
+winCheckScreenAiglxIsSupported(ScreenPtr pScreen)
+{
+  winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen);
+  winScreenInfoPtr pScreenInfo = pWinScreen->pScreenInfo;
+
+#ifdef XWIN_MULTIWINDOW
+  if (pScreenInfo->fMultiWindow)
+    return TRUE;
+#endif
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+  if (pScreenInfo->fMWExtWM)
+    return TRUE;
+#endif
+
+  return FALSE;
+}
diff --git a/hw/xwin/glx/winpriv.h b/hw/xwin/glx/winpriv.h
new file mode 100644
index 0000000..dce1edf
--- /dev/null
+++ b/hw/xwin/glx/winpriv.h
@@ -0,0 +1,11 @@
+/*
+ * Export window information for the Windows-OpenGL GLX implementation.
+ *
+ * Authors: Alexander Gottwald
+ */
+
+#include <X11/Xwindows.h>
+#include <windowstr.h>
+
+HWND winGetWindowInfo(WindowPtr pWin);
+Bool winCheckScreenAiglxIsSupported(ScreenPtr pScreen);
diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c
index 926ce69..bb360bb 100644
--- a/hw/xwin/winglobals.c
+++ b/hw/xwin/winglobals.c
@@ -85,7 +85,7 @@ HWND		g_hwndKeyboardFocus = NULL;
 Bool		g_fNoHelpMessageBox = FALSE;
 Bool		g_fSoftwareCursor = FALSE;
 Bool		g_fSilentDupError = FALSE;
-
+Bool            g_fNativeGl = FALSE;
 
 /*
  * Global variables for dynamically loaded libraries and
diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index 87ffc6d..95d9d71 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -47,6 +47,7 @@
 extern HICON		g_hIconX;
 extern HICON		g_hSmallIconX;
 extern HWND		g_hDlgDepthChange;
+extern Bool             g_fNativeGl;
 
 /*
  * Prototypes for local functions
@@ -74,7 +75,7 @@ void winInitMultiWindowClass(void)
   {
     /* Setup our window class */
     wcx.cbSize=sizeof(WNDCLASSEX);
-    wcx.style = CS_HREDRAW | CS_VREDRAW;
+    wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0);
     wcx.lpfnWndProc = winTopLevelWindowProc;
     wcx.cbClsExtra = 0;
     wcx.cbWndExtra = 0;
diff --git a/hw/xwin/winpriv.c b/hw/xwin/winpriv.c
deleted file mode 100644
index 29221cf..0000000
--- a/hw/xwin/winpriv.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Export window information for the Windows-OpenGL GLX implementation.
- *
- * Authors: Alexander Gottwald
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include "winpriv.h"
-#include "winwindow.h"
-
-void
-winCreateWindowsWindow (WindowPtr pWin);
-/**
- * Return size and handles of a window.
- * If pWin is NULL, then the information for the root window is requested.
- */ 
-extern void winGetWindowInfo(WindowPtr pWin, winWindowInfoPtr pWinInfo)
-{
-    /* Sanity check */
-    if (pWinInfo == NULL)
-        return;
-
-    winDebug("%s:%d pWin=%p\n", __FUNCTION__, __LINE__, pWin);
-
-    /* a real window was requested */
-    if (pWin != NULL) 
-    {
-        /* Initialize the size information */
-        RECT rect = {
-            pWin->drawable.x,
-            pWin->drawable.y,
-            pWin->drawable.x + pWin->drawable.width,
-            pWin->drawable.y + pWin->drawable.height
-        }, rect_extends;
-        /* Get the window and screen privates */
-        ScreenPtr pScreen = pWin->drawable.pScreen;
-        winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen);
-        winScreenInfoPtr pScreenInfo = NULL;
-
-        rect_extends = rect;
-        OffsetRect(&rect_extends, -pWin->drawable.x, -pWin->drawable.y);
-
-        if (pWinScreen == NULL) 
-        {
-            ErrorF("winGetWindowInfo: screen has no privates\n");
-            return;
-        }
-        
-        pWinInfo->hwnd = pWinScreen->hwndScreen;
-        pWinInfo->hrgn = NULL;
-        pWinInfo->rect = rect;
-    
-
-        pScreenInfo = pWinScreen->pScreenInfo;
-#ifdef XWIN_MULTIWINDOW
-        /* check for multiwindow mode */
-        if (pScreenInfo->fMultiWindow)
-        {
-            winWindowPriv(pWin);
-
-            if (pWinPriv == NULL)
-            {
-                ErrorF("winGetWindowInfo: window has no privates\n");
-                return;
-            }
-
-            if (pWinPriv->hWnd == NULL)
-            {
-                winCreateWindowsWindow(pWin);
-            }
-            if (pWinPriv->hWnd != NULL) { 
-                
-                /* copy size and window handle */
-                pWinInfo->rect = rect_extends;
-                pWinInfo->hwnd = pWinPriv->hWnd;
-
-                /* Copy window region */
-                if (pWinInfo->hrgn)
-                    DeleteObject(pWinInfo->hrgn);
-                pWinInfo->hrgn = CreateRectRgn(0,0,0,0);
-                CombineRgn(pWinInfo->hrgn, pWinPriv->hRgn, pWinPriv->hRgn, 
-                        RGN_COPY);
-            }
-            
-            return;
-        }
-#endif
-#ifdef XWIN_MULTIWINDOWEXTWM
-        /* check for multiwindow external wm mode */
-        if (pScreenInfo->fMWExtWM)
-        {
-            win32RootlessWindowPtr pRLWinPriv
-                = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
-
-            if (pRLWinPriv == NULL) {
-                ErrorF("winGetWindowInfo: window has no privates\n");
-                return;
-            }
-            
-            if (pRLWinPriv->hWnd != NULL)
-            {
-                /* copy size and window handle */
-                pWinInfo->rect = rect_extends;
-                pWinInfo->hwnd = pRLWinPriv->hWnd;
-            }
-            return;
-        }
-#endif
-    } 
-    else 
-    {
-        RECT rect = {0, 0, 0, 0};
-        ScreenPtr pScreen = g_ScreenInfo[0].pScreen;
-        winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen);
-
-        pWinInfo->hwnd = NULL;
-        pWinInfo->hrgn = NULL;
-        pWinInfo->rect = rect;
-        
-        if (pWinScreen == NULL)
-        {
-            ErrorF("winGetWindowInfo: screen has no privates\n");
-            return;
-        }
-
-        ErrorF("winGetWindowInfo: returning root window\n");
-
-        pWinInfo->hwnd = pWinScreen->hwndScreen;
-    }
-    return;
-}
diff --git a/hw/xwin/winpriv.h b/hw/xwin/winpriv.h
deleted file mode 100644
index d4505c8..0000000
--- a/hw/xwin/winpriv.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Export window information for the Windows-OpenGL GLX implementation.
- *
- * Authors: Alexander Gottwald
- */
-#include <windows.h>
-
-typedef struct
-{
-    HWND    hwnd;
-    HRGN    hrgn;
-    RECT    rect;
-} winWindowInfoRec, *winWindowInfoPtr;
-
-extern void winGetWindowInfo(WindowPtr pWin, winWindowInfoPtr pWinInfo);
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 66da76f..07dbcbd 100755
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -64,6 +64,7 @@ extern Bool			g_fKeyboardHookLL;
 extern Bool			g_fNoHelpMessageBox;                     
 extern Bool			g_fSoftwareCursor;
 extern Bool			g_fSilentDupError;
+extern Bool                     g_fNativeGl;
 
 /* globals required by callback function for monitor information */
 struct GetMonitorInfoData {
@@ -1464,6 +1465,19 @@ ddxProcessArgument (int argc, char *argv[], int i)
       g_fSilentDupError = TRUE;
       return 1;
     }
+
+  if (IS_OPTION("-wgl"))
+    {
+      g_fNativeGl = TRUE;
+      return 1;
+    }
+
+  if (IS_OPTION("-nowgl"))
+    {
+      g_fNativeGl = FALSE;
+      return 1;
+    }
+
   return 0;
 }
 


More information about the Xquartz-changes mailing list