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