Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / windows / gdi / wmesa.c
1 /*
2  * Windows (Win32/Win64) device driver for Mesa
3  *
4  */
5
6 #include "wmesadef.h"
7 #include "colors.h"
8 #include "GL/wmesa.h"
9 #include <winuser.h>
10 #include "main/context.h"
11 #include "main/extensions.h"
12 #include "main/framebuffer.h"
13 #include "main/renderbuffer.h"
14 #include "main/macros.h"
15 #include "drivers/common/driverfuncs.h"
16 #include "drivers/common/meta.h"
17 #include "vbo/vbo.h"
18 #include "swrast/swrast.h"
19 #include "swrast_setup/swrast_setup.h"
20 #include "tnl/tnl.h"
21 #include "tnl/t_context.h"
22 #include "tnl/t_pipeline.h"
23
24
25 /* linked list of our Framebuffers (windows) */
26 static WMesaFramebuffer FirstFramebuffer = NULL;
27
28
29 /**
30  * Create a new WMesaFramebuffer object which will correspond to the
31  * given HDC (Window handle).
32  */
33 static WMesaFramebuffer
34 wmesa_new_framebuffer(HDC hdc, struct gl_config *visual)
35 {
36     WMesaFramebuffer pwfb
37         = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer));
38     if (pwfb) {
39         _mesa_initialize_window_framebuffer(&pwfb->Base, visual);
40         pwfb->hDC = hdc;
41         /* insert at head of list */
42         pwfb->next = FirstFramebuffer;
43         FirstFramebuffer = pwfb;
44     }
45     return pwfb;
46 }
47
48 /**
49  * Given an hdc, free the corresponding WMesaFramebuffer
50  */
51 static void
52 wmesa_free_framebuffer(HDC hdc)
53 {
54     WMesaFramebuffer pwfb, prev;
55     for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {
56         if (pwfb->hDC == hdc)
57             break;
58         prev = pwfb;
59     }
60     if (pwfb) {
61         struct gl_framebuffer *fb;
62         if (pwfb == FirstFramebuffer)
63             FirstFramebuffer = pwfb->next;
64         else
65             prev->next = pwfb->next;
66         fb = &pwfb->Base;
67         _mesa_reference_framebuffer(&fb, NULL); 
68     }
69 }
70
71 /**
72  * Given an hdc, return the corresponding WMesaFramebuffer
73  */
74 static WMesaFramebuffer
75 wmesa_lookup_framebuffer(HDC hdc)
76 {
77     WMesaFramebuffer pwfb;
78     for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {
79         if (pwfb->hDC == hdc)
80             return pwfb;
81     }
82     return NULL;
83 }
84
85
86 /**
87  * Given a struct gl_framebuffer, return the corresponding WMesaFramebuffer.
88  */
89 static WMesaFramebuffer wmesa_framebuffer(struct gl_framebuffer *fb)
90 {
91     return (WMesaFramebuffer) fb;
92 }
93
94
95 /**
96  * Given a struct gl_context, return the corresponding WMesaContext.
97  */
98 static WMesaContext wmesa_context(const struct gl_context *ctx)
99 {
100     return (WMesaContext) ctx;
101 }
102
103
104 /*
105  * Every driver should implement a GetString function in order to
106  * return a meaningful GL_RENDERER string.
107  */
108 static const GLubyte *wmesa_get_string(struct gl_context *ctx, GLenum name)
109 {
110     return (name == GL_RENDERER) ? 
111         (GLubyte *) "Mesa Windows GDI Driver" : NULL;
112 }
113
114
115 /*
116  * Determine the pixel format based on the pixel size.
117  */
118 static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC)
119 {
120     pwfb->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
121
122     /* Only 16 and 32 bit targets are supported now */
123     assert(pwfb->cColorBits == 0 ||
124            pwfb->cColorBits == 16 || 
125            pwfb->cColorBits == 24 || 
126            pwfb->cColorBits == 32);
127
128     switch(pwfb->cColorBits){
129     case 8:
130         pwfb->pixelformat = PF_INDEX8;
131         break;
132     case 16:
133         pwfb->pixelformat = PF_5R6G5B;
134         break;
135     case 24:
136     case 32:
137         pwfb->pixelformat = PF_8R8G8B;
138         break;
139     default:
140         pwfb->pixelformat = PF_BADFORMAT;
141     }
142 }
143
144
145 /**
146  * Create DIB for back buffer.
147  * We write into this memory with the span routines and then blit it
148  * to the window on a buffer swap.
149  */
150 static BOOL wmCreateBackingStore(WMesaFramebuffer pwfb, long lxSize, long lySize)
151 {
152     LPBITMAPINFO pbmi = &(pwfb->bmi);
153     HDC          hic;
154
155     pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
156     pbmi->bmiHeader.biWidth = lxSize;
157     pbmi->bmiHeader.biHeight= -lySize;
158     pbmi->bmiHeader.biPlanes = 1;
159     pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwfb->hDC, BITSPIXEL);
160     pbmi->bmiHeader.biCompression = BI_RGB;
161     pbmi->bmiHeader.biSizeImage = 0;
162     pbmi->bmiHeader.biXPelsPerMeter = 0;
163     pbmi->bmiHeader.biYPelsPerMeter = 0;
164     pbmi->bmiHeader.biClrUsed = 0;
165     pbmi->bmiHeader.biClrImportant = 0;
166     
167     pwfb->cColorBits = pbmi->bmiHeader.biBitCount;
168     pwfb->ScanWidth = (lxSize * (pwfb->cColorBits / 8) + 3) & ~3;
169     
170     hic = CreateIC("display", NULL, NULL, NULL);
171     pwfb->dib_hDC = CreateCompatibleDC(hic);
172     
173     pwfb->hbmDIB = CreateDIBSection(hic,
174                                    &pwfb->bmi,
175                                    DIB_RGB_COLORS,
176                                    (void **)&(pwfb->pbPixels),
177                                    0,
178                                    0);
179     pwfb->hOldBitmap = SelectObject(pwfb->dib_hDC, pwfb->hbmDIB);
180     
181     DeleteDC(hic);
182
183     wmSetPixelFormat(pwfb, pwfb->hDC);
184     return TRUE;
185 }
186
187
188 static void wmDeleteBackingStore(WMesaFramebuffer pwfb)
189 {
190     if (pwfb->hbmDIB) {
191         SelectObject(pwfb->dib_hDC, pwfb->hOldBitmap);
192         DeleteDC(pwfb->dib_hDC);
193         DeleteObject(pwfb->hbmDIB);
194     }
195 }
196
197
198 /**
199  * Find the width and height of the window named by hdc.
200  */
201 static void
202 get_window_size(HDC hdc, GLuint *width, GLuint *height)
203 {
204     if (WindowFromDC(hdc)) {
205         RECT rect;
206         GetClientRect(WindowFromDC(hdc), &rect);
207         *width = rect.right - rect.left;
208         *height = rect.bottom - rect.top;
209     }
210     else { /* Memory context */
211         /* From contributed code - use the size of the desktop
212          * for the size of a memory context (?) */
213         *width = GetDeviceCaps(hdc, HORZRES);
214         *height = GetDeviceCaps(hdc, VERTRES);
215     }
216 }
217
218
219 static void
220 wmesa_get_buffer_size(struct gl_framebuffer *buffer, GLuint *width, GLuint *height)
221 {
222     WMesaFramebuffer pwfb = wmesa_framebuffer(buffer);
223     get_window_size(pwfb->hDC, width, height);
224 }
225
226
227 static void wmesa_flush(struct gl_context *ctx)
228 {
229     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->WinSysDrawBuffer);
230
231     if (ctx->Visual.doubleBufferMode == 1) {
232         BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height,
233                pwfb->dib_hDC, 0, 0, SRCCOPY);
234     }
235     else {
236         /* Do nothing for single buffer */
237     }
238 }
239
240
241 /**********************************************************************/
242 /*****                   CLEAR Functions                          *****/
243 /**********************************************************************/
244
245 /* If we do not implement these, Mesa clears the buffers via the pixel
246  * span writing interface, which is very slow for a clear operation.
247  */
248
249 /*
250  * Set the color used to clear the color buffer.
251  */
252 static void clear_color(struct gl_context *ctx, const GLfloat color[4])
253 {
254     WMesaContext pwc = wmesa_context(ctx);
255     GLubyte col[3];
256
257     CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
258     CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
259     CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
260     pwc->clearColorRef = RGB(col[0], col[1], col[2]);
261     DeleteObject(pwc->clearPen);
262     DeleteObject(pwc->clearBrush);
263     pwc->clearPen = CreatePen(PS_SOLID, 1, pwc->clearColorRef); 
264     pwc->clearBrush = CreateSolidBrush(pwc->clearColorRef); 
265 }
266
267
268 /* 
269  * Clear the specified region of the color buffer using the clear color 
270  * or index as specified by one of the two functions above. 
271  * 
272  * This procedure clears either the front and/or the back COLOR buffers. 
273  * Only the "left" buffer is cleared since we are not stereo. 
274  * Clearing of the other non-color buffers is left to the swrast. 
275  */ 
276
277 static void clear(struct gl_context *ctx, GLbitfield mask)
278 {
279 #define FLIP(Y)  (ctx->DrawBuffer->Height - (Y) - 1)
280     const GLint x = ctx->DrawBuffer->_Xmin;
281     const GLint y = ctx->DrawBuffer->_Ymin;
282     const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
283     const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
284
285     WMesaContext pwc = wmesa_context(ctx);
286     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
287     int done = 0;
288
289     /* Let swrast do all the work if the masks are not set to
290      * clear all channels. */
291     if (!ctx->Color.ColorMask[0][0] ||
292         !ctx->Color.ColorMask[0][1] ||
293         !ctx->Color.ColorMask[0][2] ||
294         !ctx->Color.ColorMask[0][3]) {
295         _swrast_Clear(ctx, mask);
296         return;
297     }
298
299     /* Back buffer */
300     if (mask & BUFFER_BIT_BACK_LEFT) { 
301         
302         int     i, rowSize; 
303         UINT    bytesPerPixel = pwfb->cColorBits / 8; 
304         LPBYTE  lpb, clearRow;
305         LPWORD  lpw;
306         BYTE    bColor; 
307         WORD    wColor; 
308         BYTE    r, g, b; 
309         DWORD   dwColor; 
310         LPDWORD lpdw; 
311         
312         /* Try for a fast clear - clearing entire buffer with a single
313          * byte value. */
314         if (width == ctx->DrawBuffer->Width &&
315             height == ctx->DrawBuffer->Height) { /* entire buffer */
316             /* Now check for an easy clear value */
317             switch (bytesPerPixel) {
318             case 1:
319                 bColor = BGR8(GetRValue(pwc->clearColorRef), 
320                               GetGValue(pwc->clearColorRef), 
321                               GetBValue(pwc->clearColorRef));
322                 memset(pwfb->pbPixels, bColor, 
323                        pwfb->ScanWidth * height);
324                 done = 1;
325                 break;
326             case 2:
327                 wColor = BGR16(GetRValue(pwc->clearColorRef), 
328                                GetGValue(pwc->clearColorRef), 
329                                GetBValue(pwc->clearColorRef)); 
330                 if (((wColor >> 8) & 0xff) == (wColor & 0xff)) {
331                     memset(pwfb->pbPixels, wColor & 0xff, 
332                            pwfb->ScanWidth * height);
333                     done = 1;
334                 }
335                 break;
336             case 3:
337                 /* fall through */
338             case 4:
339                 if (GetRValue(pwc->clearColorRef) == 
340                     GetGValue(pwc->clearColorRef) &&
341                     GetRValue(pwc->clearColorRef) == 
342                     GetBValue(pwc->clearColorRef)) {
343                     memset(pwfb->pbPixels, 
344                            GetRValue(pwc->clearColorRef), 
345                            pwfb->ScanWidth * height);
346                     done = 1;
347                 }
348                 break;
349             default:
350                 break;
351             }
352         } /* all */
353
354         if (!done) {
355             /* Need to clear a row at a time.  Begin by setting the first
356              * row in the area to be cleared to the clear color. */
357             
358             clearRow = pwfb->pbPixels + 
359                 pwfb->ScanWidth * FLIP(y) +
360                 bytesPerPixel * x; 
361             switch (bytesPerPixel) {
362             case 1:
363                 lpb = clearRow;
364                 bColor = BGR8(GetRValue(pwc->clearColorRef), 
365                               GetGValue(pwc->clearColorRef), 
366                               GetBValue(pwc->clearColorRef));
367                 memset(lpb, bColor, width);
368                 break;
369             case 2:
370                 lpw = (LPWORD)clearRow;
371                 wColor = BGR16(GetRValue(pwc->clearColorRef), 
372                                GetGValue(pwc->clearColorRef), 
373                                GetBValue(pwc->clearColorRef)); 
374                 for (i=0; i<width; i++)
375                     *lpw++ = wColor;
376                 break;
377             case 3: 
378                 lpb = clearRow;
379                 r = GetRValue(pwc->clearColorRef); 
380                 g = GetGValue(pwc->clearColorRef); 
381                 b = GetBValue(pwc->clearColorRef); 
382                 for (i=0; i<width; i++) {
383                     *lpb++ = b; 
384                     *lpb++ = g; 
385                     *lpb++ = r; 
386                 } 
387                 break;
388             case 4: 
389                 lpdw = (LPDWORD)clearRow; 
390                 dwColor = BGR32(GetRValue(pwc->clearColorRef), 
391                                 GetGValue(pwc->clearColorRef), 
392                                 GetBValue(pwc->clearColorRef)); 
393                 for (i=0; i<width; i++)
394                     *lpdw++ = dwColor;
395                 break;
396             default:
397                 break;
398             } /* switch */
399             
400             /* copy cleared row to other rows in buffer */
401             lpb = clearRow - pwfb->ScanWidth;
402             rowSize = width * bytesPerPixel;
403             for (i=1; i<height; i++) { 
404                 memcpy(lpb, clearRow, rowSize); 
405                 lpb -= pwfb->ScanWidth; 
406             } 
407         } /* not done */
408         mask &= ~BUFFER_BIT_BACK_LEFT;
409     } /* back buffer */ 
410
411     /* front buffer */
412     if (mask & BUFFER_BIT_FRONT_LEFT) { 
413         HDC DC = pwc->hDC; 
414         HPEN Old_Pen = SelectObject(DC, pwc->clearPen); 
415         HBRUSH Old_Brush = SelectObject(DC, pwc->clearBrush);
416         Rectangle(DC,
417                   x,
418                   FLIP(y) + 1,
419                   x + width + 1,
420                   FLIP(y) - height + 1);
421         SelectObject(DC, Old_Pen); 
422         SelectObject(DC, Old_Brush); 
423         mask &= ~BUFFER_BIT_FRONT_LEFT;
424     } /* front buffer */ 
425     
426     /* Call swrast if there is anything left to clear (like DEPTH) */ 
427     if (mask) 
428         _swrast_Clear(ctx, mask);
429   
430 #undef FLIP
431
432
433
434 /**********************************************************************/
435 /*****                   PIXEL Functions                          *****/
436 /**********************************************************************/
437
438 #define FLIP(Y)  (rb->Height - (Y) - 1)
439
440
441 /**
442  ** Front Buffer reading/writing
443  ** These are slow, but work with all non-indexed visual types.
444  **/
445
446 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
447 static void write_rgba_span_front(struct gl_context *ctx, 
448                                   struct gl_renderbuffer *rb, 
449                                   GLuint n, GLint x, GLint y,
450                                   const void *values, 
451                                   const GLubyte *mask)
452 {
453    const GLubyte (*rgba)[4] = (const GLubyte (*)[4])values;
454    WMesaContext pwc = wmesa_context(ctx);
455    WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(pwc->hDC);
456    HBITMAP bmp=0;
457    HDC mdc=0;
458    typedef union
459    {
460       unsigned i;
461       struct {
462          unsigned b:8, g:8, r:8, a:8;
463       };
464    } BGRA;
465    BGRA *bgra, c;
466    GLuint i;
467
468    if (n < 16) {   // the value 16 is just guessed
469       y=FLIP(y);
470       if (mask) {
471          for (i=0; i<n; i++)
472             if (mask[i])
473                SetPixel(pwc->hDC, x+i, y,
474                         RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
475       }
476       else {
477          for (i=0; i<n; i++)
478             SetPixel(pwc->hDC, x+i, y,
479                      RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
480       }
481    }
482    else {
483       if (!pwfb) {
484          _mesa_problem(NULL, "wmesa: write_rgba_span_front on unknown hdc");
485          return;
486       }
487       bgra=malloc(n*sizeof(BGRA));
488       if (!bgra) {
489          _mesa_problem(NULL, "wmesa: write_rgba_span_front: out of memory");
490          return;
491       }
492       c.a=0;
493       if (mask) {
494          for (i=0; i<n; i++) {
495             if (mask[i]) {
496                c.r=rgba[i][RCOMP];
497                c.g=rgba[i][GCOMP];
498                c.b=rgba[i][BCOMP];
499                c.a=rgba[i][ACOMP];
500                bgra[i]=c;
501             }
502             else
503                bgra[i].i=0;
504          }
505       }
506       else {
507          for (i=0; i<n; i++) {
508             c.r=rgba[i][RCOMP];
509             c.g=rgba[i][GCOMP];
510             c.b=rgba[i][BCOMP];
511             c.a=rgba[i][ACOMP];
512             bgra[i]=c;
513          }
514       }
515       bmp=CreateBitmap(n, 1,  1, 32, bgra);
516       mdc=CreateCompatibleDC(pwfb->hDC);
517       SelectObject(mdc, bmp);
518       y=FLIP(y);
519       BitBlt(pwfb->hDC, x, y, n, 1, mdc, 0, 0, SRCCOPY);
520       SelectObject(mdc, 0);
521       DeleteObject(bmp);
522       DeleteDC(mdc);
523       free(bgra);
524    }
525 }
526
527 /* Write a horizontal span of RGB color pixels with a boolean mask. */
528 static void write_rgb_span_front(struct gl_context *ctx, 
529                                  struct gl_renderbuffer *rb, 
530                                  GLuint n, GLint x, GLint y,
531                                  const void *values, 
532                                  const GLubyte *mask)
533 {
534     const GLubyte (*rgb)[3] = (const GLubyte (*)[3])values;
535     WMesaContext pwc = wmesa_context(ctx);
536     GLuint i;
537     
538     (void) ctx;
539     y=FLIP(y);
540     if (mask) {
541         for (i=0; i<n; i++)
542             if (mask[i])
543                 SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], 
544                                                rgb[i][BCOMP]));
545     }
546     else {
547         for (i=0; i<n; i++)
548             SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], 
549                                            rgb[i][BCOMP]));
550     }
551     
552 }
553
554 /*
555  * Write a horizontal span of pixels with a boolean mask.  The current color
556  * is used for all pixels.
557  */
558 static void write_mono_rgba_span_front(struct gl_context *ctx, 
559                                        struct gl_renderbuffer *rb,
560                                        GLuint n, GLint x, GLint y,
561                                        const void *value, 
562                                        const GLubyte *mask)
563 {
564     const GLchan *color = (const GLchan *)value;
565     GLuint i;
566     WMesaContext pwc = wmesa_context(ctx);
567     COLORREF colorref;
568
569     (void) ctx;
570     colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]);
571     y=FLIP(y);
572     if (mask) {
573         for (i=0; i<n; i++)
574             if (mask[i])
575                 SetPixel(pwc->hDC, x+i, y, colorref);
576     }
577     else
578         for (i=0; i<n; i++)
579             SetPixel(pwc->hDC, x+i, y, colorref);
580
581 }
582
583 /* Write an array of RGBA pixels with a boolean mask. */
584 static void write_rgba_pixels_front(struct gl_context *ctx, 
585                                     struct gl_renderbuffer *rb,
586                                     GLuint n, 
587                                     const GLint x[], const GLint y[],
588                                     const void *values, 
589                                     const GLubyte *mask)
590 {
591     const GLubyte (*rgba)[4] = (const GLubyte (*)[4])values;
592     GLuint i;
593     WMesaContext pwc = wmesa_context(ctx);
594     (void) ctx;
595     for (i=0; i<n; i++)
596         if (mask[i])
597             SetPixel(pwc->hDC, x[i], FLIP(y[i]), 
598                      RGB(rgba[i][RCOMP], rgba[i][GCOMP], 
599                          rgba[i][BCOMP]));
600 }
601
602
603
604 /*
605  * Write an array of pixels with a boolean mask.  The current color
606  * is used for all pixels.
607  */
608 static void write_mono_rgba_pixels_front(struct gl_context *ctx, 
609                                          struct gl_renderbuffer *rb,
610                                          GLuint n,
611                                          const GLint x[], const GLint y[],
612                                          const void *value,
613                                          const GLubyte *mask)
614 {
615     const GLchan *color = (const GLchan *)value;
616     GLuint i;
617     WMesaContext pwc = wmesa_context(ctx);
618     COLORREF colorref;
619     (void) ctx;
620     colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]);
621     for (i=0; i<n; i++)
622         if (mask[i])
623             SetPixel(pwc->hDC, x[i], FLIP(y[i]), colorref);
624 }
625
626 /* Read a horizontal span of color pixels. */
627 static void read_rgba_span_front(struct gl_context *ctx, 
628                                  struct gl_renderbuffer *rb,
629                                  GLuint n, GLint x, GLint y,
630                                  void *values)
631 {
632     GLubyte (*rgba)[4] = (GLubyte (*)[4])values;
633     WMesaContext pwc = wmesa_context(ctx);
634     GLuint i;
635     COLORREF Color;
636     y = FLIP(y);
637     for (i=0; i<n; i++) {
638         Color = GetPixel(pwc->hDC, x+i, y);
639         rgba[i][RCOMP] = GetRValue(Color);
640         rgba[i][GCOMP] = GetGValue(Color);
641         rgba[i][BCOMP] = GetBValue(Color);
642         rgba[i][ACOMP] = 255;
643     }
644 }
645
646
647 /* Read an array of color pixels. */
648 static void read_rgba_pixels_front(struct gl_context *ctx, 
649                                    struct gl_renderbuffer *rb,
650                                    GLuint n, const GLint x[], const GLint y[],
651                                    void *values)
652 {
653     GLubyte (*rgba)[4] = (GLubyte (*)[4])values;
654     WMesaContext pwc = wmesa_context(ctx);
655     GLuint i;
656     COLORREF Color;
657     for (i=0; i<n; i++) {
658         GLint y2 = FLIP(y[i]);
659         Color = GetPixel(pwc->hDC, x[i], y2);
660         rgba[i][RCOMP] = GetRValue(Color);
661         rgba[i][GCOMP] = GetGValue(Color);
662         rgba[i][BCOMP] = GetBValue(Color);
663         rgba[i][ACOMP] = 255;
664     }
665 }
666
667 /*********************************************************************/
668
669 /* DOUBLE BUFFER 32-bit */
670
671 #define WMSETPIXEL32(pwc, y, x, r, g, b) { \
672 LPDWORD lpdw = ((LPDWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
673 *lpdw = BGR32((r),(g),(b)); }
674
675
676
677 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
678 static void write_rgba_span_32(struct gl_context *ctx, 
679                                struct gl_renderbuffer *rb, 
680                                GLuint n, GLint x, GLint y,
681                                const void *values, 
682                                const GLubyte *mask)
683 {
684     const GLubyte (*rgba)[4] = (const GLubyte (*)[4])values;
685     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
686     GLuint i;
687     LPDWORD lpdw;
688
689     (void) ctx;
690     
691     y=FLIP(y);
692     lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
693     if (mask) {
694         for (i=0; i<n; i++)
695             if (mask[i])
696                 lpdw[i] = BGR32(rgba[i][RCOMP], rgba[i][GCOMP], 
697                                 rgba[i][BCOMP]);
698     }
699     else {
700         for (i=0; i<n; i++)
701                 *lpdw++ = BGR32(rgba[i][RCOMP], rgba[i][GCOMP], 
702                                 rgba[i][BCOMP]);
703     }
704 }
705
706
707 /* Write a horizontal span of RGB color pixels with a boolean mask. */
708 static void write_rgb_span_32(struct gl_context *ctx, 
709                               struct gl_renderbuffer *rb, 
710                               GLuint n, GLint x, GLint y,
711                               const void *values, 
712                               const GLubyte *mask)
713 {
714     const GLubyte (*rgb)[3] = (const GLubyte (*)[3])values;
715     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
716     GLuint i;
717     LPDWORD lpdw;
718
719     (void) ctx;
720     
721     y=FLIP(y);
722     lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
723     if (mask) {
724         for (i=0; i<n; i++)
725             if (mask[i])
726                 lpdw[i] = BGR32(rgb[i][RCOMP], rgb[i][GCOMP], 
727                                 rgb[i][BCOMP]);
728     }
729     else {
730         for (i=0; i<n; i++)
731                 *lpdw++ = BGR32(rgb[i][RCOMP], rgb[i][GCOMP], 
732                                 rgb[i][BCOMP]);
733     }
734 }
735
736 /*
737  * Write a horizontal span of pixels with a boolean mask.  The current color
738  * is used for all pixels.
739  */
740 static void write_mono_rgba_span_32(struct gl_context *ctx, 
741                                     struct gl_renderbuffer *rb,
742                                     GLuint n, GLint x, GLint y,
743                                     const void *value, 
744                                     const GLubyte *mask)
745 {
746     const GLchan *color = (const GLchan *)value;
747     LPDWORD lpdw;
748     DWORD pixel;
749     GLuint i;
750     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
751     lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
752     y=FLIP(y);
753     pixel = BGR32(color[RCOMP], color[GCOMP], color[BCOMP]);
754     if (mask) {
755         for (i=0; i<n; i++)
756             if (mask[i])
757                 lpdw[i] = pixel;
758     }
759     else
760         for (i=0; i<n; i++)
761                 *lpdw++ = pixel;
762
763 }
764
765 /* Write an array of RGBA pixels with a boolean mask. */
766 static void write_rgba_pixels_32(struct gl_context *ctx, 
767                                  struct gl_renderbuffer *rb,
768                                  GLuint n, const GLint x[], const GLint y[],
769                                  const void *values, 
770                                  const GLubyte *mask)
771 {
772     const GLubyte (*rgba)[4] = (const GLubyte (*)[4])values;
773     GLuint i;
774     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
775     for (i=0; i<n; i++)
776         if (mask[i])
777             WMSETPIXEL32(pwfb, FLIP(y[i]), x[i],
778                          rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
779 }
780
781 /*
782  * Write an array of pixels with a boolean mask.  The current color
783  * is used for all pixels.
784  */
785 static void write_mono_rgba_pixels_32(struct gl_context *ctx, 
786                                       struct gl_renderbuffer *rb,
787                                       GLuint n,
788                                       const GLint x[], const GLint y[],
789                                       const void *value,
790                                       const GLubyte *mask)
791 {
792     const GLchan *color = (const GLchan *)value;
793     GLuint i;
794     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
795     for (i=0; i<n; i++)
796         if (mask[i])
797             WMSETPIXEL32(pwfb, FLIP(y[i]),x[i],color[RCOMP],
798                          color[GCOMP], color[BCOMP]);
799 }
800
801 /* Read a horizontal span of color pixels. */
802 static void read_rgba_span_32(struct gl_context *ctx, 
803                               struct gl_renderbuffer *rb,
804                               GLuint n, GLint x, GLint y,
805                               void *values)
806 {
807     GLubyte (*rgba)[4] = (GLubyte (*)[4])values;
808     GLuint i;
809     DWORD pixel;
810     LPDWORD lpdw;
811     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
812     
813     y = FLIP(y);
814     lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
815     for (i=0; i<n; i++) {
816         pixel = lpdw[i];
817         rgba[i][RCOMP] = (GLubyte)((pixel & 0x00ff0000) >> 16);
818         rgba[i][GCOMP] = (GLubyte)((pixel & 0x0000ff00) >> 8);
819         rgba[i][BCOMP] = (GLubyte)(pixel & 0x000000ff);
820         rgba[i][ACOMP] = 255;
821     }
822 }
823
824
825 /* Read an array of color pixels. */
826 static void read_rgba_pixels_32(struct gl_context *ctx, 
827                                 struct gl_renderbuffer *rb,
828                                 GLuint n, const GLint x[], const GLint y[],
829                                 void *values)
830 {
831     GLubyte (*rgba)[4] = (GLubyte (*)[4])values;
832     GLuint i;
833     DWORD pixel;
834     LPDWORD lpdw;
835     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
836
837     for (i=0; i<n; i++) {
838         GLint y2 = FLIP(y[i]);
839         lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + x[i];
840         pixel = *lpdw;
841         rgba[i][RCOMP] = (GLubyte)((pixel & 0x00ff0000) >> 16);
842         rgba[i][GCOMP] = (GLubyte)((pixel & 0x0000ff00) >> 8);
843         rgba[i][BCOMP] = (GLubyte)(pixel & 0x000000ff);
844         rgba[i][ACOMP] = 255;
845   }
846 }
847
848
849 /*********************************************************************/
850
851 /* DOUBLE BUFFER 24-bit */
852
853 #define WMSETPIXEL24(pwc, y, x, r, g, b) { \
854 LPBYTE lpb = ((LPBYTE)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (3 * x)); \
855 lpb[0] = (b); \
856 lpb[1] = (g); \
857 lpb[2] = (r); }
858
859 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
860 static void write_rgba_span_24(struct gl_context *ctx, 
861                                struct gl_renderbuffer *rb, 
862                                GLuint n, GLint x, GLint y,
863                                const void *values, 
864                                const GLubyte *mask)
865 {
866     const GLubyte (*rgba)[4] = (const GLubyte (*)[4])values;
867     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
868     GLuint i;
869     LPBYTE lpb;
870
871     (void) ctx;
872     
873     y=FLIP(y);
874     lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
875     if (mask) {
876         for (i=0; i<n; i++)
877             if (mask[i]) {
878                 lpb[3*i] = rgba[i][BCOMP];
879                 lpb[3*i+1] = rgba[i][GCOMP];
880                 lpb[3*i+2] = rgba[i][RCOMP];
881             }
882     }
883     else {
884             for (i=0; i<n; i++) {
885             *lpb++ = rgba[i][BCOMP];
886             *lpb++ = rgba[i][GCOMP];
887             *lpb++ = rgba[i][RCOMP];
888             }
889     }
890 }
891
892
893 /* Write a horizontal span of RGB color pixels with a boolean mask. */
894 static void write_rgb_span_24(struct gl_context *ctx, 
895                               struct gl_renderbuffer *rb, 
896                               GLuint n, GLint x, GLint y,
897                               const void *values, 
898                               const GLubyte *mask)
899 {
900     const GLubyte (*rgb)[3] = (const GLubyte (*)[3])values;
901     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
902     GLuint i;
903     LPBYTE lpb;
904
905     (void) ctx;
906     
907     y=FLIP(y);
908     lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
909     if (mask) {
910         for (i=0; i<n; i++)
911             if (mask[i]) {
912             lpb[3*i] = rgb[i][BCOMP];
913             lpb[3*i+1] = rgb[i][GCOMP];
914             lpb[3*i+2] = rgb[i][RCOMP];
915             }
916     }
917     else {
918         for (i=0; i<n; i++) {
919                 *lpb++ = rgb[i][BCOMP];
920                 *lpb++ = rgb[i][GCOMP];
921                 *lpb++ = rgb[i][RCOMP];
922         }
923     }
924 }
925
926 /*
927  * Write a horizontal span of pixels with a boolean mask.  The current color
928  * is used for all pixels.
929  */
930 static void write_mono_rgba_span_24(struct gl_context *ctx, 
931                                     struct gl_renderbuffer *rb,
932                                     GLuint n, GLint x, GLint y,
933                                     const void *value, 
934                                     const GLubyte *mask)
935 {
936     const GLchan *color = (const GLchan *)value;
937     LPBYTE lpb;
938     GLuint i;
939     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
940     lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
941     y=FLIP(y);
942     if (mask) {
943         for (i=0; i<n; i++)
944             if (mask[i]) {
945                 lpb[3*i] = color[BCOMP];
946                 lpb[3*i+1] = color[GCOMP];
947                 lpb[3*i+2] = color[RCOMP];
948             }
949     }
950     else
951         for (i=0; i<n; i++) {
952                 *lpb++ = color[BCOMP];
953                 *lpb++ = color[GCOMP];
954                 *lpb++ = color[RCOMP];          
955         }
956 }
957
958 /* Write an array of RGBA pixels with a boolean mask. */
959 static void write_rgba_pixels_24(struct gl_context *ctx, 
960                                  struct gl_renderbuffer *rb,
961                                  GLuint n, const GLint x[], const GLint y[],
962                                  const void *values, 
963                                  const GLubyte *mask)
964 {
965     const GLubyte (*rgba)[4] = (const GLubyte (*)[4])values;
966     GLuint i;
967     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
968     for (i=0; i<n; i++)
969         if (mask[i])
970             WMSETPIXEL24(pwfb, FLIP(y[i]), x[i],
971                          rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
972 }
973
974 /*
975  * Write an array of pixels with a boolean mask.  The current color
976  * is used for all pixels.
977  */
978 static void write_mono_rgba_pixels_24(struct gl_context *ctx, 
979                                       struct gl_renderbuffer *rb,
980                                       GLuint n,
981                                       const GLint x[], const GLint y[],
982                                       const void *value,
983                                       const GLubyte *mask)
984 {
985     const GLchan *color = (const GLchan *)value;
986     GLuint i;
987     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
988     for (i=0; i<n; i++)
989         if (mask[i])
990             WMSETPIXEL24(pwfb, FLIP(y[i]),x[i],color[RCOMP],
991                          color[GCOMP], color[BCOMP]);
992 }
993
994 /* Read a horizontal span of color pixels. */
995 static void read_rgba_span_24(struct gl_context *ctx, 
996                               struct gl_renderbuffer *rb,
997                               GLuint n, GLint x, GLint y,
998                               void *values)
999 {
1000     GLubyte (*rgba)[4] = (GLubyte (*)[4])values;
1001     GLuint i;
1002     LPBYTE lpb;
1003     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
1004     
1005     y = FLIP(y);
1006     lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x);
1007     for (i=0; i<n; i++) {
1008         rgba[i][RCOMP] = lpb[3*i+2];
1009         rgba[i][GCOMP] = lpb[3*i+1];
1010         rgba[i][BCOMP] = lpb[3*i];
1011         rgba[i][ACOMP] = 255;
1012     }
1013 }
1014
1015
1016 /* Read an array of color pixels. */
1017 static void read_rgba_pixels_24(struct gl_context *ctx, 
1018                                 struct gl_renderbuffer *rb,
1019                                 GLuint n, const GLint x[], const GLint y[],
1020                                 void *values)
1021 {
1022     GLubyte (*rgba)[4] = (GLubyte (*)[4])values;
1023     GLuint i;
1024     LPBYTE lpb;
1025     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
1026
1027     for (i=0; i<n; i++) {
1028         GLint y2 = FLIP(y[i]);
1029         lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + (3 * x[i]);
1030         rgba[i][RCOMP] = lpb[3*i+2];
1031         rgba[i][GCOMP] = lpb[3*i+1];
1032         rgba[i][BCOMP] = lpb[3*i];
1033         rgba[i][ACOMP] = 255;
1034   }
1035 }
1036
1037
1038 /*********************************************************************/
1039
1040 /* DOUBLE BUFFER 16-bit */
1041
1042 #define WMSETPIXEL16(pwc, y, x, r, g, b) { \
1043 LPWORD lpw = ((LPWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
1044 *lpw = BGR16((r),(g),(b)); }
1045
1046
1047
1048 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
1049 static void write_rgba_span_16(struct gl_context *ctx, 
1050                                struct gl_renderbuffer *rb, 
1051                                GLuint n, GLint x, GLint y,
1052                                const void *values, 
1053                                const GLubyte *mask)
1054 {
1055     const GLubyte (*rgba)[4] = (const GLubyte (*)[4])values;
1056     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
1057     GLuint i;
1058     LPWORD lpw;
1059
1060     (void) ctx;
1061     
1062     y=FLIP(y);
1063     lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
1064     if (mask) {
1065         for (i=0; i<n; i++)
1066             if (mask[i])
1067                 lpw[i] = BGR16(rgba[i][RCOMP], rgba[i][GCOMP], 
1068                                rgba[i][BCOMP]);
1069     }
1070     else {
1071         for (i=0; i<n; i++)
1072                 *lpw++ = BGR16(rgba[i][RCOMP], rgba[i][GCOMP], 
1073                                rgba[i][BCOMP]);
1074     }
1075 }
1076
1077
1078 /* Write a horizontal span of RGB color pixels with a boolean mask. */
1079 static void write_rgb_span_16(struct gl_context *ctx, 
1080                               struct gl_renderbuffer *rb, 
1081                               GLuint n, GLint x, GLint y,
1082                               const void *values, 
1083                               const GLubyte *mask)
1084 {
1085     const GLubyte (*rgb)[3] = (const GLubyte (*)[3])values;
1086     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
1087     GLuint i;
1088     LPWORD lpw;
1089
1090     (void) ctx;
1091     
1092     y=FLIP(y);
1093     lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
1094     if (mask) {
1095         for (i=0; i<n; i++)
1096             if (mask[i])
1097                 lpw[i] = BGR16(rgb[i][RCOMP], rgb[i][GCOMP], 
1098                                rgb[i][BCOMP]);
1099     }
1100     else {
1101         for (i=0; i<n; i++)
1102                 *lpw++ = BGR16(rgb[i][RCOMP], rgb[i][GCOMP], 
1103                                rgb[i][BCOMP]);
1104     }
1105 }
1106
1107 /*
1108  * Write a horizontal span of pixels with a boolean mask.  The current color
1109  * is used for all pixels.
1110  */
1111 static void write_mono_rgba_span_16(struct gl_context *ctx, 
1112                                     struct gl_renderbuffer *rb,
1113                                     GLuint n, GLint x, GLint y,
1114                                     const void *value, 
1115                                     const GLubyte *mask)
1116 {
1117     const GLchan *color = (const GLchan *)value;
1118     LPWORD lpw;
1119     WORD pixel;
1120     GLuint i;
1121     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
1122     (void) ctx;
1123     lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
1124     y=FLIP(y);
1125     pixel = BGR16(color[RCOMP], color[GCOMP], color[BCOMP]);
1126     if (mask) {
1127         for (i=0; i<n; i++)
1128             if (mask[i])
1129                 lpw[i] = pixel;
1130     }
1131     else
1132         for (i=0; i<n; i++)
1133                 *lpw++ = pixel;
1134
1135 }
1136
1137 /* Write an array of RGBA pixels with a boolean mask. */
1138 static void write_rgba_pixels_16(struct gl_context *ctx, 
1139                                  struct gl_renderbuffer *rb,
1140                                  GLuint n, const GLint x[], const GLint y[],
1141                                  const void *values, 
1142                                  const GLubyte *mask)
1143 {
1144     const GLubyte (*rgba)[4] = (const GLubyte (*)[4])values;
1145     GLuint i;
1146     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
1147     (void) ctx;
1148     for (i=0; i<n; i++)
1149         if (mask[i])
1150             WMSETPIXEL16(pwfb, FLIP(y[i]), x[i],
1151                          rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1152 }
1153
1154 /*
1155  * Write an array of pixels with a boolean mask.  The current color
1156  * is used for all pixels.
1157  */
1158 static void write_mono_rgba_pixels_16(struct gl_context *ctx, 
1159                                       struct gl_renderbuffer *rb,
1160                                       GLuint n,
1161                                       const GLint x[], const GLint y[],
1162                                       const void *value,
1163                                       const GLubyte *mask)
1164 {
1165     const GLchan *color = (const GLchan *)value;
1166     GLuint i;
1167     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
1168     (void) ctx;
1169     for (i=0; i<n; i++)
1170         if (mask[i])
1171             WMSETPIXEL16(pwfb, FLIP(y[i]),x[i],color[RCOMP],
1172                          color[GCOMP], color[BCOMP]);
1173 }
1174
1175 /* Read a horizontal span of color pixels. */
1176 static void read_rgba_span_16(struct gl_context *ctx, 
1177                               struct gl_renderbuffer *rb,
1178                               GLuint n, GLint x, GLint y,
1179                               void *values)
1180 {
1181     GLubyte (*rgba)[4] = (GLubyte (*)[4])values;
1182     GLuint i, pixel;
1183     LPWORD lpw;
1184     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
1185     
1186     y = FLIP(y);
1187     lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
1188     for (i=0; i<n; i++) {
1189         pixel = lpw[i];
1190         /* Windows uses 5,5,5 for 16-bit */
1191         rgba[i][RCOMP] = (pixel & 0x7c00) >> 7;
1192         rgba[i][GCOMP] = (pixel & 0x03e0) >> 2;
1193         rgba[i][BCOMP] = (pixel & 0x001f) << 3;
1194         rgba[i][ACOMP] = 255;
1195     }
1196 }
1197
1198
1199 /* Read an array of color pixels. */
1200 static void read_rgba_pixels_16(struct gl_context *ctx, 
1201                                 struct gl_renderbuffer *rb,
1202                                 GLuint n, const GLint x[], const GLint y[],
1203                                 void *values)
1204 {
1205     GLubyte (*rgba)[4] = (GLubyte (*)[4])values;
1206     GLuint i, pixel;
1207     LPWORD lpw;
1208     WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
1209
1210     for (i=0; i<n; i++) {
1211         GLint y2 = FLIP(y[i]);
1212         lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + x[i];
1213         pixel = *lpw;
1214         /* Windows uses 5,5,5 for 16-bit */
1215         rgba[i][RCOMP] = (pixel & 0x7c00) >> 7;
1216         rgba[i][GCOMP] = (pixel & 0x03e0) >> 2;
1217         rgba[i][BCOMP] = (pixel & 0x001f) << 3;
1218         rgba[i][ACOMP] = 255;
1219   }
1220 }
1221
1222
1223
1224
1225 /**********************************************************************/
1226 /*****                   BUFFER Functions                         *****/
1227 /**********************************************************************/
1228
1229
1230
1231
1232 static void
1233 wmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
1234 {
1235     free(rb);
1236 }
1237
1238
1239 /**
1240  * This is called by Mesa whenever it determines that the window size
1241  * has changed.  Do whatever's needed to cope with that.
1242  */
1243 static GLboolean
1244 wmesa_renderbuffer_storage(struct gl_context *ctx, 
1245                            struct gl_renderbuffer *rb,
1246                            GLenum internalFormat, 
1247                            GLuint width, 
1248                            GLuint height)
1249 {
1250     rb->Width = width;
1251     rb->Height = height;
1252     return GL_TRUE;
1253 }
1254
1255
1256 /**
1257  * Plug in the Get/PutRow/Values functions for a renderbuffer depending
1258  * on if we're drawing to the front or back color buffer.
1259  */
1260 static void
1261 wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat,
1262                              int cColorBits, int double_buffer)
1263 {
1264     if (double_buffer) {
1265         /* back buffer */
1266         /* Picking the correct span functions is important because
1267          * the DIB was allocated with the indicated depth. */
1268         switch(pixelformat) {
1269         case PF_5R6G5B:
1270             rb->PutRow = write_rgba_span_16;
1271             rb->PutRowRGB = write_rgb_span_16;
1272             rb->PutMonoRow = write_mono_rgba_span_16;
1273             rb->PutValues = write_rgba_pixels_16;
1274             rb->PutMonoValues = write_mono_rgba_pixels_16;
1275             rb->GetRow = read_rgba_span_16;
1276             rb->GetValues = read_rgba_pixels_16;
1277             break;
1278         case PF_8R8G8B:
1279                 if (cColorBits == 24)
1280                 {
1281                     rb->PutRow = write_rgba_span_24;
1282                     rb->PutRowRGB = write_rgb_span_24;
1283                     rb->PutMonoRow = write_mono_rgba_span_24;
1284                     rb->PutValues = write_rgba_pixels_24;
1285                     rb->PutMonoValues = write_mono_rgba_pixels_24;
1286                     rb->GetRow = read_rgba_span_24;
1287                     rb->GetValues = read_rgba_pixels_24;
1288                 }
1289                 else
1290                 {
1291                 rb->PutRow = write_rgba_span_32;
1292                 rb->PutRowRGB = write_rgb_span_32;
1293                 rb->PutMonoRow = write_mono_rgba_span_32;
1294                 rb->PutValues = write_rgba_pixels_32;
1295                 rb->PutMonoValues = write_mono_rgba_pixels_32;
1296                 rb->GetRow = read_rgba_span_32;
1297                 rb->GetValues = read_rgba_pixels_32;
1298                 }
1299             break;
1300         default:
1301             break;
1302         }
1303     }
1304     else {
1305         /* front buffer (actual Windows window) */
1306         rb->PutRow = write_rgba_span_front;
1307         rb->PutRowRGB = write_rgb_span_front;
1308         rb->PutMonoRow = write_mono_rgba_span_front;
1309         rb->PutValues = write_rgba_pixels_front;
1310         rb->PutMonoValues = write_mono_rgba_pixels_front;
1311         rb->GetRow = read_rgba_span_front;
1312         rb->GetValues = read_rgba_pixels_front;
1313     }
1314 }
1315
1316 /**
1317  * Called by ctx->Driver.ResizeBuffers()
1318  * Resize the front/back colorbuffers to match the latest window size.
1319  */
1320 static void
1321 wmesa_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *buffer,
1322                      GLuint width, GLuint height)
1323 {
1324     WMesaFramebuffer pwfb = wmesa_framebuffer(buffer);
1325
1326     if (pwfb->Base.Width != width || pwfb->Base.Height != height) {
1327         /* Realloc back buffer */
1328         if (ctx->Visual.doubleBufferMode == 1) {
1329             wmDeleteBackingStore(pwfb);
1330             wmCreateBackingStore(pwfb, width, height);
1331         }
1332     }
1333     _mesa_resize_framebuffer(ctx, buffer, width, height);
1334 }
1335
1336
1337 /**
1338  * Called by glViewport.
1339  * This is a good time for us to poll the current window size and adjust
1340  * our renderbuffers to match the current window size.
1341  * Remember, we have no opportunity to respond to conventional
1342  * resize events since the driver has no event loop.
1343  * Thus, we poll.
1344  * MakeCurrent also ends up making a call here, so that ensures
1345  * we get the viewport set correctly, even if the app does not call
1346  * glViewport and relies on the defaults.
1347  */
1348 static void wmesa_viewport(struct gl_context *ctx, 
1349                            GLint x, GLint y, 
1350                            GLsizei width, GLsizei height)
1351 {
1352     GLuint new_width, new_height;
1353
1354     wmesa_get_buffer_size(ctx->WinSysDrawBuffer, &new_width, &new_height);
1355
1356     /**
1357      * Resize buffers if the window size changed.
1358      */
1359     wmesa_resize_buffers(ctx, ctx->WinSysDrawBuffer, new_width, new_height);
1360     ctx->NewState |= _NEW_BUFFERS;  /* to update scissor / window bounds */
1361 }
1362
1363
1364
1365
1366 /**
1367  * Called when the driver should update it's state, based on the new_state
1368  * flags.
1369  */
1370 static void wmesa_update_state(struct gl_context *ctx, GLuint new_state)
1371 {
1372     _swrast_InvalidateState(ctx, new_state);
1373     _swsetup_InvalidateState(ctx, new_state);
1374     _vbo_InvalidateState(ctx, new_state);
1375     _tnl_InvalidateState(ctx, new_state);
1376
1377     /* TODO - This code is not complete yet because I 
1378      * don't know what to do for all state updates.
1379      */
1380
1381     if (new_state & _NEW_BUFFERS) {
1382     }
1383 }
1384
1385
1386
1387
1388
1389 /**********************************************************************/
1390 /*****                   WMESA Functions                          *****/
1391 /**********************************************************************/
1392
1393 WMesaContext WMesaCreateContext(HDC hDC, 
1394                                 HPALETTE* Pal,
1395                                 GLboolean rgb_flag,
1396                                 GLboolean db_flag,
1397                                 GLboolean alpha_flag)
1398 {
1399     WMesaContext c;
1400     struct dd_function_table functions;
1401     GLint red_bits, green_bits, blue_bits, alpha_bits;
1402     struct gl_context *ctx;
1403     struct gl_config *visual;
1404
1405     (void) Pal;
1406     
1407     /* Indexed mode not supported */
1408     if (!rgb_flag)
1409         return NULL;
1410
1411     /* Allocate wmesa context */
1412     c = CALLOC_STRUCT(wmesa_context);
1413     if (!c)
1414         return NULL;
1415
1416 #if 0
1417     /* I do not understand this contributed code */
1418     /* Support memory and device contexts */
1419     if(WindowFromDC(hDC) != NULL) {
1420         c->hDC = GetDC(WindowFromDC(hDC)); /* huh ???? */
1421     }
1422     else {
1423         c->hDC = hDC;
1424     }
1425 #else
1426     c->hDC = hDC;
1427 #endif
1428
1429     /* Get data for visual */
1430     /* Dealing with this is actually a bit of overkill because Mesa will end
1431      * up treating all color component size requests less than 8 by using 
1432      * a single byte per channel.  In addition, the interface to the span
1433      * routines passes colors as an entire byte per channel anyway, so there
1434      * is nothing to be saved by telling the visual to be 16 bits if the device
1435      * is 16 bits.  That is, Mesa is going to compute colors down to 8 bits per
1436      * channel anyway.
1437      * But we go through the motions here anyway.
1438      */
1439     switch (GetDeviceCaps(c->hDC, BITSPIXEL)) {
1440     case 16:
1441         red_bits = green_bits = blue_bits = 5;
1442         alpha_bits = 0;
1443         break;
1444     default:
1445         red_bits = green_bits = blue_bits = 8;
1446         alpha_bits = 8;
1447         break;
1448     }
1449     /* Create visual based on flags */
1450     visual = _mesa_create_visual(db_flag,    /* db_flag */
1451                                  GL_FALSE,   /* stereo */
1452                                  red_bits, green_bits, blue_bits, /* color RGB */
1453                                  alpha_flag ? alpha_bits : 0, /* color A */
1454                                  DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */
1455                                  8,          /* stencil_bits */
1456                                  16,16,16,   /* accum RGB */
1457                                  alpha_flag ? 16 : 0, /* accum A */
1458                                  1);         /* num samples */
1459     
1460     if (!visual) {
1461         free(c);
1462         return NULL;
1463     }
1464
1465     /* Set up driver functions */
1466     _mesa_init_driver_functions(&functions);
1467     functions.GetString = wmesa_get_string;
1468     functions.UpdateState = wmesa_update_state;
1469     functions.GetBufferSize = wmesa_get_buffer_size;
1470     functions.Flush = wmesa_flush;
1471     functions.Clear = clear;
1472     functions.ClearColor = clear_color;
1473     functions.ResizeBuffers = wmesa_resize_buffers;
1474     functions.Viewport = wmesa_viewport;
1475
1476     /* initialize the Mesa context data */
1477     ctx = &c->gl_ctx;
1478     _mesa_initialize_context(ctx, API_OPENGL, visual,
1479                              NULL, &functions, (void *)c);
1480
1481     /* visual no longer needed - it was copied by _mesa_initialize_context() */
1482     _mesa_destroy_visual(visual);
1483
1484     _mesa_enable_sw_extensions(ctx);
1485     _mesa_enable_1_3_extensions(ctx);
1486     _mesa_enable_1_4_extensions(ctx);
1487     _mesa_enable_1_5_extensions(ctx);
1488     _mesa_enable_2_0_extensions(ctx);
1489     _mesa_enable_2_1_extensions(ctx);
1490   
1491     _mesa_meta_init(ctx);
1492
1493     /* Initialize the software rasterizer and helper modules. */
1494     if (!_swrast_CreateContext(ctx) ||
1495         !_vbo_CreateContext(ctx) ||
1496         !_tnl_CreateContext(ctx) ||
1497         !_swsetup_CreateContext(ctx)) {
1498         _mesa_free_context_data(ctx);
1499         free(c);
1500         return NULL;
1501     }
1502     _swsetup_Wakeup(ctx);
1503     TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
1504
1505     return c;
1506 }
1507
1508
1509 void WMesaDestroyContext( WMesaContext pwc )
1510 {
1511     struct gl_context *ctx = &pwc->gl_ctx;
1512     WMesaFramebuffer pwfb;
1513     GET_CURRENT_CONTEXT(cur_ctx);
1514
1515     if (cur_ctx == ctx) {
1516         /* unbind current if deleting current context */
1517         WMesaMakeCurrent(NULL, NULL);
1518     }
1519
1520     /* clean up frame buffer resources */
1521     pwfb = wmesa_lookup_framebuffer(pwc->hDC);
1522     if (pwfb) {
1523         if (ctx->Visual.doubleBufferMode == 1)
1524             wmDeleteBackingStore(pwfb);
1525         wmesa_free_framebuffer(pwc->hDC);
1526     }
1527
1528     /* Release for device, not memory contexts */
1529     if (WindowFromDC(pwc->hDC) != NULL)
1530     {
1531       ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC);
1532     }
1533     DeleteObject(pwc->clearPen); 
1534     DeleteObject(pwc->clearBrush); 
1535     
1536     _mesa_meta_free(ctx);
1537
1538     _swsetup_DestroyContext(ctx);
1539     _tnl_DestroyContext(ctx);
1540     _vbo_DestroyContext(ctx);
1541     _swrast_DestroyContext(ctx);
1542     
1543     _mesa_free_context_data(ctx);
1544     free(pwc);
1545 }
1546
1547
1548 /**
1549  * Create a new color renderbuffer.
1550  */
1551 static struct gl_renderbuffer *
1552 wmesa_new_renderbuffer(void)
1553 {
1554     struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
1555     if (!rb)
1556         return NULL;
1557
1558     _mesa_init_renderbuffer(rb, (GLuint)0);
1559     
1560     rb->_BaseFormat = GL_RGBA;
1561     rb->InternalFormat = GL_RGBA;
1562     rb->DataType = CHAN_TYPE;
1563     rb->Delete = wmesa_delete_renderbuffer;
1564     rb->AllocStorage = wmesa_renderbuffer_storage;
1565     return rb;
1566 }
1567
1568
1569 void WMesaMakeCurrent(WMesaContext c, HDC hdc)
1570 {
1571     WMesaFramebuffer pwfb;
1572
1573     {
1574         /* return if already current */
1575         GET_CURRENT_CONTEXT(ctx);
1576         WMesaContext pwc = wmesa_context(ctx);
1577         if (pwc && c == pwc && pwc->hDC == hdc)
1578             return;
1579     }
1580
1581     pwfb = wmesa_lookup_framebuffer(hdc);
1582
1583     /* Lazy creation of framebuffers */
1584     if (c && !pwfb && hdc) {
1585         struct gl_renderbuffer *rb;
1586         struct gl_config *visual = &c->gl_ctx.Visual;
1587         GLuint width, height;
1588
1589         get_window_size(hdc, &width, &height);
1590
1591         c->clearPen = CreatePen(PS_SOLID, 1, 0); 
1592         c->clearBrush = CreateSolidBrush(0); 
1593
1594         pwfb = wmesa_new_framebuffer(hdc, visual);
1595
1596         /* Create back buffer if double buffered */
1597         if (visual->doubleBufferMode == 1) {
1598             wmCreateBackingStore(pwfb, width, height);
1599         }
1600         
1601         /* make render buffers */
1602         if (visual->doubleBufferMode == 1) {
1603             rb = wmesa_new_renderbuffer();
1604             _mesa_add_renderbuffer(&pwfb->Base, BUFFER_BACK_LEFT, rb);
1605             wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, pwfb->cColorBits, 1);
1606         }
1607         rb = wmesa_new_renderbuffer();
1608         _mesa_add_renderbuffer(&pwfb->Base, BUFFER_FRONT_LEFT, rb);
1609         wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, pwfb->cColorBits, 0);
1610
1611         /* Let Mesa own the Depth, Stencil, and Accum buffers */
1612         _mesa_add_soft_renderbuffers(&pwfb->Base,
1613                                      GL_FALSE, /* color */
1614                                      visual->depthBits > 0,
1615                                      visual->stencilBits > 0,
1616                                      visual->accumRedBits > 0,
1617                                      visual->alphaBits >0, 
1618                                      GL_FALSE);
1619     }
1620
1621     if (c && pwfb)
1622         _mesa_make_current(&c->gl_ctx, &pwfb->Base, &pwfb->Base);
1623     else
1624         _mesa_make_current(NULL, NULL, NULL);
1625 }
1626
1627
1628 void WMesaSwapBuffers( HDC hdc )
1629 {
1630     GET_CURRENT_CONTEXT(ctx);
1631     WMesaContext pwc = wmesa_context(ctx);
1632     WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc);
1633
1634     if (!pwfb) {
1635         _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc");
1636         return;
1637     }
1638
1639     /* If we're swapping the buffer associated with the current context
1640      * we have to flush any pending rendering commands first.
1641      */
1642     if (pwc->hDC == hdc) {
1643         _mesa_notifySwapBuffers(ctx);
1644
1645         BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height,
1646                pwfb->dib_hDC, 0, 0, SRCCOPY);
1647     }
1648     else {
1649         /* XXX for now only allow swapping current window */
1650         _mesa_problem(NULL, "wmesa: can't swap non-current window");
1651     }
1652 }
1653
1654 void WMesaShareLists(WMesaContext ctx_to_share, WMesaContext ctx)
1655 {
1656         _mesa_share_state(&ctx->gl_ctx, &ctx_to_share->gl_ctx); 
1657 }
1658