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