Fixes from Brian to help migrate to render buffer DD interfaces. Also fix bug in...
authorKarl Schultz <kschultz@freedesktop.org>
Thu, 30 Mar 2006 07:58:24 +0000 (07:58 +0000)
committerKarl Schultz <kschultz@freedesktop.org>
Thu, 30 Mar 2006 07:58:24 +0000 (07:58 +0000)
src/mesa/drivers/windows/gdi/wgl.c
src/mesa/drivers/windows/gdi/wmesa.c
src/mesa/drivers/windows/gdi/wmesadef.h

index 47e32c579fc7b89ad2181d0bcf4a6af190545775..197de0743c7aa0251190cab3f9a711df7ee418a6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: wgl.c,v 1.11 2006/01/25 06:02:55 kschultz Exp $ */
+/* $Id: wgl.c,v 1.12 2006/03/30 07:58:24 kschultz Exp $ */
 
 /*
  * This library is free software; you can redistribute it and/or
@@ -38,8 +38,6 @@
 
 #include "GL/wmesa.h"   /* protos for wmesa* functions */
 
-typedef struct wmesa_context *PWMC;
-
 /*
  * Pixel Format Descriptors
  */
@@ -143,7 +141,6 @@ int npfd = sizeof(pfd) / sizeof(pfd[0]);
 
 typedef struct {
     WMesaContext ctx;
-    HDC hdc;
 } MesaWglCtx;
 
 #define MESAWGL_CTX_MAX_COUNT 20
@@ -154,13 +151,15 @@ static unsigned ctx_count = 0;
 static int ctx_current = -1;
 static unsigned curPFD = 0;
 
+static HDC CurrentHDC = 0;
+
+
 WINGDIAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc)
 {
     int i = 0;
     if (!ctx_count) {
        for(i=0;i<MESAWGL_CTX_MAX_COUNT;i++) {
            wgl_ctx[i].ctx = NULL;
-           wgl_ctx[i].hdc = NULL;
        }
     }
     for( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
@@ -173,7 +172,6 @@ WINGDIAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc)
                                   GL_TRUE : GL_FALSE) );
             if (wgl_ctx[i].ctx == NULL)
                 break;
-            wgl_ctx[i].hdc = hdc;
             ctx_count++;
             return ((HGLRC)wgl_ctx[i].ctx);
         }
@@ -186,11 +184,10 @@ WINGDIAPI BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc)
 {
     int i;
     for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
-       if ( wgl_ctx[i].ctx == (PWMC) hglrc ){
-            WMesaMakeCurrent((PWMC) hglrc);
-            WMesaDestroyContext();
+       if ( wgl_ctx[i].ctx == (WMesaContext) hglrc ){
+            WMesaMakeCurrent((WMesaContext) hglrc, NULL);
+            WMesaDestroyContext(wgl_ctx[i].ctx);
             wgl_ctx[i].ctx = NULL;
-            wgl_ctx[i].hdc = NULL;
             ctx_count--;
             return(TRUE);
        }
@@ -209,26 +206,24 @@ WINGDIAPI HGLRC GLAPIENTRY wglGetCurrentContext(VOID)
 
 WINGDIAPI HDC GLAPIENTRY wglGetCurrentDC(VOID)
 {
-    if (ctx_current < 0)
-       return 0;
-    else
-       return wgl_ctx[ctx_current].hdc;
+    return CurrentHDC;
 }
 
-WINGDIAPI BOOL GLAPIENTRY wglMakeCurrent(HDC hdc,HGLRC hglrc)
+WINGDIAPI BOOL GLAPIENTRY wglMakeCurrent(HDC hdc, HGLRC hglrc)
 {
     int i;
     
+    CurrentHDC = hdc;
+
     if (!hdc || !hglrc) {
-       WMesaMakeCurrent(NULL);
+       WMesaMakeCurrent(NULL, NULL);
        ctx_current = -1;
        return TRUE;
     }
     
     for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
-       if ( wgl_ctx[i].ctx == (PWMC) hglrc ) {
-           wgl_ctx[i].hdc = hdc;
-           WMesaMakeCurrent( (WMesaContext) hglrc );
+       if ( wgl_ctx[i].ctx == (WMesaContext) hglrc ) {
+           WMesaMakeCurrent( (WMesaContext) hglrc, hdc );
            ctx_current = i;
            return TRUE;
        }
@@ -353,16 +348,8 @@ WINGDIAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
 
 WINGDIAPI BOOL GLAPIENTRY wglSwapBuffers(HDC hdc)
 {
-    (void) hdc;
-    if (ctx_current < 0)
-       return FALSE;
-    
-    if(wgl_ctx[ctx_current].ctx == NULL) {
-       SetLastError(0);
-       return(FALSE);
-    }
-    WMesaSwapBuffers();
-    return(TRUE);
+    WMesaSwapBuffers(hdc);
+    return TRUE;
 }
 
 static FIXED FixedFromDouble(double d)
index 982366be42b4fc840e1d8429bb032db4d00e66c3..fd7e28817e35910e7db40e5190518337dfe74c98 100644 (file)
@@ -6,6 +6,7 @@
 #include "wmesadef.h"
 #include "colors.h"
 #include <GL/wmesa.h>
+#include "context.h"
 #include "extensions.h"
 #include "framebuffer.h"
 #include "renderbuffer.h"
 #include "tnl/t_context.h"
 #include "tnl/t_pipeline.h"
 
-#define FLIP(Y)  (Current->height-(Y)-1)
 
-/* Static Data */
+/* linked list of our Framebuffers (windows) */
+static WMesaFramebuffer FirstFramebuffer = NULL;
+
+
+/**
+ * Create a new WMesaFramebuffer object which will correspond to the
+ * given HDC (Window handle).
+ */
+WMesaFramebuffer
+wmesa_new_framebuffer(HDC hdc, GLvisual *visual)
+{
+    WMesaFramebuffer pwfb
+        = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer));
+    if (pwfb) {
+        _mesa_initialize_framebuffer(&pwfb->Base, visual);
+        pwfb->hdc = hdc;
+        /* insert at head of list */
+        pwfb->next = FirstFramebuffer;
+        FirstFramebuffer = pwfb;
+    }
+    return pwfb;
+}
+
+
+/**
+ * Given an hdc, return the corresponding WMesaFramebuffer
+ */
+WMesaFramebuffer
+wmesa_lookup_framebuffer(HDC hdc)
+{
+    WMesaFramebuffer pwfb;
+    for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {
+        if (pwfb->hdc == hdc)
+            return pwfb;
+    }
+    return NULL;
+}
+
+
+/**
+ * Given a GLframebuffer, return the corresponding WMesaFramebuffer.
+ */
+static WMesaFramebuffer wmesa_framebuffer(GLframebuffer *fb)
+{
+    return (WMesaFramebuffer) fb;
+}
+
+
+/**
+ * Given a GLcontext, return the corresponding WMesaContext.
+ */
+static WMesaContext wmesa_context(const GLcontext *ctx)
+{
+    return (WMesaContext) ctx;
+}
 
-static PWMC Current = NULL;
 
 /*
  * Every driver should implement a GetString function in order to
@@ -33,15 +86,17 @@ static const GLubyte *wmesa_get_string(GLcontext *ctx, GLenum name)
        (GLubyte *) "Mesa Windows GDI Driver" : NULL;
 }
 
+
 /*
  * Determine the pixel format based on the pixel size.
  */
-static void wmSetPixelFormat(PWMC pwc, HDC hDC)
+static void wmSetPixelFormat(WMesaContext pwc, HDC hDC)
 {
     pwc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
 
     // Only 16 and 32 bit targets are supported now
-    assert(pwc->cColorBits == 16 || 
+    assert(pwc->cColorBits == 0 ||
+          pwc->cColorBits == 16 || 
           pwc->cColorBits == 32);
 
     switch(pwc->cColorBits){
@@ -59,13 +114,15 @@ static void wmSetPixelFormat(PWMC pwc, HDC hDC)
     }
 }
 
-/*
+
+/**
  * Create DIB for back buffer.
  * We write into this memory with the span routines and then blit it
  * to the window on a buffer swap.
+ *
+ * XXX we should probably pass a WMesaFramebuffer ptr, not a WMesaContext!
  */
-
-BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
+BOOL wmCreateBackingStore(WMesaContext pwc, long lxSize, long lySize)
 {
     HDC          hdc = pwc->hDC;
     LPBITMAPINFO pbmi = &(pwc->bmi);
@@ -105,7 +162,10 @@ BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
     return TRUE;
 }
 
-static wmDeleteBackingStore(PWMC pwc)
+
+/* XXX pass WMesaFramebuffer, not WMesaContext.
+ */
+static wmDeleteBackingStore(WMesaContext pwc)
 {
     if (pwc->hbmDIB) {
        SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
@@ -114,20 +174,48 @@ static wmDeleteBackingStore(PWMC pwc)
     }
 }
 
-static void wmesa_get_buffer_size(GLframebuffer *buffer, 
-                                 GLuint *width, 
-                                 GLuint *height )
+
+/**
+ * Find the width and height of the window named by hdc.
+ */
+static void
+get_window_size(HDC hdc, GLuint *width, GLuint *height)
 {
-    *width = Current->width;
-    *height = Current->height;
+    if (WindowFromDC(hdc)) {
+        RECT rect;
+        GetClientRect(WindowFromDC(hdc), &rect);
+        *width = rect.right - rect.left;
+        *height = rect.bottom - rect.top;
+    }
+    else { /* Memory context */
+        /* From contributed code - use the size of the desktop
+         * for the size of a memory context (?) */
+        *width = GetDeviceCaps(hdc, HORZRES);
+        *height = GetDeviceCaps(hdc, VERTRES);
+    }
 }
 
 
-static void wmesa_flush(GLcontext* ctx)
+static void
+wmesa_get_buffer_size(GLframebuffer *buffer, GLuint *width, GLuint *height)
 {
-    if (Current->db_flag) {
-       BitBlt(Current->hDC, 0, 0, Current->width, Current->height,
-              Current->dib.hDC, 0, 0, SRCCOPY);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(buffer);
+    get_window_size(pwfb->hdc, width, height);
+}
+
+
+static void wmesa_flush(GLcontext *ctx)
+{
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->WinSysDrawBuffer);
+
+    /* XXX I guess we're _always_ double buffered and render to the back
+     * buffer.  So flushing involves copying the back color buffer to
+     * the front.
+     */
+    if (pwc->db_flag) {
+       BitBlt(pwc->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height,
+              pwc->dib.hDC, 0, 0, SRCCOPY);
     }
     else {
        /* Do nothing for single buffer */
@@ -146,28 +234,30 @@ static void wmesa_flush(GLcontext* ctx)
 /*
  * Set the color index used to clear the color buffer.
  */
-static void clear_index(GLcontextctx, GLuint index)
+static void clear_index(GLcontext *ctx, GLuint index)
 {
+    WMesaContext pwc = wmesa_context(ctx);
     /* Note that indexed mode is not supported yet */
-    Current->clearColorRef = RGB(0,0,0);
+    pwc->clearColorRef = RGB(0,0,0);
 }
 
 /*
  * Set the color used to clear the color buffer.
  */
-static void clear_color(GLcontextctx, const GLfloat color[4])
+static void clear_color(GLcontext *ctx, const GLfloat color[4])
 {
+    WMesaContext pwc = wmesa_context(ctx);
     GLubyte col[3];
-    UINT    bytesPerPixel = Current->cColorBits / 8; 
+    UINT    bytesPerPixel = pwc->cColorBits / 8; 
 
     CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
     CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
     CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
-    Current->clearColorRef = RGB(col[0], col[1], col[2]);
-    DeleteObject(Current->clearPen);
-    DeleteObject(Current->clearBrush);
-    Current->clearPen = CreatePen(PS_SOLID, 1, Current->clearColorRef); 
-    Current->clearBrush = CreateSolidBrush(Current->clearColorRef); 
+    pwc->clearColorRef = RGB(col[0], col[1], col[2]);
+    DeleteObject(pwc->clearPen);
+    DeleteObject(pwc->clearBrush);
+    pwc->clearPen = CreatePen(PS_SOLID, 1, pwc->clearColorRef); 
+    pwc->clearBrush = CreateSolidBrush(pwc->clearColorRef); 
 }
 
 
@@ -180,12 +270,15 @@ static void clear_color(GLcontext* ctx, const GLfloat color[4])
  * Clearing of the other non-color buffers is left to the swrast. 
  */ 
 
-static void clear(GLcontextctx, 
+static void clear(GLcontext *ctx, 
                  GLbitfield mask, 
                  GLboolean all, 
                  GLint x, GLint y, 
                  GLint width, GLint height) 
 {
+#define FLIP(Y)  (ctx->DrawBuffer->Height - (Y) - 1)
+
+    WMesaContext pwc = wmesa_context(ctx);
     int done = 0;
 
     /* Let swrast do all the work if the masks are not set to
@@ -198,18 +291,11 @@ static void clear(GLcontext* ctx,
        return;
     }
 
-    /* 'all' means clear the entire window */
-    if (all) { 
-       x = y = 0; 
-       width = Current->width; 
-       height = Current->height; 
-    } 
-
     /* Back buffer */
     if (mask & BUFFER_BIT_BACK_LEFT) { 
        
        int     i, rowSize; 
-       UINT    bytesPerPixel = Current->cColorBits / 8; 
+       UINT    bytesPerPixel = pwc->cColorBits / 8; 
        LPBYTE  lpb, clearRow;
        LPWORD  lpw;
        BYTE    bColor; 
@@ -224,33 +310,33 @@ static void clear(GLcontext* ctx,
            /* Now check for an easy clear value */
            switch (bytesPerPixel) {
            case 1:
-               bColor = BGR8(GetRValue(Current->clearColorRef), 
-                             GetGValue(Current->clearColorRef), 
-                             GetBValue(Current->clearColorRef));
-               memset(Current->pbPixels, bColor, 
-                      Current->ScanWidth * height);
+               bColor = BGR8(GetRValue(pwc->clearColorRef), 
+                             GetGValue(pwc->clearColorRef), 
+                             GetBValue(pwc->clearColorRef));
+               memset(pwc->pbPixels, bColor, 
+                      pwc->ScanWidth * height);
                done = 1;
                break;
            case 2:
-               wColor = BGR16(GetRValue(Current->clearColorRef), 
-                              GetGValue(Current->clearColorRef), 
-                              GetBValue(Current->clearColorRef)); 
+               wColor = BGR16(GetRValue(pwc->clearColorRef), 
+                              GetGValue(pwc->clearColorRef), 
+                              GetBValue(pwc->clearColorRef)); 
                if (((wColor >> 8) & 0xff) == (wColor & 0xff)) {
-                   memset(Current->pbPixels, wColor & 0xff, 
-                          Current->ScanWidth * height);
+                   memset(pwc->pbPixels, wColor & 0xff, 
+                          pwc->ScanWidth * height);
                    done = 1;
                }
                break;
            case 3:
                /* fall through */
            case 4:
-               if (GetRValue(Current->clearColorRef) == 
-                   GetGValue(Current->clearColorRef) &&
-                   GetRValue(Current->clearColorRef) == 
-                   GetBValue(Current->clearColorRef)) {
-                   memset(Current->pbPixels, 
-                          GetRValue(Current->clearColorRef), 
-                          Current->ScanWidth * height);
+               if (GetRValue(pwc->clearColorRef) == 
+                   GetGValue(pwc->clearColorRef) &&
+                   GetRValue(pwc->clearColorRef) == 
+                   GetBValue(pwc->clearColorRef)) {
+                   memset(pwc->pbPixels, 
+                          GetRValue(pwc->clearColorRef), 
+                          pwc->ScanWidth * height);
                    done = 1;
                }
                break;
@@ -263,30 +349,30 @@ static void clear(GLcontext* ctx,
            /* Need to clear a row at a time.  Begin by setting the first
             * row in the area to be cleared to the clear color. */
            
-           clearRow = Current->pbPixels + 
-               Current->ScanWidth * FLIP(y) +
+           clearRow = pwc->pbPixels + 
+               pwc->ScanWidth * FLIP(y) +
                bytesPerPixel * x; 
            switch (bytesPerPixel) {
            case 1:
                lpb = clearRow;
-               bColor = BGR8(GetRValue(Current->clearColorRef), 
-                             GetGValue(Current->clearColorRef), 
-                             GetBValue(Current->clearColorRef));
+               bColor = BGR8(GetRValue(pwc->clearColorRef), 
+                             GetGValue(pwc->clearColorRef), 
+                             GetBValue(pwc->clearColorRef));
                memset(lpb, bColor, width);
                break;
            case 2:
                lpw = (LPWORD)clearRow;
-               wColor = BGR16(GetRValue(Current->clearColorRef), 
-                              GetGValue(Current->clearColorRef), 
-                              GetBValue(Current->clearColorRef)); 
+               wColor = BGR16(GetRValue(pwc->clearColorRef), 
+                              GetGValue(pwc->clearColorRef), 
+                              GetBValue(pwc->clearColorRef)); 
                for (i=0; i<width; i++)
                    *lpw++ = wColor;
                break;
            case 3: 
                lpb = clearRow;
-               r = GetRValue(Current->clearColorRef); 
-               g = GetGValue(Current->clearColorRef); 
-               b = GetBValue(Current->clearColorRef); 
+               r = GetRValue(pwc->clearColorRef); 
+               g = GetGValue(pwc->clearColorRef); 
+               b = GetBValue(pwc->clearColorRef); 
                for (i=0; i<width; i++) {
                    *lpb++ = b; 
                    *lpb++ = g; 
@@ -295,9 +381,9 @@ static void clear(GLcontext* ctx,
                break;
            case 4: 
                lpdw = (LPDWORD)clearRow; 
-               dwColor = BGR32(GetRValue(Current->clearColorRef), 
-                               GetGValue(Current->clearColorRef), 
-                               GetBValue(Current->clearColorRef)); 
+               dwColor = BGR32(GetRValue(pwc->clearColorRef), 
+                               GetGValue(pwc->clearColorRef), 
+                               GetBValue(pwc->clearColorRef)); 
                for (i=0; i<width; i++)
                    *lpdw++ = dwColor;
                break;
@@ -306,11 +392,11 @@ static void clear(GLcontext* ctx,
            } /* switch */
            
            /* copy cleared row to other rows in buffer */
-           lpb = clearRow - Current->ScanWidth;
+           lpb = clearRow - pwc->ScanWidth;
            rowSize = width * bytesPerPixel;
            for (i=1; i<height; i++) { 
                memcpy(lpb, clearRow, rowSize); 
-               lpb -= Current->ScanWidth; 
+               lpb -= pwc->ScanWidth; 
            } 
        } /* not done */
        mask &= ~BUFFER_BIT_BACK_LEFT;
@@ -318,9 +404,9 @@ static void clear(GLcontext* ctx,
 
     /* front buffer */
     if (mask & BUFFER_BIT_FRONT_LEFT) { 
-       HDC DC = Current->hDC; 
-       HPEN Old_Pen = SelectObject(DC, Current->clearPen); 
-       HBRUSH Old_Brush = SelectObject(DC, Current->clearBrush);
+       HDC DC = pwc->hDC; 
+       HPEN Old_Pen = SelectObject(DC, pwc->clearPen); 
+       HBRUSH Old_Brush = SelectObject(DC, pwc->clearBrush);
        Rectangle(DC,
                  x,
                  FLIP(y) + 1,
@@ -335,6 +421,7 @@ static void clear(GLcontext* ctx,
     if (mask) 
        _swrast_Clear(ctx, mask, all, x, y, width, height); 
   
+#undef FLIP
 } 
 
 
@@ -342,18 +429,21 @@ static void clear(GLcontext* ctx,
 /*****                   PIXEL Functions                          *****/
 /**********************************************************************/
 
+#define FLIP(Y)  (rb->Height - (Y) - 1)
+
+
 /* SINGLE BUFFER */
 
 /* These are slow, but work with all non-indexed visual types */
 
 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
-static void write_rgba_span_single(const GLcontextctx, 
+static void write_rgba_span_single(const GLcontext *ctx, 
                                   struct gl_renderbuffer *rb, 
                                   GLuint n, GLint x, GLint y,
                                   const GLubyte rgba[][4], 
                                   const GLubyte mask[] )
 {
-    PWMC    pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     GLuint i;
     
     (void) ctx;
@@ -373,13 +463,13 @@ static void write_rgba_span_single(const GLcontext* ctx,
 }
 
 /* Write a horizontal span of RGB color pixels with a boolean mask. */
-static void write_rgb_span_single(const GLcontextctx, 
+static void write_rgb_span_single(const GLcontext *ctx, 
                                  struct gl_renderbuffer *rb, 
                                  GLuint n, GLint x, GLint y,
                                  const GLubyte rgb[][3], 
                                  const GLubyte mask[] )
 {
-    PWMC    pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     GLuint i;
     
     (void) ctx;
@@ -402,14 +492,14 @@ static void write_rgb_span_single(const GLcontext* ctx,
  * Write a horizontal span of pixels with a boolean mask.  The current color
  * is used for all pixels.
  */
-static void write_mono_rgba_span_single(const GLcontextctx, 
+static void write_mono_rgba_span_single(const GLcontext *ctx, 
                                        struct gl_renderbuffer *rb,
                                        GLuint n, GLint x, GLint y,
                                        const GLchan color[4], 
                                        const GLubyte mask[])
 {
     GLuint i;
-    PWMC pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     COLORREF colorref;
 
     (void) ctx;
@@ -427,7 +517,7 @@ static void write_mono_rgba_span_single(const GLcontext* ctx,
 }
 
 /* Write an array of RGBA pixels with a boolean mask. */
-static void write_rgba_pixels_single(const GLcontextctx, 
+static void write_rgba_pixels_single(const GLcontext *ctx, 
                                     struct gl_renderbuffer *rb,
                                     GLuint n, 
                                     const GLint x[], const GLint y[],
@@ -435,7 +525,7 @@ static void write_rgba_pixels_single(const GLcontext* ctx,
                                     const GLubyte mask[] )
 {
     GLuint i;
-    PWMC    pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     (void) ctx;
     for (i=0; i<n; i++)
        if (mask[i])
@@ -450,7 +540,7 @@ static void write_rgba_pixels_single(const GLcontext* ctx,
  * Write an array of pixels with a boolean mask.  The current color
  * is used for all pixels.
  */
-static void write_mono_rgba_pixels_single(const GLcontextctx, 
+static void write_mono_rgba_pixels_single(const GLcontext *ctx, 
                                          struct gl_renderbuffer *rb,
                                          GLuint n,
                                          const GLint x[], const GLint y[],
@@ -458,7 +548,7 @@ static void write_mono_rgba_pixels_single(const GLcontext* ctx,
                                          const GLubyte mask[] )
 {
     GLuint i;
-    PWMC    pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     COLORREF colorref;
     (void) ctx;
     colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]);
@@ -468,16 +558,17 @@ static void write_mono_rgba_pixels_single(const GLcontext* ctx,
 }
 
 /* Read a horizontal span of color pixels. */
-static void read_rgba_span_single(const GLcontextctx, 
+static void read_rgba_span_single(const GLcontext *ctx, 
                                  struct gl_renderbuffer *rb,
                                  GLuint n, GLint x, GLint y,
                                  GLubyte rgba[][4] )
 {
+    WMesaContext pwc = wmesa_context(ctx);
     GLuint i;
     COLORREF Color;
     y = FLIP(y);
     for (i=0; i<n; i++) {
-       Color = GetPixel(Current->hDC, x+i, y);
+       Color = GetPixel(pwc->hDC, x+i, y);
        rgba[i][RCOMP] = GetRValue(Color);
        rgba[i][GCOMP] = GetGValue(Color);
        rgba[i][BCOMP] = GetBValue(Color);
@@ -487,21 +578,22 @@ static void read_rgba_span_single(const GLcontext* ctx,
 
 
 /* Read an array of color pixels. */
-static void read_rgba_pixels_single(const GLcontextctx, 
+static void read_rgba_pixels_single(const GLcontext *ctx, 
                                    struct gl_renderbuffer *rb,
                                    GLuint n, const GLint x[], const GLint y[],
                                    GLubyte rgba[][4])
 {
-  GLuint i;
-  COLORREF Color;
-  for (i=0; i<n; i++) {
-      GLint y2 = FLIP(y[i]);
-      Color = GetPixel(Current->hDC, x[i], y2);
-      rgba[i][RCOMP] = GetRValue(Color);
-      rgba[i][GCOMP] = GetGValue(Color);
-      rgba[i][BCOMP] = GetBValue(Color);
-      rgba[i][ACOMP] = 255;
-  }
+    WMesaContext pwc = wmesa_context(ctx);
+    GLuint i;
+    COLORREF Color;
+    for (i=0; i<n; i++) {
+        GLint y2 = FLIP(y[i]);
+        Color = GetPixel(pwc->hDC, x[i], y2);
+        rgba[i][RCOMP] = GetRValue(Color);
+        rgba[i][GCOMP] = GetGValue(Color);
+        rgba[i][BCOMP] = GetBValue(Color);
+        rgba[i][ACOMP] = 255;
+    }
 }
 
 /*********************************************************************/
@@ -515,13 +607,13 @@ LPDWORD lpdw = ((LPDWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
 
 
 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
-static void write_rgba_span_32(const GLcontextctx, 
+static void write_rgba_span_32(const GLcontext *ctx, 
                               struct gl_renderbuffer *rb, 
                               GLuint n, GLint x, GLint y,
                               const GLubyte rgba[][4], 
                               const GLubyte mask[] )
 {
-    PWMC    pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     GLuint i;
     LPDWORD lpdw;
 
@@ -544,13 +636,13 @@ static void write_rgba_span_32(const GLcontext* ctx,
 
 
 /* Write a horizontal span of RGB color pixels with a boolean mask. */
-static void write_rgb_span_32(const GLcontextctx, 
+static void write_rgb_span_32(const GLcontext *ctx, 
                              struct gl_renderbuffer *rb, 
                              GLuint n, GLint x, GLint y,
-                             const GLubyte rgb[][4], 
+                             const GLubyte rgb[][3], 
                              const GLubyte mask[] )
 {
-    PWMC    pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     GLuint i;
     LPDWORD lpdw;
 
@@ -575,7 +667,7 @@ static void write_rgb_span_32(const GLcontext* ctx,
  * Write a horizontal span of pixels with a boolean mask.  The current color
  * is used for all pixels.
  */
-static void write_mono_rgba_span_32(const GLcontextctx, 
+static void write_mono_rgba_span_32(const GLcontext *ctx, 
                                    struct gl_renderbuffer *rb,
                                    GLuint n, GLint x, GLint y,
                                    const GLchan color[4], 
@@ -584,7 +676,7 @@ static void write_mono_rgba_span_32(const GLcontext* ctx,
     LPDWORD lpdw;
     DWORD pixel;
     GLuint i;
-    PWMC pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     lpdw = ((LPDWORD)(pwc->pbPixels + pwc->ScanWidth * y)) + x;
     y=FLIP(y);
     pixel = BGR32(color[RCOMP], color[GCOMP], color[BCOMP]);
@@ -600,14 +692,14 @@ static void write_mono_rgba_span_32(const GLcontext* ctx,
 }
 
 /* Write an array of RGBA pixels with a boolean mask. */
-static void write_rgba_pixels_32(const GLcontextctx, 
+static void write_rgba_pixels_32(const GLcontext *ctx, 
                                 struct gl_renderbuffer *rb,
                                 GLuint n, const GLint x[], const GLint y[],
                                 const GLubyte rgba[][4], 
                                 const GLubyte mask[])
 {
     GLuint i;
-    PWMC    pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);;
     for (i=0; i<n; i++)
        if (mask[i])
            WMSETPIXEL32(pwc, FLIP(y[i]), x[i],
@@ -618,7 +710,7 @@ static void write_rgba_pixels_32(const GLcontext* ctx,
  * Write an array of pixels with a boolean mask.  The current color
  * is used for all pixels.
  */
-static void write_mono_rgba_pixels_32(const GLcontextctx, 
+static void write_mono_rgba_pixels_32(const GLcontext *ctx, 
                                      struct gl_renderbuffer *rb,
                                      GLuint n,
                                      const GLint x[], const GLint y[],
@@ -626,7 +718,7 @@ static void write_mono_rgba_pixels_32(const GLcontext* ctx,
                                      const GLubyte mask[])
 {
     GLuint i;
-    PWMC pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     for (i=0; i<n; i++)
        if (mask[i])
            WMSETPIXEL32(pwc, FLIP(y[i]),x[i],color[RCOMP],
@@ -634,7 +726,7 @@ static void write_mono_rgba_pixels_32(const GLcontext* ctx,
 }
 
 /* Read a horizontal span of color pixels. */
-static void read_rgba_span_32(const GLcontextctx, 
+static void read_rgba_span_32(const GLcontext *ctx, 
                              struct gl_renderbuffer *rb,
                              GLuint n, GLint x, GLint y,
                              GLubyte rgba[][4] )
@@ -642,7 +734,7 @@ static void read_rgba_span_32(const GLcontext* ctx,
     GLuint i;
     DWORD pixel;
     LPDWORD lpdw;
-    PWMC pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     
     y = FLIP(y);
     lpdw = ((LPDWORD)(pwc->pbPixels + pwc->ScanWidth * y)) + x;
@@ -657,7 +749,7 @@ static void read_rgba_span_32(const GLcontext* ctx,
 
 
 /* Read an array of color pixels. */
-static void read_rgba_pixels_32(const GLcontextctx, 
+static void read_rgba_pixels_32(const GLcontext *ctx, 
                                struct gl_renderbuffer *rb,
                                GLuint n, const GLint x[], const GLint y[],
                                GLubyte rgba[][4])
@@ -665,7 +757,7 @@ static void read_rgba_pixels_32(const GLcontext* ctx,
     GLuint i;
     DWORD pixel;
     LPDWORD lpdw;
-    PWMC pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
 
     for (i=0; i<n; i++) {
        GLint y2 = FLIP(y[i]);
@@ -690,13 +782,13 @@ LPWORD lpw = ((LPWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
 
 
 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
-static void write_rgba_span_16(const GLcontextctx, 
+static void write_rgba_span_16(const GLcontext *ctx, 
                               struct gl_renderbuffer *rb, 
                               GLuint n, GLint x, GLint y,
                               const GLubyte rgba[][4], 
                               const GLubyte mask[] )
 {
-    PWMC    pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     GLuint i;
     LPWORD lpw;
 
@@ -719,13 +811,13 @@ static void write_rgba_span_16(const GLcontext* ctx,
 
 
 /* Write a horizontal span of RGB color pixels with a boolean mask. */
-static void write_rgb_span_16(const GLcontextctx, 
+static void write_rgb_span_16(const GLcontext *ctx, 
                              struct gl_renderbuffer *rb, 
                              GLuint n, GLint x, GLint y,
                              const GLubyte rgb[][4], 
                              const GLubyte mask[] )
 {
-    PWMC    pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     GLuint i;
     LPWORD lpw;
 
@@ -750,7 +842,7 @@ static void write_rgb_span_16(const GLcontext* ctx,
  * Write a horizontal span of pixels with a boolean mask.  The current color
  * is used for all pixels.
  */
-static void write_mono_rgba_span_16(const GLcontextctx, 
+static void write_mono_rgba_span_16(const GLcontext *ctx, 
                                    struct gl_renderbuffer *rb,
                                    GLuint n, GLint x, GLint y,
                                    const GLchan color[4], 
@@ -759,7 +851,7 @@ static void write_mono_rgba_span_16(const GLcontext* ctx,
     LPWORD lpw;
     WORD pixel;
     GLuint i;
-    PWMC pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     (void) ctx;
     lpw = ((LPWORD)(pwc->pbPixels + pwc->ScanWidth * y)) + x;
     y=FLIP(y);
@@ -776,14 +868,14 @@ static void write_mono_rgba_span_16(const GLcontext* ctx,
 }
 
 /* Write an array of RGBA pixels with a boolean mask. */
-static void write_rgba_pixels_16(const GLcontextctx, 
+static void write_rgba_pixels_16(const GLcontext *ctx, 
                                 struct gl_renderbuffer *rb,
                                 GLuint n, const GLint x[], const GLint y[],
                                 const GLubyte rgba[][4], 
                                 const GLubyte mask[])
 {
     GLuint i;
-    PWMC    pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     (void) ctx;
     for (i=0; i<n; i++)
        if (mask[i])
@@ -795,7 +887,7 @@ static void write_rgba_pixels_16(const GLcontext* ctx,
  * Write an array of pixels with a boolean mask.  The current color
  * is used for all pixels.
  */
-static void write_mono_rgba_pixels_16(const GLcontextctx, 
+static void write_mono_rgba_pixels_16(const GLcontext *ctx, 
                                      struct gl_renderbuffer *rb,
                                      GLuint n,
                                      const GLint x[], const GLint y[],
@@ -803,7 +895,7 @@ static void write_mono_rgba_pixels_16(const GLcontext* ctx,
                                      const GLubyte mask[])
 {
     GLuint i;
-    PWMC    pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     (void) ctx;
     for (i=0; i<n; i++)
        if (mask[i])
@@ -812,14 +904,14 @@ static void write_mono_rgba_pixels_16(const GLcontext* ctx,
 }
 
 /* Read a horizontal span of color pixels. */
-static void read_rgba_span_16(const GLcontextctx, 
+static void read_rgba_span_16(const GLcontext *ctx, 
                              struct gl_renderbuffer *rb,
                              GLuint n, GLint x, GLint y,
                              GLubyte rgba[][4] )
 {
     GLuint i, pixel;
     LPWORD lpw;
-    PWMC pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
     
     y = FLIP(y);
     lpw = ((LPWORD)(pwc->pbPixels + pwc->ScanWidth * y)) + x;
@@ -835,14 +927,14 @@ static void read_rgba_span_16(const GLcontext* ctx,
 
 
 /* Read an array of color pixels. */
-static void read_rgba_pixels_16(const GLcontextctx, 
+static void read_rgba_pixels_16(const GLcontext *ctx, 
                                struct gl_renderbuffer *rb,
                                GLuint n, const GLint x[], const GLint y[],
                                GLubyte rgba[][4])
 {
     GLuint i, pixel;
     LPWORD lpw;
-    PWMC pwc = Current;
+    WMesaContext pwc = wmesa_context(ctx);
 
     for (i=0; i<n; i++) {
        GLint y2 = FLIP(y[i]);
@@ -872,6 +964,11 @@ wmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
     _mesa_free(rb);
 }
 
+
+/**
+ * This is called by Mesa whenever it determines that the window size
+ * has changed.  Do whatever's needed to cope with that.
+ */
 static GLboolean
 wmesa_renderbuffer_storage(GLcontext *ctx, 
                           struct gl_renderbuffer *rb,
@@ -879,6 +976,8 @@ wmesa_renderbuffer_storage(GLcontext *ctx,
                           GLuint width, 
                           GLuint height)
 {
+    rb->Width = width;
+    rb->Height = height;
     return GL_TRUE;
 }
 
@@ -930,13 +1029,14 @@ static void
 wmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer,
                      GLuint width, GLuint height)
 {
-    if (Current->width != width || Current->height != height) {
-       Current->width = width;
-       Current->height = height;
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_framebuffer(buffer);
+
+    if (pwfb->Base.Width != width || pwfb->Base.Height != height) {
        /* Realloc back buffer */
-       if (Current->db_flag) {
-           wmDeleteBackingStore(Current);
-           wmCreateBackingStore(Current, width, height);
+       if (pwc->db_flag) {
+           wmDeleteBackingStore(pwc);
+           wmCreateBackingStore(pwc, width, height);
        }
     }
     _mesa_resize_framebuffer(ctx, buffer, width, height);
@@ -950,15 +1050,25 @@ wmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer,
  * Remember, we have no opportunity to respond to conventional
  * resize events since the driver has no event loop.
  * Thus, we poll.
- * Note that this trick isn't fool-proof.  If the application never calls
- * glViewport, our notion of the current window size may be incorrect.
+ * MakeCurrent also ends up making a call here, so that ensures
+ * we get the viewport set correctly, even if the app does not call
+ * glViewport and relies on the defaults.
  */
 static void wmesa_viewport(GLcontext *ctx, 
                           GLint x, GLint y, 
                           GLsizei width, GLsizei height)
 {
-   if (Current->width != width || Current->height != height) {
-       wmesa_resize_buffers(ctx, ctx->WinSysDrawBuffer, width, height);
+    WMesaContext pwc = wmesa_context(ctx);
+    GLuint new_width, new_height;
+
+    wmesa_get_buffer_size(ctx->WinSysDrawBuffer, &new_width, &new_height);
+
+    if (new_width != width || new_height != height) {
+        /**
+        * Either the window was resized or the viewport changed - not sure which.
+        * So call resize buffers to resize them if the window size changed.
+        */
+       wmesa_resize_buffers(ctx, ctx->WinSysDrawBuffer, new_width, new_height);
        ctx->NewState |= _NEW_BUFFERS;  /* to update scissor / window bounds */
    }
 }
@@ -1014,6 +1124,8 @@ WMesaContext WMesaCreateContext(HDC hDC,
     WMesaContext c;
     struct dd_function_table functions;
     GLint red_bits, green_bits, blue_bits, alpha_bits;
+    GLcontext *ctx;
+    GLvisual *visual;
 
     (void) Pal;
     
@@ -1065,19 +1177,19 @@ WMesaContext WMesaCreateContext(HDC hDC,
        break;
     }
     /* Create visual based on flags */
-    c->gl_visual = _mesa_create_visual(rgb_flag,
-                                      db_flag,    /* db_flag */
-                                      GL_FALSE,   /* stereo */
-                                      red_bits, green_bits, blue_bits, /* color RGB */
-                                      alpha_flag ? alpha_bits : 0, /* color A */
-                                      0,          /* index bits */
-                                      DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */
-                                      8,          /* stencil_bits */
-                                      16,16,16,   /* accum RGB */
-                                      alpha_flag ? 16 : 0, /* accum A */
-                                      1);         /* num samples */
+    visual = _mesa_create_visual(rgb_flag,
+                                 db_flag,    /* db_flag */
+                                 GL_FALSE,   /* stereo */
+                                 red_bits, green_bits, blue_bits, /* color RGB */
+                                 alpha_flag ? alpha_bits : 0, /* color A */
+                                 0,          /* index bits */
+                                 DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */
+                                 8,          /* stencil_bits */
+                                 16,16,16,   /* accum RGB */
+                                 alpha_flag ? 16 : 0, /* accum A */
+                                 1);         /* num samples */
     
-    if (!c->gl_visual) {
+    if (!visual) {
        _mesa_free(c);
        return NULL;
     }
@@ -1094,155 +1206,163 @@ WMesaContext WMesaCreateContext(HDC hDC,
     functions.ResizeBuffers = wmesa_resize_buffers;
     functions.Viewport = wmesa_viewport;
 
-    /* allocate a new Mesa context */
-    c->gl_ctx = _mesa_create_context(c->gl_visual, NULL,
-                                    &functions, (void *)c);
-    if (!c->gl_ctx) {
-       _mesa_destroy_visual( c->gl_visual );
-       _mesa_free(c);
-       return NULL;
-    }
-    
-    _mesa_enable_sw_extensions(c->gl_ctx);
-    _mesa_enable_1_3_extensions(c->gl_ctx);
-    _mesa_enable_1_4_extensions(c->gl_ctx);
-    _mesa_enable_1_5_extensions(c->gl_ctx);
-    _mesa_enable_2_0_extensions(c->gl_ctx);
+    /* initialize the Mesa context data */
+    ctx = &c->gl_ctx;
+    _mesa_initialize_context(ctx, visual, NULL, &functions, (void *)c);
+
+    _mesa_enable_sw_extensions(ctx);
+    _mesa_enable_1_3_extensions(ctx);
+    _mesa_enable_1_4_extensions(ctx);
+    _mesa_enable_1_5_extensions(ctx);
+    _mesa_enable_2_0_extensions(ctx);
   
     /* Initialize the software rasterizer and helper modules. */
-    if (!_swrast_CreateContext(c->gl_ctx) ||
-        !_ac_CreateContext(c->gl_ctx) ||
-        !_tnl_CreateContext(c->gl_ctx) ||
-       !_swsetup_CreateContext(c->gl_ctx)) {
-       _mesa_destroy_visual(c->gl_visual);
-       _mesa_destroy_framebuffer(c->gl_buffer);
-       _mesa_free_context_data(c->gl_ctx);
+    if (!_swrast_CreateContext(ctx) ||
+        !_ac_CreateContext(ctx) ||
+        !_tnl_CreateContext(ctx) ||
+       !_swsetup_CreateContext(ctx)) {
+       _mesa_free_context_data(ctx);
        _mesa_free(c);
        return NULL;
     }
-    _swsetup_Wakeup(c->gl_ctx);
-    TNL_CONTEXT(c->gl_ctx)->Driver.RunPipeline = _tnl_run_pipeline;
+    _swsetup_Wakeup(ctx);
+    TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
 
     return c;
 }
 
-void WMesaDestroyContext( void )
+
+void WMesaDestroyContext( WMesaContext pwc )
 {
-    WMesaContext c = Current;
+    GLcontext *ctx = &pwc->gl_ctx;
+    GET_CURRENT_CONTEXT(cur_ctx);
 
-    WMesaMakeCurrent(NULL);
+    if (cur_ctx == ctx) {
+        /* unbind current if deleting current context */
+        WMesaMakeCurrent(NULL, NULL);
+    }
 
     /* Release for device, not memory contexts */
-    if(WindowFromDC(c->hDC) != NULL)
+    if (WindowFromDC(pwc->hDC) != NULL)
     {
-      ReleaseDC(WindowFromDC(c->hDC), c->hDC);
+      ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC);
     }
-    DeleteObject(c->clearPen); 
-    DeleteObject(c->clearBrush); 
+    DeleteObject(pwc->clearPen); 
+    DeleteObject(pwc->clearBrush); 
     
-    if (c->db_flag)
-       wmDeleteBackingStore(c);
+    if (pwc->db_flag)
+       wmDeleteBackingStore(pwc);
 
-    _swsetup_DestroyContext(c->gl_ctx);
-    _tnl_DestroyContext(c->gl_ctx);
-    _ac_DestroyContext(c->gl_ctx);
-    _swrast_DestroyContext(c->gl_ctx);
+    _swsetup_DestroyContext(ctx);
+    _tnl_DestroyContext(ctx);
+    _ac_DestroyContext(ctx);
+    _swrast_DestroyContext(ctx);
     
-    _mesa_destroy_visual(c->gl_visual);
-    _mesa_destroy_framebuffer(c->gl_buffer);
-    _mesa_free_context_data(c->gl_ctx);
-    _mesa_free(c->gl_ctx);
-    _mesa_free(c);
+    _mesa_free_context_data(ctx);
+    _mesa_free(pwc);
 }
 
 
-void WMesaMakeCurrent(WMesaContext c)
+/**
+ * Create a new color renderbuffer.
+ */
+struct gl_renderbuffer *
+wmesa_new_renderbuffer(void)
 {
-    /* return if already current */
-    if (Current == c || c == NULL)
-       return;
+    struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
+    if (!rb)
+        return NULL;
+
+    _mesa_init_renderbuffer(rb, (GLuint)0);
+    
+    rb->_BaseFormat = GL_RGBA;
+    rb->InternalFormat = GL_RGBA;
+    rb->DataType = CHAN_TYPE;
+    rb->Delete = wmesa_delete_renderbuffer;
+    rb->AllocStorage = wmesa_renderbuffer_storage;
+    return rb;
+}
+
+
+void WMesaMakeCurrent(WMesaContext c, HDC hdc)
+{
+    WMesaFramebuffer pwfb;
+
+    {
+        /* return if already current */
+        GET_CURRENT_CONTEXT(ctx);
+        WMesaContext pwc = wmesa_context(ctx);
+        if (c == pwc && pwc->hDC == hdc)
+            return;
+    }
 
-    /* Lazy creation of buffers */
-    if (!c->gl_buffer) {
+    pwfb = wmesa_lookup_framebuffer(hdc);
+
+    /* Lazy creation of framebuffers */
+    if (c && !pwfb) {
         struct gl_renderbuffer *rb;
-        RECT rect;
-       
-       /* Determine window size */
-       if (WindowFromDC(c->hDC)) {
-           GetClientRect(WindowFromDC(c->hDC), &rect);
-           c->width = rect.right - rect.left;
-           c->height = rect.bottom - rect.top;
-       }
-       else { /* Memory context */
-           /* From contributed code - use the size of the desktop
-            * for the size of a memory context (?) */
-           c->width = GetDeviceCaps(c->hDC, HORZRES);
-           c->height = GetDeviceCaps(c->hDC, VERTRES);
-       }
+        GLvisual *visual = &c->gl_ctx.Visual;
+        GLuint width, height;
+
+        get_window_size(hdc, &width, &height);
+
        c->clearPen = CreatePen(PS_SOLID, 1, 0); 
        c->clearBrush = CreateSolidBrush(0); 
 
        /* Create back buffer if double buffered */
        if (c->db_flag) {
-           wmCreateBackingStore(c, c->width, c->height);
-                   
+           wmCreateBackingStore(c, width, height);
        }
        
-       c->gl_buffer = _mesa_create_framebuffer(c->gl_visual);
-       if (!c->gl_buffer)
-           return;
-    
-       rb = CALLOC_STRUCT(gl_renderbuffer);
-
-       if (!rb)
-           return;
-
-       _mesa_init_renderbuffer(rb, (GLuint)0);
-    
-       rb->_BaseFormat = GL_RGBA;
-       rb->InternalFormat = GL_RGBA;
-       rb->DataType = CHAN_TYPE;
-       rb->Delete = wmesa_delete_renderbuffer;
-       rb->AllocStorage = wmesa_renderbuffer_storage;
-
-       if (c->db_flag)
-           _mesa_add_renderbuffer(c->gl_buffer, BUFFER_BACK_LEFT, rb);
-       else
-           _mesa_add_renderbuffer(c->gl_buffer, BUFFER_FRONT_LEFT, rb);
-       wmesa_set_renderbuffer_funcs(rb, c->pixelformat, c->db_flag);
-
-       /* Let Mesa own the Depth, Stencil, and Accum buffers */
-       _mesa_add_soft_renderbuffers(c->gl_buffer,
-                                    GL_FALSE, /* color */
-                                    c->gl_visual->depthBits > 0,
-                                    c->gl_visual->stencilBits > 0,
-                                    c->gl_visual->accumRedBits > 0,
-                                    c->alpha_flag, 
-                                    GL_FALSE);
+        pwfb = wmesa_new_framebuffer(hdc, visual);
+
+        /* need a color renderbuffer */
+        rb = wmesa_new_renderbuffer();
+        if (c->db_flag)
+            _mesa_add_renderbuffer(&pwfb->Base, BUFFER_BACK_LEFT, rb);
+        else
+            _mesa_add_renderbuffer(&pwfb->Base, BUFFER_FRONT_LEFT, rb);
+        wmesa_set_renderbuffer_funcs(rb, c->pixelformat, c->db_flag);
+
+        /* Let Mesa own the Depth, Stencil, and Accum buffers */
+        _mesa_add_soft_renderbuffers(&pwfb->Base,
+                                     GL_FALSE, /* color */
+                                     visual->depthBits > 0,
+                                     visual->stencilBits > 0,
+                                     visual->accumRedBits > 0,
+                                     c->alpha_flag, 
+                                     GL_FALSE);
     }
 
-
-
-
-    if (Current = c)
-       _mesa_make_current(c->gl_ctx, c->gl_buffer, c->gl_buffer);
+    if (c && pwfb)
+       _mesa_make_current(&c->gl_ctx, &pwfb->Base, &pwfb->Base);
+    else
+        _mesa_make_current(NULL, NULL, NULL);
 }
 
 
-void WMesaSwapBuffers( void )
+void WMesaSwapBuffers( HDC hdc )
 {
     GET_CURRENT_CONTEXT(ctx);
-    
+    WMesaContext pwc = wmesa_context(ctx);
+    WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc);
+
+    if (!pwfb) {
+        _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc");
+        return;
+    }
+
     /* If we're swapping the buffer associated with the current context
      * we have to flush any pending rendering commands first.
      */
-    if (Current && Current->gl_ctx == ctx)
+    if (pwc->hDC == hdc) {
        _mesa_notifySwapBuffers(ctx);
-    
-    if (Current->db_flag)
-       wmesa_flush(ctx);
-}
 
-/**********************************************************************/
-/*****                        END                                 *****/
-/**********************************************************************/
+       BitBlt(pwc->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height,
+              pwc->dib.hDC, 0, 0, SRCCOPY);
+    }
+    else {
+        /* XXX for now only allow swapping current window */
+        _mesa_problem(NULL, "wmesa: can't swap non-current window");
+    }
+}
index 8b2f4912d6c42749dedaa07fdfb2e38f95503d4e..296000a12f70eaf556e82776287debb69c46edd7 100644 (file)
@@ -1,27 +1,28 @@
+#ifndef WMESADEF_H
+#define WMESADEF_H
 
 #include "context.h"
 
-typedef struct _dibSection{
+typedef struct _dibSection {
     HDC                hDC;
     HANDLE     hFileMap;
     BOOL       fFlushed;
     LPVOID     base;
-}WMDIBSECTION, *PWMDIBSECTION;
+} WMDIBSECTION, *PWMDIBSECTION;
 
-typedef struct wmesa_context{
-    GLcontext           *gl_ctx;       /* The core GL/Mesa context */
-    GLvisual            *gl_visual;    /* Describes the buffers */
-    GLframebuffer       *gl_buffer;    /* Depth, stencil, accum, etc buffers*/
+/**
+ * The Windows Mesa rendering context, derived from GLcontext.
+ */
+struct wmesa_context {
+    GLcontext           gl_ctx;                /* The core GL/Mesa context */
     HDC                 hDC;
     COLORREF           clearColorRef;
     HPEN                clearPen;
     HBRUSH              clearBrush;
-    GLuint             width;
-    GLuint             height;
-    GLuint             ScanWidth;
-    GLboolean          rgb_flag;
-    GLboolean          db_flag;
-    GLboolean          alpha_flag;
+    GLuint             ScanWidth; /* XXX move into wmesa_framebuffer */
+    GLboolean          rgb_flag; /* XXX remove - use gl_visual field */
+    GLboolean          db_flag; /* XXX remove - use gl_visual field */
+    GLboolean          alpha_flag; /* XXX remove - use gl_visual field */
     WMDIBSECTION       dib;
     BITMAPINFO          bmi;
     HBITMAP             hbmDIB;
@@ -29,6 +30,20 @@ typedef struct wmesa_context{
     PBYTE               pbPixels;
     BYTE               cColorBits;
     int                        pixelformat;
-}  *PWMC;
+};
 
 
+/**
+ * Windows framebuffer, derived from gl_framebuffer
+ */
+struct wmesa_framebuffer
+{
+    struct gl_framebuffer Base;
+    HDC hdc;
+    struct wmesa_framebuffer *next;
+};
+
+typedef struct wmesa_framebuffer *WMesaFramebuffer;
+
+
+#endif /* WMESADEF_H */