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