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