wmesa.c revision ffe52c64448a4a3cf10565d3b01591fa9f520c42
1
2/*
3 * Windows (Win32) device driver for Mesa 3.4
4 *
5 * Original author:
6 *
7 *  Copyright (C) 1996-  Li Wei
8 *  Address      :       Institute of Artificial Intelligence
9 *               :           & Robotics
10 *               :       Xi'an Jiaotong University
11 *  Email        :       liwei@aiar.xjtu.edu.cn
12 *  Web page :       http://sun.aiar.xjtu.edu.cn
13 *
14 *  This file and its associations are partially borrowed from the
15 *  Windows NT driver for Mesa 1.8 , written by Mark Leaming
16 *  (mark@rsinc.com).
17 *
18 * Updated for Mesa 4.0 by Karl Schultz (kschultz@sourceforge.net)
19 */
20
21#ifdef NDEBUG
22#pragma auto_inline(on)
23#pragma inline_depth(255)
24#pragma inline_recursion(on)
25#endif
26
27#include "wmesadef.h"
28#include <GL/wmesa.h>
29//#include "mesa_extend.h"
30
31#include "glheader.h"
32#include "colors.h"
33#include "context.h"
34#include "colormac.h"
35#include "dd.h"
36#include "depth.h"
37#include "extensions.h"
38#include "imports.h"
39#include "macros.h"
40#include "matrix.h"
41#include "mtypes.h"
42#include "texformat.h"
43#include "teximage.h"
44#include "texstore.h"
45#include "array_cache/acache.h"
46#include "swrast/swrast.h"
47#include "swrast_setup/swrast_setup.h"
48#include "swrast/s_alphabuf.h"
49#include "swrast/s_context.h"
50#include "swrast/s_depth.h"
51#include "swrast/s_lines.h"
52#include "swrast/s_triangle.h"
53#include "swrast/s_trispan.h"
54#include "tnl/tnl.h"
55#include "tnl/t_context.h"
56#include "tnl/t_pipeline.h"
57#include "drivers/common/driverfuncs.h"
58
59/* Dither not tested for Mesa 4.0 */
60#ifdef DITHER
61#ifdef USE_WING
62#include <wing.h>
63#endif // USE_WING
64#endif
65
66#ifdef __CYGWIN32__
67#include "macros.h"
68#include <string.h>
69#define CopyMemory memcpy
70#endif
71
72/* Stereo and parallel not tested for Mesa 4.0. */
73#define NO_STEREO
74#if !defined(NO_STEREO)
75#include "gl\glu.h"
76#include "stereo.h"
77#endif
78
79#define NO_PARALLEL
80#if !defined(NO_PARALLEL)
81#include "parallel.h"
82#endif
83
84
85/* File global varaibles */
86struct DISPLAY_OPTIONS {
87	int  stereo;
88	int  fullScreen;
89	int	 mode;
90	int	 bpp;
91};
92
93struct DISPLAY_OPTIONS displayOptions =
94{
95	0,		// stereo
96	0,		// fullScreen
97	0,		// full screen mode (1,2,3,4)
98	0		// bpp (8,16,24,32)
99};
100GLenum stereoCompile = GL_FALSE ;
101GLenum stereoShowing  = GL_FALSE ;
102GLenum stereoBuffer = GL_FALSE;
103#if !defined(NO_STEREO)
104GLint displayList = MAXIMUM_DISPLAY_LIST ;
105#endif
106GLint stereo_flag = 0 ;
107
108static PWMC Current = NULL;
109WMesaContext WC = NULL;
110
111#ifdef COMPILE_SETPIXEL
112
113#if defined(_MSC_VER) && _MSC_VER >= 1200
114#define FORCEINLINE __forceinline
115#else
116#define FORCEINLINE __inline
117#endif
118
119FORCEINLINE void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
120{
121	pwc->wmSetPixel(pwc,iScanLine,iPixel,r,g,b);
122}
123
124void ChooseSetPixel(PWMC pwc);
125
126#endif // COMPILE_SETPIXEL
127
128/* If we are double-buffering, we want to get the DC for the
129 * off-screen DIB, otherwise the DC for the window.
130 */
131#define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
132#define DD_RELEASEDC
133
134#define FLIP(Y)  (Current->height-(Y)-1)
135
136#define DITHER_RGB_TO_8BIT_SETUP            \
137GLubyte pixelDithered;
138
139#define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline)        \
140{                                                                    \
141    char unsigned redtemp, greentemp, bluetemp, paletteindex;        \
142    redtemp = aDividedBy51[red]                                      \
143    + (aModulo51[red] > aHalftone8x8[(pixel%8)*8                     \
144    + scanline%8]);                                                  \
145    greentemp = aDividedBy51[(char unsigned)green]                   \
146    + (aModulo51[green] > aHalftone8x8[                              \
147    (pixel%8)*8 + scanline%8]);                                      \
148    bluetemp = aDividedBy51[(char unsigned)blue]                     \
149    + (aModulo51[blue] > aHalftone8x8[                               \
150    (pixel%8)*8 +scanline%8]);                                       \
151    paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp];\
152    pixelDithered = aWinGHalftoneTranslation[paletteindex];          \
153}
154
155#ifdef DDRAW
156static BOOL DDInit( WMesaContext wc, HWND hwnd);
157static void DDFree( WMesaContext wc);
158static HRESULT DDRestoreAll( WMesaContext wc );
159static void DDDeleteOffScreen(WMesaContext wc);
160static BOOL DDCreateOffScreen(WMesaContext wc);
161
162// define this to use the GDI Rectangle call to
163// clear the back buffer. Otherwise will manually
164// set the pixels. On an NVidia GEForce 2MX under Windows XP
165// and DirectX 8 , defining this makes apps run much much faster
166#define USE_GDI_TO_CLEAR 1
167#endif
168
169BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
170BOOL wmDeleteBackingStore(PWMC pwc);
171void wmCreatePalette( PWMC pwdc );
172BOOL wmSetDibColors(PWMC pwc);
173void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
174BOOL wmFlush(PWMC pwc);
175void wmCreateDIBSection(
176    HDC  hDC,
177    PWMC pwc,   // handle of device context
178    CONST BITMAPINFO *pbmi, // bitmap size, format, and color data
179    UINT iUsage // color data type indicator: RGB values or palette indices
180    );
181void WMesaViewport( GLcontext *ctx,
182                    GLint x, GLint y, GLsizei width, GLsizei height );
183
184
185static void wmSetPixelFormat( PWMC wc, HDC hDC)
186{
187  if(wc->rgb_flag)
188    wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
189  else
190    wc->cColorBits = 8;
191  switch(wc->cColorBits){
192  case 8:
193    if(wc->dither_flag != GL_TRUE)
194      wc->pixelformat = PF_INDEX8;
195    else
196      wc->pixelformat = PF_DITHER8;
197    break;
198  case 16:
199    wc->pixelformat = PF_5R6G5B;
200    break;
201  case 32:
202    wc->pixelformat = PF_8R8G8B;
203    break;
204  default:
205    wc->pixelformat = PF_BADFORMAT;
206  }
207}
208
209
210/* This function sets the color table of a DIB section
211 * to match that of the destination DC
212 */
213BOOL wmSetDibColors(PWMC pwc)
214{
215  RGBQUAD         *pColTab, *pRGB;
216  PALETTEENTRY    *pPal, *pPE;
217  int             i, nColors;
218  BOOL            bRet=TRUE;
219  DWORD           dwErr=0;
220
221  /* Build a color table in the DIB that maps to the
222   *  selected palette in the DC.
223   */
224  nColors = 1 << pwc->cColorBits;
225  pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
226  memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
227  GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
228  pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
229  for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
230    pRGB->rgbRed = pPE->peRed;
231    pRGB->rgbGreen = pPE->peGreen;
232    pRGB->rgbBlue = pPE->peBlue;
233  }
234  if(pwc->db_flag)
235    bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab );
236
237  if(!bRet)
238    dwErr = GetLastError();
239
240  free( pColTab );
241  free( pPal );
242
243  return bRet;
244}
245
246
247/*
248 * Free up the dib section that was created
249 */
250BOOL wmDeleteBackingStore(PWMC pwc)
251{
252  SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
253  DeleteDC(pwc->dib.hDC);
254  DeleteObject(pwc->hbmDIB);
255#ifdef USE_MAPPED_FILE
256  UnmapViewOfFile(pwc->dib.base);
257  CloseHandle(pwc->dib.hFileMap);
258#endif
259  return TRUE;
260}
261
262
263/*
264 * This function creates the DIB section that is used for combined
265 * GL and GDI calls
266 */
267BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
268{
269  HDC hdc = pwc->hDC;
270  LPBITMAPINFO pbmi = &(pwc->bmi);
271  int     iUsage;
272
273  pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
274  pbmi->bmiHeader.biWidth = lxSize;
275  pbmi->bmiHeader.biHeight= -lySize;
276  pbmi->bmiHeader.biPlanes = 1;
277  if(pwc->rgb_flag)
278    pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
279  else
280    pbmi->bmiHeader.biBitCount = 8;
281  pbmi->bmiHeader.biCompression = BI_RGB;
282  pbmi->bmiHeader.biSizeImage = 0;
283  pbmi->bmiHeader.biXPelsPerMeter = 0;
284  pbmi->bmiHeader.biYPelsPerMeter = 0;
285  pbmi->bmiHeader.biClrUsed = 0;
286  pbmi->bmiHeader.biClrImportant = 0;
287
288  iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
289
290  pwc->cColorBits = pbmi->bmiHeader.biBitCount;
291  pwc->ScanWidth = pwc->pitch = lxSize;
292
293  wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
294
295  if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
296    wmCreatePalette( pwc );
297    wmSetDibColors( pwc );
298  }
299  wmSetPixelFormat(pwc, pwc->hDC);
300  return TRUE;
301}
302
303#if 0
304// D.R.S. 10/30/01 - this function is never referenced
305/*
306 * This function copies one scan line in a DIB section to another
307 */
308BOOL wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans,
309			UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
310{
311  UINT    uiScans = 0;
312  LPBYTE  pDest = pwc->pbPixels;
313  DWORD   dwNextScan = uiScanWidth;
314  DWORD   dwNewScan = uiNewWidth;
315  DWORD   dwScanWidth = (uiScanWidth * nBypp);
316
317  /*
318   * We need to round up to the nearest DWORD
319   * and multiply by the number of bytes per
320   * pixel
321   */
322  dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
323  dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
324
325  for(uiScans = 0; uiScans < uiNumScans; uiScans++){
326    CopyMemory(pDest, pBits, dwScanWidth);
327    pBits += dwNextScan;
328    pDest += dwNewScan;
329  }
330  return TRUE;
331}
332#endif // 0
333
334#if defined(FAST_RASTERIZERS)
335
336#define PIXELADDR(X,Y)  \
337  ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* \
338  Current->ScanWidth + (X)*nBypp)
339#define PIXELADDR1( X, Y )  \
340((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
341#define PIXELADDR2( X, Y )  \
342((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
343#define PIXELADDR4( X, Y )  \
344((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
345
346#endif // 0
347
348BYTE DITHER_RGB_2_8BIT( int r, int g, int b, int x, int y);
349
350#if 0 /* unused */
351
352/* Finish all pending operations and synchronize. */
353static void finish(GLcontext* ctx)
354{
355  /* No op */
356  (void) ctx;
357}
358
359#endif /* unused */
360
361static void flush(GLcontext* ctx)
362{
363  (void) ctx;
364  if((Current->rgb_flag &&!(Current->db_flag))
365     ||(!Current->rgb_flag))
366    {
367      wmFlush(Current);
368    }
369
370}
371
372
373
374/*
375 * Set the color index used to clear the color buffer.
376 */
377static void clear_index(GLcontext* ctx, GLuint index)
378{
379  (void) ctx;
380  Current->clearpixel = index;
381}
382
383
384
385/*
386 * Set the color used to clear the color buffer.
387 */
388static void clear_color( GLcontext* ctx, const GLfloat color[4] )
389{
390  GLubyte col[4];
391  (void) ctx;
392  CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
393  CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
394  CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
395  Current->clearpixel = RGB(col[0], col[1], col[2]);
396}
397
398
399/*
400 * Clear the specified region of the color buffer using the clear color
401 * or index as specified by one of the two functions above.
402 *
403 * This procedure clears either the front and/or the back COLOR buffers.
404 * Only the "left" buffer is cleared since we are not stereo.
405 * Clearing of the other non-color buffers is left to the swrast.
406 * We also only clear the color buffers if the color masks are all 1's.
407 * Otherwise, we let swrast do it.
408 */
409
410static void clear(GLcontext* ctx, GLbitfield mask,
411      GLboolean all, GLint x, GLint y, GLint width, GLint height)
412{
413  const   GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
414
415  if (all){
416    x=y=0;
417    width=Current->width;
418    height=Current->height;
419  }
420
421
422  /* sanity check - can't have right(stereo) buffers */
423  assert((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_RIGHT_BIT)) == 0);
424
425  /* clear alpha */
426  if ((mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) &&
427      ctx->DrawBuffer->UseSoftwareAlphaBuffers &&
428      ctx->Color.ColorMask[ACOMP]) {
429      _swrast_clear_alpha_buffers( ctx );
430  }
431
432  if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
433      if (mask & DD_BACK_LEFT_BIT) {
434#if defined(USE_GDI_TO_CLEAR)
435#if defined(DDRAW)
436 // D.R.S. 10/29/01 on my system (Pentium 4 with nvidia GeForce2 MX card,
437 // this is almose 100 times faster that the code below
438 HDC DC=NULL;
439 HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
440 HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
441 HPEN Old_Pen=NULL;
442 HBRUSH Old_Brush=NULL;
443 Current->lpDDSOffScreen->lpVtbl->Unlock(Current->lpDDSOffScreen,NULL);
444 Current->lpDDSOffScreen->lpVtbl->GetDC(Current->lpDDSOffScreen,&DC);
445 Old_Pen=SelectObject(DC,Pen);
446 Old_Brush=SelectObject(DC,Brush);
447 Rectangle(DC,x,y,x+width,y+height);
448 SelectObject(DC,Old_Pen);
449 SelectObject(DC,Old_Brush);
450 DeleteObject(Pen);
451 DeleteObject(Brush);
452 Current->lpDDSOffScreen->lpVtbl->ReleaseDC(Current->lpDDSOffScreen,DC);
453 while (Current->lpDDSOffScreen->lpVtbl->Lock(Current->lpDDSOffScreen,NULL, &(Current->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING);
454
455   mask &= ~DD_BACK_LEFT_BIT;
456#else
457   /* single-buffer */
458   HDC DC=DD_GETDC;
459   HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
460   HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
461   HPEN Old_Pen=SelectObject(DC,Pen);
462   HBRUSH Old_Brush=SelectObject(DC,Brush);
463   Rectangle(DC,x+Current->rectSurface.left,Current->rectSurface.top+y,x+width+Current->rectSurface.left,y+height+Current->rectSurface.top);
464
465   SelectObject(DC,Old_Pen);
466   SelectObject(DC,Old_Brush);
467   DeleteObject(Pen);
468   DeleteObject(Brush);
469   DD_RELEASEDC;
470   mask &= ~DD_BACK_LEFT_BIT;
471#endif // DDRAW
472#else
473   DWORD   dwColor;
474   WORD    wColor;
475   BYTE    bColor;
476   LPDWORD lpdw = (LPDWORD)Current->pbPixels;
477   /*LPWORD  lpw = (LPWORD)Current->pbPixels; */
478   LPBYTE  lpb = Current->pbPixels;
479   int     lines;
480   /* Double-buffering - clear back buffer */
481   UINT    nBypp = Current->cColorBits / 8;
482   int     i = 0;
483   int     iSize = 0;
484   int   mult = 4;
485
486
487   assert(Current->db_flag==GL_TRUE); /* we'd better be double buffer */
488   if(nBypp ==1 ){
489       iSize = Current->width/4;
490       bColor  = BGR8(GetRValue(Current->clearpixel),
491        GetGValue(Current->clearpixel),
492        GetBValue(Current->clearpixel));
493       wColor  = MAKEWORD(bColor,bColor);
494       dwColor = MAKELONG(wColor, wColor);
495   }
496   else if(nBypp == 2){
497       iSize = Current->width / 2;
498       wColor = BGR16(GetRValue(Current->clearpixel),
499        GetGValue(Current->clearpixel),
500        GetBValue(Current->clearpixel));
501       dwColor = MAKELONG(wColor, wColor);
502   }
503   else if(nBypp == 3){
504      BYTE r, g, b;
505      r = GetRValue(Current->clearpixel);
506      g = GetGValue(Current->clearpixel);
507      b = GetBValue(Current->clearpixel);
508      iSize = Current->width;
509      while (i < iSize) {
510        *lpb++ = b;
511        *lpb++ = g;
512        *lpb++ = r;
513        i++;
514      }
515      lpb = Current->pbPixels + Current->ScanWidth;
516      mult = 3;
517   }
518   else if(nBypp == 4){
519       iSize = Current->width;
520       dwColor = BGR32(GetRValue(Current->clearpixel),
521         GetGValue(Current->clearpixel),
522         GetBValue(Current->clearpixel));
523   }
524   else
525       dwColor = 0;
526
527   if (nBypp != 3)
528   {
529      /* clear a line */
530    while(i < iSize){
531        *lpdw = dwColor;
532     lpdw++;
533        i++;
534    }
535   }
536
537   i = 0;
538   if (stereo_flag)
539       lines = height /2;
540   else
541       lines = height;
542   /* copy cleared line to other lines in buffer */
543   do {
544       memcpy(lpb, Current->pbPixels, iSize*mult);
545       lpb += Current->ScanWidth;
546       i++;
547   }
548   while (i<lines-1);
549   mask &= ~DD_BACK_LEFT_BIT;
550#endif // defined(USE_GDI_TO_CLEAR)
551      } /* double-buffer */
552
553      if (mask & DD_FRONT_LEFT_BIT) {
554   /* single-buffer */
555   HDC DC=DD_GETDC;
556   HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
557   HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
558   HPEN Old_Pen=SelectObject(DC,Pen);
559   HBRUSH Old_Brush=SelectObject(DC,Brush);
560   Rectangle(DC,x+Current->rectSurface.left,Current->rectSurface.top+y,x+width+Current->rectSurface.left,y+height+Current->rectSurface.top);
561
562   SelectObject(DC,Old_Pen);
563   SelectObject(DC,Old_Brush);
564   DeleteObject(Pen);
565   DeleteObject(Brush);
566   DD_RELEASEDC;
567   mask &= ~DD_FRONT_LEFT_BIT;
568      } /* single-buffer */
569  } /* if masks are all 1's */
570
571  /* Call swrast if there is anything left to clear (like DEPTH) */
572  if (mask)
573      _swrast_Clear( ctx, mask, all, x, y, width, height );
574}
575
576
577static void enable( GLcontext* ctx, GLenum pname, GLboolean enable )
578{
579  (void) ctx;
580  if (!Current)
581    return;
582
583  if (pname == GL_DITHER) {
584    if(enable == GL_FALSE){
585      Current->dither_flag = GL_FALSE;
586      if(Current->cColorBits == 8)
587	Current->pixelformat = PF_INDEX8;
588    }
589    else{
590      if (Current->rgb_flag && Current->cColorBits == 8){
591	Current->pixelformat = PF_DITHER8;
592	Current->dither_flag = GL_TRUE;
593      }
594      else
595	Current->dither_flag = GL_FALSE;
596    }
597  }
598}
599
600
601
602static void set_buffer(GLcontext *ctx, GLframebuffer *colorBuffer,
603                       GLuint bufferBit )
604{
605  (void) ctx; (void) colorBuffer; (void) bufferBit;
606  /* XXX todo - examine bufferBit and set read/write pointers */
607  return;
608}
609
610
611
612/* Return characteristics of the output buffer. */
613static void buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
614{
615  /*GET_CURRENT_CONTEXT(ctx);*/
616  int New_Size;
617  RECT CR;
618  (void) buffer;
619
620  GetClientRect(Current->Window,&CR);
621
622   *width=CR.right;
623   *height=CR.bottom;
624
625   New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
626
627   if (New_Size){
628     Current->width=*width;
629     Current->height=*height;
630     Current->ScanWidth=Current->width;
631     if ((Current->ScanWidth%sizeof(long))!=0)
632       Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
633
634     if (Current->db_flag){
635#ifdef DDRAW
636       DDDeleteOffScreen(Current);
637       DDCreateOffScreen(Current);
638#else
639       if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){
640	 wmDeleteBackingStore(Current);
641	 wmCreateBackingStore(Current, Current->width, Current->height);
642       }
643#endif
644     }
645
646     /*  Resize OsmesaBuffer if in Parallel mode */
647#if !defined(NO_PARALLEL)
648     if(parallelFlag)
649       PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
650			  Current->rgb_flag == GL_TRUE ? Current->pbPixels:
651			  Current->ScreenMem);
652#endif
653   }
654}
655
656
657
658/**********************************************************************/
659/*****           Accelerated point, line, polygon rendering       *****/
660/**********************************************************************/
661
662/* Accelerated routines are not implemented in 4.0. See OSMesa for ideas. */
663
664#if 0 /* unused */
665
666static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
667{
668  (void) ctx; (void) first; (void) last;
669}
670
671#endif /* unused */
672
673/* Return pointer to accelerated points function */
674extern tnl_points_func choose_points_function( GLcontext* ctx )
675{
676  (void) ctx;
677  return NULL;
678}
679
680#if 0 /* unused */
681
682static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0,
683				GLuint v1, GLuint pv )
684{
685  (void) ctx; (void) v0; (void) v1; (void) pv;
686}
687
688static tnl_line_func choose_line_function( GLcontext* ctx )
689{
690  (void) ctx;
691}
692
693#endif /* unused */
694
695/**********************************************************************/
696/*****                 Span-based pixel drawing                   *****/
697/**********************************************************************/
698
699
700/* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
701static void write_ci32_span( const GLcontext* ctx,
702                             GLuint n, GLint x, GLint y,
703                             const GLuint index[],
704                             const GLubyte mask[] )
705{
706  GLuint i;
707  PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
708  (void) ctx;
709  assert(Current->rgb_flag==GL_FALSE);
710  for (i=0; i<n; i++)
711    if (mask[i])
712      Mem[i]=index[i];
713}
714
715
716/* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
717static void write_ci8_span( const GLcontext* ctx,
718                            GLuint n, GLint x, GLint y,
719                            const GLubyte index[],
720                            const GLubyte mask[] )
721{
722  GLuint i;
723  PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
724  (void) ctx;
725  assert(Current->rgb_flag==GL_FALSE);
726  for (i=0; i<n; i++)
727    if (mask[i])
728      Mem[i]=index[i];
729}
730
731
732
733/*
734 * Write a horizontal span of pixels with a boolean mask.  The current
735 * color index is used for all pixels.
736 */
737static void write_mono_ci_span(const GLcontext* ctx,
738                               GLuint n,GLint x,GLint y,
739                               GLuint colorIndex, const GLubyte mask[])
740{
741  GLuint i;
742  BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
743  (void) ctx;
744  assert(Current->rgb_flag==GL_FALSE);
745  for (i=0; i<n; i++)
746    if (mask[i])
747      Mem[i]=colorIndex;
748}
749
750/*
751 * To improve the performance of this routine, frob the data into an actual
752 * scanline and call bitblt on the complete scan line instead of SetPixel.
753 */
754
755/* Write a horizontal span of RGBA color pixels with a boolean mask. */
756static void write_rgba_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
757                             const GLubyte rgba[][4], const GLubyte mask[] )
758{
759  PWMC    pwc = Current;
760  (void) ctx;
761
762  if (pwc->rgb_flag==GL_TRUE)
763    {
764      GLuint i;
765      /*HDC DC=DD_GETDC;*/
766      y=FLIP(y);
767      if (mask) {
768	for (i=0; i<n; i++)
769	  if (mask[i])
770	    wmSetPixel(pwc, y, x + i,
771		       rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
772      }
773      else {
774	for (i=0; i<n; i++)
775	  wmSetPixel(pwc, y, x + i,
776		     rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
777      }
778      DD_RELEASEDC;
779    }
780  else
781    {
782      GLuint i;
783      BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
784      y = FLIP(y);
785      if (mask) {
786	for (i=0; i<n; i++)
787	  if (mask[i])
788	    Mem[i] = GetNearestPaletteIndex(Current->hPal,
789					    RGB(rgba[i][RCOMP],
790						rgba[i][GCOMP],
791						rgba[i][BCOMP]));
792      }
793      else {
794	for (i=0; i<n; i++)
795	  Mem[i] = GetNearestPaletteIndex(Current->hPal,
796					  RGB(rgba[i][RCOMP],
797					      rgba[i][GCOMP],
798					      rgba[i][BCOMP]));
799      }
800    }
801}
802
803/* Write a horizontal span of RGB color pixels with a boolean mask. */
804static void write_rgb_span( const GLcontext* ctx,
805                            GLuint n, GLint x, GLint y,
806                            const GLubyte rgb[][3], const GLubyte mask[] )
807{
808  PWMC    pwc = Current;
809  (void) ctx;
810
811  if (pwc->rgb_flag==GL_TRUE)
812    {
813      GLuint i;
814      /*HDC DC=DD_GETDC;*/
815      y=FLIP(y);
816      if (mask) {
817	for (i=0; i<n; i++)
818	  if (mask[i])
819	    wmSetPixel(pwc, y, x + i,
820		       rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
821      }
822      else {
823	for (i=0; i<n; i++)
824	  wmSetPixel(pwc, y, x + i,
825		     rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
826      }
827      DD_RELEASEDC;
828    }
829  else
830    {
831      GLuint i;
832      BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
833      y = FLIP(y);
834      if (mask) {
835	for (i=0; i<n; i++)
836	  if (mask[i])
837	    Mem[i] = GetNearestPaletteIndex(Current->hPal,
838					    RGB(rgb[i][RCOMP],
839						rgb[i][GCOMP],
840						rgb[i][BCOMP]));
841      }
842      else {
843	for (i=0; i<n; i++)
844	  Mem[i] = GetNearestPaletteIndex(Current->hPal,
845					  RGB(rgb[i][RCOMP],
846					      rgb[i][GCOMP],
847					      rgb[i][BCOMP]));
848      }
849    }
850}
851
852/*
853 * Write a horizontal span of pixels with a boolean mask.  The current color
854 * is used for all pixels.
855 */
856static void write_mono_rgba_span( const GLcontext* ctx,
857                                  GLuint n, GLint x, GLint y,
858                                  const GLchan color[4], const GLubyte mask[])
859{
860  GLuint i;
861  PWMC pwc = Current;
862  (void) ctx;
863  assert(Current->rgb_flag==GL_TRUE);
864  y=FLIP(y);
865  if(Current->rgb_flag==GL_TRUE)
866  {
867	for (i=0; i<n; i++)
868		if (mask[i])
869			wmSetPixel(pwc,y,x+i,color[RCOMP], color[GCOMP], color[BCOMP]);
870  }
871  else
872  {
873	HDC DC=DD_GETDC;
874    ULONG pixel =  RGB( color[RCOMP], color[GCOMP], color[BCOMP] );
875    for (i=0; i<n; i++)
876      if (mask[i])
877		SetPixel(DC, y, x+i, pixel);
878	  DD_RELEASEDC;
879  }
880}
881
882
883
884/**********************************************************************/
885/*****                   Array-based pixel drawing                *****/
886/**********************************************************************/
887
888
889/* Write an array of 32-bit index pixels with a boolean mask. */
890static void write_ci32_pixels( const GLcontext* ctx,
891                               GLuint n, const GLint x[], const GLint y[],
892                               const GLuint index[], const GLubyte mask[] )
893{
894  GLuint i;
895  (void) ctx;
896  assert(Current->rgb_flag==GL_FALSE);
897  for (i=0; i<n; i++) {
898    if (mask[i]) {
899      BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
900      *Mem = index[i];
901    }
902  }
903}
904
905
906
907/*
908 * Write an array of pixels with a boolean mask.  The current color
909 * index is used for all pixels.
910 */
911static void write_mono_ci_pixels( const GLcontext* ctx,
912                                  GLuint n,
913                                  const GLint x[], const GLint y[],
914                                  GLuint colorIndex, const GLubyte mask[] )
915{
916  GLuint i;
917  (void) ctx;
918  assert(Current->rgb_flag==GL_FALSE);
919  for (i=0; i<n; i++) {
920    if (mask[i]) {
921      BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
922      *Mem = colorIndex;
923    }
924  }
925}
926
927
928
929/* Write an array of RGBA pixels with a boolean mask. */
930static void write_rgba_pixels( const GLcontext* ctx,
931                               GLuint n, const GLint x[], const GLint y[],
932                               const GLubyte rgba[][4], const GLubyte mask[] )
933{
934  GLuint i;
935  PWMC    pwc = Current;
936  /*HDC DC=DD_GETDC;*/
937  (void) ctx;
938  assert(Current->rgb_flag==GL_TRUE);
939  for (i=0; i<n; i++)
940    if (mask[i])
941      wmSetPixel(pwc, FLIP(y[i]), x[i],
942		 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
943  DD_RELEASEDC;
944}
945
946
947
948/*
949 * Write an array of pixels with a boolean mask.  The current color
950 * is used for all pixels.
951 */
952static void write_mono_rgba_pixels( const GLcontext* ctx,
953                                    GLuint n,
954                                    const GLint x[], const GLint y[],
955                                    const GLchan color[4],
956                                    const GLubyte mask[] )
957{
958  GLuint i;
959  PWMC    pwc = Current;
960  /*HDC DC=DD_GETDC;*/
961  (void) ctx;
962  assert(Current->rgb_flag==GL_TRUE);
963  for (i=0; i<n; i++)
964    if (mask[i])
965      wmSetPixel(pwc, FLIP(y[i]),x[i],color[RCOMP],
966		 color[GCOMP], color[BCOMP]);
967  DD_RELEASEDC;
968}
969
970
971
972/**********************************************************************/
973/*****            Read spans/arrays of pixels                     *****/
974/**********************************************************************/
975
976
977/* Read a horizontal span of color-index pixels. */
978static void read_ci32_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
979                            GLuint index[])
980{
981  GLuint i;
982  BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
983  (void) ctx;
984  assert(Current->rgb_flag==GL_FALSE);
985  for (i=0; i<n; i++)
986    index[i]=Mem[i];
987}
988
989
990
991
992/* Read an array of color index pixels. */
993static void read_ci32_pixels( const GLcontext* ctx,
994                              GLuint n, const GLint x[], const GLint y[],
995                              GLuint indx[], const GLubyte mask[] )
996{
997  GLuint i;
998  (void) ctx;
999  assert(Current->rgb_flag==GL_FALSE);
1000  for (i=0; i<n; i++) {
1001    if (mask[i]) {
1002      indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]);
1003    }
1004  }
1005}
1006
1007
1008
1009/* Read a horizontal span of color pixels. */
1010static void read_rgba_span( const GLcontext* ctx,
1011                            GLuint n, GLint x, GLint y,
1012                            GLubyte rgba[][4] )
1013{
1014  UINT i;
1015  COLORREF Color;
1016  HDC DC=DD_GETDC;
1017  (void) ctx;
1018  assert(Current->rgb_flag==GL_TRUE);
1019  y = Current->height - y - 1;
1020  for (i=0; i<n; i++) {
1021    Color=GetPixel(DC,x+i,y);
1022    rgba[i][RCOMP] = GetRValue(Color);
1023    rgba[i][GCOMP] = GetGValue(Color);
1024    rgba[i][BCOMP] = GetBValue(Color);
1025    rgba[i][ACOMP] = 255;
1026  }
1027  DD_RELEASEDC;
1028}
1029
1030
1031/* Read an array of color pixels. */
1032static void read_rgba_pixels( const GLcontext* ctx,
1033                              GLuint n, const GLint x[], const GLint y[],
1034                              GLubyte rgba[][4], const GLubyte mask[] )
1035{
1036  GLuint i;
1037  COLORREF Color;
1038  HDC DC=DD_GETDC;
1039  (void) ctx;
1040  assert(Current->rgb_flag==GL_TRUE);
1041  for (i=0; i<n; i++) {
1042    if (mask[i]) {
1043      GLint y2 = Current->height - y[i] - 1;
1044      Color=GetPixel(DC,x[i],y2);
1045      rgba[i][RCOMP] = GetRValue(Color);
1046      rgba[i][GCOMP] = GetGValue(Color);
1047      rgba[i][BCOMP] = GetBValue(Color);
1048      rgba[i][ACOMP] = 255;
1049    }
1050  }
1051  DD_RELEASEDC;
1052}
1053
1054
1055
1056/**********************************************************************/
1057/**********************************************************************/
1058
1059
1060static const GLubyte *get_string(GLcontext *ctx, GLenum name)
1061{
1062  (void) ctx;
1063  if (name == GL_RENDERER) {
1064    return (GLubyte *) "Mesa Windows";
1065  }
1066  else {
1067    return NULL;
1068  }
1069}
1070
1071static void wmesa_update_state( GLcontext *ctx, GLuint new_state );
1072
1073static void SetFunctionPointers( struct dd_function_table *functions )
1074{
1075  functions->GetString = get_string;
1076  functions->UpdateState = wmesa_update_state;
1077  functions->ResizeBuffers = _swrast_alloc_buffers;
1078  functions->GetBufferSize = buffer_size;
1079
1080  functions->Clear = clear;
1081
1082  functions->Flush = flush;
1083  functions->ClearIndex = clear_index;
1084  functions->ClearColor = clear_color;
1085  functions->Enable = enable;
1086}
1087
1088
1089static void SetSWrastPointers(GLcontext *ctx)
1090{
1091  struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
1092  swdd->SetBuffer = set_buffer;
1093
1094  /* Pixel/span writing functions: */
1095  swdd->WriteRGBASpan        = write_rgba_span;
1096  swdd->WriteRGBSpan         = write_rgb_span;
1097  swdd->WriteMonoRGBASpan    = write_mono_rgba_span;
1098  swdd->WriteRGBAPixels      = write_rgba_pixels;
1099  swdd->WriteMonoRGBAPixels  = write_mono_rgba_pixels;
1100  swdd->WriteCI32Span        = write_ci32_span;
1101  swdd->WriteCI8Span         = write_ci8_span;
1102  swdd->WriteMonoCISpan      = write_mono_ci_span;
1103  swdd->WriteCI32Pixels      = write_ci32_pixels;
1104  swdd->WriteMonoCIPixels    = write_mono_ci_pixels;
1105
1106  swdd->ReadCI32Span        = read_ci32_span;
1107  swdd->ReadRGBASpan        = read_rgba_span;
1108  swdd->ReadCI32Pixels      = read_ci32_pixels;
1109  swdd->ReadRGBAPixels      = read_rgba_pixels;
1110}
1111
1112
1113static void wmesa_update_state( GLcontext *ctx, GLuint new_state )
1114{
1115  /*struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );*/
1116  TNLcontext *tnl = TNL_CONTEXT(ctx);
1117
1118  /*
1119   * XXX these function pointers could be initialized just once during
1120   * context creation since they don't depend on any state changes.
1121   * kws - This is true - this function gets called a lot and it
1122   * would be good to minimize setting all this when not needed.
1123   */
1124#ifndef SET_FPOINTERS_ONCE
1125  SetFunctionPointers(&ctx->Driver);
1126  SetSWrastPointers(ctx);
1127#if 0
1128  ctx->Driver.GetString = get_string;
1129  ctx->Driver.UpdateState = wmesa_update_state;
1130  ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
1131  ctx->Driver.GetBufferSize = buffer_size;
1132
1133  ctx->Driver.Accum = _swrast_Accum;
1134  ctx->Driver.Bitmap = _swrast_Bitmap;
1135  ctx->Driver.Clear = clear;
1136
1137  ctx->Driver.Flush = flush;
1138  ctx->Driver.ClearIndex = clear_index;
1139  ctx->Driver.ClearColor = clear_color;
1140  ctx->Driver.Enable = enable;
1141
1142  ctx->Driver.CopyPixels = _swrast_CopyPixels;
1143  ctx->Driver.DrawPixels = _swrast_DrawPixels;
1144  ctx->Driver.ReadPixels = _swrast_ReadPixels;
1145
1146  ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
1147  ctx->Driver.TexImage1D = _mesa_store_teximage1d;
1148  ctx->Driver.TexImage2D = _mesa_store_teximage2d;
1149  ctx->Driver.TexImage3D = _mesa_store_teximage3d;
1150  ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
1151  ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
1152  ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
1153  ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
1154
1155  ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
1156  ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
1157  ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
1158  ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
1159  ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
1160  ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
1161
1162  ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
1163  ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
1164  ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
1165  ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
1166  ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
1167  ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1168  ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1169  ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1170  ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1171
1172  swdd->SetBuffer = set_buffer;
1173
1174  /* Pixel/span writing functions: */
1175  swdd->WriteRGBASpan        = write_rgba_span;
1176  swdd->WriteRGBSpan         = write_rgb_span;
1177  swdd->WriteMonoRGBASpan    = write_mono_rgba_span;
1178  swdd->WriteRGBAPixels      = write_rgba_pixels;
1179  swdd->WriteMonoRGBAPixels  = write_mono_rgba_pixels;
1180  swdd->WriteCI32Span        = write_ci32_span;
1181  swdd->WriteCI8Span         = write_ci8_span;
1182  swdd->WriteMonoCISpan      = write_mono_ci_span;
1183  swdd->WriteCI32Pixels      = write_ci32_pixels;
1184  swdd->WriteMonoCIPixels    = write_mono_ci_pixels;
1185
1186  swdd->ReadCI32Span        = read_ci32_span;
1187  swdd->ReadRGBASpan        = read_rgba_span;
1188  swdd->ReadCI32Pixels      = read_ci32_pixels;
1189  swdd->ReadRGBAPixels      = read_rgba_pixels;
1190#endif // 0
1191#endif //  !SET_FPOINTERS_ONCE
1192  tnl->Driver.RunPipeline = _tnl_run_pipeline;
1193
1194  _swrast_InvalidateState( ctx, new_state );
1195  _swsetup_InvalidateState( ctx, new_state );
1196  _ac_InvalidateState( ctx, new_state );
1197  _tnl_InvalidateState( ctx, new_state );
1198}
1199
1200
1201
1202
1203/**********************************************************************/
1204/*****                  WMesa API Functions                       *****/
1205/**********************************************************************/
1206
1207#if 0 /* unused */
1208
1209#define PAL_SIZE 256
1210static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
1211{
1212  int i;
1213  HDC hdc;
1214  struct
1215  {
1216    WORD Version;
1217    WORD NumberOfEntries;
1218    PALETTEENTRY aEntries[PAL_SIZE];
1219  } Palette;
1220  Palette.Version = 0x300;
1221  Palette.NumberOfEntries = PAL_SIZE;
1222  hdc=GetDC(NULL);
1223  if (Pal!=NULL)
1224    GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
1225  else
1226    GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
1227  if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
1228    {
1229      for(i = 0; i <PAL_SIZE; i++)
1230	Palette.aEntries[i].peFlags = PC_RESERVED;
1231      Palette.aEntries[255].peRed = 255;
1232      Palette.aEntries[255].peGreen = 255;
1233      Palette.aEntries[255].peBlue = 255;
1234      Palette.aEntries[255].peFlags = 0;
1235      Palette.aEntries[0].peRed = 0;
1236      Palette.aEntries[0].peGreen = 0;
1237      Palette.aEntries[0].peBlue = 0;
1238      Palette.aEntries[0].peFlags = 0;
1239    }
1240  else
1241    {
1242      int nStaticColors;
1243      int nUsableColors;
1244      nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
1245      for (i=0; i<nStaticColors; i++)
1246	Palette.aEntries[i].peFlags = 0;
1247      nUsableColors = PAL_SIZE-nStaticColors;
1248      for (; i<nUsableColors; i++)
1249	Palette.aEntries[i].peFlags = PC_RESERVED;
1250      for (; i<PAL_SIZE-nStaticColors; i++)
1251	Palette.aEntries[i].peFlags = PC_RESERVED;
1252      for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
1253	Palette.aEntries[i].peFlags = 0;
1254    }
1255  ReleaseDC(NULL,hdc);
1256  for (i=0; i<PAL_SIZE; i++)
1257    {
1258      aRGB[i].rgbRed=Palette.aEntries[i].peRed;
1259      aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
1260      aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
1261      aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
1262    }
1263}
1264
1265#endif /* unused */
1266
1267WMesaContext WMesaCreateContext( HWND hWnd, HPALETTE* Pal,
1268				 GLboolean rgb_flag,
1269				 GLboolean db_flag,
1270                                 GLboolean alpha_flag )
1271{
1272  RECT CR;
1273  WMesaContext c;
1274  GLboolean true_color_flag;
1275  struct dd_function_table functions;
1276  (void) Pal;
1277
1278  c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
1279  if (!c)
1280    return NULL;
1281
1282  c->Window=hWnd;
1283  c->hDC = GetDC(hWnd);
1284  true_color_flag = GetDeviceCaps(c->hDC, BITSPIXEL) > 8;
1285#ifdef DDRAW
1286  if(true_color_flag) c->rgb_flag = rgb_flag = GL_TRUE;
1287#endif
1288
1289
1290#ifdef DITHER
1291  if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){
1292    c->dither_flag = GL_TRUE;
1293#ifdef USE_WING
1294    c->hPalHalfTone = WinGCreateHalftonePalette();
1295#else
1296	c->hPalHalfTone = CreateHalftonePalette(c->hDC);
1297#endif
1298  }
1299  else
1300    c->dither_flag = GL_FALSE;
1301#else
1302  c->dither_flag = GL_FALSE;
1303#endif
1304
1305
1306  if (rgb_flag==GL_FALSE)
1307    {
1308      c->rgb_flag = GL_FALSE;
1309#if 0
1310      /* Old WinG stuff???? */
1311      c->db_flag = db_flag =GL_TRUE; /* WinG requires double buffering */
1312      printf("Single buffer is not supported in color index mode, ",
1313	     "setting to double buffer.\n");
1314#endif
1315    }
1316  else
1317    {
1318      c->rgb_flag = GL_TRUE;
1319    }
1320  GetClientRect(c->Window,&CR);
1321  c->width=CR.right;
1322  c->height=CR.bottom;
1323  if (db_flag)
1324    {
1325      c->db_flag = 1;
1326      /* Double buffered */
1327#ifndef DDRAW
1328      {
1329	wmCreateBackingStore(c, c->width, c->height);
1330
1331      }
1332#endif
1333    }
1334  else
1335    {
1336      /* Single Buffered */
1337      if (c->rgb_flag)
1338	c->db_flag = 0;
1339    }
1340#ifdef DDRAW
1341  if (DDInit(c,hWnd) == GL_FALSE) {
1342    free( (void *) c );
1343    exit(1);
1344  }
1345#endif
1346
1347
1348  c->gl_visual = _mesa_create_visual(rgb_flag,
1349				     db_flag,    /* db_flag */
1350				     GL_FALSE,   /* stereo */
1351				     8,8,8,      /* r, g, b bits */
1352                                     alpha_flag ? 8 : 0, /* alpha bits */
1353				     0,          /* index bits */
1354				     16,         /* depth_bits */
1355				     8,          /* stencil_bits */
1356				     16,16,16,/* accum_bits */
1357                                     alpha_flag ? 16 : 0, /* alpha accum */
1358				     1);
1359
1360  if (!c->gl_visual) {
1361    return NULL;
1362  }
1363
1364  _mesa_init_driver_functions(&functions);
1365  SetFunctionPointers(&functions);
1366
1367  /* allocate a new Mesa context */
1368  c->gl_ctx = _mesa_create_context( c->gl_visual, NULL,
1369                                    &functions, (void *) c );
1370
1371  if (!c->gl_ctx) {
1372    _mesa_destroy_visual( c->gl_visual );
1373    free(c);
1374    return NULL;
1375  }
1376
1377  _mesa_enable_sw_extensions(c->gl_ctx);
1378  _mesa_enable_1_3_extensions(c->gl_ctx);
1379  _mesa_enable_1_4_extensions(c->gl_ctx);
1380
1381  c->gl_buffer = _mesa_create_framebuffer( c->gl_visual,
1382					   c->gl_visual->depthBits > 0,
1383					   c->gl_visual->stencilBits > 0,
1384					   c->gl_visual->accumRedBits > 0,
1385					   alpha_flag /* s/w alpha */ );
1386  if (!c->gl_buffer) {
1387    _mesa_destroy_visual( c->gl_visual );
1388    _mesa_free_context_data( c->gl_ctx );
1389    free(c);
1390    return NULL;
1391  }
1392
1393  /* Initialize the software rasterizer and helper modules.
1394   */
1395  {
1396    GLcontext *ctx = c->gl_ctx;
1397    _swrast_CreateContext( ctx );
1398    _ac_CreateContext( ctx );
1399    _tnl_CreateContext( ctx );
1400    _swsetup_CreateContext( ctx );
1401
1402#ifdef SET_FPOINTERS_ONCE
1403    /*SetFunctionPointers(ctx);*/
1404    SetSWrastPointers(ctx);
1405#endif // SET_FPOINTERS_ONCE
1406    _swsetup_Wakeup( ctx );
1407  }
1408#ifdef COMPILE_SETPIXEL
1409  ChooseSetPixel(c);
1410#endif
1411  return c;
1412}
1413
1414void WMesaDestroyContext( void )
1415{
1416  WMesaContext c = Current;
1417  ReleaseDC(c->Window,c->hDC);
1418  WC = c;
1419  if(c->hPalHalfTone != NULL)
1420    DeleteObject(c->hPalHalfTone);
1421
1422  _swsetup_DestroyContext( c->gl_ctx );
1423  _tnl_DestroyContext( c->gl_ctx );
1424  _ac_DestroyContext( c->gl_ctx );
1425  _swrast_DestroyContext( c->gl_ctx );
1426
1427  _mesa_destroy_visual( c->gl_visual );
1428  _mesa_destroy_framebuffer( c->gl_buffer );
1429  _mesa_free_context_data( c->gl_ctx );
1430  free( (void *) c->gl_ctx);
1431
1432  if (c->db_flag)
1433#ifdef DDRAW
1434    DDFree(c);
1435#else
1436  wmDeleteBackingStore(c);
1437#endif
1438  free( (void *) c );
1439#if !defined(NO_PARALLEL)
1440  if(parallelMachine)
1441    PRDestroyRenderBuffer();
1442#endif
1443
1444  // Destroyed context no longer valid
1445  WMesaMakeCurrent( NULL );
1446}
1447
1448
1449void WMesaMakeCurrent( WMesaContext c )
1450{
1451  if(!c){
1452    Current = c;
1453    return;
1454  }
1455
1456  if(Current == c)
1457    return;
1458
1459  Current = c;
1460  wmesa_update_state(c->gl_ctx, 0);
1461  _mesa_make_current(c->gl_ctx, c->gl_buffer);
1462  if (Current->gl_ctx->Viewport.Width==0) {
1463    /* initialize viewport to window size */
1464    _mesa_Viewport( 0, 0, Current->width, Current->height );
1465    Current->gl_ctx->Scissor.Width = Current->width;
1466    Current->gl_ctx->Scissor.Height = Current->height;
1467  }
1468  if ((c->cColorBits <= 8 ) && (c->rgb_flag == GL_TRUE)){
1469    WMesaPaletteChange(c->hPalHalfTone);
1470  }
1471}
1472
1473
1474
1475void WMesaSwapBuffers( void )
1476{
1477/*  HDC DC = Current->hDC;*/
1478  GET_CURRENT_CONTEXT(ctx);
1479
1480  /* If we're swapping the buffer associated with the current context
1481   * we have to flush any pending rendering commands first.
1482   */
1483  if (Current && Current->gl_ctx == ctx)
1484    _mesa_notifySwapBuffers(ctx);
1485
1486  if (Current->db_flag)
1487    wmFlush(Current);
1488}
1489
1490
1491
1492void WMesaPaletteChange(HPALETTE Pal)
1493{
1494#ifndef DDRAW
1495  int vRet;
1496#endif
1497  LPPALETTEENTRY pPal;
1498  if (Current && (Current->rgb_flag==GL_FALSE ||
1499		  Current->dither_flag == GL_TRUE))
1500    {
1501      pPal = (PALETTEENTRY *)malloc( 256 * sizeof(PALETTEENTRY));
1502      Current->hPal=Pal;
1503      GetPaletteEntries( Pal, 0, 256, pPal );
1504#ifdef DDRAW
1505      Current->lpDD->lpVtbl->CreatePalette(Current->lpDD,DDPCAPS_8BIT,
1506					   pPal, &(Current->lpDDPal), NULL);
1507      if (Current->lpDDPal)
1508	Current->lpDDSPrimary->lpVtbl->SetPalette(Current->lpDDSPrimary,
1509						  Current->lpDDPal);
1510#else
1511      vRet = SetDIBColorTable(Current->dib.hDC, 0, 256, (RGBQUAD*)pPal);
1512#endif
1513      free( pPal );
1514    }
1515}
1516
1517
1518
1519
1520static unsigned char threeto8[8] = {
1521  0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1522};
1523
1524static unsigned char twoto8[4] = {
1525  0, 0x55, 0xaa, 0xff
1526};
1527
1528static unsigned char oneto8[2] = {
1529  0, 255
1530};
1531
1532static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
1533{
1534  unsigned char val;
1535
1536  val = i >> shift;
1537  switch (nbits) {
1538
1539  case 1:
1540    val &= 0x1;
1541    return oneto8[val];
1542
1543  case 2:
1544    val &= 0x3;
1545    return twoto8[val];
1546
1547  case 3:
1548    val &= 0x7;
1549    return threeto8[val];
1550
1551  default:
1552    return 0;
1553  }
1554}
1555
1556void wmCreatePalette( PWMC pwdc )
1557{
1558  /* Create a compressed and re-expanded 3:3:2 palette */
1559  int            i;
1560  LOGPALETTE     *pPal;
1561  BYTE           rb, rs, gb, gs, bb, bs;
1562
1563  pwdc->nColors = 0x100;
1564
1565  pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) +
1566			     pwdc->nColors * sizeof(PALETTEENTRY));
1567  memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
1568
1569  pPal->palVersion = 0x300;
1570
1571  rb = REDBITS;
1572  rs = REDSHIFT;
1573  gb = GREENBITS;
1574  gs = GREENSHIFT;
1575  bb = BLUEBITS;
1576  bs = BLUESHIFT;
1577
1578  if (pwdc->db_flag) {
1579
1580    /* Need to make two palettes: one for the screen DC and one for the DIB. */
1581    pPal->palNumEntries = pwdc->nColors;
1582    for (i = 0; i < pwdc->nColors; i++) {
1583      pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
1584      pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
1585      pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
1586      pPal->palPalEntry[i].peFlags = 0;
1587    }
1588    pwdc->hGLPalette = CreatePalette( pPal );
1589    pwdc->hPalette = CreatePalette( pPal );
1590  }
1591
1592  else {
1593    pPal->palNumEntries = pwdc->nColors;
1594    for (i = 0; i < pwdc->nColors; i++) {
1595      pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
1596      pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
1597      pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
1598      pPal->palPalEntry[i].peFlags = 0;
1599    }
1600    pwdc->hGLPalette = CreatePalette( pPal );
1601  }
1602
1603  free(pPal);
1604
1605}
1606
1607
1608void
1609#ifdef COMPILE_SETPIXEL
1610
1611wmSetPixelDefault(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1612{
1613	if (Current->db_flag)
1614	{
1615#ifdef DDRAW
1616		HDC hdc = NULL;
1617		Current->lpDDSOffScreen->lpVtbl->Unlock(Current->lpDDSOffScreen,NULL);
1618		Current->lpDDSOffScreen->lpVtbl->GetDC(Current->lpDDSOffScreen,&hdc);
1619		SetPixelV(hdc,iPixel, iScanLine, RGB(r,g,b));
1620		Current->lpDDSOffScreen->lpVtbl->ReleaseDC(Current->lpDDSOffScreen,hdc);
1621		while (Current->lpDDSOffScreen->lpVtbl->Lock(Current->lpDDSOffScreen,NULL, &(Current->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING);
1622#else
1623		SetPixelV(Current->hDC, iPixel, iScanLine, RGB(r,g,b));
1624#endif
1625	}
1626	else
1627	{
1628		SetPixelV(Current->hDC, iPixel+pwc->rectSurface.left, pwc->rectSurface.top+iScanLine, RGB(r,g,b));
1629	}
1630}
1631#else
1632wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1633{
1634	if (Current->db_flag)
1635	{
1636		LPBYTE  lpb = pwc->pbPixels;
1637		UINT    nBypp = pwc->cColorBits >> 3;
1638
1639		lpb += pwc->ScanWidth * iScanLine;
1640		lpb += iPixel * nBypp;
1641
1642		if(nBypp == 1)
1643		{
1644			if(pwc->dither_flag)
1645				*lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
1646			else
1647				*lpb = BGR8(r,g,b);
1648		}
1649		else if(nBypp == 2)
1650			*((LPWORD)lpb) = BGR16(r,g,b);
1651		else if (nBypp == 3)
1652			{
1653			*lpb++ = b;
1654			*lpb++ = g;
1655			*lpb   = r;
1656			}
1657		else if (nBypp == 4)
1658			*((LPDWORD)lpb) = BGR32(r,g,b);
1659	}
1660	else
1661	{
1662		SetPixel(Current->hDC, iPixel, iScanLine, RGB(r,g,b));
1663	}
1664}
1665#endif
1666#ifdef COMPILE_SETPIXEL
1667void wmSetPixel4(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1668{
1669	LPDWORD lpdw = ((LPDWORD)(pwc->pbPixels + pwc->ScanWidth * iScanLine)) + iPixel;
1670	*lpdw = BGR32(r,g,b);
1671//	LPBYTE  lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel + iPixel;
1672//	*((LPDWORD)lpb) = BGR32(r,g,b);
1673}
1674
1675void wmSetPixel3(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1676{
1677	LPBYTE  lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel;
1678	*lpb++ = b;
1679	*lpb++ = g;
1680	*lpb   = r;
1681}
1682
1683void wmSetPixel2(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1684{
1685	LPWORD lpw = ((LPWORD)(pwc->pbPixels + pwc->ScanWidth * iScanLine)) + iPixel;
1686	*lpw = BGR16(r,g,b);
1687//	LPBYTE  lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel;
1688//	*((LPWORD)lpb) = BGR16(r,g,b);
1689}
1690
1691void wmSetPixel1(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1692{
1693	LPBYTE  lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel;
1694	*lpb = BGR8(r,g,b);
1695}
1696
1697void wmSetPixel1Dither(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1698{
1699	LPBYTE  lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel;
1700	*lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
1701}
1702
1703
1704void ChooseSetPixel(PWMC pwc)
1705{
1706	UINT nBypp = (pwc ) ? pwc->cColorBits >> 3 : 0;
1707	switch(nBypp)
1708	{
1709		case 1:
1710			pwc->wmSetPixel = pwc->dither_flag ? &wmSetPixel1Dither : &wmSetPixel1;
1711			break;
1712		case 2:
1713			pwc->wmSetPixel = &wmSetPixel2;
1714			break;
1715		case 3:
1716			pwc->wmSetPixel = &wmSetPixel3;
1717			break;
1718		case 4:
1719			pwc->wmSetPixel = &wmSetPixel4;
1720			break;
1721		default:
1722			pwc->wmSetPixel = &wmSetPixelDefault;
1723			break;
1724	}
1725}
1726
1727#endif
1728
1729void  wmCreateDIBSection(
1730  HDC   hDC,
1731  PWMC pwc,    // handle of device context
1732  CONST BITMAPINFO *pbmi,  // bitmap size, format, and color data
1733  UINT iUsage  // color data type indicator: RGB values or palette indices
1734  )
1735{
1736  DWORD   dwSize = 0;
1737  DWORD   dwScanWidth;
1738  UINT    nBypp = pwc->cColorBits / 8;
1739  HDC     hic;
1740  (void) hDC;
1741  (void) pbmi;
1742
1743  dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
1744
1745  pwc->ScanWidth =pwc->pitch = dwScanWidth;
1746
1747  if (stereo_flag)
1748    pwc->ScanWidth = 2* pwc->pitch;
1749
1750  dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
1751#ifdef USE_MAPPED_FILE
1752  pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
1753					NULL,
1754					PAGE_READWRITE | SEC_COMMIT,
1755					0,
1756					dwSize,
1757					NULL);
1758
1759  if (!pwc->dib.hFileMap)
1760    return;
1761
1762  pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
1763				FILE_MAP_ALL_ACCESS,
1764				0,
1765				0,
1766				0);
1767
1768  if(!pwc->dib.base){
1769    CloseHandle(pwc->dib.hFileMap);
1770    return;
1771  }
1772
1773
1774  CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
1775#endif // USE_MAPPED_FILE
1776
1777  hic = CreateIC("display", NULL, NULL, NULL);
1778  pwc->dib.hDC = CreateCompatibleDC(hic);
1779
1780#ifdef USE_MAPPED_FILE
1781
1782  pwc->hbmDIB = CreateDIBSection(hic,
1783				 &(pwc->bmi),
1784				 (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
1785				 (void **)&(pwc->pbPixels),
1786				 pwc->dib.hFileMap,
1787				 0);
1788#else
1789  pwc->hbmDIB = CreateDIBSection(hic,
1790				 &(pwc->bmi),
1791				 (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
1792				 (void **)&(pwc->pbPixels),
1793				 0,
1794				 0);
1795#endif // USE_MAPPED_FILE
1796  pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;
1797  pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
1798
1799  DeleteDC(hic);
1800
1801  return;
1802
1803}
1804
1805/*
1806 * Blit memory DC to screen DC
1807 */
1808BOOL wmFlush(PWMC pwc)
1809{
1810  BOOL    bRet = 0;
1811/*  DWORD   dwErr = 0;*/
1812#ifdef DDRAW
1813  HRESULT             ddrval;
1814#endif
1815
1816  if(pwc->db_flag){
1817#ifdef DDRAW
1818    if (pwc->lpDDSOffScreen == NULL)
1819      if(DDCreateOffScreen(pwc) == GL_FALSE)
1820	return FALSE;
1821
1822    pwc->lpDDSOffScreen->lpVtbl->Unlock(pwc->lpDDSOffScreen, NULL);
1823
1824    while( 1 )
1825      {
1826	ddrval = pwc->lpDDSPrimary->lpVtbl->Blt( pwc->lpDDSPrimary,
1827						 &(pwc->rectSurface),
1828						 pwc->lpDDSOffScreen,
1829						 &(pwc->rectOffScreen),
1830						 0, NULL );
1831
1832	if( ddrval == DD_OK )
1833	  {
1834	    break;
1835	  }
1836	if( ddrval == DDERR_SURFACELOST )
1837	  {
1838	    if(!DDRestoreAll(pwc))
1839	      {
1840		break;
1841	      }
1842	  }
1843	if( ddrval != DDERR_WASSTILLDRAWING )
1844	  {
1845	    break;
1846	  }
1847      }
1848
1849    while (pwc->lpDDSOffScreen->lpVtbl->Lock(pwc->lpDDSOffScreen,
1850					     NULL, &(pwc->ddsd), 0, NULL) ==
1851	   DDERR_WASSTILLDRAWING)
1852      ;
1853
1854    if(ddrval != DD_OK)
1855      dwErr = GetLastError();
1856#else
1857    bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,
1858		  pwc->dib.hDC, 0, 0, SRCCOPY);
1859#endif
1860  }
1861
1862  return(TRUE);
1863
1864}
1865
1866
1867/* The following code is added by Li Wei to enable stereo display */
1868
1869#if !defined(NO_STEREO)
1870
1871static void __gluMakeIdentityf(GLfloat m[16])
1872{
1873    m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
1874    m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
1875    m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
1876    m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
1877}
1878
1879static void normalize(float v[3])
1880{
1881    float r;
1882
1883    r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
1884    if (r == 0.0) return;
1885
1886    v[0] /= r;
1887    v[1] /= r;
1888    v[2] /= r;
1889}
1890
1891static void cross(float v1[3], float v2[3], float result[3])
1892{
1893    result[0] = v1[1]*v2[2] - v1[2]*v2[1];
1894    result[1] = v1[2]*v2[0] - v1[0]*v2[2];
1895    result[2] = v1[0]*v2[1] - v1[1]*v2[0];
1896}
1897
1898
1899static void
1900__gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
1901	  GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
1902	  GLdouble upz)
1903{
1904    int i;
1905    float forward[3], side[3], up[3];
1906    GLfloat m[4][4];
1907
1908    forward[0] = centerx - eyex;
1909    forward[1] = centery - eyey;
1910    forward[2] = centerz - eyez;
1911
1912    up[0] = upx;
1913    up[1] = upy;
1914    up[2] = upz;
1915
1916    normalize(forward);
1917
1918    /* Side = forward x up */
1919    cross(forward, up, side);
1920    normalize(side);
1921
1922    /* Recompute up as: up = side x forward */
1923    cross(side, forward, up);
1924
1925    __gluMakeIdentityf(&m[0][0]);
1926    m[0][0] = side[0];
1927    m[1][0] = side[1];
1928    m[2][0] = side[2];
1929
1930    m[0][1] = up[0];
1931    m[1][1] = up[1];
1932    m[2][1] = up[2];
1933
1934    m[0][2] = -forward[0];
1935    m[1][2] = -forward[1];
1936    m[2][2] = -forward[2];
1937
1938    glMultMatrixf(&m[0][0]);
1939    glTranslated(-eyex, -eyey, -eyez);
1940}
1941
1942GLfloat viewDistance = 1.0;
1943
1944void WMesaShowStereo(GLuint list)
1945{
1946
1947  GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
1948  GLfloat cm[16];
1949  GLint matrix_mode;
1950  /* Must use double Buffer */
1951  if( ! Current-> db_flag )
1952    return;
1953
1954
1955  glGetIntegerv(GL_MATRIX_MODE,&matrix_mode);
1956
1957  WMesaViewport(Current->gl_ctx,0,Current->height/2,
1958		Current->width,Current->height/2);
1959  if(matrix_mode!=GL_MODELVIEW)
1960    glMatrixMode(GL_MODELVIEW);
1961
1962  glGetFloatv(GL_MODELVIEW_MATRIX,cm);
1963  glLoadIdentity();
1964  __gluLookAt(viewDistance/2,0.0,0.0 ,
1965	    viewDistance/2,0.0,-1.0,
1966	    0.0,1.0,0.0 );
1967  glMultMatrixf( cm );
1968
1969  Current->ScreenMem = Current->pbPixels = Current->addrOffScreen;
1970  glCallList( list );
1971
1972  glGetFloatv(GL_MODELVIEW_MATRIX,cm);
1973  glLoadIdentity();
1974  __gluLookAt(-viewDistance/2,0.0,0.0 ,
1975	    -viewDistance/2,0.0,-1.0,
1976	    0.0,1.0,0.0 );
1977  glMultMatrixf(cm);
1978
1979  Current->ScreenMem = Current->pbPixels = Current->addrOffScreen + Current->pitch;
1980  glCallList(list);
1981  if(matrix_mode!=GL_MODELVIEW)
1982    glMatrixMode(matrix_mode);
1983
1984  glFlush();
1985
1986  WMesaViewport(Current->gl_ctx,0,0,Current->width,Current->height);
1987  WMesaSwapBuffers();
1988}
1989
1990void toggleStereoMode()
1991{
1992  if(!Current->db_flag)
1993    return;
1994  if(!stereo_flag){
1995    stereo_flag = 1;
1996    if(stereoBuffer==GL_FALSE)
1997#if !defined(NO_PARALLEL)
1998      if(!parallelFlag)
1999#endif
2000	{
2001	  Current->ScanWidth = Current->pitch*2;
2002	}
2003  }
2004  else {
2005    stereo_flag = 0;
2006#if !defined(NO_PARALLEL)
2007    if(!parallelFlag)
2008#endif
2009      Current->ScanWidth = Current->pitch;
2010    Current->pbPixels = Current->addrOffScreen;
2011  }
2012}
2013
2014/* if in stereo mode, the following function is called */
2015void glShowStereo(GLuint list)
2016{
2017  WMesaShowStereo(list);
2018}
2019
2020#endif /* NO_STEREO */
2021
2022#if !defined(NO_PARALLEL)
2023
2024void toggleParallelMode(void)
2025{
2026  if(!parallelFlag){
2027    parallelFlag = GL_TRUE;
2028    if(parallelMachine==GL_FALSE){
2029      PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
2030			    Current->cColorBits/8,
2031			    Current->width ,Current->height,
2032			    Current->ScanWidth,
2033			    Current->rgb_flag? Current->pbPixels:
2034			    Current->ScreenMem);
2035      parallelMachine = GL_TRUE;
2036    }
2037  }
2038  else {
2039    parallelFlag = GL_FALSE;
2040    if(parallelMachine==GL_TRUE){
2041      PRDestroyRenderBuffer();
2042      parallelMachine=GL_FALSE;
2043      ReadyForNextFrame = GL_TRUE;
2044    }
2045
2046    /***********************************************
2047     * Seems something wrong!!!!
2048     ************************************************/
2049
2050    WMesaMakeCurrent(Current);
2051#if !defined(NO_STEREO)
2052    stereo_flag = GL_FALSE ;
2053#endif
2054  }
2055}
2056
2057void PRShowRenderResult(void)
2058{
2059  int flag = 0;
2060  if(!glImageRendered())
2061    return;
2062
2063  if (parallelFlag)
2064    {
2065      WMesaSwapBuffers();
2066    }
2067
2068}
2069#endif /* NO_PARALLEL */
2070
2071BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)
2072{
2073  char unsigned redtemp, greentemp, bluetemp, paletteindex;
2074
2075  //*** now, look up each value in the halftone matrix
2076  //*** using an 8x8 ordered dither.
2077  redtemp = aDividedBy51[red]
2078    + (aModulo51[red] > aHalftone8x8[(pixel%8)*8
2079				    + scanline%8]);
2080  greentemp = aDividedBy51[(char unsigned)green]
2081    + (aModulo51[green] > aHalftone8x8[
2082      (pixel%8)*8 + scanline%8]);
2083  bluetemp = aDividedBy51[(char unsigned)blue]
2084    + (aModulo51[blue] > aHalftone8x8[
2085      (pixel%8)*8 +scanline%8]);
2086
2087  //*** recombine the halftoned rgb values into a palette index
2088  paletteindex =
2089    redtemp + aTimes6[greentemp] + aTimes36[bluetemp];
2090
2091  //*** and translate through the wing halftone palette
2092  //*** translation vector to give the correct value.
2093  return aWinGHalftoneTranslation[paletteindex];
2094}
2095
2096#ifdef DDRAW
2097/*
2098 * restoreAll
2099 *
2100 * restore all lost objects
2101 */
2102HRESULT DDRestoreAll( WMesaContext wc )
2103{
2104  HRESULT     ddrval;
2105
2106  ddrval = wc->lpDDSPrimary->lpVtbl->Restore(wc->lpDDSPrimary);
2107  if( ddrval == DD_OK )
2108    {
2109      ddrval = wc->lpDDSOffScreen->lpVtbl->Restore(wc->lpDDSOffScreen);
2110    }
2111  return ddrval;
2112
2113} /* restoreAll */
2114
2115
2116/*
2117 * This function is called if the initialization function fails
2118 */
2119BOOL initFail( HWND hwnd, WMesaContext wc )
2120{
2121  DDFree(wc);
2122  MessageBox( hwnd, "DirectDraw Init FAILED", "", MB_OK );
2123  return FALSE;
2124
2125} /* initFail */
2126
2127
2128static void DDDeleteOffScreen(WMesaContext wc)
2129{
2130  if( wc->lpDDSOffScreen != NULL )
2131    {
2132      wc->lpDDSOffScreen->lpVtbl->Unlock(wc->lpDDSOffScreen,NULL);
2133      wc->lpDDSOffScreen->lpVtbl->Release(wc->lpDDSOffScreen);
2134      wc->lpDDSOffScreen = NULL;
2135    }
2136
2137}
2138
2139static void DDFreePrimarySurface(WMesaContext wc)
2140{
2141  if( wc->lpDDSPrimary != NULL )
2142    {
2143      if(wc->db_flag == GL_FALSE)
2144	wc->lpDDSPrimary->lpVtbl->ReleaseDC(wc->lpDDSPrimary, wc->hDC);
2145      wc->lpDDSPrimary->lpVtbl->Release(wc->lpDDSPrimary);
2146      wc->lpDDSPrimary = NULL;
2147    }
2148}
2149
2150static BOOL DDCreatePrimarySurface(WMesaContext wc)
2151{
2152  HRESULT ddrval;
2153//  DDSCAPS             ddscaps;
2154  wc->ddsd.dwSize = sizeof( wc->ddsd );
2155  wc->ddsd.dwFlags = DDSD_CAPS;
2156  wc->ddsd.ddsCaps.dwCaps =   DDSCAPS_PRIMARYSURFACE;
2157
2158  ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD,&(wc->ddsd),
2159					    &(wc->lpDDSPrimary), NULL );
2160  if( ddrval != DD_OK )
2161    {
2162      return initFail(wc->hwnd , wc);
2163    }
2164  if(wc->db_flag == GL_FALSE)
2165    wc->lpDDSPrimary->lpVtbl->GetDC(wc->lpDDSPrimary, &(wc->hDC));
2166  return TRUE;
2167}
2168
2169static BOOL DDCreateOffScreen(WMesaContext wc)
2170{
2171  POINT   pt;
2172  HRESULT     ddrval;
2173  if(wc->lpDD == NULL)
2174    return FALSE;
2175  GetClientRect( wc->hwnd, &(wc->rectOffScreen) );
2176  wc->ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2177  wc->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2178  wc->ddsd.dwHeight = wc->rectOffScreen.bottom - wc->rectOffScreen.top;
2179  wc->ddsd.dwWidth = wc->rectOffScreen.right - wc->rectOffScreen.left;
2180
2181  ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD, &(wc->ddsd),
2182					    &(wc->lpDDSOffScreen), NULL );
2183  if( ddrval != DD_OK )
2184    {
2185      return FALSE;
2186    }
2187
2188  while (wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL,
2189					  &(wc->ddsd), 0, NULL) ==
2190	 DDERR_WASSTILLDRAWING)
2191    ;
2192
2193  if(wc->ddsd.lpSurface==NULL)
2194    return initFail(wc->hwnd, wc);
2195
2196  wc->ScreenMem = wc->pbPixels = wc->addrOffScreen =
2197    (PBYTE)(wc->ddsd.lpSurface);
2198  wc->ScanWidth = wc->pitch = wc->ddsd.lPitch;
2199  if (stereo_flag)
2200    wc->ScanWidth = wc->ddsd.lPitch*2;
2201
2202  GetClientRect( wc->hwnd, &(wc->rectSurface) );
2203  pt.x = pt.y = 0;
2204  ClientToScreen( wc->hwnd, &pt );
2205  OffsetRect(&(wc->rectSurface), pt.x, pt.y);
2206  wmSetPixelFormat(wc, wc->hDC);
2207  return TRUE;
2208}
2209
2210typedef
2211struct tagWMesaContextList
2212{
2213	WMesaContext wc;
2214	struct tagWMesaContextList *next;
2215}WMesaContextList;
2216
2217WMesaContextList *head = 0;
2218
2219void AddContext(WMesaContext wc)
2220{
2221	WMesaContextList *lst = (WMesaContextList *)malloc(sizeof(WMesaContextList));
2222	lst->wc = wc;
2223	if( head )
2224		lst->next = head;
2225	head = lst;
2226}
2227
2228WMesaContext FindContext(HWND hWnd)
2229{
2230	WMesaContextList *tmp = head;
2231	while(tmp)
2232	{
2233		if( tmp->wc->hwnd == hWnd )
2234			return tmp->wc;
2235		tmp = tmp->next;
2236	}
2237	return NULL;
2238}
2239
2240void RemoveContext(HWND hWnd)
2241{
2242	WMesaContextList *tmp = head;
2243	if(tmp )
2244	{
2245		if( tmp->wc->hwnd == hWnd )
2246		{
2247			WMesaContextList *lst = tmp;
2248
2249			head = tmp->next;
2250			free((void *)lst);
2251		}
2252		else
2253			while(tmp->next)
2254			{
2255				if( tmp->next->wc->hwnd == hWnd )
2256				{
2257					WMesaContextList *lst = tmp->next;
2258					tmp->next = tmp->next->next;
2259					free((void *)lst);
2260				}
2261				tmp = tmp->next;
2262			}
2263	}
2264}
2265
2266static LRESULT CALLBACK MyWndProc(HWND hwnd,UINT message,WPARAM wParam, LPARAM lParam)
2267{
2268	WMesaContext wc;
2269
2270	if (Current==0 || Current->hwnd != hwnd)
2271		wc=FindContext(hwnd);
2272	else
2273		wc=Current;
2274
2275
2276	 if( wc )
2277	 {
2278		LRESULT lret = CallWindowProc((WNDPROC)(wc->oldWndProc),hwnd,message,wParam,lParam);
2279		if( message = WM_MOVE )
2280		{
2281			 POINT pt = {0};
2282			GetClientRect( wc->hwnd, &(wc->rectSurface) );
2283			ClientToScreen( hwnd, &pt );
2284			OffsetRect(&(wc->rectSurface), pt.x, pt.y);
2285		 }
2286		return lret;
2287	}
2288	 return 0L;
2289}
2290
2291/*
2292 * doInit - do work required for every instance of the application:
2293 *                create the window, initialize data
2294 */
2295static BOOL DDInit( WMesaContext wc, HWND hwnd)
2296{
2297  HRESULT             ddrval;
2298//  DWORD dwFrequency;
2299
2300//  LPDIRECTDRAW            lpDD;           // DirectDraw object
2301//  LPDIRECTDRAW2            lpDD2;
2302  LPDIRECTDRAWCLIPPER pcClipper = NULL;
2303
2304  wc->fullScreen = displayOptions.fullScreen;
2305  wc->gMode = displayOptions.mode;
2306  wc->hwnd = hwnd;
2307  stereo_flag = displayOptions.stereo;
2308  if(wc->db_flag!= GL_TRUE)
2309    stereo_flag = GL_FALSE;
2310  /*
2311   * create the main DirectDraw object
2312   */
2313  ddrval = DirectDrawCreate( NULL, &(wc->lpDD), NULL );
2314  if( ddrval != DD_OK )
2315    {
2316      return initFail(hwnd,wc);
2317    }
2318
2319  // Get exclusive mode if requested
2320  if(wc->fullScreen)
2321    {
2322      ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd,
2323						      DDSCL_EXCLUSIVE |
2324						      DDSCL_FULLSCREEN );
2325    }
2326  else
2327    {
2328      ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd,
2329						      DDSCL_NORMAL );
2330    }
2331  if( ddrval != DD_OK )
2332    {
2333      return initFail(hwnd , wc);
2334    }
2335
2336
2337  if(ddrval != DD_OK)
2338    return initFail(hwnd , wc);
2339
2340
2341  switch( wc->gMode )
2342    {
2343    case 1:
2344      ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 640, 480,
2345						 displayOptions.bpp);
2346      break;
2347    case 2:
2348      ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 800, 600,
2349						 displayOptions.bpp);
2350      break;
2351    case 3:
2352      ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1024, 768,
2353						 displayOptions.bpp);
2354      break;
2355    case 4:
2356      ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1152, 864,
2357						 displayOptions.bpp);
2358      break;
2359    case 5:
2360      ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1280, 1024,
2361						 displayOptions.bpp);
2362      break;
2363    }
2364
2365  if( ddrval != DD_OK )
2366    {
2367      printf("Can't modify display mode, current mode used\n");
2368    }
2369  switch(ddrval){
2370  case DDERR_INVALIDOBJECT:
2371    break;
2372  case DDERR_INVALIDPARAMS:
2373    break;
2374  case DDERR_UNSUPPORTEDMODE:
2375    ;
2376  }
2377
2378  if(DDCreatePrimarySurface(wc) == GL_FALSE)
2379    return initFail(hwnd, wc);
2380
2381  if(wc->db_flag)
2382    DDCreateOffScreen(wc);
2383
2384    if( FAILED( ddrval = wc->lpDD->lpVtbl->CreateClipper(wc->lpDD, 0, &pcClipper, NULL ) ) )
2385        return E_FAIL;
2386
2387    if( FAILED( ddrval = pcClipper->lpVtbl->SetHWnd(pcClipper,  0, wc->hwnd ) ) )
2388    {
2389        pcClipper->lpVtbl->Release(pcClipper);
2390        return E_FAIL;
2391    }
2392
2393    if( FAILED( ddrval = wc->lpDDSPrimary->lpVtbl->SetClipper(wc->lpDDSPrimary,  pcClipper ) ) )
2394    {
2395        pcClipper->lpVtbl->Release(pcClipper);
2396        return E_FAIL;
2397    }
2398
2399    // Done with clipper
2400    pcClipper->lpVtbl->Release(pcClipper);
2401	AddContext(wc);
2402	// Hook the window so we can update the drawing rectangle when the window moves
2403	wc->oldWndProc = SetWindowLong(wc->hwnd,GWL_WNDPROC,(LONG)MyWndProc);
2404
2405	return TRUE;
2406
2407} /* DDInit */
2408
2409static void DDFree( WMesaContext wc)
2410{
2411  RemoveContext(wc->hwnd);
2412  SetWindowLong(wc->hwnd,GWL_WNDPROC,(LONG)(wc->oldWndProc));
2413  wc->oldWndProc = 0;
2414  if( wc->lpDD != NULL )
2415    {
2416      DDFreePrimarySurface(wc);
2417      DDDeleteOffScreen(wc);
2418      wc->lpDD->lpVtbl->Release(wc->lpDD);
2419      wc->lpDD = NULL;
2420    }
2421  // Clean up the screen on exit
2422  RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
2423		RDW_ALLCHILDREN );
2424
2425}
2426#endif
2427
2428void WMesaMove(void)
2429{
2430  WMesaContext wc = Current;
2431  POINT   pt;
2432  if (Current != NULL){
2433    GetClientRect( wc->hwnd, &(wc->rectSurface) );
2434    pt.x = pt.y = 0;
2435    ClientToScreen( wc->hwnd, &pt );
2436    OffsetRect(&(wc->rectSurface), pt.x, pt.y);
2437  }
2438}
2439
2440
2441/************************************************
2442 * Mesa 4.0 - These triangle rasterizers are not
2443 * implemented in this version of the Windows
2444 * driver.  They could be implemented for a
2445 * potential performance improvement.
2446 * See OSMesa for an example of the approach
2447 * to use.
2448 * This old code is left in this file in case
2449 * it is useful.  However, it may end up looking
2450 * a lot more like the OSMesa code.
2451 ************************************************/
2452
2453
2454#if defined(FAST_RASTERIZERS)
2455
2456
2457/*
2458 * Like PACK_8A8B8G8R() but don't use alpha.  This is usually an acceptable
2459 * shortcut.
2460 */
2461#define PACK_8B8G8R( R, G, B )   ( ((B) << 16) | ((G) << 8) | (R) )
2462
2463/**********************************************************************/
2464/***                   Triangle rendering                            ***/
2465/**********************************************************************/
2466
2467/*
2468 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2469 */
2470static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx,
2471                                       GLuint v0, GLuint v1, GLuint v2,
2472                                       GLuint pv )
2473{
2474    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2475#define INTERP_Z 1
2476#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
2477#define INTERP_RGB 1
2478#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2479#define PIXEL_TYPE GLuint
2480    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2481#define BYTES_PER_ROW (wmesa->ScanWidth)
2482#define INNER_LOOP( LEFT, RIGHT, Y )                    \
2483    {                                   \
2484    GLint i, len = RIGHT-LEFT;                      \
2485    for (i=0;i<len;i++) {                       \
2486    GLdepth z = FixedToDepth(ffz);                  \
2487    if (z < zRow[i]) {                      \
2488    pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),    \
2489    FixedToInt(ffb) );          \
2490    zRow[i] = z;                            \
2491    }                                   \
2492    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
2493    ffz += fdzdx;                           \
2494    }                                   \
2495    }
2496
2497#ifdef __MINGW32__
2498	#include "tritemp.h"
2499#else
2500
2501	#ifdef WIN32
2502//		#include "..\tritemp.h"
2503	#else
2504		#include "tritemp.h"
2505	#endif
2506#endif
2507}
2508
2509
2510/*
2511* XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2512*/
2513static void smooth_8R8G8B_z_triangle( GLcontext *ctx,
2514                                     GLuint v0, GLuint v1, GLuint v2,
2515                                     GLuint pv )
2516{
2517    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2518#define INTERP_Z 1
2519#define INTERP_RGB 1
2520#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2521#define PIXEL_TYPE GLuint
2522    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2523#define BYTES_PER_ROW (wmesa->ScanWidth)
2524#define INNER_LOOP( LEFT, RIGHT, Y )                    \
2525    {                                   \
2526    GLint i, len = RIGHT-LEFT;                      \
2527    for (i=0;i<len;i++) {                       \
2528    GLdepth z = FixedToDepth(ffz);                  \
2529    if (z < zRow[i]) {                      \
2530    pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),    \
2531    FixedToInt(ffb) );          \
2532    zRow[i] = z;                            \
2533    }                                   \
2534    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
2535    ffz += fdzdx;                           \
2536    }                                   \
2537    }
2538#ifdef __MINGW32__
2539	#include "tritemp.h"
2540#else
2541
2542	#ifdef WIN32
2543//		#include "..\tritemp.h"
2544	#else
2545		#include "tritemp.h"
2546	#endif
2547#endif
2548}
2549
2550
2551
2552/*
2553* XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2554*/
2555static void smooth_5R6G5B_z_triangle( GLcontext *ctx,
2556                                     GLuint v0, GLuint v1, GLuint v2,
2557                                     GLuint pv )
2558{
2559    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2560#define INTERP_Z 1
2561#define INTERP_RGB 1
2562#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2563#define PIXEL_TYPE GLushort
2564    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2565#define BYTES_PER_ROW (wmesa->ScanWidth)
2566#define INNER_LOOP( LEFT, RIGHT, Y )                    \
2567    {                                   \
2568    GLint i, len = RIGHT-LEFT;                      \
2569    for (i=0;i<len;i++) {                       \
2570    GLdepth z = FixedToDepth(ffz);                  \
2571    if (z < zRow[i]) {                      \
2572    pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),    \
2573    FixedToInt(ffb) );          \
2574    zRow[i] = z;                            \
2575    }                                   \
2576    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
2577    ffz += fdzdx;                           \
2578    }                                   \
2579    }
2580#ifdef __MINGW32__
2581	#include "tritemp.h"
2582#else
2583
2584	#ifdef WIN32
2585//		#include "..\tritemp.h"
2586	#else
2587		#include "tritemp.h"
2588	#endif
2589#endif
2590}
2591
2592/*
2593* XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2594*/
2595static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0,
2596                                     GLuint v1, GLuint v2, GLuint pv )
2597{
2598    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2599#define INTERP_Z 1
2600#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2601#define PIXEL_TYPE GLuint
2602    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2603#define BYTES_PER_ROW (wmesa->ScanWidth)
2604#define SETUP_CODE                  \
2605    unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0],    \
2606    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2607#define INNER_LOOP( LEFT, RIGHT, Y )                    \
2608    {                                   \
2609    GLint i, len = RIGHT-LEFT;                      \
2610    for (i=0;i<len;i++) {                       \
2611    GLdepth z = FixedToDepth(ffz);                  \
2612    if (z < zRow[i]) {                      \
2613    pRow[i] = p;                            \
2614    zRow[i] = z;                            \
2615    }                                   \
2616    ffz += fdzdx;                           \
2617    }                                   \
2618    }
2619#ifdef __MINGW32__
2620	#include "tritemp.h"
2621#else
2622
2623	#ifdef WIN32
2624//		#include "..\tritemp.h"
2625	#else
2626		#include "tritemp.h"
2627	#endif
2628#endif
2629}
2630
2631
2632/*
2633* XImage, flat, depth-buffered, PF_8R8G8B triangle.
2634*/
2635static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2636                                   GLuint v2, GLuint pv )
2637{
2638    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2639#define INTERP_Z 1
2640#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2641#define PIXEL_TYPE GLuint
2642    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2643#define BYTES_PER_ROW (wmesa->ScanWidth)
2644#define SETUP_CODE                  \
2645    unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0],    \
2646    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2647#define INNER_LOOP( LEFT, RIGHT, Y )            \
2648    {                           \
2649    GLint i, len = RIGHT-LEFT;              \
2650    for (i=0;i<len;i++) {               \
2651    GLdepth z = FixedToDepth(ffz);          \
2652    if (z < zRow[i]) {              \
2653    pRow[i] = p;                    \
2654    zRow[i] = z;                    \
2655    }                           \
2656    ffz += fdzdx;                   \
2657    }                           \
2658    }
2659#ifdef __MINGW32__
2660	#include "tritemp.h"
2661#else
2662
2663	#ifdef WIN32
2664//		#include "..\tritemp.h"
2665	#else
2666		#include "tritemp.h"
2667	#endif
2668#endif
2669}
2670
2671
2672/*
2673* XImage, flat, depth-buffered, PF_5R6G5B triangle.
2674*/
2675static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2676                                   GLuint v2, GLuint pv )
2677{
2678    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2679#define INTERP_Z 1
2680#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2681#define PIXEL_TYPE GLushort
2682    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2683#define BYTES_PER_ROW (wmesa->ScanWidth)
2684#define SETUP_CODE                  \
2685    unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0],    \
2686    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2687#define INNER_LOOP( LEFT, RIGHT, Y )            \
2688    {                           \
2689    GLint i, len = RIGHT-LEFT;              \
2690    for (i=0;i<len;i++) {               \
2691    GLdepth z = FixedToDepth(ffz);          \
2692    if (z < zRow[i]) {              \
2693    pRow[i] = p;                    \
2694    zRow[i] = z;                    \
2695    }                           \
2696    ffz += fdzdx;                   \
2697    }                           \
2698    }
2699#ifdef __MINGW32__
2700	#include "tritemp.h"
2701#else
2702
2703	#ifdef WIN32
2704//		#include "..\tritemp.h"
2705	#else
2706		#include "tritemp.h"
2707	#endif
2708#endif
2709}
2710
2711
2712/*
2713* XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2714*/
2715static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2716                                     GLuint v2, GLuint pv )
2717{
2718    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2719#define INTERP_RGB 1
2720#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2721#define PIXEL_TYPE GLuint
2722    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2723#define BYTES_PER_ROW (wmesa->ScanWidth)
2724#define INNER_LOOP( LEFT, RIGHT, Y )                    \
2725    {                                   \
2726    GLint xx;                               \
2727    PIXEL_TYPE *pixel = pRow;                       \
2728    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
2729    *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),     \
2730                FixedToInt(ffb) );          \
2731                ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
2732    }                                   \
2733    }
2734#ifdef __MINGW32__
2735	#include "tritemp.h"
2736#else
2737
2738	#ifdef WIN32
2739//		#include "..\tritemp.h"
2740	#else
2741		#include "tritemp.h"
2742	#endif
2743#endif
2744}
2745
2746
2747/*
2748* XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2749*/
2750static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2751                                   GLuint v2, GLuint pv )
2752{
2753    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2754#define INTERP_RGB 1
2755#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2756#define PIXEL_TYPE GLuint
2757    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2758#define BYTES_PER_ROW (wmesa->ScanWidth)
2759#define INNER_LOOP( LEFT, RIGHT, Y )                    \
2760    {                                   \
2761    GLint xx;                               \
2762    PIXEL_TYPE *pixel = pRow;                       \
2763    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
2764    *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),     \
2765                FixedToInt(ffb) );          \
2766                ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
2767    }                                   \
2768    }
2769#ifdef __MINGW32__
2770	#include "tritemp.h"
2771#else
2772
2773	#ifdef WIN32
2774//		#include "..\tritemp.h"
2775	#else
2776		#include "tritemp.h"
2777	#endif
2778#endif
2779}
2780
2781
2782/*
2783* XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2784*/
2785static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2786                                   GLuint v2, GLuint pv )
2787{
2788    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2789#define INTERP_RGB 1
2790#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2791#define PIXEL_TYPE GLushort
2792    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2793#define BYTES_PER_ROW (wmesa->ScanWidth)
2794#define INNER_LOOP( LEFT, RIGHT, Y )                    \
2795    {                                   \
2796    GLint xx;                               \
2797    PIXEL_TYPE *pixel = pRow;                       \
2798    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
2799    *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),     \
2800                FixedToInt(ffb) );          \
2801                ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
2802    }                                   \
2803    }
2804#ifdef __MINGW32__
2805	#include "tritemp.h"
2806#else
2807
2808	#ifdef WIN32
2809//		#include "..\tritemp.h"
2810	#else
2811		#include "tritemp.h"
2812	#endif
2813#endif
2814}
2815
2816
2817
2818/*
2819* XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2820*/
2821static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0,
2822                                   GLuint v1, GLuint v2, GLuint pv )
2823{
2824    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2825#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2826#define PIXEL_TYPE GLuint
2827    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2828#define BYTES_PER_ROW (wmesa->ScanWidth)
2829#define SETUP_CODE                  \
2830    unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0],    \
2831    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2832#define INNER_LOOP( LEFT, RIGHT, Y )            \
2833    {                           \
2834    GLint xx;                       \
2835    PIXEL_TYPE *pixel = pRow;               \
2836    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
2837    *pixel = p;                 \
2838    }                           \
2839    }
2840
2841#ifdef __MINGW32__
2842	#include "tritemp.h"
2843#else
2844
2845	#ifdef WIN32
2846//		#include "..\tritemp.h"
2847	#else
2848		#include "tritemp.h"
2849	#endif
2850#endif
2851}
2852
2853
2854/*
2855* XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2856*/
2857static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2858                                 GLuint v2, GLuint pv )
2859{
2860    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2861#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2862#define PIXEL_TYPE GLuint
2863    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2864#define BYTES_PER_ROW (wmesa->ScanWidth)
2865#define SETUP_CODE                  \
2866    unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0],    \
2867    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2868#define INNER_LOOP( LEFT, RIGHT, Y )            \
2869    {                           \
2870    GLint xx;                       \
2871    PIXEL_TYPE *pixel = pRow;               \
2872    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
2873    *pixel = p;                 \
2874    }                           \
2875    }
2876#ifdef __MINGW32__
2877	#include "tritemp.h"
2878#else
2879
2880	#ifdef WIN32
2881//		#include "..\tritemp.h"
2882	#else
2883		#include "tritemp.h"
2884	#endif
2885#endif
2886}
2887
2888
2889/*
2890* XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2891*/
2892static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2893                                 GLuint v2, GLuint pv )
2894{
2895    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2896#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2897#define PIXEL_TYPE GLushort
2898    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2899#define BYTES_PER_ROW (wmesa->ScanWidth)
2900#define SETUP_CODE                  \
2901    unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0],    \
2902    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
2903#define INNER_LOOP( LEFT, RIGHT, Y )            \
2904    {                           \
2905    GLint xx;                       \
2906    PIXEL_TYPE *pixel = pRow;               \
2907    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
2908    *pixel = p;                 \
2909    }                           \
2910    }
2911#ifdef __MINGW32__
2912	#include "tritemp.h"
2913#else
2914
2915	#ifdef WIN32
2916//		#include "..\tritemp.h"
2917	#else
2918		#include "tritemp.h"
2919	#endif
2920#endif
2921}
2922
2923
2924/*
2925* XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2926*/
2927
2928static void smooth_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2929                                 GLuint v2, GLuint pv )
2930{
2931    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2932#define INTERP_Z 1
2933#define INTERP_INDEX 1
2934#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2935#define PIXEL_TYPE GLubyte
2936#define BYTES_PER_ROW (wmesa->ScanWidth)
2937#define INNER_LOOP( LEFT, RIGHT, Y )                                \
2938    {                                                                   \
2939    GLint i, len = RIGHT-LEFT;                                      \
2940    for (i=0;i<len;i++) {                                           \
2941    GLdepth z = FixedToDepth(ffz);                              \
2942    if (z < zRow[i]) {                                          \
2943    pRow[i] = FixedToInt(ffi);                                  \
2944    zRow[i] = z;                                                \
2945    }                                                               \
2946    ffi += fdidx;                                                   \
2947    ffz += fdzdx;                                                   \
2948    }                                                               \
2949    }
2950#ifdef __MINGW32__
2951	#include "tritemp.h"
2952#else
2953
2954	#ifdef WIN32
2955//		#include "..\tritemp.h"
2956	#else
2957		#include "tritemp.h"
2958	#endif
2959#endif
2960}
2961
2962
2963/*
2964* XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2965*/
2966
2967static void flat_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2968                               GLuint v2, GLuint pv )
2969{
2970    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2971#define INTERP_Z 1
2972#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2973#define PIXEL_TYPE GLubyte
2974#define BYTES_PER_ROW (wmesa->ScanWidth)
2975#define SETUP_CODE			\
2976   GLuint index = VB->IndexPtr->data[pv];	\
2977   (*ctx->Driver.Index)( ctx, index );
2978#define INNER_LOOP( LEFT, RIGHT, Y )	\
2979   {					\
2980      GLint i, len = RIGHT-LEFT;	\
2981      for (i=0;i<len;i++) {		\
2982         GLdepth z = FixedToDepth(ffz);	\
2983         if (z < zRow[i]) {		\
2984            pRow[i] = index;		\
2985            zRow[i] = z;		\
2986         }				\
2987         ffz += fdzdx;			\
2988      }					\
2989   }
2990#ifdef __MINGW32__
2991	#include "tritemp.h"
2992#else
2993
2994	#ifdef WIN32
2995//		#include "..\tritemp.h"
2996	#else
2997		#include "tritemp.h"
2998	#endif
2999#endif
3000}
3001
3002
3003
3004/*
3005* XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
3006*/
3007
3008static void smooth_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
3009                               GLuint v2, GLuint pv )
3010{
3011    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3012#define INTERP_Z 1
3013#define INTERP_INDEX 1
3014#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3015#define PIXEL_TYPE GLubyte
3016#define BYTES_PER_ROW (wmesa->ScanWidth)
3017#define INNER_LOOP( LEFT, RIGHT, Y )                    \
3018    {                                   \
3019    GLint xx;                               \
3020    PIXEL_TYPE *pixel = pRow;                       \
3021    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
3022    *pixel = FixedToInt(ffi);           \
3023    ffi += fdidx;           \
3024    }                                   \
3025    }
3026#ifdef __MINGW32__
3027	#include "tritemp.h"
3028#else
3029
3030	#ifdef WIN32
3031//		#include "..\tritemp.h"
3032	#else
3033		#include "tritemp.h"
3034	#endif
3035#endif
3036}
3037
3038
3039/*
3040* XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
3041*/
3042static void flat_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
3043                             GLuint v2, GLuint pv )
3044{
3045    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3046#define INTERP_Z 1
3047#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3048#define PIXEL_TYPE GLubyte
3049#define BYTES_PER_ROW (wmesa->ScanWidth)
3050#define SETUP_CODE			\
3051   GLuint index = VB->IndexPtr->data[pv];	\
3052   (*ctx->Driver.Index)( ctx, index );
3053#define INNER_LOOP( LEFT, RIGHT, Y )		\
3054   {						\
3055      GLint xx;					\
3056      PIXEL_TYPE *pixel = pRow;			\
3057      for (xx=LEFT;xx<RIGHT;xx++,pixel++) {	\
3058         *pixel = index;			\
3059      }						\
3060   }
3061#ifdef __MINGW32__
3062	#include "tritemp.h"
3063#else
3064
3065	#ifdef WIN32
3066//		#include "..\tritemp.h"
3067	#else
3068		#include "tritemp.h"
3069	#endif
3070#endif
3071}
3072
3073/*
3074* XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
3075*/
3076static void smooth_DITHER8_z_triangle( GLcontext *ctx,
3077                                      GLuint v0, GLuint v1, GLuint v2,
3078                                      GLuint pv )
3079{
3080    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3081    DITHER_RGB_TO_8BIT_SETUP
3082#define INTERP_Z 1
3083#define INTERP_RGB 1
3084#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3085#define PIXEL_TYPE GLubyte
3086#define BYTES_PER_ROW (wmesa->ScanWidth)
3087#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
3088    {                                                                       \
3089    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                 \
3090    for (i=0;i<len;i++,xx++) {                                          \
3091    GLdepth z = FixedToDepth(ffz);                                  \
3092    if (z < zRow[i]) {                                              \
3093    DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg),           \
3094    FixedToInt(ffb), xx, yy);               \
3095    pRow[i] = pixelDithered;                                        \
3096    zRow[i] = z;                                                    \
3097    }                                                                   \
3098    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                     \
3099    ffz += fdzdx;                                                       \
3100    }                                                                   \
3101    }
3102#ifdef __MINGW32__
3103	#include "tritemp.h"
3104#else
3105
3106	#ifdef WIN32
3107//		#include "..\tritemp.h"
3108	#else
3109		#include "tritemp.h"
3110	#endif
3111#endif
3112}
3113
3114/*
3115* XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
3116*/
3117static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
3118                                    GLuint v2, GLuint pv )
3119{
3120    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3121    DITHER_RGB_TO_8BIT_SETUP
3122#define INTERP_Z 1
3123#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3124#define PIXEL_TYPE GLubyte
3125#define BYTES_PER_ROW (wmesa->ScanWidth)
3126
3127#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
3128    {                                                                       \
3129    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                 \
3130    for (i=0;i<len;i++,xx++) {                                          \
3131    GLdepth z = FixedToDepth(ffz);                                  \
3132    if (z < zRow[i]) {                                              \
3133    DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0],                           \
3134             VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);               \
3135             pRow[i] = pixelDithered;                                       \
3136             zRow[i] = z;                                                   \
3137    }                                                                   \
3138    ffz += fdzdx;                                                       \
3139    }                                                                   \
3140    }
3141#ifdef __MINGW32__
3142	#include "tritemp.h"
3143#else
3144
3145	#ifdef WIN32
3146//		#include "..\tritemp.h"
3147	#else
3148		#include "tritemp.h"
3149	#endif
3150#endif
3151}
3152
3153/*
3154* XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
3155*/
3156static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
3157                                    GLuint v2, GLuint pv )
3158{
3159    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3160    DITHER_RGB_TO_8BIT_SETUP
3161#define INTERP_RGB 1
3162#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3163#define PIXEL_TYPE GLubyte
3164#define BYTES_PER_ROW (wmesa->ScanWidth)
3165#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
3166    {                                                                       \
3167    GLint xx, yy = FLIP(Y);                                             \
3168    PIXEL_TYPE *pixel = pRow;                                           \
3169    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \
3170    DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0],   VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
3171    *pixel = pixelDithered;                                         \
3172    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                     \
3173    }                                                                   \
3174    }
3175#ifdef __MINGW32__
3176	#include "tritemp.h"
3177#else
3178
3179	#ifdef WIN32
3180//		#include "..\tritemp.h"
3181	#else
3182		#include "tritemp.h"
3183	#endif
3184#endif
3185}
3186
3187/*
3188* XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
3189*/
3190
3191static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
3192                                  GLuint v2, GLuint pv )
3193{
3194    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3195    DITHER_RGB_TO_8BIT_SETUP
3196#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
3197#define PIXEL_TYPE GLubyte
3198#define BYTES_PER_ROW (wmesa->ScanWidth)
3199
3200#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
3201    {                                                                       \
3202    GLint xx, yy = FLIP(Y);                                             \
3203    PIXEL_TYPE *pixel = pRow;                                           \
3204    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \
3205    DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0],                               \
3206             VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);               \
3207             *pixel = pixelDithered;                                            \
3208    }                                                                   \
3209    }
3210#ifdef __MINGW32__
3211	#include "tritemp.h"
3212#else
3213
3214	#ifdef WIN32
3215//		#include "..\tritemp.h"
3216	#else
3217		#include "tritemp.h"
3218	#endif
3219#endif
3220}
3221
3222#endif
3223/************** END DEAD TRIANGLE CODE ***********************/
3224
3225#if 0 /* unused */
3226
3227static tnl_triangle_func choose_triangle_function( GLcontext *ctx )
3228{
3229    (void) ctx;
3230#if 0
3231    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
3232    int depth = wmesa->cColorBits;
3233
3234    if (ctx->Polygon.SmoothFlag)     return NULL;
3235    if (ctx->Texture._EnabledUnits)  return NULL;
3236    if (!wmesa->db_flag) return NULL;
3237    if (ctx->swrast->_RasterMask & MULTI_DRAW_BIT) return NULL;
3238
3239    /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
3240    if (   ctx->Light.ShadeModel==GL_SMOOTH
3241        && ctx->_RasterMask==DEPTH_BIT
3242        && ctx->Depth.Func==GL_LESS
3243        && ctx->Depth.Mask==GL_TRUE
3244        && ctx->Polygon.StippleFlag==GL_FALSE) {
3245        switch (wmesa->pixelformat) {
3246        case PF_8A8B8G8R:
3247            return smooth_8A8B8G8R_z_triangle;
3248        case PF_8R8G8B:
3249            return smooth_8R8G8B_z_triangle;
3250        case PF_5R6G5B:
3251            return smooth_5R6G5B_z_triangle;
3252        case PF_DITHER8:
3253            return  smooth_DITHER8_z_triangle;
3254        case PF_INDEX8:
3255            return smooth_ci_z_triangle;
3256        default:
3257            return NULL;
3258        }
3259    }
3260    if (   ctx->Light.ShadeModel==GL_FLAT
3261        && ctx->_RasterMask==DEPTH_BIT
3262        && ctx->Depth.Func==GL_LESS
3263        && ctx->Depth.Mask==GL_TRUE
3264        && ctx->Polygon.StippleFlag==GL_FALSE) {
3265        switch (wmesa->pixelformat) {
3266        case PF_8A8B8G8R:
3267            return flat_8A8B8G8R_z_triangle;
3268        case PF_8R8G8B:
3269            return flat_8R8G8B_z_triangle;
3270        case PF_5R6G5B:
3271            return flat_5R6G5B_z_triangle;
3272        case PF_DITHER8:
3273            return flat_DITHER8_z_triangle;
3274        case PF_INDEX8:
3275            return flat_ci_z_triangle;
3276        default:
3277            return NULL;
3278        }
3279    }
3280    if (   ctx->_RasterMask==0   /* no depth test */
3281        && ctx->Light.ShadeModel==GL_SMOOTH
3282        && ctx->Polygon.StippleFlag==GL_FALSE) {
3283        switch (wmesa->pixelformat) {
3284        case PF_8A8B8G8R:
3285            return smooth_8A8B8G8R_triangle;
3286        case PF_8R8G8B:
3287            return smooth_8R8G8B_triangle;
3288        case PF_5R6G5B:
3289            return smooth_5R6G5B_triangle;
3290        case PF_DITHER8:
3291            return smooth_DITHER8_triangle;
3292        case PF_INDEX8:
3293            return smooth_ci_triangle;
3294        default:
3295            return NULL;
3296        }
3297    }
3298
3299    if (   ctx->_RasterMask==0   /* no depth test */
3300        && ctx->Light.ShadeModel==GL_FLAT
3301        && ctx->Polygon.StippleFlag==GL_FALSE) {
3302        switch (wmesa->pixelformat) {
3303        case PF_8A8B8G8R:
3304            return flat_8A8B8G8R_triangle;
3305        case PF_8R8G8B:
3306            return flat_8R8G8B_triangle;
3307        case PF_5R6G5B:
3308            return flat_5R6G5B_triangle;
3309        case PF_DITHER8:
3310            return flat_DITHER8_triangle;
3311        case PF_INDEX8:
3312            return flat_ci_triangle;
3313        default:
3314            return NULL;
3315        }
3316    }
3317
3318    return NULL;
3319    }
3320#endif
3321}
3322
3323#endif /* unused */
3324
3325/*
3326 * Define a new viewport and reallocate auxillary buffers if the size of
3327 * the window (color buffer) has changed.
3328 */
3329void WMesaViewport( GLcontext *ctx,
3330		    GLint x, GLint y, GLsizei width, GLsizei height )
3331{
3332  (void) ctx; (void) x; (void) y; (void) width; (void) height;
3333  assert(0);  /* I don't think that this is being used. */
3334#if 0
3335  /* Save viewport */
3336  ctx->Viewport.X = x;
3337  ctx->Viewport.Width = width;
3338  ctx->Viewport.Y = y;
3339  ctx->Viewport.Height = height;
3340
3341  /* compute scale and bias values */
3342/* Pre-Keith 3.1 changes
3343   ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
3344   ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
3345   ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
3346   ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
3347*/
3348  ctx->Viewport.WindowMap.m[MAT_SX] = (GLfloat) width / 2.0F;
3349  ctx->Viewport.WindowMap.m[MAT_TX] = ctx->Viewport.WindowMap.m[MAT_SX] + x;
3350  ctx->Viewport.WindowMap.m[MAT_SY] = (GLfloat) height / 2.0F;
3351  ctx->Viewport.WindowMap.m[MAT_TY] = ctx->Viewport.WindowMap.m[MAT_SY] + y;
3352#endif
3353}
3354