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