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