OSDN Git Service

Source code for GDI driver.
authorKarl Schultz <kschultz@freedesktop.org>
Thu, 24 Jul 2003 03:47:46 +0000 (03:47 +0000)
committerKarl Schultz <kschultz@freedesktop.org>
Thu, 24 Jul 2003 03:47:46 +0000 (03:47 +0000)
src/mesa/drivers/windows/gdi/colors.h [new file with mode: 0644]
src/mesa/drivers/windows/gdi/wgl.c [new file with mode: 0644]
src/mesa/drivers/windows/gdi/wmesa.c [new file with mode: 0644]
src/mesa/drivers/windows/gdi/wmesadef.h [new file with mode: 0644]

diff --git a/src/mesa/drivers/windows/gdi/colors.h b/src/mesa/drivers/windows/gdi/colors.h
new file mode 100644 (file)
index 0000000..7070b85
--- /dev/null
@@ -0,0 +1,530 @@
+/*     File name       :       colors.h
+ *  Version            :       2.3
+ *
+ *  Header file for display driver for Mesa 2.3  under 
+ *     Windows95 and WindowsNT 
+ *     This file defines macros and global variables  needed
+ *     for converting color format
+ *
+ *     Copyright (C) 1996-  Li Wei
+ *  Address            :               Institute of Artificial Intelligence
+ *                             :                       & Robotics
+ *                             :               Xi'an Jiaotong University
+ *  Email              :               liwei@aiar.xjtu.edu.cn
+ *  Web page   :               http://sun.aiar.xjtu.edu.cn
+ *
+ *  This file and its associations are partially based on the 
+ *  Windows NT driver for Mesa, written by Mark Leaming
+ *  (mark@rsinc.com).
+ */
+
+/* $Log: ddcolors.h 1997/6/14 by Li Wei(liwei@aiar.xjtu.edu.cn)
+ * Macros for pixel format defined
+ */
+
+/*
+ * $Log: colors.h,v $
+ * Revision 1.1  2003/07/24 03:47:46  kschultz
+ * Source code for GDI driver.
+ *
+ * Revision 1.3  2002/01/15 18:14:34  kschultz
+ * Fixed pixel color component problem and clear code for 24-bit Windows
+ *   devices.  (Jeff Lewis)
+ *
+ * Revision 1.2  2002/01/15 18:11:36  kschultz
+ * Remove trailing CR's.   No logical changes.
+ *
+ * Revision 1.1.1.1  1999/08/19 00:55:42  jtg
+ * Imported sources
+ *
+ * Revision 1.2  1999/01/03 03:08:57  brianp
+ * Ted Jump's changes
+ *
+ * Revision 1.1  1999/01/03 03:08:12  brianp
+ * Initial revision
+ *
+ * Revision 2.0.2  1997/4/30 15:58:00  CST by Li Wei(liwei@aiar.xjtu.edu.cn)
+ * Add LUTs need for dithering
+ */
+
+/*
+ * $Log: colors.h,v $
+ * Revision 1.1  2003/07/24 03:47:46  kschultz
+ * Source code for GDI driver.
+ *
+ * Revision 1.3  2002/01/15 18:14:34  kschultz
+ * Fixed pixel color component problem and clear code for 24-bit Windows
+ *   devices.  (Jeff Lewis)
+ *
+ * Revision 1.2  2002/01/15 18:11:36  kschultz
+ * Remove trailing CR's.   No logical changes.
+ *
+ * Revision 1.1.1.1  1999/08/19 00:55:42  jtg
+ * Imported sources
+ *
+ * Revision 1.2  1999/01/03 03:08:57  brianp
+ * Ted Jump's changes
+ *
+ * Revision 1.1  1999/01/03 03:08:12  brianp
+ * Initial revision
+ *
+ * Revision 2.0.1  1997/4/29 15:52:00  CST by Li Wei(liwei@aiar.xjtu.edu.cn)
+ * Add BGR8 Macro
+ */
+/*
+ * $Log: colors.h,v $
+ * Revision 1.1  2003/07/24 03:47:46  kschultz
+ * Source code for GDI driver.
+ *
+ * Revision 1.3  2002/01/15 18:14:34  kschultz
+ * Fixed pixel color component problem and clear code for 24-bit Windows
+ *   devices.  (Jeff Lewis)
+ *
+ * Revision 1.2  2002/01/15 18:11:36  kschultz
+ * Remove trailing CR's.   No logical changes.
+ *
+ * Revision 1.1.1.1  1999/08/19 00:55:42  jtg
+ * Imported sources
+ *
+ * Revision 1.2  1999/01/03 03:08:57  brianp
+ * Ted Jump's changes
+ *
+ * Revision 1.1  1999/01/03 03:08:12  brianp
+ * Initial revision
+ *
+ * Revision 2.0  1996/11/15 10:55:00  CST by Li Wei(liwei@aiar.xjtu.edu.cn)
+ * Initial revision
+ */
+/* Values for wmesa->pixelformat: */
+
+#define PF_8A8B8G8R    3       /* 32-bit TrueColor:  8-A, 8-B, 8-G, 8-R */
+#define PF_8R8G8B      4       /* 32-bit TrueColor:  8-R, 8-G, 8-B */
+#define PF_5R6G5B      5       /* 16-bit TrueColor:  5-R, 6-G, 5-B bits */
+#define PF_DITHER8     6       /* Dithered RGB using a lookup table */
+#define PF_LOOKUP      7       /* Undithered RGB using a lookup table */
+#define PF_GRAYSCALE   10      /* Grayscale or StaticGray */
+#define PF_BADFORMAT   11
+#define PF_INDEX8              12
+
+char ColorMap16[] = {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
+0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
+0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
+0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,
+0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,
+0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,
+0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,
+0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,
+0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
+0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,
+0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,
+0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,
+0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,
+0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F};
+
+#define BGR8(r,g,b)            (unsigned)(((BYTE)(b & 0xc0 | (g & 0xe0)>>2 | (r & 0xe0)>>5)))
+#ifdef DDRAW
+#define BGR16(r,g,b)   ((WORD)(((BYTE)(ColorMap16[b]) | ((BYTE)(g&0xfc) << 3)) | (((WORD)(BYTE)(ColorMap16[r])) << 11)))
+#else
+#define BGR16(r,g,b)   ((WORD)(((BYTE)(ColorMap16[b]) | ((BYTE)(ColorMap16[g]) << 5)) | (((WORD)(BYTE)(ColorMap16[r])) << 10)))
+#endif
+#define BGR24(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(r))<<16)))
+
+#define BGR32(r,g,b)   (unsigned long)((DWORD)(((BYTE)(b)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(r))<<16)))
+
+
+
+/*
+ * If pixelformat==PF_8A8B8G8R:
+ */
+#define PACK_8A8B8G8R( R, G, B, A )    \
+       ( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) )
+
+
+/*
+ * If pixelformat==PF_8R8G8B:
+ */
+#define PACK_8R8G8B( R, G, B)   ( ((R) << 16) | ((G) << 8) | (B) )
+
+
+/*
+ * If pixelformat==PF_5R6G5B:
+ */
+
+
+#ifdef DDRAW
+#define PACK_5R6G5B( R, G, B) ((WORD)(((BYTE)(ColorMap16[B]) | ((BYTE)(G&0xfc) << 3)) | (((WORD)(BYTE)(ColorMap16[R])) << 11)))
+#else
+#define PACK_5R6G5B( R, G, B)  ((WORD)(((BYTE)(ColorMap16[B]) | ((BYTE)(ColorMap16[G]) << 5)) | (((WORD)(BYTE)(ColorMap16[R])) << 10)))
+#endif
+/*----------------------------------------------------------------------------
+
+Division lookup tables.  These tables compute 0-255 divided by 51 and
+modulo 51.  These tables could approximate gamma correction.
+
+*/
+
+char unsigned const aDividedBy51Rounded[256] =
+{
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+  2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+};
+
+char unsigned const aDividedBy51[256] =
+{
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+  2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 
+};
+
+char unsigned const aModulo51[256] =
+{
+  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+  20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+  38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6,
+  7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+  26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+  44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+  13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+  31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+  49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+  18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+  36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3,
+  4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+  23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 
+};
+
+/*----------------------------------------------------------------------------
+
+Multiplication LUTs.  These compute 0-5 times 6 and 36.
+
+*/
+
+char unsigned const aTimes6[6] =
+{
+  0, 6, 12, 18, 24, 30
+};
+
+char unsigned const aTimes36[6] =
+{
+  0, 36, 72, 108, 144, 180
+};
+
+
+/*----------------------------------------------------------------------------
+
+Dither matrices for 8 bit to 2.6 bit halftones.
+
+*/
+
+char unsigned const aHalftone16x16[256] =
+{
+  0, 44, 9, 41, 3, 46, 12, 43, 1, 44, 10, 41, 3, 46, 12, 43,
+  34, 16, 25, 19, 37, 18, 28, 21, 35, 16, 26, 19, 37, 18, 28, 21,
+  38, 6, 47, 3, 40, 9, 50, 6, 38, 7, 47, 4, 40, 9, 49, 6,
+  22, 28, 13, 31, 25, 31, 15, 34, 22, 29, 13, 32, 24, 31, 15, 34,
+  2, 46, 12, 43, 1, 45, 10, 42, 2, 45, 11, 42, 1, 45, 11, 42,
+  37, 18, 27, 21, 35, 17, 26, 20, 36, 17, 27, 20, 36, 17, 26, 20,
+  40, 8, 49, 5, 38, 7, 48, 4, 39, 8, 48, 5, 39, 7, 48, 4,
+  24, 30, 15, 33, 23, 29, 13, 32, 23, 30, 14, 33, 23, 29, 14, 32,
+  2, 46, 12, 43, 0, 44, 10, 41, 3, 47, 12, 44, 0, 44, 10, 41,
+  37, 18, 27, 21, 35, 16, 25, 19, 37, 19, 28, 22, 35, 16, 25, 19,
+  40, 9, 49, 5, 38, 7, 47, 4, 40, 9, 50, 6, 38, 6, 47, 3,
+  24, 30, 15, 34, 22, 29, 13, 32, 25, 31, 15, 34, 22, 28, 13, 31,
+  1, 45, 11, 42, 2, 46, 11, 42, 1, 45, 10, 41, 2, 46, 11, 43,
+  36, 17, 26, 20, 36, 17, 27, 21, 35, 16, 26, 20, 36, 18, 27, 21,
+  39, 8, 48, 4, 39, 8, 49, 5, 38, 7, 48, 4, 39, 8, 49, 5,
+  23, 29, 14, 33, 24, 30, 14, 33, 23, 29, 13, 32, 24, 30, 14, 33,
+};
+
+char unsigned const aHalftone8x8[64] =
+{
+   0, 38,  9, 47,  2, 40, 11, 50,
+  25, 12, 35, 22, 27, 15, 37, 24,
+   6, 44,  3, 41,  8, 47,  5, 43,
+  31, 19, 28, 15, 34, 21, 31, 18,
+   1, 39, 11, 49,  0, 39, 10, 48,
+  27, 14, 36, 23, 26, 13, 35, 23,
+   7, 46,  4, 43,  7, 45,  3, 42,
+  33, 20, 30, 17, 32, 19, 29, 16,
+};
+
+char unsigned const aHalftone4x4_1[16] =
+{
+  0, 25, 6, 31,
+  38, 12, 44, 19,
+  9, 35, 3, 28,
+  47, 22, 41, 15
+};
+
+char unsigned const aHalftone4x4_2[16] =
+{
+  41, 3, 9, 28,
+  35, 15, 22, 47,
+  6, 25, 38, 0,
+  19, 44, 31, 12
+};
+
+/***************************************************************************
+  aWinGHalftoneTranslation
+
+  Translates a 2.6 bit-per-pixel halftoned representation into the
+  slightly rearranged WinG Halftone Palette.
+*/
+
+char unsigned const aWinGHalftoneTranslation[216] =
+{
+  0,
+  29,
+  30,
+  31,
+  32,
+  249,
+  33,
+  34,
+  35,
+  36,
+  37,
+  38,
+  39,
+  40,
+  41,
+  42,
+  43,
+  44,
+  45,
+  46,
+  47,
+  48,
+  49,
+  50,
+  51,
+  52,
+  53,
+  54,
+  55,
+  56,
+  250,
+  250,
+  57,
+  58,
+  59,
+  251,
+  60,
+  61,
+  62,
+  63,
+  64,
+  65,
+  66,
+  67,
+  68,
+  69,
+  70,
+  71,
+  72,
+  73,
+  74,
+  75,
+  76,
+  77,
+  78,
+  79,
+  80,
+  81,
+  82,
+  83,
+  84,
+  85,
+  86,
+  87,
+  88,
+  89,
+  250,
+  90,
+  91,
+  92,
+  93,
+  94,
+  95,
+  96,
+  97,
+  98,
+  99,
+  100,
+  101,
+  102,
+  103,
+  104,
+  105,
+  106,
+  107,
+  108,
+  109,
+  110,
+  111,
+  227,
+  112,
+  113,
+  114,
+  115,
+  116,
+  117,
+  118,
+  119,
+  151,
+  120,
+  121,
+  122,
+  123,
+  124,
+  228,
+  125,
+  126,
+  229,
+  133,
+  162,
+  135,
+  131,
+  132,
+  137,
+  166,
+  134,
+  140,
+  130,
+  136,
+  143,
+  138,
+  139,
+  174,
+  141,
+  142,
+  177,
+  129,
+  144,
+  145,
+  146,
+  147,
+  148,
+  149,
+  150,
+  157,
+  152,
+  153,
+  154,
+  155,
+  156,
+  192,
+  158,
+  159,
+  160,
+  161,
+  196,
+  163,
+  164,
+  165,
+  127,
+  199,
+  167,
+  168,
+  169,
+  170,
+  171,
+  172,
+  173,
+  207,
+  175,
+  176,
+  210,
+  178,
+  179,
+  180,
+  181,
+  182,
+  183,
+  184,
+  185,
+  186,
+  187,
+  188,
+  189,
+  190,
+  191,
+  224,
+  193,
+  194,
+  195,
+  252,
+  252,
+  197,
+  198,
+  128,
+  253,
+  252,
+  200,
+  201,
+  202,
+  203,
+  204,
+  205,
+  206,
+  230,
+  208,
+  209,
+  231,
+  211,
+  212,
+  213,
+  214,
+  215,
+  216,
+  217,
+  218,
+  219,
+  220,
+  221,
+  222,
+  254,
+  223,
+  232,
+  225,
+  226,
+  255,
+};
diff --git a/src/mesa/drivers/windows/gdi/wgl.c b/src/mesa/drivers/windows/gdi/wgl.c
new file mode 100644 (file)
index 0000000..bceaeb3
--- /dev/null
@@ -0,0 +1,623 @@
+/* $Id: wgl.c,v 1.1 2003/07/24 03:47:46 kschultz Exp $ */
+
+/*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Library General Public
+* License as published by the Free Software Foundation; either
+* version 2 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Library General Public License for more details.
+*
+* You should have received a copy of the GNU Library General Public
+* License along with this library; if not, write to the Free
+* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*/
+
+/*
+* File name    : wgl.c
+* WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru
+* Some things originated from the 3Dfx WGL functions
+*/
+
+#ifdef WIN32
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <windows.h>
+#define GL_GLEXT_PROTOTYPES
+#include <GL/gl.h>
+#include <GL/glext.h>
+//#include <GL/glu.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <stdio.h>
+#include <tchar.h>
+#include "wmesadef.h"
+#include "GL/wmesa.h"
+#include "mtypes.h"
+#include "glapi.h"
+
+#define MAX_MESA_ATTRS 20
+
+struct __pixelformat__
+{
+    PIXELFORMATDESCRIPTOR      pfd;
+    GLboolean doubleBuffered;
+};
+
+struct __pixelformat__ pix[] =
+{
+    /* Double Buffer, alpha */
+    {  {       sizeof(PIXELFORMATDESCRIPTOR),  1,
+        PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
+        PFD_TYPE_RGBA,
+        24,    8,      0,      8,      8,      8,      16,     8,      24,
+        0,     0,      0,      0,      0,      16,     8,      0,      0,      0,      0,      0,      0 },
+        GL_TRUE
+    },
+    /* Single Buffer, alpha */
+    {  {       sizeof(PIXELFORMATDESCRIPTOR),  1,
+        PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_FORMAT,
+        PFD_TYPE_RGBA,
+        24,    8,      0,      8,      8,      8,      16,     8,      24,
+        0,     0,      0,      0,      0,      16,     8,      0,      0,      0,      0,      0,      0 },
+        GL_FALSE
+    },
+    /* Double Buffer, no alpha */
+    {  {       sizeof(PIXELFORMATDESCRIPTOR),  1,
+        PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
+        PFD_TYPE_RGBA,
+        24,    8,      0,      8,      8,      8,      16,     0,      0,
+        0,     0,      0,      0,      0,      16,     8,      0,      0,      0,      0,      0,      0 },
+        GL_TRUE
+    },
+    /* Single Buffer, no alpha */
+    {  {       sizeof(PIXELFORMATDESCRIPTOR),  1,
+        PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_FORMAT,
+        PFD_TYPE_RGBA,
+        24,    8,      0,      8,      8,      8,      16,     0,      0,
+        0,     0,      0,      0,      0,      16,     8,      0,      0,      0,      0,      0,      0 },
+        GL_FALSE
+    },
+};
+
+int qt_pix = sizeof(pix) / sizeof(pix[0]);
+
+typedef struct {
+    WMesaContext ctx;
+    HDC hdc;
+} MesaWglCtx;
+
+#define MESAWGL_CTX_MAX_COUNT 20
+
+static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT];
+
+static unsigned ctx_count = 0;
+static unsigned ctx_current = -1;
+static unsigned curPFD = 0;
+
+WGLAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask)
+{
+    return(FALSE);
+}
+
+WGLAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc)
+{
+    HWND               hWnd;
+    int i = 0;
+    if(!(hWnd = WindowFromDC(hdc)))
+    {
+        SetLastError(0);
+        return(NULL);
+    }
+    if (!ctx_count)
+    {
+       for(i=0;i<MESAWGL_CTX_MAX_COUNT;i++)
+       {
+               wgl_ctx[i].ctx = NULL;
+               wgl_ctx[i].hdc = NULL;
+       }
+    }
+    for( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ )
+    {
+        if ( wgl_ctx[i].ctx == NULL )
+        {
+            wgl_ctx[i].ctx = WMesaCreateContext( hWnd, NULL, GL_TRUE,
+                pix[curPFD-1].doubleBuffered, 
+                pix[curPFD-1].pfd.cAlphaBits ? GL_TRUE : GL_FALSE);
+            if (wgl_ctx[i].ctx == NULL)
+                break;
+            wgl_ctx[i].hdc = hdc;
+            ctx_count++;
+            return ((HGLRC)wgl_ctx[i].ctx);
+        }
+    }
+    SetLastError(0);
+    return(NULL);
+}
+
+WGLAPI BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc)
+{
+    int i;
+    for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ )
+    {
+       if ( wgl_ctx[i].ctx == (PWMC) hglrc )
+       {
+            WMesaMakeCurrent((PWMC) hglrc);
+            WMesaDestroyContext();
+            wgl_ctx[i].ctx = NULL;
+            wgl_ctx[i].hdc = NULL;
+            ctx_count--;
+            return(TRUE);
+       }
+    }
+    SetLastError(0);
+    return(FALSE);
+}
+
+WGLAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc,int iLayerPlane)
+{
+    SetLastError(0);
+    return(NULL);
+}
+
+WGLAPI HGLRC GLAPIENTRY wglGetCurrentContext(VOID)
+{
+   if (ctx_current < 0)
+      return 0;
+   else
+      return (HGLRC) wgl_ctx[ctx_current].ctx;
+}
+
+WGLAPI HDC GLAPIENTRY wglGetCurrentDC(VOID)
+{
+   if (ctx_current < 0)
+      return 0;
+   else
+      return wgl_ctx[ctx_current].hdc;
+}
+
+WGLAPI BOOL GLAPIENTRY wglMakeCurrent(HDC hdc,HGLRC hglrc)
+{
+    int i;
+
+    /* new code suggested by Andy Sy */
+    if (!hdc || !hglrc) {
+       WMesaMakeCurrent(NULL);
+       ctx_current = -1;
+       return TRUE;
+    }
+
+    for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ )
+    {
+        if ( wgl_ctx[i].ctx == (PWMC) hglrc )
+        {
+            wgl_ctx[i].hdc = hdc;
+            WMesaMakeCurrent( (WMesaContext) hglrc );
+            ctx_current = i;
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+WGLAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1,HGLRC hglrc2)
+{
+    return(TRUE);
+}
+
+
+static FIXED FixedFromDouble(double d)
+{
+   long l = (long) (d * 65536L);
+   return *(FIXED *)&l;
+}
+
+
+/*
+** This is cribbed from FX/fxwgl.c, and seems to implement support
+** for bitmap fonts where the wglUseFontBitmapsA() code implements
+** support for outline fonts.  In combination they hopefully give
+** fairly generic support for fonts.
+*/
+static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar,
+                                 DWORD numChars, DWORD listBase)
+{
+#define VERIFY(a) a
+
+  TEXTMETRIC metric;
+  BITMAPINFO *dibInfo;
+  HDC bitDevice;
+  COLORREF tempColor;
+  int i;
+
+  VERIFY(GetTextMetrics(fontDevice, &metric));
+
+  dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1);
+  dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+  dibInfo->bmiHeader.biPlanes = 1;
+  dibInfo->bmiHeader.biBitCount = 1;
+  dibInfo->bmiHeader.biCompression = BI_RGB;
+
+  bitDevice = CreateCompatibleDC(fontDevice);
+  // HDC bitDevice = CreateDC("DISPLAY", NULL, NULL, NULL);
+  // VERIFY(bitDevice);
+
+  // Swap fore and back colors so the bitmap has the right polarity
+  tempColor = GetBkColor(bitDevice);
+  SetBkColor(bitDevice, GetTextColor(bitDevice));
+  SetTextColor(bitDevice, tempColor);
+
+  // Place chars based on base line
+  VERIFY(SetTextAlign(bitDevice, TA_BASELINE) >= 0 ? 1 : 0);
+
+  for(i = 0; i < numChars; i++) {
+    SIZE size;
+    char curChar;
+    int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res;
+    HBITMAP bitObject;
+    HGDIOBJ origBmap;
+    unsigned char *bmap;
+
+    curChar = i + firstChar;
+
+    // Find how high/wide this character is
+    VERIFY(GetTextExtentPoint32(bitDevice, &curChar, 1, &size));
+
+    // Create the output bitmap
+    charWidth = size.cx;
+    charHeight = size.cy;
+    bmapWidth = ((charWidth + 31) / 32) * 32;   // Round up to the next multiple of 32 bits
+    bmapHeight = charHeight;
+    bitObject = CreateCompatibleBitmap(bitDevice,
+                                       bmapWidth,
+                                       bmapHeight);
+    //VERIFY(bitObject);
+
+    // Assign the output bitmap to the device
+    origBmap = SelectObject(bitDevice, bitObject);
+    VERIFY(origBmap);
+
+    VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) );
+
+    // Use our source font on the device
+    VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT)));
+
+    // Draw the character
+    VERIFY(TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1));
+
+    // Unselect our bmap object
+    VERIFY(SelectObject(bitDevice, origBmap));
+
+    // Convert the display dependant representation to a 1 bit deep DIB
+    numBytes = (bmapWidth * bmapHeight) / 8;
+    bmap = malloc(numBytes);
+    dibInfo->bmiHeader.biWidth = bmapWidth;
+    dibInfo->bmiHeader.biHeight = bmapHeight;
+    res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap,
+                    dibInfo,
+                    DIB_RGB_COLORS);
+    //VERIFY(res);
+
+    // Create the GL object
+    glNewList(i + listBase, GL_COMPILE);
+    glBitmap(bmapWidth, bmapHeight, 0.0, metric.tmDescent,
+             charWidth, 0.0,
+             bmap);
+    glEndList();
+    // CheckGL();
+
+    // Destroy the bmap object
+    DeleteObject(bitObject);
+
+    // Deallocate the bitmap data
+    free(bmap);
+  }
+
+  // Destroy the DC
+  VERIFY(DeleteDC(bitDevice));
+
+  free(dibInfo);
+
+  return TRUE;
+#undef VERIFY
+}
+
+WGLAPI BOOL GLAPIENTRY wglUseFontBitmapsA(HDC hdc, DWORD first,
+                                       DWORD count, DWORD listBase)
+{
+   int i;
+   GLuint font_list;
+   DWORD size;
+   GLYPHMETRICS gm;
+   HANDLE hBits;
+   LPSTR lpBits;
+   MAT2 mat;
+   int  success = TRUE;
+
+   if (first<0)
+      return FALSE;
+   if (count<0)
+      return FALSE;
+   if (listBase<0)
+      return FALSE;
+
+   font_list = listBase;
+
+   mat.eM11 = FixedFromDouble(1);
+   mat.eM12 = FixedFromDouble(0);
+   mat.eM21 = FixedFromDouble(0);
+   mat.eM22 = FixedFromDouble(-1);
+
+   memset(&gm,0,sizeof(gm));
+
+   /*
+   ** If we can't get the glyph outline, it may be because this is a fixed
+   ** font.  Try processing it that way.
+   */
+   if( GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat)
+       == GDI_ERROR )
+   {
+       return wglUseFontBitmaps_FX( hdc, first, count, listBase );
+   }
+
+   /*
+   ** Otherwise process all desired characters.
+   */
+   for (i = 0; i < count; i++)
+   {
+       DWORD err;
+       
+      glNewList( font_list+i, GL_COMPILE );
+
+      /* allocate space for the bitmap/outline */
+      size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 0, NULL, &mat);
+      if (size == GDI_ERROR)
+      {
+         glEndList( );
+         err = GetLastError();
+         success = FALSE;
+         continue;
+      }
+
+      hBits  = GlobalAlloc(GHND, size+1);
+      lpBits = GlobalLock(hBits);
+
+      err = 
+      GetGlyphOutline(hdc,    /* handle to device context */
+                      first + i,          /* character to query */
+                      GGO_BITMAP,         /* format of data to return */
+                      &gm,                /* pointer to structure for metrics*/
+                      size,               /* size of buffer for data */
+                      lpBits,             /* pointer to buffer for data */
+                      &mat                /* pointer to transformation */
+                                          /* matrix structure */
+                  );
+
+      if (err == GDI_ERROR)
+      {
+         GlobalUnlock(hBits);
+         GlobalFree(hBits);
+         
+         glEndList( );
+         err = GetLastError();
+         success = FALSE;
+         continue;
+      }
+
+      glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY,
+               -gm.gmptGlyphOrigin.x,
+               gm.gmptGlyphOrigin.y,
+               gm.gmCellIncX,gm.gmCellIncY,
+               (const GLubyte * )lpBits);
+
+      GlobalUnlock(hBits);
+      GlobalFree(hBits);
+
+      glEndList( );
+   }
+
+   return success;
+}
+
+
+WGLAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc,DWORD first,DWORD count,DWORD listBase)
+{
+    return FALSE;
+}
+
+WGLAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count,
+                                  DWORD listBase,FLOAT deviation,
+                                  FLOAT extrusion,int format,
+                                  LPGLYPHMETRICSFLOAT lpgmf)
+{
+    SetLastError(0);
+    return(FALSE);
+}
+
+WGLAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc,DWORD first,DWORD count,
+                                  DWORD listBase,FLOAT deviation,
+                                  FLOAT extrusion,int format,
+                                  LPGLYPHMETRICSFLOAT lpgmf)
+{
+    SetLastError(0);
+    return(FALSE);
+}
+
+WGLAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc,int iPixelFormat,
+                                    int iLayerPlane,UINT nBytes,
+                                    LPLAYERPLANEDESCRIPTOR plpd)
+{
+    SetLastError(0);
+    return(FALSE);
+}
+
+WGLAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc,int iLayerPlane,
+                                       int iStart,int cEntries,
+                                       CONST COLORREF *pcr)
+{
+    SetLastError(0);
+    return(0);
+}
+
+WGLAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc,int iLayerPlane,
+                                       int iStart,int cEntries,
+                                       COLORREF *pcr)
+{
+    SetLastError(0);
+    return(0);
+}
+
+WGLAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc,int iLayerPlane,BOOL bRealize)
+{
+    SetLastError(0);
+    return(FALSE);
+}
+
+WGLAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc,UINT fuPlanes)
+{
+    if( !hdc )
+    {
+        WMesaSwapBuffers();
+        return(TRUE);
+    }
+    SetLastError(0);
+    return(FALSE);
+}
+
+WGLAPI int GLAPIENTRY wglChoosePixelFormat(HDC hdc,
+                                  CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+    int                i,best = -1,bestdelta = 0x7FFFFFFF,delta,qt_valid_pix;
+
+    qt_valid_pix = qt_pix;
+    if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1)
+    {
+        SetLastError(0);
+        return(0);
+    }
+    for(i = 0;i < qt_valid_pix;i++)
+    {
+        delta = 0;
+        if(
+            (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) &&
+            !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))
+            continue;
+        if(
+            (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) &&
+            !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))
+            continue;
+        if(
+            (ppfd->dwFlags & PFD_SUPPORT_GDI) &&
+            !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI))
+            continue;
+        if(
+            (ppfd->dwFlags & PFD_SUPPORT_OPENGL) &&
+            !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))
+            continue;
+        if(
+            !(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
+            ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))
+            continue;
+        if(
+            !(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&
+            ((ppfd->dwFlags & PFD_STEREO) != (pix[i].pfd.dwFlags & PFD_STEREO)))
+            continue;
+        if(ppfd->iPixelType != pix[i].pfd.iPixelType)
+            delta++;
+        if(ppfd->cAlphaBits != pix[i].pfd.cAlphaBits)
+            delta++;
+        if(delta < bestdelta)
+        {
+            best = i + 1;
+            bestdelta = delta;
+            if(bestdelta == 0)
+                break;
+        }
+    }
+    if(best == -1)
+    {
+        SetLastError(0);
+        return(0);
+    }
+    return(best);
+}
+
+WGLAPI int GLAPIENTRY wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
+                                    LPPIXELFORMATDESCRIPTOR ppfd)
+{
+    int                qt_valid_pix;
+
+    qt_valid_pix = qt_pix;
+    if(ppfd == NULL)
+       return(qt_valid_pix);
+    if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix || nBytes != sizeof(PIXELFORMATDESCRIPTOR))
+    {
+        SetLastError(0);
+        return(0);
+    }
+    *ppfd = pix[iPixelFormat - 1].pfd;
+    return(qt_valid_pix);
+}
+
+/*
+* GetProcAddress - return the address of an appropriate extension
+*/
+WGLAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc)
+{
+   PROC p = (PROC) _glapi_get_proc_address((const char *) lpszProc);
+   if (p)
+      return p;
+
+   SetLastError(0);
+   return(NULL);
+}
+
+WGLAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc)
+{
+    if(curPFD == 0)
+    {
+        SetLastError(0);
+        return(0);
+    }
+    return(curPFD);
+}
+
+WGLAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
+                                PIXELFORMATDESCRIPTOR *ppfd)
+{
+    int                qt_valid_pix;
+
+    qt_valid_pix = qt_pix;
+    if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix || ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR))
+    {
+        SetLastError(0);
+        return(FALSE);
+    }
+    curPFD = iPixelFormat;
+    return(TRUE);
+}
+
+WGLAPI BOOL GLAPIENTRY wglSwapBuffers(HDC hdc)
+{
+   if (ctx_current < 0)
+      return FALSE;
+
+   if(wgl_ctx[ctx_current].ctx == NULL) {
+      SetLastError(0);
+      return(FALSE);
+   }
+   WMesaSwapBuffers();
+   return(TRUE);
+}
+
+#endif /* WIN32 */
diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c
new file mode 100644 (file)
index 0000000..01b08e8
--- /dev/null
@@ -0,0 +1,3322 @@
+/* $Id: wmesa.c,v 1.1 2003/07/24 03:47:46 kschultz Exp $ */
+
+/*
+ * Windows (Win32) device driver for Mesa 3.4
+ *
+ * Original author:
+ *
+ *  Copyright (C) 1996-  Li Wei
+ *  Address      :       Institute of Artificial Intelligence
+ *               :           & Robotics
+ *               :       Xi'an Jiaotong University
+ *  Email        :       liwei@aiar.xjtu.edu.cn
+ *  Web page :       http://sun.aiar.xjtu.edu.cn
+ *
+ *  This file and its associations are partially borrowed from the
+ *  Windows NT driver for Mesa 1.8 , written by Mark Leaming
+ *  (mark@rsinc.com).
+ *
+ * Updated for Mesa 4.0 by Karl Schultz (kschultz@sourceforge.net)
+ */
+
+#ifdef NDEBUG
+#pragma auto_inline(on)
+#pragma inline_depth(255)
+#pragma inline_recursion(on)
+#endif
+
+#include "wmesadef.h"
+#include <GL/wmesa.h>
+//#include "mesa_extend.h"
+
+#include "glheader.h"
+#include "colors.h"
+#include "context.h"
+#include "colormac.h"
+#include "dd.h"
+#include "depth.h"
+#include "extensions.h"
+#include "imports.h"
+#include "macros.h"
+#include "matrix.h"
+#include "mtypes.h"
+#include "texformat.h"
+#include "teximage.h"
+#include "texstore.h"
+#include "array_cache/acache.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "swrast/s_context.h"
+#include "swrast/s_depth.h"
+#include "swrast/s_lines.h"
+#include "swrast/s_triangle.h"
+#include "swrast/s_trispan.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+
+/* Dither not tested for Mesa 4.0 */ 
+#ifdef DITHER
+#ifdef USE_WING
+#include <wing.h>
+#endif // USE_WING
+#endif
+
+#ifdef __CYGWIN32__
+#include "macros.h"
+#include <string.h>
+#define CopyMemory memcpy
+#endif
+
+/* Stereo and parallel not tested for Mesa 4.0. */
+#define NO_STEREO
+#if !defined(NO_STEREO)
+#include "gl\glu.h"
+#include "stereo.h"
+#endif
+
+#define NO_PARALLEL
+#if !defined(NO_PARALLEL)
+#include "parallel.h"
+#endif
+
+
+/* File global varaibles */
+struct DISPLAY_OPTIONS {
+       int  stereo;
+       int  fullScreen;
+       int      mode;
+       int      bpp;
+};
+
+struct DISPLAY_OPTIONS displayOptions = 
+{
+       0,              // stereo
+       0,              // fullScreen
+       0,              // full screen mode (1,2,3,4)
+       0               // bpp (8,16,24,32)
+};
+GLenum stereoCompile = GL_FALSE ;
+GLenum stereoShowing  = GL_FALSE ;
+GLenum stereoBuffer = GL_FALSE;
+#if !defined(NO_STEREO)
+GLint displayList = MAXIMUM_DISPLAY_LIST ;
+#endif
+GLint stereo_flag = 0 ;
+
+static PWMC Current = NULL;
+WMesaContext WC = NULL;
+
+#ifdef COMPILE_SETPIXEL
+
+#if defined(_MSC_VER) && _MSC_VER >= 1200
+#define FORCEINLINE __forceinline
+#else
+#define FORCEINLINE __inline
+#endif
+
+FORCEINLINE void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
+{
+       pwc->wmSetPixel(pwc,iScanLine,iPixel,r,g,b);
+}
+
+void ChooseSetPixel(PWMC pwc);
+
+#endif // COMPILE_SETPIXEL
+
+/* If we are double-buffering, we want to get the DC for the
+ * off-screen DIB, otherwise the DC for the window.
+ */
+#define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
+#define DD_RELEASEDC
+
+#define FLIP(Y)  (Current->height-(Y)-1)
+
+#define DITHER_RGB_TO_8BIT_SETUP            \
+GLubyte pixelDithered;
+
+#define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline)        \
+{                                                                    \
+    char unsigned redtemp, greentemp, bluetemp, paletteindex;        \
+    redtemp = aDividedBy51[red]                                      \
+    + (aModulo51[red] > aHalftone8x8[(pixel%8)*8                     \
+    + scanline%8]);                                                  \
+    greentemp = aDividedBy51[(char unsigned)green]                   \
+    + (aModulo51[green] > aHalftone8x8[                              \
+    (pixel%8)*8 + scanline%8]);                                      \
+    bluetemp = aDividedBy51[(char unsigned)blue]                     \
+    + (aModulo51[blue] > aHalftone8x8[                               \
+    (pixel%8)*8 +scanline%8]);                                       \
+    paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp];\
+    pixelDithered = aWinGHalftoneTranslation[paletteindex];          \
+}
+
+#ifdef DDRAW
+static BOOL DDInit( WMesaContext wc, HWND hwnd);
+static void DDFree( WMesaContext wc);
+static HRESULT DDRestoreAll( WMesaContext wc );
+static void DDDeleteOffScreen(WMesaContext wc);
+static BOOL DDCreateOffScreen(WMesaContext wc);
+
+// define this to use the GDI Rectangle call to
+// clear the back buffer. Otherwise will manually
+// set the pixels. On an NVidia GEForce 2MX under Windows XP
+// and DirectX 8 , defining this makes apps run much much faster
+#define USE_GDI_TO_CLEAR 1
+#endif
+
+static void FlushToFile(PWMC pwc, PSTR  szFile);
+BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
+BOOL wmDeleteBackingStore(PWMC pwc);
+void wmCreatePalette( PWMC pwdc );
+BOOL wmSetDibColors(PWMC pwc);
+void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
+BOOL wmFlush(PWMC pwc);
+void wmCreateDIBSection(
+    HDC  hDC,
+    PWMC pwc,   // handle of device context
+    CONST BITMAPINFO *pbmi, // bitmap size, format, and color data
+    UINT iUsage // color data type indicator: RGB values or palette indices
+    );
+void WMesaViewport( GLcontext *ctx,
+                    GLint x, GLint y, GLsizei width, GLsizei height );
+
+
+static void wmSetPixelFormat( PWMC wc, HDC hDC)
+{
+  if(wc->rgb_flag)
+    wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
+  else
+    wc->cColorBits = 8;
+  switch(wc->cColorBits){
+  case 8:
+    if(wc->dither_flag != GL_TRUE)
+      wc->pixelformat = PF_INDEX8;
+    else
+      wc->pixelformat = PF_DITHER8;
+    break;
+  case 16:
+    wc->pixelformat = PF_5R6G5B;
+    break;
+  case 32:
+    wc->pixelformat = PF_8R8G8B;
+    break;
+  default:
+    wc->pixelformat = PF_BADFORMAT;
+  }
+}
+
+
+/* This function sets the color table of a DIB section
+ * to match that of the destination DC
+ */
+BOOL wmSetDibColors(PWMC pwc)
+{
+  RGBQUAD         *pColTab, *pRGB;
+  PALETTEENTRY    *pPal, *pPE;
+  int             i, nColors;
+  BOOL            bRet=TRUE;
+  DWORD           dwErr=0;
+  
+  /* Build a color table in the DIB that maps to the
+   *  selected palette in the DC.
+   */
+  nColors = 1 << pwc->cColorBits;
+  pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
+  memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
+  GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
+  pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
+  for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
+    pRGB->rgbRed = pPE->peRed;
+    pRGB->rgbGreen = pPE->peGreen;
+    pRGB->rgbBlue = pPE->peBlue;
+  }
+  if(pwc->db_flag)
+    bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab );
+  
+  if(!bRet)
+    dwErr = GetLastError();
+  
+  free( pColTab );
+  free( pPal );
+  
+  return bRet;
+}
+
+
+/*
+ * Free up the dib section that was created
+ */
+BOOL wmDeleteBackingStore(PWMC pwc)
+{
+  SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
+  DeleteDC(pwc->dib.hDC);
+  DeleteObject(pwc->hbmDIB);
+#ifdef USE_MAPPED_FILE
+  UnmapViewOfFile(pwc->dib.base);
+  CloseHandle(pwc->dib.hFileMap);
+#endif
+  return TRUE;
+}
+
+
+/*
+ * This function creates the DIB section that is used for combined
+ * GL and GDI calls
+ */
+BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
+{
+  HDC hdc = pwc->hDC;
+  LPBITMAPINFO pbmi = &(pwc->bmi);
+  int     iUsage;
+  
+  pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+  pbmi->bmiHeader.biWidth = lxSize;
+  pbmi->bmiHeader.biHeight= -lySize;
+  pbmi->bmiHeader.biPlanes = 1;
+  if(pwc->rgb_flag)
+    pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
+  else
+    pbmi->bmiHeader.biBitCount = 8;
+  pbmi->bmiHeader.biCompression = BI_RGB;
+  pbmi->bmiHeader.biSizeImage = 0;
+  pbmi->bmiHeader.biXPelsPerMeter = 0;
+  pbmi->bmiHeader.biYPelsPerMeter = 0;
+  pbmi->bmiHeader.biClrUsed = 0;
+  pbmi->bmiHeader.biClrImportant = 0;
+  
+  iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
+
+  pwc->cColorBits = pbmi->bmiHeader.biBitCount;
+  pwc->ScanWidth = pwc->pitch = lxSize;
+  
+  wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
+  
+  if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
+    wmCreatePalette( pwc );
+    wmSetDibColors( pwc );
+  }
+  wmSetPixelFormat(pwc, pwc->hDC);
+  return TRUE;
+}
+
+#if 0
+// D.R.S. 10/30/01 - this function is never referenced
+/*
+ * This function copies one scan line in a DIB section to another
+ */
+BOOL wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, 
+                       UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
+{
+  UINT    uiScans = 0;
+  LPBYTE  pDest = pwc->pbPixels;
+  DWORD   dwNextScan = uiScanWidth;
+  DWORD   dwNewScan = uiNewWidth;
+  DWORD   dwScanWidth = (uiScanWidth * nBypp);
+  
+  /*
+   * We need to round up to the nearest DWORD
+   * and multiply by the number of bytes per
+   * pixel
+   */
+  dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
+  dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
+  
+  for(uiScans = 0; uiScans < uiNumScans; uiScans++){
+    CopyMemory(pDest, pBits, dwScanWidth);
+    pBits += dwNextScan;
+    pDest += dwNewScan;
+  }
+  return TRUE;
+}
+#endif // 0
+
+#if defined(FAST_RASTERIZERS)
+
+#define PIXELADDR(X,Y)  \
+  ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* \
+  Current->ScanWidth + (X)*nBypp)
+#define PIXELADDR1( X, Y )  \
+((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
+#define PIXELADDR2( X, Y )  \
+((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
+#define PIXELADDR4( X, Y )  \
+((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
+
+#endif // 0
+
+BYTE DITHER_RGB_2_8BIT( int r, int g, int b, int x, int y);
+
+/* Finish all pending operations and synchronize. */
+static void finish(GLcontext* ctx)
+{
+  /* No op */
+}
+
+
+static void flush(GLcontext* ctx)
+{
+  if((Current->rgb_flag &&!(Current->db_flag))
+     ||(!Current->rgb_flag))
+    {
+      wmFlush(Current);
+    }
+  
+}
+
+
+
+/*
+ * Set the color index used to clear the color buffer.
+ */
+static void clear_index(GLcontext* ctx, GLuint index)
+{
+  Current->clearpixel = index;
+}
+
+
+
+/*
+ * Set the color used to clear the color buffer.
+ */
+static void clear_color( GLcontext* ctx, const GLfloat color[4] )
+{
+  GLubyte col[4];
+  CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
+  CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
+  CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
+  Current->clearpixel = RGB(col[0], col[1], col[2]);
+}
+
+
+/* 
+ * Clear the specified region of the color buffer using the clear color 
+ * or index as specified by one of the two functions above. 
+ * 
+ * This procedure clears either the front and/or the back COLOR buffers. 
+ * Only the "left" buffer is cleared since we are not stereo. 
+ * Clearing of the other non-color buffers is left to the swrast. 
+ * We also only clear the color buffers if the color masks are all 1's. 
+ * Otherwise, we let swrast do it. 
+ */ 
+
+static clear(GLcontext* ctx, GLbitfield mask, 
+      GLboolean all, GLint x, GLint y, GLint width, GLint height) 
+{ 
+  const   GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask; 
+  
+  if (all){ 
+    x=y=0; 
+    width=Current->width; 
+    height=Current->height; 
+  } 
+  
+  
+  /* sanity check - can't have right(stereo) buffers */ 
+  assert((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_RIGHT_BIT)) == 0); 
+  
+  /* clear alpha */
+  if ((mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) &&
+      ctx->DrawBuffer->UseSoftwareAlphaBuffers &&
+      ctx->Color.ColorMask[ACOMP]) {
+      _swrast_clear_alpha_buffers( ctx );
+  }
+
+  if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { 
+      if (mask & DD_BACK_LEFT_BIT) { 
+#if defined(USE_GDI_TO_CLEAR) 
+#if defined(DDRAW) 
+ // D.R.S. 10/29/01 on my system (Pentium 4 with nvidia GeForce2 MX card, 
+ // this is almose 100 times faster that the code below 
+ HDC DC=NULL; 
+ HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel); 
+ HBRUSH Brush=CreateSolidBrush(Current->clearpixel); 
+ HPEN Old_Pen=NULL; 
+ HBRUSH Old_Brush=NULL; 
+ Current->lpDDSOffScreen->lpVtbl->Unlock(Current->lpDDSOffScreen,NULL); 
+ Current->lpDDSOffScreen->lpVtbl->GetDC(Current->lpDDSOffScreen,&DC); 
+ Old_Pen=SelectObject(DC,Pen); 
+ Old_Brush=SelectObject(DC,Brush); 
+ Rectangle(DC,x,y,x+width,y+height); 
+ SelectObject(DC,Old_Pen); 
+ SelectObject(DC,Old_Brush); 
+ DeleteObject(Pen); 
+ DeleteObject(Brush); 
+ Current->lpDDSOffScreen->lpVtbl->ReleaseDC(Current->lpDDSOffScreen,DC); 
+ while (Current->lpDDSOffScreen->lpVtbl->Lock(Current->lpDDSOffScreen,NULL, &(Current->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING);
+
+   mask &= ~DD_BACK_LEFT_BIT; 
+#else 
+   /* single-buffer */ 
+   HDC DC=DD_GETDC; 
+   HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel); 
+   HBRUSH Brush=CreateSolidBrush(Current->clearpixel); 
+   HPEN Old_Pen=SelectObject(DC,Pen); 
+   HBRUSH Old_Brush=SelectObject(DC,Brush); 
+   Rectangle(DC,x+Current->rectSurface.left,Current->rectSurface.top+y,x+width+Current->rectSurface.left,y+height+Current->rectSurface.top);
+
+   SelectObject(DC,Old_Pen); 
+   SelectObject(DC,Old_Brush); 
+   DeleteObject(Pen); 
+   DeleteObject(Brush); 
+   DD_RELEASEDC; 
+   mask &= ~DD_BACK_LEFT_BIT; 
+#endif // DDRAW 
+#else 
+   DWORD   dwColor; 
+   WORD    wColor; 
+   BYTE    bColor; 
+   LPDWORD lpdw = (LPDWORD)Current->pbPixels; 
+   LPWORD  lpw = (LPWORD)Current->pbPixels; 
+   LPBYTE  lpb = Current->pbPixels; 
+   int     lines; 
+   /* Double-buffering - clear back buffer */ 
+   UINT    nBypp = Current->cColorBits / 8; 
+   int     i = 0; 
+   int     iSize = 0; 
+   int   mult = 4; 
+
+   
+   assert(Current->db_flag==GL_TRUE); /* we'd better be double buffer */ 
+   if(nBypp ==1 ){ 
+       iSize = Current->width/4; 
+       bColor  = BGR8(GetRValue(Current->clearpixel), 
+        GetGValue(Current->clearpixel), 
+        GetBValue(Current->clearpixel)); 
+       wColor  = MAKEWORD(bColor,bColor); 
+       dwColor = MAKELONG(wColor, wColor); 
+   } 
+   else if(nBypp == 2){ 
+       iSize = Current->width / 2; 
+       wColor = BGR16(GetRValue(Current->clearpixel), 
+        GetGValue(Current->clearpixel), 
+        GetBValue(Current->clearpixel)); 
+       dwColor = MAKELONG(wColor, wColor); 
+   } 
+   else if(nBypp == 3){ 
+      BYTE r, g, b; 
+      r = GetRValue(Current->clearpixel); 
+      g = GetGValue(Current->clearpixel); 
+      b = GetBValue(Current->clearpixel); 
+      iSize = Current->width; 
+      while (i < iSize) { 
+        *lpb++ = b; 
+        *lpb++ = g; 
+        *lpb++ = r; 
+        i++; 
+      } 
+      lpb = Current->pbPixels + Current->ScanWidth; 
+      mult = 3; 
+   }   
+   else if(nBypp == 4){ 
+       iSize = Current->width; 
+       dwColor = BGR32(GetRValue(Current->clearpixel), 
+         GetGValue(Current->clearpixel), 
+         GetBValue(Current->clearpixel)); 
+   } 
+
+   if (nBypp != 3) 
+   { 
+      /* clear a line */ 
+    while(i < iSize){ 
+        *lpdw = dwColor; 
+     lpdw++; 
+        i++; 
+    } 
+   } 
+   
+   i = 0; 
+   if (stereo_flag) 
+       lines = height /2; 
+   else 
+       lines = height; 
+   /* copy cleared line to other lines in buffer */ 
+   do { 
+       memcpy(lpb, Current->pbPixels, iSize*mult); 
+       lpb += Current->ScanWidth; 
+       i++; 
+   } 
+   while (i<lines-1); 
+   mask &= ~DD_BACK_LEFT_BIT; 
+#endif // defined(USE_GDI_TO_CLEAR) 
+      } /* double-buffer */ 
+      
+      if (mask & DD_FRONT_LEFT_BIT) { 
+   /* single-buffer */ 
+   HDC DC=DD_GETDC; 
+   HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel); 
+   HBRUSH Brush=CreateSolidBrush(Current->clearpixel); 
+   HPEN Old_Pen=SelectObject(DC,Pen); 
+   HBRUSH Old_Brush=SelectObject(DC,Brush); 
+   Rectangle(DC,x+Current->rectSurface.left,Current->rectSurface.top+y,x+width+Current->rectSurface.left,y+height+Current->rectSurface.top);
+
+   SelectObject(DC,Old_Pen); 
+   SelectObject(DC,Old_Brush); 
+   DeleteObject(Pen); 
+   DeleteObject(Brush); 
+   DD_RELEASEDC; 
+   mask &= ~DD_FRONT_LEFT_BIT; 
+      } /* single-buffer */ 
+  } /* if masks are all 1's */ 
+    
+  /* Call swrast if there is anything left to clear (like DEPTH) */ 
+  if (mask) 
+      _swrast_Clear( ctx, mask, all, x, y, width, height ); 
+} 
+
+
+static void enable( GLcontext* ctx, GLenum pname, GLboolean enable )
+{
+  if (!Current)
+    return;
+  
+  if (pname == GL_DITHER) {
+    if(enable == GL_FALSE){
+      Current->dither_flag = GL_FALSE;
+      if(Current->cColorBits == 8)
+       Current->pixelformat = PF_INDEX8;
+    }
+    else{
+      if (Current->rgb_flag && Current->cColorBits == 8){
+       Current->pixelformat = PF_DITHER8;
+       Current->dither_flag = GL_TRUE;
+      }
+      else
+       Current->dither_flag = GL_FALSE;
+    }
+  }
+}
+
+
+
+static void set_buffer(GLcontext *ctx, GLframebuffer *colorBuffer,
+                       GLuint bufferBit )
+{
+  /* XXX todo - examine bufferBit and set read/write pointers */
+  return;
+}
+
+
+
+/* Return characteristics of the output buffer. */
+static void buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
+{
+  GET_CURRENT_CONTEXT(ctx);
+  int New_Size;
+  RECT CR;
+  
+  GetClientRect(Current->Window,&CR);
+  
+   *width=CR.right;
+   *height=CR.bottom;
+   
+   New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
+   
+   if (New_Size){
+     Current->width=*width;
+     Current->height=*height;
+     Current->ScanWidth=Current->width;
+     if ((Current->ScanWidth%sizeof(long))!=0)
+       Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
+     
+     if (Current->db_flag){
+#ifdef DDRAW
+       DDDeleteOffScreen(Current);
+       DDCreateOffScreen(Current);
+#else
+       if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){
+        wmDeleteBackingStore(Current);
+        wmCreateBackingStore(Current, Current->width, Current->height);
+       }
+#endif
+     }
+     
+     /*  Resize OsmesaBuffer if in Parallel mode */
+#if !defined(NO_PARALLEL)
+     if(parallelFlag)
+       PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
+                         Current->rgb_flag == GL_TRUE ? Current->pbPixels: 
+                         Current->ScreenMem);
+#endif
+   }
+}
+
+
+
+/**********************************************************************/
+/*****           Accelerated point, line, polygon rendering       *****/
+/**********************************************************************/
+
+/* Accelerated routines are not implemented in 4.0. See OSMesa for ideas. */
+
+static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
+{
+}
+
+/* Return pointer to accelerated points function */
+extern points_func choose_points_function( GLcontext* ctx )
+{
+  return NULL;
+}
+
+static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, 
+                               GLuint v1, GLuint pv )
+{
+}
+
+static line_func choose_line_function( GLcontext* ctx )
+{
+}
+
+
+/**********************************************************************/
+/*****                 Span-based pixel drawing                   *****/
+/**********************************************************************/
+
+
+/* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
+static void write_ci32_span( const GLcontext* ctx,
+                             GLuint n, GLint x, GLint y,
+                             const GLuint index[],
+                             const GLubyte mask[] )
+{
+  GLuint i;
+  PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
+  assert(Current->rgb_flag==GL_FALSE);
+  for (i=0; i<n; i++)
+    if (mask[i])
+      Mem[i]=index[i];
+}
+
+
+/* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
+static void write_ci8_span( const GLcontext* ctx,
+                            GLuint n, GLint x, GLint y,
+                            const GLubyte index[],
+                            const GLubyte mask[] )
+{
+  GLuint i;
+  PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
+  assert(Current->rgb_flag==GL_FALSE);
+  for (i=0; i<n; i++)
+    if (mask[i])
+      Mem[i]=index[i];
+}
+
+
+
+/*
+ * Write a horizontal span of pixels with a boolean mask.  The current
+ * color index is used for all pixels.
+ */
+static void write_mono_ci_span(const GLcontext* ctx,
+                               GLuint n,GLint x,GLint y,
+                               GLuint colorIndex, const GLubyte mask[])
+{
+  GLuint i;
+  BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
+  assert(Current->rgb_flag==GL_FALSE);
+  for (i=0; i<n; i++)
+    if (mask[i])
+      Mem[i]=colorIndex;
+}
+
+/*
+ * To improve the performance of this routine, frob the data into an actual
+ * scanline and call bitblt on the complete scan line instead of SetPixel.
+ */
+
+/* Write a horizontal span of RGBA color pixels with a boolean mask. */
+static void write_rgba_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
+                             const GLubyte rgba[][4], const GLubyte mask[] )
+{
+  PWMC    pwc = Current;
+  
+  if (pwc->rgb_flag==GL_TRUE)
+    {
+      GLuint i;
+      HDC DC=DD_GETDC;
+      y=FLIP(y);
+      if (mask) {
+       for (i=0; i<n; i++)
+         if (mask[i])
+           wmSetPixel(pwc, y, x + i, 
+                      rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
+      }
+      else {
+       for (i=0; i<n; i++)
+         wmSetPixel(pwc, y, x + i, 
+                    rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
+      }
+      DD_RELEASEDC;
+    }
+  else
+    {
+      GLuint i;
+      BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
+      y = FLIP(y);
+      if (mask) {
+       for (i=0; i<n; i++)
+         if (mask[i])
+           Mem[i] = GetNearestPaletteIndex(Current->hPal, 
+                                           RGB(rgba[i][RCOMP], 
+                                               rgba[i][GCOMP], 
+                                               rgba[i][BCOMP]));
+      }
+      else {
+       for (i=0; i<n; i++)
+         Mem[i] = GetNearestPaletteIndex(Current->hPal,
+                                         RGB(rgba[i][RCOMP], 
+                                             rgba[i][GCOMP], 
+                                             rgba[i][BCOMP]));
+      }
+    }
+}
+
+/* Write a horizontal span of RGB color pixels with a boolean mask. */
+static void write_rgb_span( const GLcontext* ctx,
+                            GLuint n, GLint x, GLint y,
+                            const GLubyte rgb[][3], const GLubyte mask[] )
+{
+  PWMC    pwc = Current;
+  
+  if (pwc->rgb_flag==GL_TRUE)
+    {
+      GLuint i;
+      HDC DC=DD_GETDC;
+      y=FLIP(y);
+      if (mask) {
+       for (i=0; i<n; i++)
+         if (mask[i])
+           wmSetPixel(pwc, y, x + i, 
+                      rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
+      }
+      else {
+       for (i=0; i<n; i++)
+         wmSetPixel(pwc, y, x + i, 
+                    rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
+      }
+      DD_RELEASEDC;
+    }
+  else
+    {
+      GLuint i;
+      BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
+      y = FLIP(y);
+      if (mask) {
+       for (i=0; i<n; i++)
+         if (mask[i])
+           Mem[i] = GetNearestPaletteIndex(Current->hPal,
+                                           RGB(rgb[i][RCOMP], 
+                                               rgb[i][GCOMP], 
+                                               rgb[i][BCOMP]));
+      }
+      else {
+       for (i=0; i<n; i++)
+         Mem[i] = GetNearestPaletteIndex(Current->hPal,
+                                         RGB(rgb[i][RCOMP], 
+                                             rgb[i][GCOMP], 
+                                             rgb[i][BCOMP]));
+      }
+    }
+}
+
+/*
+ * Write a horizontal span of pixels with a boolean mask.  The current color
+ * is used for all pixels.
+ */
+static void write_mono_rgba_span( const GLcontext* ctx,
+                                  GLuint n, GLint x, GLint y,
+                                  const GLchan color[4], const GLubyte mask[])
+{
+  GLuint i;
+  PWMC pwc = Current;
+  assert(Current->rgb_flag==GL_TRUE);
+  y=FLIP(y);
+  if(Current->rgb_flag==GL_TRUE)
+  {
+       for (i=0; i<n; i++)
+               if (mask[i])
+                       wmSetPixel(pwc,y,x+i,color[RCOMP], color[GCOMP], color[BCOMP]);
+  }
+  else
+  {
+       HDC DC=DD_GETDC;
+    ULONG pixel =  RGB( color[RCOMP], color[GCOMP], color[BCOMP] );
+    for (i=0; i<n; i++)
+      if (mask[i])
+               SetPixel(DC, y, x+i, pixel);
+         DD_RELEASEDC;
+  }
+}
+
+
+
+/**********************************************************************/
+/*****                   Array-based pixel drawing                *****/
+/**********************************************************************/
+
+
+/* Write an array of 32-bit index pixels with a boolean mask. */
+static void write_ci32_pixels( const GLcontext* ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                               const GLuint index[], const GLubyte mask[] )
+{
+  GLuint i;
+  assert(Current->rgb_flag==GL_FALSE);
+  for (i=0; i<n; i++) {
+    if (mask[i]) {
+      BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
+      *Mem = index[i];
+    }
+  }
+}
+
+
+
+/*
+ * Write an array of pixels with a boolean mask.  The current color
+ * index is used for all pixels.
+ */
+static void write_mono_ci_pixels( const GLcontext* ctx,
+                                  GLuint n,
+                                  const GLint x[], const GLint y[],
+                                  GLuint colorIndex, const GLubyte mask[] )
+{
+  GLuint i;
+  assert(Current->rgb_flag==GL_FALSE);
+  for (i=0; i<n; i++) {
+    if (mask[i]) {
+      BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
+      *Mem = colorIndex;
+    }
+  }
+}
+
+
+
+/* Write an array of RGBA pixels with a boolean mask. */
+static void write_rgba_pixels( const GLcontext* ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                               const GLubyte rgba[][4], const GLubyte mask[] )
+{
+  GLuint i;
+  PWMC    pwc = Current;
+  HDC DC=DD_GETDC;
+  assert(Current->rgb_flag==GL_TRUE);
+  for (i=0; i<n; i++)
+    if (mask[i])
+      wmSetPixel(pwc, FLIP(y[i]), x[i],
+                rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
+  DD_RELEASEDC;
+}
+
+
+
+/*
+ * Write an array of pixels with a boolean mask.  The current color
+ * is used for all pixels.
+ */
+static void write_mono_rgba_pixels( const GLcontext* ctx,
+                                    GLuint n,
+                                    const GLint x[], const GLint y[],
+                                    const GLchan color[4],
+                                    const GLubyte mask[] )
+{
+  GLuint i;
+  PWMC    pwc = Current;
+  HDC DC=DD_GETDC;
+  assert(Current->rgb_flag==GL_TRUE);
+  for (i=0; i<n; i++)
+    if (mask[i])
+      wmSetPixel(pwc, FLIP(y[i]),x[i],color[RCOMP],
+                color[GCOMP], color[BCOMP]);
+  DD_RELEASEDC;
+}
+
+
+
+/**********************************************************************/
+/*****            Read spans/arrays of pixels                     *****/
+/**********************************************************************/
+
+
+/* Read a horizontal span of color-index pixels. */
+static void read_ci32_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
+                            GLuint index[])
+{
+  GLuint i;
+  BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
+  assert(Current->rgb_flag==GL_FALSE);
+  for (i=0; i<n; i++)
+    index[i]=Mem[i];
+}
+
+
+
+
+/* Read an array of color index pixels. */
+static void read_ci32_pixels( const GLcontext* ctx,
+                              GLuint n, const GLint x[], const GLint y[],
+                              GLuint indx[], const GLubyte mask[] )
+{
+  GLuint i;
+  assert(Current->rgb_flag==GL_FALSE);
+  for (i=0; i<n; i++) {
+    if (mask[i]) {
+      indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]);
+    }
+  }
+}
+
+
+
+/* Read a horizontal span of color pixels. */
+static void read_rgba_span( const GLcontext* ctx,
+                            GLuint n, GLint x, GLint y,
+                            GLubyte rgba[][4] )
+{
+  UINT i;
+  COLORREF Color;
+  HDC DC=DD_GETDC;
+  assert(Current->rgb_flag==GL_TRUE);
+  y = Current->height - y - 1;
+  for (i=0; i<n; i++) {
+    Color=GetPixel(DC,x+i,y);
+    rgba[i][RCOMP] = GetRValue(Color);
+    rgba[i][GCOMP] = GetGValue(Color);
+    rgba[i][BCOMP] = GetBValue(Color);
+    rgba[i][ACOMP] = 255;
+  }
+  DD_RELEASEDC;
+}
+
+
+/* Read an array of color pixels. */
+static void read_rgba_pixels( const GLcontext* ctx,
+                              GLuint n, const GLint x[], const GLint y[],
+                              GLubyte rgba[][4], const GLubyte mask[] )
+{
+  GLuint i;
+  COLORREF Color;
+  HDC DC=DD_GETDC;
+  assert(Current->rgb_flag==GL_TRUE);
+  for (i=0; i<n; i++) {
+    if (mask[i]) {
+      GLint y2 = Current->height - y[i] - 1;
+      Color=GetPixel(DC,x[i],y2);
+      rgba[i][RCOMP] = GetRValue(Color);
+      rgba[i][GCOMP] = GetGValue(Color);
+      rgba[i][BCOMP] = GetBValue(Color);
+      rgba[i][ACOMP] = 255;
+    }
+  }
+  DD_RELEASEDC;
+}
+
+
+
+/**********************************************************************/
+/**********************************************************************/
+
+
+static const GLubyte *get_string(GLcontext *ctx, GLenum name)
+{
+  if (name == GL_RENDERER) {
+    return (GLubyte *) "Mesa Windows";
+  }
+  else {
+    return NULL;
+  }
+}
+
+static void wmesa_update_state( GLcontext *ctx, GLuint new_state );
+
+static void SetFunctionPointers(GLcontext *ctx)
+{
+  struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
+  ctx->Driver.GetString = get_string;
+  ctx->Driver.UpdateState = wmesa_update_state;
+  ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
+  ctx->Driver.GetBufferSize = buffer_size;
+  
+  ctx->Driver.Accum = _swrast_Accum;
+  ctx->Driver.Bitmap = _swrast_Bitmap;
+  ctx->Driver.Clear = clear;
+  
+  ctx->Driver.Flush = flush;
+  ctx->Driver.ClearIndex = clear_index;
+  ctx->Driver.ClearColor = clear_color;
+  ctx->Driver.Enable = enable;
+  
+  ctx->Driver.CopyPixels = _swrast_CopyPixels;
+  ctx->Driver.DrawPixels = _swrast_DrawPixels;
+  ctx->Driver.ReadPixels = _swrast_ReadPixels;
+  ctx->Driver.DrawBuffer = _swrast_DrawBuffer;
+  
+  ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
+  ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+  ctx->Driver.TexImage2D = _mesa_store_teximage2d;
+  ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+  ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
+  ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
+  ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+  ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
+  
+  ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
+  ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
+  ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
+  ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
+  ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
+  ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
+
+  ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
+  ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
+  ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+  ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+  ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+  ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+  ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+  ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+  ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+
+  swdd->SetBuffer = set_buffer;
+
+  /* Pixel/span writing functions: */
+  swdd->WriteRGBASpan        = write_rgba_span;
+  swdd->WriteRGBSpan         = write_rgb_span;
+  swdd->WriteMonoRGBASpan    = write_mono_rgba_span;
+  swdd->WriteRGBAPixels      = write_rgba_pixels;
+  swdd->WriteMonoRGBAPixels  = write_mono_rgba_pixels;
+  swdd->WriteCI32Span        = write_ci32_span;
+  swdd->WriteCI8Span         = write_ci8_span;
+  swdd->WriteMonoCISpan      = write_mono_ci_span;
+  swdd->WriteCI32Pixels      = write_ci32_pixels;
+  swdd->WriteMonoCIPixels    = write_mono_ci_pixels;
+  
+  swdd->ReadCI32Span        = read_ci32_span;
+  swdd->ReadRGBASpan        = read_rgba_span;
+  swdd->ReadCI32Pixels      = read_ci32_pixels;
+  swdd->ReadRGBAPixels      = read_rgba_pixels;
+}
+
+static void wmesa_update_state( GLcontext *ctx, GLuint new_state )
+{
+  struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
+  TNLcontext *tnl = TNL_CONTEXT(ctx);
+  
+  /*
+   * XXX these function pointers could be initialized just once during
+   * context creation since they don't depend on any state changes.
+   * kws - This is true - this function gets called a lot and it
+   * would be good to minimize setting all this when not needed.
+   */
+#ifndef SET_FPOINTERS_ONCE  
+  SetFunctionPointers(ctx);
+#if 0
+  ctx->Driver.GetString = get_string;
+  ctx->Driver.UpdateState = wmesa_update_state;
+  ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
+  ctx->Driver.GetBufferSize = buffer_size;
+  
+  ctx->Driver.Accum = _swrast_Accum;
+  ctx->Driver.Bitmap = _swrast_Bitmap;
+  ctx->Driver.Clear = clear;
+  
+  ctx->Driver.Flush = flush;
+  ctx->Driver.ClearIndex = clear_index;
+  ctx->Driver.ClearColor = clear_color;
+  ctx->Driver.Enable = enable;
+  
+  ctx->Driver.CopyPixels = _swrast_CopyPixels;
+  ctx->Driver.DrawPixels = _swrast_DrawPixels;
+  ctx->Driver.ReadPixels = _swrast_ReadPixels;
+  
+  ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
+  ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+  ctx->Driver.TexImage2D = _mesa_store_teximage2d;
+  ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+  ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
+  ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
+  ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+  ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
+  
+  ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
+  ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
+  ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
+  ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
+  ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
+  ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
+
+  ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
+  ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
+  ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+  ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+  ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+  ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+  ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+  ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+  ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+  
+  swdd->SetBuffer = set_buffer;
+  
+  /* Pixel/span writing functions: */
+  swdd->WriteRGBASpan        = write_rgba_span;
+  swdd->WriteRGBSpan         = write_rgb_span;
+  swdd->WriteMonoRGBASpan    = write_mono_rgba_span;
+  swdd->WriteRGBAPixels      = write_rgba_pixels;
+  swdd->WriteMonoRGBAPixels  = write_mono_rgba_pixels;
+  swdd->WriteCI32Span        = write_ci32_span;
+  swdd->WriteCI8Span         = write_ci8_span;
+  swdd->WriteMonoCISpan      = write_mono_ci_span;
+  swdd->WriteCI32Pixels      = write_ci32_pixels;
+  swdd->WriteMonoCIPixels    = write_mono_ci_pixels;
+  
+  swdd->ReadCI32Span        = read_ci32_span;
+  swdd->ReadRGBASpan        = read_rgba_span;
+  swdd->ReadCI32Pixels      = read_ci32_pixels;
+  swdd->ReadRGBAPixels      = read_rgba_pixels;
+#endif // 0  
+#endif //  !SET_FPOINTERS_ONCE  
+  tnl->Driver.RunPipeline = _tnl_run_pipeline;
+  
+  _swrast_InvalidateState( ctx, new_state );
+  _swsetup_InvalidateState( ctx, new_state );
+  _ac_InvalidateState( ctx, new_state );
+  _tnl_InvalidateState( ctx, new_state );
+}
+
+
+
+
+/**********************************************************************/
+/*****                  WMesa API Functions                       *****/
+/**********************************************************************/
+
+
+
+#define PAL_SIZE 256
+static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
+{
+  int i;
+  HDC hdc;
+  struct
+  {
+    WORD Version;
+    WORD NumberOfEntries;
+    PALETTEENTRY aEntries[PAL_SIZE];
+  } Palette =
+    {
+      0x300,
+      PAL_SIZE
+    };
+  hdc=GetDC(NULL);
+  if (Pal!=NULL)
+    GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
+  else
+    GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
+  if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
+    {
+      for(i = 0; i <PAL_SIZE; i++)
+       Palette.aEntries[i].peFlags = PC_RESERVED;
+      Palette.aEntries[255].peRed = 255;
+      Palette.aEntries[255].peGreen = 255;
+      Palette.aEntries[255].peBlue = 255;
+      Palette.aEntries[255].peFlags = 0;
+      Palette.aEntries[0].peRed = 0;
+      Palette.aEntries[0].peGreen = 0;
+      Palette.aEntries[0].peBlue = 0;
+      Palette.aEntries[0].peFlags = 0;
+    }
+  else
+    {
+      int nStaticColors;
+      int nUsableColors;
+      nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
+      for (i=0; i<nStaticColors; i++)
+       Palette.aEntries[i].peFlags = 0;
+      nUsableColors = PAL_SIZE-nStaticColors;
+      for (; i<nUsableColors; i++)
+       Palette.aEntries[i].peFlags = PC_RESERVED;
+      for (; i<PAL_SIZE-nStaticColors; i++)
+       Palette.aEntries[i].peFlags = PC_RESERVED;
+      for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
+       Palette.aEntries[i].peFlags = 0;
+    }
+  ReleaseDC(NULL,hdc);
+  for (i=0; i<PAL_SIZE; i++)
+    {
+      aRGB[i].rgbRed=Palette.aEntries[i].peRed;
+      aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
+      aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
+      aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
+    }
+}
+
+
+WMesaContext WMesaCreateContext( HWND hWnd, HPALETTE* Pal,
+                                GLboolean rgb_flag,
+                                GLboolean db_flag,
+                                 GLboolean alpha_flag )
+{
+  RECT CR;
+  WMesaContext c;
+  GLboolean true_color_flag;
+
+  c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
+  if (!c)
+    return NULL;
+  
+  c->Window=hWnd;
+  c->hDC = GetDC(hWnd);
+  true_color_flag = GetDeviceCaps(c->hDC, BITSPIXEL) > 8;
+#ifdef DDRAW
+  if(true_color_flag) c->rgb_flag = rgb_flag = GL_TRUE;
+#endif
+  
+  
+#ifdef DITHER
+  if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){
+    c->dither_flag = GL_TRUE;
+#ifdef USE_WING
+    c->hPalHalfTone = WinGCreateHalftonePalette();
+#else
+       c->hPalHalfTone = CreateHalftonePalette(c->hDC);
+#endif
+  }
+  else
+    c->dither_flag = GL_FALSE;
+#else
+  c->dither_flag = GL_FALSE;
+#endif
+  
+  
+  if (rgb_flag==GL_FALSE)
+    {
+      c->rgb_flag = GL_FALSE;
+#if 0
+      /* Old WinG stuff???? */
+      c->db_flag = db_flag =GL_TRUE; /* WinG requires double buffering */
+      printf("Single buffer is not supported in color index mode, ",
+            "setting to double buffer.\n");
+#endif
+    }
+  else
+    {
+      c->rgb_flag = GL_TRUE;
+    }
+  GetClientRect(c->Window,&CR);
+  c->width=CR.right;
+  c->height=CR.bottom;
+  if (db_flag)
+    {
+      c->db_flag = 1;
+      /* Double buffered */
+#ifndef DDRAW
+      {
+       wmCreateBackingStore(c, c->width, c->height);
+       
+      }
+#endif
+    }
+  else
+    {
+      /* Single Buffered */
+      if (c->rgb_flag)
+       c->db_flag = 0;
+    }
+#ifdef DDRAW
+  if (DDInit(c,hWnd) == GL_FALSE) {
+    free( (void *) c );
+    exit(1);
+  }
+#endif
+  
+  
+  c->gl_visual = _mesa_create_visual(rgb_flag,
+                                    db_flag,    /* db_flag */
+                                    GL_FALSE,   /* stereo */
+                                    8,8,8,      /* r, g, b bits */
+                                     alpha_flag ? 8 : 0, /* alpha bits */
+                                    0,          /* index bits */
+                                    16,         /* depth_bits */
+                                    8,          /* stencil_bits */
+                                    16,16,16,/* accum_bits */
+                                     alpha_flag ? 16 : 0, /* alpha accum */
+                                    1);
+  
+  if (!c->gl_visual) {
+    return NULL;
+  }
+  
+  /* allocate a new Mesa context */
+  c->gl_ctx = _mesa_create_context( c->gl_visual, NULL, (void *) c, GL_FALSE );
+  
+  if (!c->gl_ctx) {
+    _mesa_destroy_visual( c->gl_visual );
+    free(c);
+    return NULL;
+  }
+  
+  _mesa_enable_sw_extensions(c->gl_ctx);
+  _mesa_enable_1_3_extensions(c->gl_ctx);
+  _mesa_enable_1_4_extensions(c->gl_ctx);
+
+  c->gl_buffer = _mesa_create_framebuffer( c->gl_visual,
+                                          c->gl_visual->depthBits > 0,
+                                          c->gl_visual->stencilBits > 0,
+                                          c->gl_visual->accumRedBits > 0,
+                                          alpha_flag /* s/w alpha */ );
+  if (!c->gl_buffer) {
+    _mesa_destroy_visual( c->gl_visual );
+    _mesa_free_context_data( c->gl_ctx );
+    free(c);
+    return NULL;
+  }
+  
+  /* Initialize the software rasterizer and helper modules.
+   */
+  {
+    GLcontext *ctx = c->gl_ctx;
+    _swrast_CreateContext( ctx );
+    _ac_CreateContext( ctx );
+    _tnl_CreateContext( ctx );
+    _swsetup_CreateContext( ctx );
+    
+#ifdef SET_FPOINTERS_ONCE
+    SetFunctionPointers(ctx);
+#endif // SET_FPOINTERS_ONCE
+    _swsetup_Wakeup( ctx );
+  }
+#ifdef COMPILE_SETPIXEL
+  ChooseSetPixel(c);
+#endif
+  return c;
+}
+
+void WMesaDestroyContext( void )
+{
+  WMesaContext c = Current;
+  ReleaseDC(c->Window,c->hDC);
+  WC = c;
+  if(c->hPalHalfTone != NULL)
+    DeleteObject(c->hPalHalfTone);
+
+  _swsetup_DestroyContext( c->gl_ctx );
+  _tnl_DestroyContext( c->gl_ctx );
+  _ac_DestroyContext( c->gl_ctx );
+  _swrast_DestroyContext( c->gl_ctx );
+  
+  _mesa_destroy_visual( c->gl_visual );
+  _mesa_destroy_framebuffer( c->gl_buffer );
+  _mesa_free_context_data( c->gl_ctx );
+  free( (void *) c->gl_ctx);
+    
+  if (c->db_flag)
+#ifdef DDRAW
+    DDFree(c);
+#else
+  wmDeleteBackingStore(c);
+#endif
+  free( (void *) c );
+#if !defined(NO_PARALLEL)
+  if(parallelMachine)
+    PRDestroyRenderBuffer();
+#endif
+
+  // Destroyed context no longer valid
+  WMesaMakeCurrent( NULL );
+}
+
+
+void WMesaMakeCurrent( WMesaContext c )
+{
+  if(!c){
+    Current = c;
+    return;
+  }
+  
+  if(Current == c)
+    return;
+  
+  Current = c;
+  wmesa_update_state(c->gl_ctx, 0);
+  _mesa_make_current(c->gl_ctx, c->gl_buffer);
+  if (Current->gl_ctx->Viewport.Width==0) {
+    /* initialize viewport to window size */
+    _mesa_Viewport( 0, 0, Current->width, Current->height );
+    Current->gl_ctx->Scissor.Width = Current->width;
+    Current->gl_ctx->Scissor.Height = Current->height;
+  }
+  if ((c->cColorBits <= 8 ) && (c->rgb_flag == GL_TRUE)){
+    WMesaPaletteChange(c->hPalHalfTone);
+  }
+}
+
+
+
+void WMesaSwapBuffers( void )
+{
+  HDC DC = Current->hDC;
+  GET_CURRENT_CONTEXT(ctx);
+  
+  /* If we're swapping the buffer associated with the current context
+   * we have to flush any pending rendering commands first.
+   */
+  if (Current && Current->gl_ctx == ctx)
+    _mesa_notifySwapBuffers(ctx);
+  
+  if (Current->db_flag)
+    wmFlush(Current);
+}
+
+
+
+void WMesaPaletteChange(HPALETTE Pal)
+{
+#ifndef DDRAW
+  int vRet;
+#endif
+  LPPALETTEENTRY pPal;
+  if (Current && (Current->rgb_flag==GL_FALSE || 
+                 Current->dither_flag == GL_TRUE))
+    {
+      pPal = (PALETTEENTRY *)malloc( 256 * sizeof(PALETTEENTRY));
+      Current->hPal=Pal;
+      GetPaletteEntries( Pal, 0, 256, pPal );
+#ifdef DDRAW
+      Current->lpDD->lpVtbl->CreatePalette(Current->lpDD,DDPCAPS_8BIT,
+                                          pPal, &(Current->lpDDPal), NULL);
+      if (Current->lpDDPal)
+       Current->lpDDSPrimary->lpVtbl->SetPalette(Current->lpDDSPrimary,
+                                                 Current->lpDDPal);
+#else
+      vRet = SetDIBColorTable(Current->dib.hDC, 0, 256, (RGBQUAD*)pPal);
+#endif
+      free( pPal );
+    }
+}
+
+
+
+
+static unsigned char threeto8[8] = {
+  0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
+};
+
+static unsigned char twoto8[4] = {
+  0, 0x55, 0xaa, 0xff
+};
+
+static unsigned char oneto8[2] = {
+  0, 255
+};
+
+static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
+{
+  unsigned char val;
+  
+  val = i >> shift;
+  switch (nbits) {
+    
+  case 1:
+    val &= 0x1;
+    return oneto8[val];
+    
+  case 2:
+    val &= 0x3;
+    return twoto8[val];
+    
+  case 3:
+    val &= 0x7;
+    return threeto8[val];
+    
+  default:
+    return 0;
+  }
+}
+
+void wmCreatePalette( PWMC pwdc )
+{
+  /* Create a compressed and re-expanded 3:3:2 palette */
+  int            i;
+  LOGPALETTE     *pPal;
+  BYTE           rb, rs, gb, gs, bb, bs;
+  
+  pwdc->nColors = 0x100;
+  
+  pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + 
+                            pwdc->nColors * sizeof(PALETTEENTRY));
+  memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
+  
+  pPal->palVersion = 0x300;
+  
+  rb = REDBITS;
+  rs = REDSHIFT;
+  gb = GREENBITS;
+  gs = GREENSHIFT;
+  bb = BLUEBITS;
+  bs = BLUESHIFT;
+  
+  if (pwdc->db_flag) {
+    
+    /* Need to make two palettes: one for the screen DC and one for the DIB. */
+    pPal->palNumEntries = pwdc->nColors;
+    for (i = 0; i < pwdc->nColors; i++) {
+      pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
+      pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
+      pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
+      pPal->palPalEntry[i].peFlags = 0;
+    }
+    pwdc->hGLPalette = CreatePalette( pPal );
+    pwdc->hPalette = CreatePalette( pPal );
+  }
+  
+  else {
+    pPal->palNumEntries = pwdc->nColors;
+    for (i = 0; i < pwdc->nColors; i++) {
+      pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
+      pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
+      pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
+      pPal->palPalEntry[i].peFlags = 0;
+    }
+    pwdc->hGLPalette = CreatePalette( pPal );
+  }
+  
+  free(pPal);
+  
+}
+
+
+void 
+#ifdef COMPILE_SETPIXEL
+
+wmSetPixelDefault(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
+{
+       if (Current->db_flag)
+       {
+#ifdef DDRAW
+               HDC hdc = NULL;
+               Current->lpDDSOffScreen->lpVtbl->Unlock(Current->lpDDSOffScreen,NULL);
+               Current->lpDDSOffScreen->lpVtbl->GetDC(Current->lpDDSOffScreen,&hdc);
+               SetPixelV(hdc,iPixel, iScanLine, RGB(r,g,b));
+               Current->lpDDSOffScreen->lpVtbl->ReleaseDC(Current->lpDDSOffScreen,hdc);
+               while (Current->lpDDSOffScreen->lpVtbl->Lock(Current->lpDDSOffScreen,NULL, &(Current->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING);
+#else
+               SetPixelV(Current->hDC, iPixel, iScanLine, RGB(r,g,b));
+#endif
+       }
+       else
+       {
+               SetPixelV(Current->hDC, iPixel+pwc->rectSurface.left, pwc->rectSurface.top+iScanLine, RGB(r,g,b));
+       }
+}
+#else
+wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
+{
+       if (Current->db_flag)
+       {
+               LPBYTE  lpb = pwc->pbPixels;
+               UINT    nBypp = pwc->cColorBits >> 3;
+    
+               lpb += pwc->ScanWidth * iScanLine;
+               lpb += iPixel * nBypp;
+    
+               if(nBypp == 1)
+               {
+                       if(pwc->dither_flag)
+                               *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
+                       else
+                               *lpb = BGR8(r,g,b);
+               }
+               else if(nBypp == 2)
+                       *((LPWORD)lpb) = BGR16(r,g,b);
+               else if (nBypp == 3)
+                       {
+                       *lpb++ = b;
+                       *lpb++ = g;
+                       *lpb   = r;
+                       }
+               else if (nBypp == 4)
+                       *((LPDWORD)lpb) = BGR32(r,g,b);
+       }
+       else
+       {
+               SetPixel(Current->hDC, iPixel, iScanLine, RGB(r,g,b));
+       }
+}
+#endif
+#ifdef COMPILE_SETPIXEL
+void wmSetPixel4(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
+{
+       LPDWORD lpdw = ((LPDWORD)(pwc->pbPixels + pwc->ScanWidth * iScanLine)) + iPixel;
+       *lpdw = BGR32(r,g,b);
+//     LPBYTE  lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel + iPixel;
+//     *((LPDWORD)lpb) = BGR32(r,g,b);
+}
+
+void wmSetPixel3(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
+{
+       LPBYTE  lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel;
+       *lpb++ = b;
+       *lpb++ = g;
+       *lpb   = r;
+}
+
+void wmSetPixel2(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
+{
+       LPWORD lpw = ((LPWORD)(pwc->pbPixels + pwc->ScanWidth * iScanLine)) + iPixel;
+       *lpw = BGR16(r,g,b);
+//     LPBYTE  lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel;
+//     *((LPWORD)lpb) = BGR16(r,g,b);
+}
+
+void wmSetPixel1(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
+{
+       LPBYTE  lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel;
+       *lpb = BGR8(r,g,b);
+}
+
+void wmSetPixel1Dither(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
+{
+       LPBYTE  lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel;
+       *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
+}
+
+
+void ChooseSetPixel(PWMC pwc)
+{
+       UINT nBypp = (pwc ) ? pwc->cColorBits >> 3 : 0;
+       switch(nBypp)
+       {
+               case 1:
+                       pwc->wmSetPixel = pwc->dither_flag ? &wmSetPixel1Dither : &wmSetPixel1;
+                       break;
+               case 2:
+                       pwc->wmSetPixel = &wmSetPixel2;
+                       break;
+               case 3:
+                       pwc->wmSetPixel = &wmSetPixel3;
+                       break;
+               case 4:
+                       pwc->wmSetPixel = &wmSetPixel4;
+                       break;
+               default:
+                       pwc->wmSetPixel = &wmSetPixelDefault;
+                       break;
+       }
+}
+
+#endif
+
+void  wmCreateDIBSection(
+  HDC   hDC,
+  PWMC pwc,    // handle of device context
+  CONST BITMAPINFO *pbmi,  // bitmap size, format, and color data
+  UINT iUsage  // color data type indicator: RGB values or palette indices
+  )
+{
+  DWORD   dwSize = 0;
+  DWORD   dwScanWidth;
+  UINT    nBypp = pwc->cColorBits / 8;
+  HDC     hic;
+  
+  dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
+  
+  pwc->ScanWidth =pwc->pitch = dwScanWidth;
+  
+  if (stereo_flag)
+    pwc->ScanWidth = 2* pwc->pitch;
+  
+  dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
+#ifdef USE_MAPPED_FILE  
+  pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
+                                       NULL,
+                                       PAGE_READWRITE | SEC_COMMIT,
+                                       0,
+                                       dwSize,
+                                       NULL);
+  
+  if (!pwc->dib.hFileMap)
+    return;
+  
+  pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
+                               FILE_MAP_ALL_ACCESS,
+                               0,
+                               0,
+                               0);
+  
+  if(!pwc->dib.base){
+    CloseHandle(pwc->dib.hFileMap);
+    return;
+  }
+
+
+  CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
+#endif // USE_MAPPED_FILE
+  
+  hic = CreateIC("display", NULL, NULL, NULL);
+  pwc->dib.hDC = CreateCompatibleDC(hic);
+  
+#ifdef USE_MAPPED_FILE  
+
+  pwc->hbmDIB = CreateDIBSection(hic,
+                                &(pwc->bmi),
+                                (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
+                                &(pwc->pbPixels),
+                                pwc->dib.hFileMap,
+                                0);
+#else
+  pwc->hbmDIB = CreateDIBSection(hic,
+                                &(pwc->bmi),
+                                (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
+                                &(pwc->pbPixels),
+                                0,
+                                0);
+#endif // USE_MAPPED_FILE
+  pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;
+  pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
+  
+  DeleteDC(hic);
+  
+  return;
+  
+}
+
+/*
+ * Blit memory DC to screen DC
+ */
+BOOL wmFlush(PWMC pwc)
+{
+  BOOL    bRet = 0;
+  DWORD   dwErr = 0;
+#ifdef DDRAW
+  HRESULT             ddrval;
+#endif
+  
+  if(pwc->db_flag){
+#ifdef DDRAW
+    if (pwc->lpDDSOffScreen == NULL)
+      if(DDCreateOffScreen(pwc) == GL_FALSE)
+       return FALSE;
+    
+    pwc->lpDDSOffScreen->lpVtbl->Unlock(pwc->lpDDSOffScreen, NULL);
+    
+    while( 1 )
+      {
+       ddrval = pwc->lpDDSPrimary->lpVtbl->Blt( pwc->lpDDSPrimary,
+                                                &(pwc->rectSurface), 
+                                                pwc->lpDDSOffScreen, 
+                                                &(pwc->rectOffScreen), 
+                                                0, NULL );
+       
+       if( ddrval == DD_OK )
+         {
+           break;
+         }
+       if( ddrval == DDERR_SURFACELOST )
+         {
+           if(!DDRestoreAll(pwc))
+             {
+               break;
+             }
+         }
+       if( ddrval != DDERR_WASSTILLDRAWING )
+         {
+           break;
+         }
+      }
+    
+    while (pwc->lpDDSOffScreen->lpVtbl->Lock(pwc->lpDDSOffScreen,
+                                            NULL, &(pwc->ddsd), 0, NULL) == 
+          DDERR_WASSTILLDRAWING)
+      ;
+    
+    if(ddrval != DD_OK)
+      dwErr = GetLastError();
+#else
+    bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,
+                 pwc->dib.hDC, 0, 0, SRCCOPY);
+#endif
+  }
+  
+  return(TRUE);
+  
+}
+
+
+/* The following code is added by Li Wei to enable stereo display */
+
+#if !defined(NO_STEREO)
+
+static void __gluMakeIdentityf(GLfloat m[16])
+{
+    m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
+    m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
+    m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
+    m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
+}
+
+static void normalize(float v[3])
+{
+    float r;
+
+    r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
+    if (r == 0.0) return;
+
+    v[0] /= r;
+    v[1] /= r;
+    v[2] /= r;
+}
+
+static void cross(float v1[3], float v2[3], float result[3])
+{
+    result[0] = v1[1]*v2[2] - v1[2]*v2[1];
+    result[1] = v1[2]*v2[0] - v1[0]*v2[2];
+    result[2] = v1[0]*v2[1] - v1[1]*v2[0];
+}
+
+
+static void 
+__gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
+         GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
+         GLdouble upz)
+{
+    int i;
+    float forward[3], side[3], up[3];
+    GLfloat m[4][4];
+
+    forward[0] = centerx - eyex;
+    forward[1] = centery - eyey;
+    forward[2] = centerz - eyez;
+
+    up[0] = upx;
+    up[1] = upy;
+    up[2] = upz;
+
+    normalize(forward);
+
+    /* Side = forward x up */
+    cross(forward, up, side);
+    normalize(side);
+
+    /* Recompute up as: up = side x forward */
+    cross(side, forward, up);
+
+    __gluMakeIdentityf(&m[0][0]);
+    m[0][0] = side[0];
+    m[1][0] = side[1];
+    m[2][0] = side[2];
+
+    m[0][1] = up[0];
+    m[1][1] = up[1];
+    m[2][1] = up[2];
+
+    m[0][2] = -forward[0];
+    m[1][2] = -forward[1];
+    m[2][2] = -forward[2];
+
+    glMultMatrixf(&m[0][0]);
+    glTranslated(-eyex, -eyey, -eyez);
+}
+
+GLfloat viewDistance = 1.0;
+
+void WMesaShowStereo(GLuint list)
+{
+  
+  GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
+  GLfloat cm[16];
+  GLint matrix_mode;
+  /* Must use double Buffer */
+  if( ! Current-> db_flag )
+    return;
+  
+  
+  glGetIntegerv(GL_MATRIX_MODE,&matrix_mode);
+  
+  WMesaViewport(Current->gl_ctx,0,Current->height/2,
+               Current->width,Current->height/2);
+  if(matrix_mode!=GL_MODELVIEW)
+    glMatrixMode(GL_MODELVIEW);
+  
+  glGetFloatv(GL_MODELVIEW_MATRIX,cm);
+  glLoadIdentity();
+  __gluLookAt(viewDistance/2,0.0,0.0 ,
+           viewDistance/2,0.0,-1.0,
+           0.0,1.0,0.0 );
+  glMultMatrixf( cm );
+  
+  Current->ScreenMem = Current->pbPixels = Current->addrOffScreen;
+  glCallList( list );
+  
+  glGetFloatv(GL_MODELVIEW_MATRIX,cm);
+  glLoadIdentity();
+  __gluLookAt(-viewDistance/2,0.0,0.0 ,
+           -viewDistance/2,0.0,-1.0,
+           0.0,1.0,0.0 );
+  glMultMatrixf(cm);
+  
+  Current->ScreenMem = Current->pbPixels = Current->addrOffScreen + Current->pitch;
+  glCallList(list);
+  if(matrix_mode!=GL_MODELVIEW)
+    glMatrixMode(matrix_mode);
+  
+  glFlush();
+  
+  WMesaViewport(Current->gl_ctx,0,0,Current->width,Current->height);
+  WMesaSwapBuffers();
+}
+
+void toggleStereoMode()
+{
+  if(!Current->db_flag)
+    return;
+  if(!stereo_flag){
+    stereo_flag = 1;
+    if(stereoBuffer==GL_FALSE)
+#if !defined(NO_PARALLEL)
+      if(!parallelFlag)
+#endif
+       {
+         Current->ScanWidth = Current->pitch*2;
+       }
+  }
+  else {
+    stereo_flag = 0;
+#if !defined(NO_PARALLEL)
+    if(!parallelFlag)
+#endif
+      Current->ScanWidth = Current->pitch;
+    Current->pbPixels = Current->addrOffScreen;
+  }
+}
+
+/* if in stereo mode, the following function is called */
+void glShowStereo(GLuint list)
+{
+  WMesaShowStereo(list);
+}
+
+#endif /* NO_STEREO */
+
+#if !defined(NO_PARALLEL)
+
+void toggleParallelMode(void)
+{
+  if(!parallelFlag){
+    parallelFlag = GL_TRUE;
+    if(parallelMachine==GL_FALSE){
+      PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
+                           Current->cColorBits/8,
+                           Current->width ,Current->height,
+                           Current->ScanWidth,
+                           Current->rgb_flag? Current->pbPixels: 
+                           Current->ScreenMem);
+      parallelMachine = GL_TRUE;
+    }
+  }
+  else {
+    parallelFlag = GL_FALSE;
+    if(parallelMachine==GL_TRUE){
+      PRDestroyRenderBuffer();
+      parallelMachine=GL_FALSE;
+      ReadyForNextFrame = GL_TRUE;
+    }
+    
+    /***********************************************
+     * Seems something wrong!!!!
+     ************************************************/
+    
+    WMesaMakeCurrent(Current);
+#if !defined(NO_STEREO)
+    stereo_flag = GL_FALSE ;
+#endif
+  }
+}
+
+void PRShowRenderResult(void)
+{
+  int flag = 0;
+  if(!glImageRendered())
+    return;
+  
+  if (parallelFlag)
+    {
+      WMesaSwapBuffers();
+    }
+  
+}
+#endif /* NO_PARALLEL */
+
+BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)
+{
+  char unsigned redtemp, greentemp, bluetemp, paletteindex;
+  
+  //*** now, look up each value in the halftone matrix
+  //*** using an 8x8 ordered dither.
+  redtemp = aDividedBy51[red]
+    + (aModulo51[red] > aHalftone8x8[(pixel%8)*8
+                                   + scanline%8]);
+  greentemp = aDividedBy51[(char unsigned)green]
+    + (aModulo51[green] > aHalftone8x8[
+      (pixel%8)*8 + scanline%8]);
+  bluetemp = aDividedBy51[(char unsigned)blue]
+    + (aModulo51[blue] > aHalftone8x8[
+      (pixel%8)*8 +scanline%8]);
+  
+  //*** recombine the halftoned rgb values into a palette index
+  paletteindex =
+    redtemp + aTimes6[greentemp] + aTimes36[bluetemp];
+  
+  //*** and translate through the wing halftone palette
+  //*** translation vector to give the correct value.
+  return aWinGHalftoneTranslation[paletteindex];
+}
+
+#ifdef DDRAW
+/*
+ * restoreAll
+ *
+ * restore all lost objects
+ */
+HRESULT DDRestoreAll( WMesaContext wc )
+{
+  HRESULT     ddrval;
+  
+  ddrval = wc->lpDDSPrimary->lpVtbl->Restore(wc->lpDDSPrimary);
+  if( ddrval == DD_OK )
+    {
+      ddrval = wc->lpDDSOffScreen->lpVtbl->Restore(wc->lpDDSOffScreen);
+    }
+  return ddrval;
+  
+} /* restoreAll */
+
+
+/*
+ * This function is called if the initialization function fails
+ */
+BOOL initFail( HWND hwnd, WMesaContext wc )
+{
+  DDFree(wc);
+  MessageBox( hwnd, "DirectDraw Init FAILED", "", MB_OK );
+  return FALSE;
+  
+} /* initFail */
+
+
+static void DDDeleteOffScreen(WMesaContext wc)
+{
+  if( wc->lpDDSOffScreen != NULL )
+    {
+      wc->lpDDSOffScreen->lpVtbl->Unlock(wc->lpDDSOffScreen,NULL);
+      wc->lpDDSOffScreen->lpVtbl->Release(wc->lpDDSOffScreen);
+      wc->lpDDSOffScreen = NULL;
+    }
+  
+}
+
+static void DDFreePrimarySurface(WMesaContext wc)
+{
+  if( wc->lpDDSPrimary != NULL )
+    {
+      if(wc->db_flag == GL_FALSE)
+       wc->lpDDSPrimary->lpVtbl->ReleaseDC(wc->lpDDSPrimary, wc->hDC);
+      wc->lpDDSPrimary->lpVtbl->Release(wc->lpDDSPrimary);
+      wc->lpDDSPrimary = NULL;
+    }
+}
+
+static BOOL DDCreatePrimarySurface(WMesaContext wc)
+{
+  HRESULT ddrval;
+//  DDSCAPS             ddscaps;
+  wc->ddsd.dwSize = sizeof( wc->ddsd );
+  wc->ddsd.dwFlags = DDSD_CAPS;
+  wc->ddsd.ddsCaps.dwCaps =   DDSCAPS_PRIMARYSURFACE;
+  
+  ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD,&(wc->ddsd), 
+                                           &(wc->lpDDSPrimary), NULL );
+  if( ddrval != DD_OK )
+    {
+      return initFail(wc->hwnd , wc);
+    }
+  if(wc->db_flag == GL_FALSE)
+    wc->lpDDSPrimary->lpVtbl->GetDC(wc->lpDDSPrimary, &(wc->hDC));
+  return TRUE;
+}
+
+static BOOL DDCreateOffScreen(WMesaContext wc)
+{
+  POINT   pt;
+  HRESULT     ddrval;
+  if(wc->lpDD == NULL)
+    return FALSE;
+  GetClientRect( wc->hwnd, &(wc->rectOffScreen) );
+  wc->ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
+  wc->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+  wc->ddsd.dwHeight = wc->rectOffScreen.bottom - wc->rectOffScreen.top;
+  wc->ddsd.dwWidth = wc->rectOffScreen.right - wc->rectOffScreen.left;
+  
+  ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD, &(wc->ddsd), 
+                                           &(wc->lpDDSOffScreen), NULL );
+  if( ddrval != DD_OK )
+    {
+      return FALSE;
+    }
+  
+  while (wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, 
+                                         &(wc->ddsd), 0, NULL) == 
+        DDERR_WASSTILLDRAWING)
+    ;
+  
+  if(wc->ddsd.lpSurface==NULL)
+    return initFail(wc->hwnd, wc);
+  
+  wc->ScreenMem = wc->pbPixels = wc->addrOffScreen = 
+    (PBYTE)(wc->ddsd.lpSurface);
+  wc->ScanWidth = wc->pitch = wc->ddsd.lPitch;
+  if (stereo_flag)
+    wc->ScanWidth = wc->ddsd.lPitch*2;
+  
+  GetClientRect( wc->hwnd, &(wc->rectSurface) );
+  pt.x = pt.y = 0;
+  ClientToScreen( wc->hwnd, &pt );
+  OffsetRect(&(wc->rectSurface), pt.x, pt.y);
+  wmSetPixelFormat(wc, wc->hDC);
+  return TRUE;
+}
+
+typedef
+struct tagWMesaContextList
+{
+       WMesaContext wc;
+       struct tagWMesaContextList *next;
+}WMesaContextList;
+
+WMesaContextList *head = 0;
+
+void AddContext(WMesaContext wc)
+{
+       WMesaContextList *lst = (WMesaContextList *)malloc(sizeof(WMesaContextList));
+       lst->wc = wc;
+       if( head )
+               lst->next = head;
+       head = lst;
+}
+
+WMesaContext FindContext(HWND hWnd)
+{
+       WMesaContextList *tmp = head;
+       while(tmp)
+       {
+               if( tmp->wc->hwnd == hWnd )
+                       return tmp->wc;
+               tmp = tmp->next;
+       }
+       return NULL;
+}
+
+void RemoveContext(HWND hWnd)
+{
+       WMesaContextList *tmp = head;
+       if(tmp )
+       {
+               if( tmp->wc->hwnd == hWnd )
+               {
+                       WMesaContextList *lst = tmp;
+
+                       head = tmp->next;
+                       free((void *)lst);
+               }
+               else
+                       while(tmp->next)
+                       {
+                               if( tmp->next->wc->hwnd == hWnd )
+                               {
+                                       WMesaContextList *lst = tmp->next;
+                                       tmp->next = tmp->next->next;
+                                       free((void *)lst);
+                               }
+                               tmp = tmp->next;
+                       }
+       }
+}
+
+static LRESULT CALLBACK MyWndProc(HWND hwnd,UINT message,WPARAM wParam, LPARAM lParam)
+{
+       WMesaContext wc = Current->hwnd == hwnd ? Current : FindContext(hwnd);
+        if( wc )
+        {
+               LRESULT lret = CallWindowProc((WNDPROC)(wc->oldWndProc),hwnd,message,wParam,lParam);
+               if( message = WM_MOVE )
+               {
+                        POINT pt = {0};
+                       GetClientRect( wc->hwnd, &(wc->rectSurface) );
+                       ClientToScreen( hwnd, &pt );
+                       OffsetRect(&(wc->rectSurface), pt.x, pt.y);
+                }
+               return lret;
+       }
+        return 0L;
+}
+
+/*
+ * doInit - do work required for every instance of the application:
+ *                create the window, initialize data
+ */
+static BOOL DDInit( WMesaContext wc, HWND hwnd)
+{
+  HRESULT             ddrval;
+//  DWORD dwFrequency;
+  
+//  LPDIRECTDRAW            lpDD;           // DirectDraw object
+//  LPDIRECTDRAW2            lpDD2;
+  LPDIRECTDRAWCLIPPER pcClipper = NULL;
+  
+  wc->fullScreen = displayOptions.fullScreen;
+  wc->gMode = displayOptions.mode;
+  wc->hwnd = hwnd;
+  stereo_flag = displayOptions.stereo;
+  if(wc->db_flag!= GL_TRUE)
+    stereo_flag = GL_FALSE;
+  /*
+   * create the main DirectDraw object
+   */
+  ddrval = DirectDrawCreate( NULL, &(wc->lpDD), NULL );
+  if( ddrval != DD_OK )
+    {
+      return initFail(hwnd,wc);
+    }
+  
+  // Get exclusive mode if requested
+  if(wc->fullScreen)
+    {
+      ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, 
+                                                     DDSCL_EXCLUSIVE | 
+                                                     DDSCL_FULLSCREEN );
+    }
+  else
+    {
+      ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, 
+                                                     DDSCL_NORMAL );
+    }
+  if( ddrval != DD_OK )
+    {
+      return initFail(hwnd , wc);
+    }
+  
+  
+  if(ddrval != DD_OK)
+    return initFail(hwnd , wc);
+  
+  
+  switch( wc->gMode )
+    {
+    case 1:  
+      ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 640, 480, 
+                                                displayOptions.bpp); 
+      break;
+    case 2:  
+      ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 800, 600, 
+                                                displayOptions.bpp); 
+      break;
+    case 3:  
+      ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1024, 768, 
+                                                displayOptions.bpp); 
+      break;
+    case 4:  
+      ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1152, 864, 
+                                                displayOptions.bpp); 
+      break;
+    case 5:  
+      ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1280, 1024, 
+                                                displayOptions.bpp); 
+      break;
+    }
+
+  if( ddrval != DD_OK )
+    {
+      printf("Can't modify display mode, current mode used\n");
+    }
+  switch(ddrval){
+  case DDERR_INVALIDOBJECT:
+    break;
+  case DDERR_INVALIDPARAMS:
+    break;
+  case DDERR_UNSUPPORTEDMODE:
+    ;
+  }
+  
+  if(DDCreatePrimarySurface(wc) == GL_FALSE)
+    return initFail(hwnd, wc);
+  
+  if(wc->db_flag)
+    DDCreateOffScreen(wc);
+
+    if( FAILED( ddrval = wc->lpDD->lpVtbl->CreateClipper(wc->lpDD, 0, &pcClipper, NULL ) ) )
+        return E_FAIL;
+
+    if( FAILED( ddrval = pcClipper->lpVtbl->SetHWnd(pcClipper,  0, wc->hwnd ) ) )
+    {
+        pcClipper->lpVtbl->Release(pcClipper);
+        return E_FAIL;
+    }
+
+    if( FAILED( ddrval = wc->lpDDSPrimary->lpVtbl->SetClipper(wc->lpDDSPrimary,  pcClipper ) ) )
+    {
+        pcClipper->lpVtbl->Release(pcClipper);
+        return E_FAIL;
+    }
+
+    // Done with clipper
+    pcClipper->lpVtbl->Release(pcClipper);
+       AddContext(wc);
+       // Hook the window so we can update the drawing rectangle when the window moves
+       wc->oldWndProc = SetWindowLong(wc->hwnd,GWL_WNDPROC,(LONG)MyWndProc);
+
+       return TRUE;
+
+} /* DDInit */
+
+static void DDFree( WMesaContext wc)
+{
+  RemoveContext(wc->hwnd);
+  SetWindowLong(wc->hwnd,GWL_WNDPROC,(LONG)(wc->oldWndProc));
+  wc->oldWndProc = 0;
+  if( wc->lpDD != NULL )
+    {
+      DDFreePrimarySurface(wc);
+      DDDeleteOffScreen(wc);
+      wc->lpDD->lpVtbl->Release(wc->lpDD);
+      wc->lpDD = NULL;
+    }
+  // Clean up the screen on exit
+  RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
+               RDW_ALLCHILDREN );
+  
+}
+#endif
+
+void WMesaMove(void)
+{
+  WMesaContext wc = Current;
+  POINT   pt;
+  if (Current != NULL){
+    GetClientRect( wc->hwnd, &(wc->rectSurface) );
+    pt.x = pt.y = 0;
+    ClientToScreen( wc->hwnd, &pt );
+    OffsetRect(&(wc->rectSurface), pt.x, pt.y);
+  }
+}
+
+
+/************************************************
+ * Mesa 4.0 - These triangle rasterizers are not
+ * implemented in this version of the Windows
+ * driver.  They could be implemented for a
+ * potential performance improvement.
+ * See OSMesa for an example of the approach
+ * to use.
+ * This old code is left in this file in case
+ * it is useful.  However, it may end up looking
+ * a lot more like the OSMesa code.
+ ************************************************/
+
+
+#if defined(FAST_RASTERIZERS)
+
+
+/*
+ * Like PACK_8A8B8G8R() but don't use alpha.  This is usually an acceptable
+ * shortcut.
+ */
+#define PACK_8B8G8R( R, G, B )   ( ((B) << 16) | ((G) << 8) | (R) )
+
+/**********************************************************************/
+/***                   Triangle rendering                            ***/
+/**********************************************************************/
+
+/*
+ * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
+ */
+static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx,
+                                       GLuint v0, GLuint v1, GLuint v2,
+                                       GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint i, len = RIGHT-LEFT;                      \
+    for (i=0;i<len;i++) {                       \
+    GLdepth z = FixedToDepth(ffz);                  \
+    if (z < zRow[i]) {                      \
+    pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),    \
+    FixedToInt(ffb) );          \
+    zRow[i] = z;                            \
+    }                                   \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    ffz += fdzdx;                           \
+    }                                   \
+    }
+
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, smooth, depth-buffered, PF_8R8G8B triangle.
+*/
+static void smooth_8R8G8B_z_triangle( GLcontext *ctx,
+                                     GLuint v0, GLuint v1, GLuint v2,
+                                     GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint i, len = RIGHT-LEFT;                      \
+    for (i=0;i<len;i++) {                       \
+    GLdepth z = FixedToDepth(ffz);                  \
+    if (z < zRow[i]) {                      \
+    pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),    \
+    FixedToInt(ffb) );          \
+    zRow[i] = z;                            \
+    }                                   \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    ffz += fdzdx;                           \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+
+/*
+* XImage, smooth, depth-buffered, PF_5R6G5B triangle.
+*/
+static void smooth_5R6G5B_z_triangle( GLcontext *ctx,
+                                     GLuint v0, GLuint v1, GLuint v2,
+                                     GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
+#define PIXEL_TYPE GLushort
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint i, len = RIGHT-LEFT;                      \
+    for (i=0;i<len;i++) {                       \
+    GLdepth z = FixedToDepth(ffz);                  \
+    if (z < zRow[i]) {                      \
+    pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),    \
+    FixedToInt(ffb) );          \
+    zRow[i] = z;                            \
+    }                                   \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    ffz += fdzdx;                           \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+/*
+* XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
+*/
+static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0,
+                                     GLuint v1, GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0],    \
+    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint i, len = RIGHT-LEFT;                      \
+    for (i=0;i<len;i++) {                       \
+    GLdepth z = FixedToDepth(ffz);                  \
+    if (z < zRow[i]) {                      \
+    pRow[i] = p;                            \
+    zRow[i] = z;                            \
+    }                                   \
+    ffz += fdzdx;                           \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, flat, depth-buffered, PF_8R8G8B triangle.
+*/
+static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0],    \
+    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint i, len = RIGHT-LEFT;              \
+    for (i=0;i<len;i++) {               \
+    GLdepth z = FixedToDepth(ffz);          \
+    if (z < zRow[i]) {              \
+    pRow[i] = p;                    \
+    zRow[i] = z;                    \
+    }                           \
+    ffz += fdzdx;                   \
+    }                           \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, flat, depth-buffered, PF_5R6G5B triangle.
+*/
+static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
+#define PIXEL_TYPE GLushort
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0],    \
+    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint i, len = RIGHT-LEFT;              \
+    for (i=0;i<len;i++) {               \
+    GLdepth z = FixedToDepth(ffz);          \
+    if (z < zRow[i]) {              \
+    pRow[i] = p;                    \
+    zRow[i] = z;                    \
+    }                           \
+    ffz += fdzdx;                   \
+    }                           \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
+*/
+static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                     GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint xx;                               \
+    PIXEL_TYPE *pixel = pRow;                       \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
+    *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),     \
+                FixedToInt(ffb) );          \
+                ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
+*/
+static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint xx;                               \
+    PIXEL_TYPE *pixel = pRow;                       \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
+    *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),     \
+                FixedToInt(ffb) );          \
+                ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
+*/
+static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
+#define PIXEL_TYPE GLushort
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint xx;                               \
+    PIXEL_TYPE *pixel = pRow;                       \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
+    *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),     \
+                FixedToInt(ffb) );          \
+                ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+
+/*
+* XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
+*/
+static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0,
+                                   GLuint v1, GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0],    \
+    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint xx;                       \
+    PIXEL_TYPE *pixel = pRow;               \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
+    *pixel = p;                 \
+    }                           \
+    }
+
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
+*/
+static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                 GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0],    \
+    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint xx;                       \
+    PIXEL_TYPE *pixel = pRow;               \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
+    *pixel = p;                 \
+    }                           \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
+*/
+static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                 GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
+#define PIXEL_TYPE GLushort
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0],    \
+    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint xx;                       \
+    PIXEL_TYPE *pixel = pRow;               \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
+    *pixel = p;                 \
+    }                           \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
+*/
+
+static void smooth_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                 GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                                \
+    {                                                                   \
+    GLint i, len = RIGHT-LEFT;                                      \
+    for (i=0;i<len;i++) {                                           \
+    GLdepth z = FixedToDepth(ffz);                              \
+    if (z < zRow[i]) {                                          \
+    pRow[i] = FixedToInt(ffi);                                  \
+    zRow[i] = z;                                                \
+    }                                                               \
+    ffi += fdidx;                                                   \
+    ffz += fdzdx;                                                   \
+    }                                                               \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
+*/
+
+static void flat_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                               GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                     \
+   GLuint index = VB->IndexPtr->data[pv];      \
+   (*ctx->Driver.Index)( ctx, index );
+#define INNER_LOOP( LEFT, RIGHT, Y )   \
+   {                                   \
+      GLint i, len = RIGHT-LEFT;       \
+      for (i=0;i<len;i++) {            \
+         GLdepth z = FixedToDepth(ffz);        \
+         if (z < zRow[i]) {            \
+            pRow[i] = index;           \
+            zRow[i] = z;               \
+         }                             \
+         ffz += fdzdx;                 \
+      }                                        \
+   }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+
+/*
+* XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
+*/
+
+static void smooth_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                               GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint xx;                               \
+    PIXEL_TYPE *pixel = pRow;                       \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
+    *pixel = FixedToInt(ffi);           \
+    ffi += fdidx;           \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
+*/
+static void flat_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                             GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                     \
+   GLuint index = VB->IndexPtr->data[pv];      \
+   (*ctx->Driver.Index)( ctx, index );
+#define INNER_LOOP( LEFT, RIGHT, Y )           \
+   {                                           \
+      GLint xx;                                        \
+      PIXEL_TYPE *pixel = pRow;                        \
+      for (xx=LEFT;xx<RIGHT;xx++,pixel++) {    \
+         *pixel = index;                       \
+      }                                                \
+   }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+/*
+* XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
+*/
+static void smooth_DITHER8_z_triangle( GLcontext *ctx,
+                                      GLuint v0, GLuint v1, GLuint v2,
+                                      GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    DITHER_RGB_TO_8BIT_SETUP
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
+    {                                                                       \
+    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                 \
+    for (i=0;i<len;i++,xx++) {                                          \
+    GLdepth z = FixedToDepth(ffz);                                  \
+    if (z < zRow[i]) {                                              \
+    DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg),           \
+    FixedToInt(ffb), xx, yy);               \
+    pRow[i] = pixelDithered;                                        \
+    zRow[i] = z;                                                    \
+    }                                                                   \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                     \
+    ffz += fdzdx;                                                       \
+    }                                                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+/*
+* XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
+*/
+static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                    GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    DITHER_RGB_TO_8BIT_SETUP
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+
+#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
+    {                                                                       \
+    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                 \
+    for (i=0;i<len;i++,xx++) {                                          \
+    GLdepth z = FixedToDepth(ffz);                                  \
+    if (z < zRow[i]) {                                              \
+    DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0],                           \
+             VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);               \
+             pRow[i] = pixelDithered;                                       \
+             zRow[i] = z;                                                   \
+    }                                                                   \
+    ffz += fdzdx;                                                       \
+    }                                                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+/*
+* XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
+*/
+static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                    GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    DITHER_RGB_TO_8BIT_SETUP
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
+    {                                                                       \
+    GLint xx, yy = FLIP(Y);                                             \
+    PIXEL_TYPE *pixel = pRow;                                           \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \
+    DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0],   VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
+    *pixel = pixelDithered;                                         \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                     \
+    }                                                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+/*
+* XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
+*/
+
+static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                  GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    DITHER_RGB_TO_8BIT_SETUP
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+
+#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
+    {                                                                       \
+    GLint xx, yy = FLIP(Y);                                             \
+    PIXEL_TYPE *pixel = pRow;                                           \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \
+    DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0],                               \
+             VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);               \
+             *pixel = pixelDithered;                                            \
+    }                                                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+//             #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+#endif
+/************** END DEAD TRIANGLE CODE ***********************/
+
+static triangle_func choose_triangle_function( GLcontext *ctx )
+{
+#if 0
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    int depth = wmesa->cColorBits;
+
+    if (ctx->Polygon.SmoothFlag)     return NULL;
+    if (ctx->Texture._EnabledUnits)  return NULL;
+    if (!wmesa->db_flag) return NULL;
+    if (ctx->swrast->_RasterMask & MULTI_DRAW_BIT) return NULL;
+
+    /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
+    if (   ctx->Light.ShadeModel==GL_SMOOTH
+        && ctx->_RasterMask==DEPTH_BIT
+        && ctx->Depth.Func==GL_LESS
+        && ctx->Depth.Mask==GL_TRUE
+        && ctx->Polygon.StippleFlag==GL_FALSE) {
+        switch (wmesa->pixelformat) {
+        case PF_8A8B8G8R:
+            return smooth_8A8B8G8R_z_triangle;
+        case PF_8R8G8B:
+            return smooth_8R8G8B_z_triangle;
+        case PF_5R6G5B:
+            return smooth_5R6G5B_z_triangle;
+        case PF_DITHER8:
+            return  smooth_DITHER8_z_triangle;
+        case PF_INDEX8:
+            return smooth_ci_z_triangle;
+        default:
+            return NULL;
+        }
+    }
+    if (   ctx->Light.ShadeModel==GL_FLAT
+        && ctx->_RasterMask==DEPTH_BIT
+        && ctx->Depth.Func==GL_LESS
+        && ctx->Depth.Mask==GL_TRUE
+        && ctx->Polygon.StippleFlag==GL_FALSE) {
+        switch (wmesa->pixelformat) {
+        case PF_8A8B8G8R:
+            return flat_8A8B8G8R_z_triangle;
+        case PF_8R8G8B:
+            return flat_8R8G8B_z_triangle;
+        case PF_5R6G5B:
+            return flat_5R6G5B_z_triangle;
+        case PF_DITHER8:
+            return flat_DITHER8_z_triangle;
+        case PF_INDEX8:
+            return flat_ci_z_triangle;
+        default:
+            return NULL;
+        }
+    }
+    if (   ctx->_RasterMask==0   /* no depth test */
+        && ctx->Light.ShadeModel==GL_SMOOTH
+        && ctx->Polygon.StippleFlag==GL_FALSE) {
+        switch (wmesa->pixelformat) {
+        case PF_8A8B8G8R:
+            return smooth_8A8B8G8R_triangle;
+        case PF_8R8G8B:
+            return smooth_8R8G8B_triangle;
+        case PF_5R6G5B:
+            return smooth_5R6G5B_triangle;
+        case PF_DITHER8:
+            return smooth_DITHER8_triangle;
+        case PF_INDEX8:
+            return smooth_ci_triangle;
+        default:
+            return NULL;
+        }
+    }
+
+    if (   ctx->_RasterMask==0   /* no depth test */
+        && ctx->Light.ShadeModel==GL_FLAT
+        && ctx->Polygon.StippleFlag==GL_FALSE) {
+        switch (wmesa->pixelformat) {
+        case PF_8A8B8G8R:
+            return flat_8A8B8G8R_triangle;
+        case PF_8R8G8B:
+            return flat_8R8G8B_triangle;
+        case PF_5R6G5B:
+            return flat_5R6G5B_triangle;
+        case PF_DITHER8:
+            return flat_DITHER8_triangle;
+        case PF_INDEX8:
+            return flat_ci_triangle;
+        default:
+            return NULL;
+        }
+    }
+
+    return NULL;
+    }
+#endif
+}
+
+/*
+ * Define a new viewport and reallocate auxillary buffers if the size of
+ * the window (color buffer) has changed.
+ */
+void WMesaViewport( GLcontext *ctx,
+                   GLint x, GLint y, GLsizei width, GLsizei height )
+{
+  assert(0);  /* I don't think that this is being used. */
+#if 0
+  /* Save viewport */
+  ctx->Viewport.X = x;
+  ctx->Viewport.Width = width;
+  ctx->Viewport.Y = y;
+  ctx->Viewport.Height = height;
+  
+  /* compute scale and bias values */
+/* Pre-Keith 3.1 changes
+   ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
+   ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
+   ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
+   ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
+*/
+  ctx->Viewport.WindowMap.m[MAT_SX] = (GLfloat) width / 2.0F;
+  ctx->Viewport.WindowMap.m[MAT_TX] = ctx->Viewport.WindowMap.m[MAT_SX] + x;
+  ctx->Viewport.WindowMap.m[MAT_SY] = (GLfloat) height / 2.0F;
+  ctx->Viewport.WindowMap.m[MAT_TY] = ctx->Viewport.WindowMap.m[MAT_SY] + y;
+#endif
+}
diff --git a/src/mesa/drivers/windows/gdi/wmesadef.h b/src/mesa/drivers/windows/gdi/wmesadef.h
new file mode 100644 (file)
index 0000000..29fff9f
--- /dev/null
@@ -0,0 +1,174 @@
+/*     File name       :       wmesadef.h
+ *  Version            :       2.3
+ *
+ *  Header file for display driver for Mesa 2.3  under
+ *     Windows95, WindowsNT and Win32
+ *
+ *     Copyright (C) 1996-  Li Wei
+ *  Address            :               Institute of Artificial Intelligence
+ *                             :                       & Robotics
+ *                             :               Xi'an Jiaotong University
+ *  Email              :               liwei@aiar.xjtu.edu.cn
+ *  Web page   :               http://sun.aiar.xjtu.edu.cn
+ *
+ *  This file and its associations are partially based on the
+ *  Windows NT driver for Mesa, written by Mark Leaming
+ *  (mark@rsinc.com).
+ */
+
+/*
+ * $Log: wmesadef.h,v 
+ * Revision 1.1.1.1  1999/08/19 00:55:42  jt
+ * Imported source
+ * Revision 1.3  1999/01/03 03:08:57  brian
+ * Ted Jump's change
+ *
+ * Initial version 1997/6/14 CST by Li Wei(liwei@aiar.xjtu.edu.cn)
+ */
+
+/*
+ * $Log: wmesadef.h,v 
+ * Revision 1.1.1.1  1999/08/19 00:55:42  jt
+ * Imported source
+ * Revision 1.3  1999/01/03 03:08:57  brian
+ * Ted Jump's change
+ *
+ * Revision 2.1  1996/11/15 10:54:00  CST by Li Wei(liwei@aiar.xjtu.edu.cn)
+ * a new element added to wmesa_context :
+ * dither_flag
+ */
+
+/*
+ * $Log: wmesadef.h,v 
+ * Revision 1.1.1.1  1999/08/19 00:55:42  jt
+ * Imported source
+ * Revision 1.3  1999/01/03 03:08:57  brian
+ * Ted Jump's change
+ *
+ * Revision 2.0  1996/11/15 10:54:00  CST by Li Wei(liwei@aiar.xjtu.edu.cn)
+ * Initial revision
+ */
+
+
+
+#ifndef DDMESADEF_H
+#define DDMESADEF_H
+
+// uncomment this to use DirectDraw driver
+//#define DDRAW 1
+// uncomment this to use a pointer to a function for setting the pixels
+// in the buffer
+#define COMPILE_SETPIXEL 1
+// uncomment this to enable the fast win32 rasterizers ( commented out for MesaGL 4.0 )
+// #define FAST_RASTERIZERS 1
+// uncomment this to enable setting function pointers once inside of
+// WMesaCreateContext instead of on every call to wmesa_update_state()
+#define SET_FPOINTERS_ONCE 1
+
+
+#include <windows.h>
+#include <GL\gl.h>
+#include "context.h"
+#ifdef DDRAW
+#define DIRECTDRAW_VERSION 0x0100
+       #include <ddraw.h>
+#endif
+//#include "profile.h"
+
+#define REDBITS                0x03
+#define REDSHIFT       0x00
+#define GREENBITS      0x03
+#define GREENSHIFT     0x03
+#define BLUEBITS       0x02
+#define BLUESHIFT      0x06
+
+typedef struct _dibSection{
+       HDC             hDC;
+       HANDLE  hFileMap;
+       BOOL    fFlushed;
+       LPVOID  base;
+}WMDIBSECTION, *PWMDIBSECTION;
+
+#ifdef COMPILE_SETPIXEL
+typedef void (*SETPIXELTYPE)(struct wmesa_context *pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
+#endif
+
+typedef struct wmesa_context{
+    GLcontext *gl_ctx;         /* The core GL/Mesa context */
+       GLvisual *gl_visual;            /* Describes the buffers */
+    GLframebuffer *gl_buffer;  /* Depth, stencil, accum, etc buffers */
+
+
+       HWND                            Window;
+    HDC                 hDC;
+    HPALETTE            hPalette;
+    HPALETTE            hOldPalette;
+    HPEN                hPen;
+    HPEN                hOldPen;
+    HCURSOR             hOldCursor;
+    COLORREF            crColor;
+    // 3D projection stuff
+    RECT                drawRect;
+    UINT                uiDIBoffset;
+    // OpenGL stuff
+    HPALETTE            hGLPalette;
+       GLuint                          width;
+       GLuint                          height;
+       GLuint                          ScanWidth;
+       GLboolean                       db_flag;        //* double buffered?
+       GLboolean                       rgb_flag;       //* RGB mode?
+       GLboolean                       dither_flag;    //* use dither when 256 color mode for RGB?
+       GLuint                          depth;          //* bits per pixel (1, 8, 24, etc)
+       ULONG                           pixel;  // current color index or RGBA pixel value
+       ULONG                           clearpixel; //* pixel for clearing the color buffers
+       PBYTE                           ScreenMem; // WinG memory
+       BITMAPINFO                      *IndexFormat;
+       HPALETTE                        hPal; // Current Palette
+       HPALETTE                        hPalHalfTone;
+
+
+       WMDIBSECTION            dib;
+    BITMAPINFO          bmi;
+    HBITMAP             hbmDIB;
+    HBITMAP             hOldBitmap;
+       HBITMAP                         Old_Compat_BM;
+       HBITMAP                         Compat_BM;            // Bitmap for double buffering
+    PBYTE               pbPixels;
+    int                 nColors;
+       BYTE                            cColorBits;
+       int                                     pixelformat;
+
+#ifdef DDRAW
+       LPDIRECTDRAW            lpDD;           // DirectDraw object
+//     LPDIRECTDRAW2            lpDD2;           // DirectDraw object
+       LPDIRECTDRAWSURFACE     lpDDSPrimary;   // DirectDraw primary surface
+       LPDIRECTDRAWSURFACE     lpDDSOffScreen; // DirectDraw off screen surface
+       LPDIRECTDRAWPALETTE     lpDDPal;        // DirectDraw palette
+       BOOL                    bActive;        // is application active?
+       DDSURFACEDESC           ddsd;                   // surface description
+       int                                     fullScreen;             // fullscreen ?
+       int                                 gMode ;                     // fullscreen mode
+       LONG                                    oldWndProc;             // old Window proc. we need to hook WM_MOVE message to update the drawing rectangle
+#endif
+       RECT                                    rectOffScreen;
+       RECT                                    rectSurface;
+       HWND                                    hwnd;
+       DWORD                                   pitch;
+       PBYTE                                   addrOffScreen;
+#ifdef COMPILE_SETPIXEL
+      SETPIXELTYPE                    wmSetPixel;
+#endif // COMPILE_SETPIXEL
+//#ifdef PROFILE
+//     MESAPROF        profile;
+//#endif
+}  *PWMC;
+
+
+#define PAGE_FILE              0xffffffff
+
+
+
+#endif