From 2702c90d7a39fca2a3319c5e915fd290cb31fc70 Mon Sep 17 00:00:00 2001 From: Radosław Kujawa Date: Fri, 17 Jul 2026 14:54:32 +0200 Subject: Initial import. --- src/mesa/drivers/windows/gdi/colors.h | 539 ++++ src/mesa/drivers/windows/gdi/gdi.dsp | 137 + src/mesa/drivers/windows/gdi/mesa.def | 1057 ++++++ src/mesa/drivers/windows/gdi/wgl.c | 639 ++++ src/mesa/drivers/windows/gdi/wmesa.c | 3353 ++++++++++++++++++++ src/mesa/drivers/windows/gdi/wmesadef.h | 175 + src/mesa/drivers/windows/gldirect/ddlog.c | 192 ++ src/mesa/drivers/windows/gldirect/ddlog.h | 109 + src/mesa/drivers/windows/gldirect/dglcontext.c | 2213 +++++++++++++ src/mesa/drivers/windows/gldirect/dglcontext.h | 281 ++ src/mesa/drivers/windows/gldirect/dglglobals.c | 149 + src/mesa/drivers/windows/gldirect/dglglobals.h | 198 ++ src/mesa/drivers/windows/gldirect/dglmacros.h | 91 + src/mesa/drivers/windows/gldirect/dglpf.c | 620 ++++ src/mesa/drivers/windows/gldirect/dglpf.h | 77 + src/mesa/drivers/windows/gldirect/dglwgl.c | 2958 +++++++++++++++++ src/mesa/drivers/windows/gldirect/dglwgl.h | 102 + src/mesa/drivers/windows/gldirect/dll_main.c | 816 +++++ src/mesa/drivers/windows/gldirect/dllmain.h | 64 + src/mesa/drivers/windows/gldirect/gld_debug_clip.c | 40 + src/mesa/drivers/windows/gldirect/gld_debug_norm.c | 40 + .../drivers/windows/gldirect/gld_debug_xform.c | 42 + src/mesa/drivers/windows/gldirect/gld_dispatch.c | 73 + src/mesa/drivers/windows/gldirect/gld_driver.c | 279 ++ src/mesa/drivers/windows/gldirect/gld_driver.h | 90 + src/mesa/drivers/windows/gldirect/gldlame8.c | 181 ++ src/mesa/drivers/windows/gldirect/opengl32.def | 488 +++ src/mesa/drivers/windows/gldirect/pixpack.h | 108 + src/mesa/drivers/windows/icd/icd.c | 347 ++ src/mesa/drivers/windows/icd/icdlist.h | 336 ++ src/mesa/drivers/windows/icd/mesa.def | 110 + 31 files changed, 15904 insertions(+) create mode 100644 src/mesa/drivers/windows/gdi/colors.h create mode 100644 src/mesa/drivers/windows/gdi/gdi.dsp create mode 100644 src/mesa/drivers/windows/gdi/mesa.def create mode 100644 src/mesa/drivers/windows/gdi/wgl.c create mode 100644 src/mesa/drivers/windows/gdi/wmesa.c create mode 100644 src/mesa/drivers/windows/gdi/wmesadef.h create mode 100644 src/mesa/drivers/windows/gldirect/ddlog.c create mode 100644 src/mesa/drivers/windows/gldirect/ddlog.h create mode 100644 src/mesa/drivers/windows/gldirect/dglcontext.c create mode 100644 src/mesa/drivers/windows/gldirect/dglcontext.h create mode 100644 src/mesa/drivers/windows/gldirect/dglglobals.c create mode 100644 src/mesa/drivers/windows/gldirect/dglglobals.h create mode 100644 src/mesa/drivers/windows/gldirect/dglmacros.h create mode 100644 src/mesa/drivers/windows/gldirect/dglpf.c create mode 100644 src/mesa/drivers/windows/gldirect/dglpf.h create mode 100644 src/mesa/drivers/windows/gldirect/dglwgl.c create mode 100644 src/mesa/drivers/windows/gldirect/dglwgl.h create mode 100644 src/mesa/drivers/windows/gldirect/dll_main.c create mode 100644 src/mesa/drivers/windows/gldirect/dllmain.h create mode 100644 src/mesa/drivers/windows/gldirect/gld_debug_clip.c create mode 100644 src/mesa/drivers/windows/gldirect/gld_debug_norm.c create mode 100644 src/mesa/drivers/windows/gldirect/gld_debug_xform.c create mode 100644 src/mesa/drivers/windows/gldirect/gld_dispatch.c create mode 100644 src/mesa/drivers/windows/gldirect/gld_driver.c create mode 100644 src/mesa/drivers/windows/gldirect/gld_driver.h create mode 100644 src/mesa/drivers/windows/gldirect/gldlame8.c create mode 100644 src/mesa/drivers/windows/gldirect/opengl32.def create mode 100644 src/mesa/drivers/windows/gldirect/pixpack.h create mode 100644 src/mesa/drivers/windows/icd/icd.c create mode 100644 src/mesa/drivers/windows/icd/icdlist.h create mode 100644 src/mesa/drivers/windows/icd/mesa.def (limited to 'src/mesa/drivers/windows') diff --git a/src/mesa/drivers/windows/gdi/colors.h b/src/mesa/drivers/windows/gdi/colors.h new file mode 100644 index 0000000..5ee66e8 --- /dev/null +++ b/src/mesa/drivers/windows/gdi/colors.h @@ -0,0 +1,539 @@ +/* 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.2 2004/08/25 15:59:48 brianp + * Silence gcc 3.4 warnings on ReactOS. Mostly unused var warnings. (patch 1015696) + * + * 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.2 2004/08/25 15:59:48 brianp + * Silence gcc 3.4 warnings on ReactOS. Mostly unused var warnings. (patch 1015696) + * + * 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.2 2004/08/25 15:59:48 brianp + * Silence gcc 3.4 warnings on ReactOS. Mostly unused var warnings. (patch 1015696) + * + * 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/gdi.dsp b/src/mesa/drivers/windows/gdi/gdi.dsp new file mode 100644 index 0000000..886cbd6 --- /dev/null +++ b/src/mesa/drivers/windows/gdi/gdi.dsp @@ -0,0 +1,137 @@ +# Microsoft Developer Studio Project File - Name="gdi" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=gdi - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gdi.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gdi.mak" CFG="gdi - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gdi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "gdi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gdi - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDI_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../../../../src/mesa/main" /I "../../../../../src/mesa/glapi" /I "../../../../../src/mesa/math" /I "../../../../../src/mesa/transform" /I "../../../../../src/mesa/swrast" /I "../../../../../src/mesa/swrast_setup" /I "../../../../../include" /I "../../../../../src/mesa" /I "../../../../../src/mesa/shader" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDI_EXPORTS" /D "BUILD_GL32" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 winmm.lib msvcrt.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /nodefaultlib /out:"Release/OPENGL32.DLL" +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Desc=Copy import lib and dll +PostBuild_Cmds=if not exist ..\..\..\..\..\lib md ..\..\..\..\..\lib copy Release\OPENGL32.LIB ..\..\..\..\..\lib copy Release\OPENGL32.DLL ..\..\..\..\..\lib +# End Special Build Tool + +!ELSEIF "$(CFG)" == "gdi - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDI_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../../../src/mesa/main" /I "../../../../../src/mesa/glapi" /I "../../../../../src/mesa/math" /I "../../../../../src/mesa/transform" /I "../../../../../src/mesa/swrast" /I "../../../../../src/mesa/swrast_setup" /I "../../../../../include" /I "../../../../../src/mesa" /I "../../../../../src/mesa/shader" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDI_EXPORTS" /D "BUILD_GL32" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 winmm.lib msvcrtd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /nodefaultlib /out:"Debug/OPENGL32.DLL" /pdbtype:sept +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Desc=Copy import lib and dll +PostBuild_Cmds=if not exist ..\..\..\..\..\lib md ..\..\..\..\..\lib copy Debug\OPENGL32.LIB ..\..\..\..\..\lib copy Debug\OPENGL32.DLL ..\..\..\..\..\lib +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "gdi - Win32 Release" +# Name "gdi - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\common\driverfuncs.c +# End Source File +# Begin Source File + +SOURCE=.\mesa.def +# End Source File +# Begin Source File + +SOURCE=.\wgl.c +# End Source File +# Begin Source File + +SOURCE=.\wmesa.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\common\driverfuncs.h +# End Source File +# Begin Source File + +SOURCE=.\wmesadef.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/src/mesa/drivers/windows/gdi/mesa.def b/src/mesa/drivers/windows/gdi/mesa.def new file mode 100644 index 0000000..a393149 --- /dev/null +++ b/src/mesa/drivers/windows/gdi/mesa.def @@ -0,0 +1,1057 @@ +; DO NOT EDIT - This file generated automatically by mesadef.py script +DESCRIPTION 'Mesa (OpenGL work-alike) for Win32' +VERSION 6.0 +; +; Module definition file for Mesa (OPENGL32.DLL) +; +; Note: The OpenGL functions use the STDCALL +; function calling convention. Microsoft's +; OPENGL32 uses this convention and so must the +; Mesa OPENGL32 so that the Mesa DLL can be used +; as a drop-in replacement. +; +; The linker exports STDCALL entry points with +; 'decorated' names; e.g., _glBegin@0, where the +; trailing number is the number of bytes of +; parameter data pushed onto the stack. The +; callee is responsible for popping this data +; off the stack, usually via a RETF n instruction. +; +; However, the Microsoft OPENGL32.DLL does not export +; the decorated names, even though the calling convention +; is STDCALL. So, this module definition file is +; needed to force the Mesa OPENGL32.DLL to export the +; symbols in the same manner as the Microsoft DLL. +; Were it not for this problem, this file would not +; be needed (for the gl* functions) since the entry +; points are compiled with dllexport declspec. +; +; However, this file is still needed to export "internal" +; Mesa symbols for the benefit of the OSMESA32.DLL. +; +EXPORTS + glNewList + glEndList + glCallList + glCallLists + glDeleteLists + glGenLists + glListBase + glBegin + glBitmap + glColor3b + glColor3bv + glColor3d + glColor3dv + glColor3f + glColor3fv + glColor3i + glColor3iv + glColor3s + glColor3sv + glColor3ub + glColor3ubv + glColor3ui + glColor3uiv + glColor3us + glColor3usv + glColor4b + glColor4bv + glColor4d + glColor4dv + glColor4f + glColor4fv + glColor4i + glColor4iv + glColor4s + glColor4sv + glColor4ub + glColor4ubv + glColor4ui + glColor4uiv + glColor4us + glColor4usv + glEdgeFlag + glEdgeFlagv + glEnd + glIndexd + glIndexdv + glIndexf + glIndexfv + glIndexi + glIndexiv + glIndexs + glIndexsv + glNormal3b + glNormal3bv + glNormal3d + glNormal3dv + glNormal3f + glNormal3fv + glNormal3i + glNormal3iv + glNormal3s + glNormal3sv + glRasterPos2d + glRasterPos2dv + glRasterPos2f + glRasterPos2fv + glRasterPos2i + glRasterPos2iv + glRasterPos2s + glRasterPos2sv + glRasterPos3d + glRasterPos3dv + glRasterPos3f + glRasterPos3fv + glRasterPos3i + glRasterPos3iv + glRasterPos3s + glRasterPos3sv + glRasterPos4d + glRasterPos4dv + glRasterPos4f + glRasterPos4fv + glRasterPos4i + glRasterPos4iv + glRasterPos4s + glRasterPos4sv + glRectd + glRectdv + glRectf + glRectfv + glRecti + glRectiv + glRects + glRectsv + glTexCoord1d + glTexCoord1dv + glTexCoord1f + glTexCoord1fv + glTexCoord1i + glTexCoord1iv + glTexCoord1s + glTexCoord1sv + glTexCoord2d + glTexCoord2dv + glTexCoord2f + glTexCoord2fv + glTexCoord2i + glTexCoord2iv + glTexCoord2s + glTexCoord2sv + glTexCoord3d + glTexCoord3dv + glTexCoord3f + glTexCoord3fv + glTexCoord3i + glTexCoord3iv + glTexCoord3s + glTexCoord3sv + glTexCoord4d + glTexCoord4dv + glTexCoord4f + glTexCoord4fv + glTexCoord4i + glTexCoord4iv + glTexCoord4s + glTexCoord4sv + glVertex2d + glVertex2dv + glVertex2f + glVertex2fv + glVertex2i + glVertex2iv + glVertex2s + glVertex2sv + glVertex3d + glVertex3dv + glVertex3f + glVertex3fv + glVertex3i + glVertex3iv + glVertex3s + glVertex3sv + glVertex4d + glVertex4dv + glVertex4f + glVertex4fv + glVertex4i + glVertex4iv + glVertex4s + glVertex4sv + glClipPlane + glColorMaterial + glCullFace + glFogf + glFogfv + glFogi + glFogiv + glFrontFace + glHint + glLightf + glLightfv + glLighti + glLightiv + glLightModelf + glLightModelfv + glLightModeli + glLightModeliv + glLineStipple + glLineWidth + glMaterialf + glMaterialfv + glMateriali + glMaterialiv + glPointSize + glPolygonMode + glPolygonStipple + glScissor + glShadeModel + glTexParameterf + glTexParameterfv + glTexParameteri + glTexParameteriv + glTexImage1D + glTexImage2D + glTexEnvf + glTexEnvfv + glTexEnvi + glTexEnviv + glTexGend + glTexGendv + glTexGenf + glTexGenfv + glTexGeni + glTexGeniv + glFeedbackBuffer + glSelectBuffer + glRenderMode + glInitNames + glLoadName + glPassThrough + glPopName + glPushName + glDrawBuffer + glClear + glClearAccum + glClearIndex + glClearColor + glClearStencil + glClearDepth + glStencilMask + glColorMask + glDepthMask + glIndexMask + glAccum + glDisable + glEnable + glFinish + glFlush + glPopAttrib + glPushAttrib + glMap1d + glMap1f + glMap2d + glMap2f + glMapGrid1d + glMapGrid1f + glMapGrid2d + glMapGrid2f + glEvalCoord1d + glEvalCoord1dv + glEvalCoord1f + glEvalCoord1fv + glEvalCoord2d + glEvalCoord2dv + glEvalCoord2f + glEvalCoord2fv + glEvalMesh1 + glEvalPoint1 + glEvalMesh2 + glEvalPoint2 + glAlphaFunc + glBlendFunc + glLogicOp + glStencilFunc + glStencilOp + glDepthFunc + glPixelZoom + glPixelTransferf + glPixelTransferi + glPixelStoref + glPixelStorei + glPixelMapfv + glPixelMapuiv + glPixelMapusv + glReadBuffer + glCopyPixels + glReadPixels + glDrawPixels + glGetBooleanv + glGetClipPlane + glGetDoublev + glGetError + glGetFloatv + glGetIntegerv + glGetLightfv + glGetLightiv + glGetMapdv + glGetMapfv + glGetMapiv + glGetMaterialfv + glGetMaterialiv + glGetPixelMapfv + glGetPixelMapuiv + glGetPixelMapusv + glGetPolygonStipple + glGetString + glGetTexEnvfv + glGetTexEnviv + glGetTexGendv + glGetTexGenfv + glGetTexGeniv + glGetTexImage + glGetTexParameterfv + glGetTexParameteriv + glGetTexLevelParameterfv + glGetTexLevelParameteriv + glIsEnabled + glIsList + glDepthRange + glFrustum + glLoadIdentity + glLoadMatrixf + glLoadMatrixd + glMatrixMode + glMultMatrixf + glMultMatrixd + glOrtho + glPopMatrix + glPushMatrix + glRotated + glRotatef + glScaled + glScalef + glTranslated + glTranslatef + glViewport + glArrayElement + glColorPointer + glDisableClientState + glDrawArrays + glDrawElements + glEdgeFlagPointer + glEnableClientState + glGetPointerv + glIndexPointer + glInterleavedArrays + glNormalPointer + glTexCoordPointer + glVertexPointer + glPolygonOffset + glCopyTexImage1D + glCopyTexImage2D + glCopyTexSubImage1D + glCopyTexSubImage2D + glTexSubImage1D + glTexSubImage2D + glAreTexturesResident + glBindTexture + glDeleteTextures + glGenTextures + glIsTexture + glPrioritizeTextures + glIndexub + glIndexubv + glPopClientAttrib + glPushClientAttrib + glBlendColor + glBlendEquation + glDrawRangeElements + glColorTable + glColorTableParameterfv + glColorTableParameteriv + glCopyColorTable + glGetColorTable + glGetColorTableParameterfv + glGetColorTableParameteriv + glColorSubTable + glCopyColorSubTable + glConvolutionFilter1D + glConvolutionFilter2D + glConvolutionParameterf + glConvolutionParameterfv + glConvolutionParameteri + glConvolutionParameteriv + glCopyConvolutionFilter1D + glCopyConvolutionFilter2D + glGetConvolutionFilter + glGetConvolutionParameterfv + glGetConvolutionParameteriv + glGetSeparableFilter + glSeparableFilter2D + glGetHistogram + glGetHistogramParameterfv + glGetHistogramParameteriv + glGetMinmax + glGetMinmaxParameterfv + glGetMinmaxParameteriv + glHistogram + glMinmax + glResetHistogram + glResetMinmax + glTexImage3D + glTexSubImage3D + glCopyTexSubImage3D + glActiveTextureARB + glClientActiveTextureARB + glMultiTexCoord1dARB + glMultiTexCoord1dvARB + glMultiTexCoord1fARB + glMultiTexCoord1fvARB + glMultiTexCoord1iARB + glMultiTexCoord1ivARB + glMultiTexCoord1sARB + glMultiTexCoord1svARB + glMultiTexCoord2dARB + glMultiTexCoord2dvARB + glMultiTexCoord2fARB + glMultiTexCoord2fvARB + glMultiTexCoord2iARB + glMultiTexCoord2ivARB + glMultiTexCoord2sARB + glMultiTexCoord2svARB + glMultiTexCoord3dARB + glMultiTexCoord3dvARB + glMultiTexCoord3fARB + glMultiTexCoord3fvARB + glMultiTexCoord3iARB + glMultiTexCoord3ivARB + glMultiTexCoord3sARB + glMultiTexCoord3svARB + glMultiTexCoord4dARB + glMultiTexCoord4dvARB + glMultiTexCoord4fARB + glMultiTexCoord4fvARB + glMultiTexCoord4iARB + glMultiTexCoord4ivARB + glMultiTexCoord4sARB + glMultiTexCoord4svARB + glLoadTransposeMatrixfARB + glLoadTransposeMatrixdARB + glMultTransposeMatrixfARB + glMultTransposeMatrixdARB + glSampleCoverageARB + glCompressedTexImage3DARB + glCompressedTexImage2DARB + glCompressedTexImage1DARB + glCompressedTexSubImage3DARB + glCompressedTexSubImage2DARB + glCompressedTexSubImage1DARB + glGetCompressedTexImageARB + glActiveTexture + glClientActiveTexture + glMultiTexCoord1d + glMultiTexCoord1dv + glMultiTexCoord1f + glMultiTexCoord1fv + glMultiTexCoord1i + glMultiTexCoord1iv + glMultiTexCoord1s + glMultiTexCoord1sv + glMultiTexCoord2d + glMultiTexCoord2dv + glMultiTexCoord2f + glMultiTexCoord2fv + glMultiTexCoord2i + glMultiTexCoord2iv + glMultiTexCoord2s + glMultiTexCoord2sv + glMultiTexCoord3d + glMultiTexCoord3dv + glMultiTexCoord3f + glMultiTexCoord3fv + glMultiTexCoord3i + glMultiTexCoord3iv + glMultiTexCoord3s + glMultiTexCoord3sv + glMultiTexCoord4d + glMultiTexCoord4dv + glMultiTexCoord4f + glMultiTexCoord4fv + glMultiTexCoord4i + glMultiTexCoord4iv + glMultiTexCoord4s + glMultiTexCoord4sv + glLoadTransposeMatrixf + glLoadTransposeMatrixd + glMultTransposeMatrixf + glMultTransposeMatrixd + glSampleCoverage + glCompressedTexImage3D + glCompressedTexImage2D + glCompressedTexImage1D + glCompressedTexSubImage3D + glCompressedTexSubImage2D + glCompressedTexSubImage1D + glGetCompressedTexImage + glBlendColorEXT + glPolygonOffsetEXT + glTexImage3DEXT + glTexSubImage3DEXT + glGetTexFilterFuncSGIS + glTexFilterFuncSGIS + glTexSubImage1DEXT + glTexSubImage2DEXT + glCopyTexImage1DEXT + glCopyTexImage2DEXT + glCopyTexSubImage1DEXT + glCopyTexSubImage2DEXT + glCopyTexSubImage3DEXT + glGetHistogramEXT + glGetHistogramParameterfvEXT + glGetHistogramParameterivEXT + glGetMinmaxEXT + glGetMinmaxParameterfvEXT + glGetMinmaxParameterivEXT + glHistogramEXT + glMinmaxEXT + glResetHistogramEXT + glResetMinmaxEXT + glConvolutionFilter1DEXT + glConvolutionFilter2DEXT + glConvolutionParameterfEXT + glConvolutionParameterfvEXT + glConvolutionParameteriEXT + glConvolutionParameterivEXT + glCopyConvolutionFilter1DEXT + glCopyConvolutionFilter2DEXT + glGetConvolutionFilterEXT + glGetConvolutionParameterfvEXT + glGetConvolutionParameterivEXT + glGetSeparableFilterEXT + glSeparableFilter2DEXT + glColorTableSGI + glColorTableParameterfvSGI + glColorTableParameterivSGI + glCopyColorTableSGI + glGetColorTableSGI + glGetColorTableParameterfvSGI + glGetColorTableParameterivSGI + glPixelTexGenSGIX + glPixelTexGenParameteriSGIS + glPixelTexGenParameterivSGIS + glPixelTexGenParameterfSGIS + glPixelTexGenParameterfvSGIS + glGetPixelTexGenParameterivSGIS + glGetPixelTexGenParameterfvSGIS + glTexImage4DSGIS + glTexSubImage4DSGIS + glAreTexturesResidentEXT + glBindTextureEXT + glDeleteTexturesEXT + glGenTexturesEXT + glIsTextureEXT + glPrioritizeTexturesEXT + glDetailTexFuncSGIS + glGetDetailTexFuncSGIS + glSharpenTexFuncSGIS + glGetSharpenTexFuncSGIS + glSampleMaskSGIS + glSamplePatternSGIS + glArrayElementEXT + glColorPointerEXT + glDrawArraysEXT + glEdgeFlagPointerEXT + glGetPointervEXT + glIndexPointerEXT + glNormalPointerEXT + glTexCoordPointerEXT + glVertexPointerEXT + glBlendEquationEXT + glSpriteParameterfSGIX + glSpriteParameterfvSGIX + glSpriteParameteriSGIX + glSpriteParameterivSGIX + glPointParameterfEXT + glPointParameterfvEXT + glPointParameterfARB + glPointParameterfvARB + glPointParameterfSGIS + glPointParameterfvSGIS + glGetInstrumentsSGIX + glInstrumentsBufferSGIX + glPollInstrumentsSGIX + glReadInstrumentsSGIX + glStartInstrumentsSGIX + glStopInstrumentsSGIX + glFrameZoomSGIX + glTagSampleBufferSGIX + glReferencePlaneSGIX + glFlushRasterSGIX + glColorSubTableEXT + glCopyColorSubTableEXT + glHintPGI + glColorTableEXT + glGetColorTableEXT + glGetColorTableParameterivEXT + glGetColorTableParameterfvEXT + glGetListParameterfvSGIX + glGetListParameterivSGIX + glListParameterfSGIX + glListParameterfvSGIX + glListParameteriSGIX + glListParameterivSGIX + glIndexMaterialEXT + glIndexFuncEXT + glLockArraysEXT + glUnlockArraysEXT + glCullParameterdvEXT + glCullParameterfvEXT + glFragmentColorMaterialSGIX + glFragmentLightfSGIX + glFragmentLightfvSGIX + glFragmentLightiSGIX + glFragmentLightivSGIX + glFragmentLightModelfSGIX + glFragmentLightModelfvSGIX + glFragmentLightModeliSGIX + glFragmentLightModelivSGIX + glFragmentMaterialfSGIX + glFragmentMaterialfvSGIX + glFragmentMaterialiSGIX + glFragmentMaterialivSGIX + glGetFragmentLightfvSGIX + glGetFragmentLightivSGIX + glGetFragmentMaterialfvSGIX + glGetFragmentMaterialivSGIX + glLightEnviSGIX + glDrawRangeElementsEXT + glSecondaryColor3bEXT + glSecondaryColor3bvEXT + glSecondaryColor3dEXT + glSecondaryColor3dvEXT + glSecondaryColor3fEXT + glSecondaryColor3fvEXT + glSecondaryColor3iEXT + glSecondaryColor3ivEXT + glSecondaryColor3sEXT + glSecondaryColor3svEXT + glSecondaryColor3ubEXT + glSecondaryColor3ubvEXT + glSecondaryColor3uiEXT + glSecondaryColor3uivEXT + glSecondaryColor3usEXT + glSecondaryColor3usvEXT + glSecondaryColorPointerEXT + glMultiDrawArraysEXT + glMultiDrawElementsEXT + glFogCoordfEXT + glFogCoordfvEXT + glFogCoorddEXT + glFogCoorddvEXT + glFogCoordPointerEXT + glBlendFuncSeparateEXT + glBlendFuncSeparateINGR + glVertexWeightfEXT + glVertexWeightfvEXT + glVertexWeightPointerEXT + glFlushVertexArrayRangeNV + glVertexArrayRangeNV + glCombinerParameterfvNV + glCombinerParameterfNV + glCombinerParameterivNV + glCombinerParameteriNV + glCombinerInputNV + glCombinerOutputNV + glFinalCombinerInputNV + glGetCombinerInputParameterfvNV + glGetCombinerInputParameterivNV + glGetCombinerOutputParameterfvNV + glGetCombinerOutputParameterivNV + glGetFinalCombinerInputParameterfvNV + glGetFinalCombinerInputParameterivNV + glResizeBuffersMESA + glWindowPos2dMESA + glWindowPos2dvMESA + glWindowPos2fMESA + glWindowPos2fvMESA + glWindowPos2iMESA + glWindowPos2ivMESA + glWindowPos2sMESA + glWindowPos2svMESA + glWindowPos3dMESA + glWindowPos3dvMESA + glWindowPos3fMESA + glWindowPos3fvMESA + glWindowPos3iMESA + glWindowPos3ivMESA + glWindowPos3sMESA + glWindowPos3svMESA + glWindowPos4dMESA + glWindowPos4dvMESA + glWindowPos4fMESA + glWindowPos4fvMESA + glWindowPos4iMESA + glWindowPos4ivMESA + glWindowPos4sMESA + glWindowPos4svMESA + glMultiModeDrawArraysIBM + glMultiModeDrawElementsIBM + glTbufferMask3DFX + glSampleMaskEXT + glSamplePatternEXT + glWindowPos2dARB + glWindowPos2fARB + glWindowPos2iARB + glWindowPos2sARB + glWindowPos2dvARB + glWindowPos2fvARB + glWindowPos2ivARB + glWindowPos2svARB + glWindowPos3dARB + glWindowPos3fARB + glWindowPos3iARB + glWindowPos3sARB + glWindowPos3dvARB + glWindowPos3fvARB + glWindowPos3ivARB + glWindowPos3svARB + glAreProgramsResidentNV + glBindProgramNV + glDeleteProgramsNV + glExecuteProgramNV + glGenProgramsNV + glGetProgramParameterdvNV + glGetProgramParameterfvNV + glGetProgramivNV + glGetProgramStringNV + glGetTrackMatrixivNV + glGetVertexAttribdvNV + glGetVertexAttribfvNV + glGetVertexAttribivNV + glGetVertexAttribPointervNV + glIsProgramNV + glLoadProgramNV + glProgramParameter4dNV + glProgramParameter4dvNV + glProgramParameter4fNV + glProgramParameter4fvNV + glProgramParameters4dvNV + glProgramParameters4fvNV + glRequestResidentProgramsNV + glTrackMatrixNV + glVertexAttribPointerNV + glVertexAttrib1dNV + glVertexAttrib1dvNV + glVertexAttrib1fNV + glVertexAttrib1fvNV + glVertexAttrib1sNV + glVertexAttrib1svNV + glVertexAttrib2dNV + glVertexAttrib2dvNV + glVertexAttrib2fNV + glVertexAttrib2fvNV + glVertexAttrib2sNV + glVertexAttrib2svNV + glVertexAttrib3dNV + glVertexAttrib3dvNV + glVertexAttrib3fNV + glVertexAttrib3fvNV + glVertexAttrib3sNV + glVertexAttrib3svNV + glVertexAttrib4dNV + glVertexAttrib4dvNV + glVertexAttrib4fNV + glVertexAttrib4fvNV + glVertexAttrib4sNV + glVertexAttrib4svNV + glVertexAttrib4ubNV + glVertexAttrib4ubvNV + glVertexAttribs1dvNV + glVertexAttribs1fvNV + glVertexAttribs1svNV + glVertexAttribs2dvNV + glVertexAttribs2fvNV + glVertexAttribs2svNV + glVertexAttribs3dvNV + glVertexAttribs3fvNV + glVertexAttribs3svNV + glVertexAttribs4dvNV + glVertexAttribs4fvNV + glVertexAttribs4svNV + glVertexAttribs4ubvNV + glPointParameteriNV + glPointParameterivNV + glBlendFuncSeparate + glFogCoordf + glFogCoordfv + glFogCoordd + glFogCoorddv + glFogCoordPointer + glMultiDrawArrays + glMultiDrawElements + glPointParameterf + glPointParameterfv + glPointParameteri + glPointParameteriv + glSecondaryColor3b + glSecondaryColor3bv + glSecondaryColor3d + glSecondaryColor3dv + glSecondaryColor3f + glSecondaryColor3fv + glSecondaryColor3i + glSecondaryColor3iv + glSecondaryColor3s + glSecondaryColor3sv + glSecondaryColor3ub + glSecondaryColor3ubv + glSecondaryColor3ui + glSecondaryColor3uiv + glSecondaryColor3us + glSecondaryColor3usv + glSecondaryColorPointer + glWindowPos2d + glWindowPos2dv + glWindowPos2f + glWindowPos2fv + glWindowPos2i + glWindowPos2iv + glWindowPos2s + glWindowPos2sv + glWindowPos3d + glWindowPos3dv + glWindowPos3f + glWindowPos3fv + glWindowPos3i + glWindowPos3iv + glWindowPos3s + glWindowPos3sv + glActiveStencilFaceEXT + glDeleteFencesNV + glGenFencesNV + glIsFenceNV + glTestFenceNV + glGetFenceivNV + glFinishFenceNV + glSetFenceNV + glVertexAttrib1sARB + glVertexAttrib1fARB + glVertexAttrib1dARB + glVertexAttrib2sARB + glVertexAttrib2fARB + glVertexAttrib2dARB + glVertexAttrib3sARB + glVertexAttrib3fARB + glVertexAttrib3dARB + glVertexAttrib4sARB + glVertexAttrib4fARB + glVertexAttrib4dARB + glVertexAttrib4NubARB + glVertexAttrib1svARB + glVertexAttrib1fvARB + glVertexAttrib1dvARB + glVertexAttrib2svARB + glVertexAttrib2fvARB + glVertexAttrib2dvARB + glVertexAttrib3svARB + glVertexAttrib3fvARB + glVertexAttrib3dvARB + glVertexAttrib4bvARB + glVertexAttrib4svARB + glVertexAttrib4ivARB + glVertexAttrib4ubvARB + glVertexAttrib4usvARB + glVertexAttrib4uivARB + glVertexAttrib4fvARB + glVertexAttrib4dvARB + glVertexAttrib4NbvARB + glVertexAttrib4NsvARB + glVertexAttrib4NivARB + glVertexAttrib4NubvARB + glVertexAttrib4NusvARB + glVertexAttrib4NuivARB + glVertexAttribPointerARB + glEnableVertexAttribArrayARB + glDisableVertexAttribArrayARB + glProgramStringARB + glBindProgramARB + glDeleteProgramsARB + glGenProgramsARB + glIsProgramARB + glProgramEnvParameter4dARB + glProgramEnvParameter4dvARB + glProgramEnvParameter4fARB + glProgramEnvParameter4fvARB + glProgramLocalParameter4dARB + glProgramLocalParameter4dvARB + glProgramLocalParameter4fARB + glProgramLocalParameter4fvARB + glGetProgramEnvParameterdvARB + glGetProgramEnvParameterfvARB + glGetProgramLocalParameterdvARB + glGetProgramLocalParameterfvARB + glGetProgramivARB + glGetProgramStringARB + glGetVertexAttribdvARB + glGetVertexAttribfvARB + glGetVertexAttribivARB + glGetVertexAttribPointervARB + glProgramNamedParameter4fNV + glProgramNamedParameter4dNV + glProgramNamedParameter4fvNV + glProgramNamedParameter4dvNV + glGetProgramNamedParameterfvNV + glGetProgramNamedParameterdvNV + glBindBufferARB + glBufferDataARB + glBufferSubDataARB + glDeleteBuffersARB + glGenBuffersARB + glGetBufferParameterivARB + glGetBufferPointervARB + glGetBufferSubDataARB + glIsBufferARB + glMapBufferARB + glUnmapBufferARB + glDepthBoundsEXT + glGenQueriesARB + glDeleteQueriesARB + glIsQueryARB + glBeginQueryARB + glEndQueryARB + glGetQueryivARB + glGetQueryObjectivARB + glGetQueryObjectuivARB + glBindBuffer + glBufferData + glBufferSubData + glDeleteBuffers + glGenBuffers + glGetBufferParameteriv + glGetBufferPointerv + glGetBufferSubData + glIsBuffer + glMapBuffer + glUnmapBuffer + glGenQueries + glDeleteQueries + glIsQuery + glBeginQuery + glEndQuery + glGetQueryiv + glGetQueryObjectiv + glGetQueryObjectuiv +; +; WGL API + wglChoosePixelFormat + wglCopyContext + wglCreateContext + wglCreateLayerContext + wglDeleteContext + wglDescribeLayerPlane + wglDescribePixelFormat + wglGetCurrentContext + wglGetCurrentDC + wglGetLayerPaletteEntries + wglGetPixelFormat + wglGetProcAddress + wglMakeCurrent + wglRealizeLayerPalette + wglSetLayerPaletteEntries + wglSetPixelFormat + wglShareLists + wglSwapBuffers + wglSwapLayerBuffers + wglUseFontBitmapsA + wglUseFontBitmapsW + wglUseFontOutlinesA + wglUseFontOutlinesW +; +; Mesa internals - mostly for OSMESA + _ac_CreateContext + _ac_DestroyContext + _ac_InvalidateState + _glapi_get_context + _glapi_get_proc_address + _mesa_buffer_data + _mesa_buffer_map + _mesa_buffer_subdata + _mesa_bzero + _mesa_calloc + _mesa_choose_tex_format + _mesa_compressed_texture_size + _mesa_create_framebuffer + _mesa_create_visual + _mesa_delete_buffer_object + _mesa_delete_texture_object + _mesa_destroy_framebuffer + _mesa_destroy_visual + _mesa_enable_1_3_extensions + _mesa_enable_1_4_extensions + _mesa_enable_1_5_extensions + _mesa_enable_sw_extensions + _mesa_error + _mesa_free + _mesa_free_context_data + _mesa_get_current_context + _mesa_init_default_imports + _mesa_init_driver_functions + _mesa_initialize_context + _mesa_make_current + _mesa_memcpy + _mesa_memset + _mesa_new_buffer_object + _mesa_new_texture_object + _mesa_problem + _mesa_ResizeBuffersMESA + _mesa_store_compressed_teximage1d + _mesa_store_compressed_teximage2d + _mesa_store_compressed_teximage3d + _mesa_store_compressed_texsubimage1d + _mesa_store_compressed_texsubimage2d + _mesa_store_compressed_texsubimage3d + _mesa_store_teximage1d + _mesa_store_teximage2d + _mesa_store_teximage3d + _mesa_store_texsubimage1d + _mesa_store_texsubimage2d + _mesa_store_texsubimage3d + _mesa_strcmp + _mesa_test_proxy_teximage + _mesa_Viewport + _swrast_Accum + _swrast_alloc_buffers + _swrast_Bitmap + _swrast_CopyPixels + _swrast_DrawBuffer + _swrast_DrawPixels + _swrast_GetDeviceDriverReference + _swrast_Clear + _swrast_choose_line + _swrast_choose_triangle + _swrast_CopyColorSubTable + _swrast_CopyColorTable + _swrast_CopyConvolutionFilter1D + _swrast_CopyConvolutionFilter2D + _swrast_copy_teximage1d + _swrast_copy_teximage2d + _swrast_copy_texsubimage1d + _swrast_copy_texsubimage2d + _swrast_copy_texsubimage3d + _swrast_CreateContext + _swrast_DestroyContext + _swrast_InvalidateState + _swrast_ReadPixels + _swrast_zbuffer_address + _swsetup_Wakeup + _swsetup_CreateContext + _swsetup_DestroyContext + _swsetup_InvalidateState + _tnl_CreateContext + _tnl_DestroyContext + _tnl_InvalidateState + _tnl_MakeCurrent + _tnl_run_pipeline diff --git a/src/mesa/drivers/windows/gdi/wgl.c b/src/mesa/drivers/windows/gdi/wgl.c new file mode 100644 index 0000000..920929c --- /dev/null +++ b/src/mesa/drivers/windows/gdi/wgl.c @@ -0,0 +1,639 @@ +/* $Id: wgl.c,v 1.6 2004/08/30 08:37:57 dborca 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 +#define GL_GLEXT_PROTOTYPES +#include +#include +//#include + +#ifdef __cplusplus +} +#endif + +#include +#include +#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 int ctx_current = -1; +static unsigned curPFD = 0; + +WGLAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask) +{ + (void) hglrcSrc; (void) hglrcDst; (void) 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;ibmiHeader.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) != GDI_ERROR ? 1 : 0); + + for(i = 0; i < (int)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); + (void) 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 (count == 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 < (int)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) +{ + (void) hdc; (void) first; (void) count; (void) listBase; + return FALSE; +} + +WGLAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count, + DWORD listBase,FLOAT deviation, + FLOAT extrusion,int format, + LPGLYPHMETRICSFLOAT lpgmf) +{ + (void) hdc; (void) first; (void) count; + (void) listBase; (void) deviation; (void) extrusion; (void) format; + (void) 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) +{ + (void) hdc; (void) first; (void) count; + (void) listBase; (void) deviation; (void) extrusion; (void) format; + (void) lpgmf; + SetLastError(0); + return(FALSE); +} + +WGLAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc,int iPixelFormat, + int iLayerPlane,UINT nBytes, + LPLAYERPLANEDESCRIPTOR plpd) +{ + (void) hdc; (void) iPixelFormat; (void) iLayerPlane; (void) nBytes; (void) plpd; + SetLastError(0); + return(FALSE); +} + +WGLAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc,int iLayerPlane, + int iStart,int cEntries, + CONST COLORREF *pcr) +{ + (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr; + SetLastError(0); + return(0); +} + +WGLAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc,int iLayerPlane, + int iStart,int cEntries, + COLORREF *pcr) +{ + (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr; + SetLastError(0); + return(0); +} + +WGLAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc,int iLayerPlane,BOOL bRealize) +{ + (void) hdc; (void) iLayerPlane; (void) bRealize; + SetLastError(0); + return(FALSE); +} + +WGLAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc,UINT fuPlanes) +{ + (void) 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; + (void) hdc; + + 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; + (void) hdc; + + 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) +{ + (void) hdc; + if(curPFD == 0) + { + SetLastError(0); + return(0); + } + return(curPFD); +} + +WGLAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat, + PIXELFORMATDESCRIPTOR *ppfd) +{ + int qt_valid_pix; + (void) hdc; + + 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) +{ + (void) 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 index 0000000..ea13a31 --- /dev/null +++ b/src/mesa/drivers/windows/gdi/wmesa.c @@ -0,0 +1,3353 @@ + +/* + * 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 +//#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_alphabuf.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" +#include "drivers/common/driverfuncs.h" + +/* Dither not tested for Mesa 4.0 */ +#ifdef DITHER +#ifdef USE_WING +#include +#endif // USE_WING +#endif + +#ifdef __CYGWIN32__ +#include "macros.h" +#include +#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 + +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); + +#if 0 /* unused */ + +/* Finish all pending operations and synchronize. */ +static void finish(GLcontext* ctx) +{ + /* No op */ + (void) ctx; +} + +#endif /* unused */ + +static void flush(GLcontext* ctx) +{ + (void) 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) +{ + (void) ctx; + 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]; + (void) ctx; + 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 void 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)); + } + else + dwColor = 0; + + 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 (iclearpixel); + 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 ) +{ + (void) ctx; + 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 ) +{ + (void) ctx; (void) colorBuffer; (void) 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; + (void) buffer; + + 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. */ + +#if 0 /* unused */ + +static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last ) +{ + (void) ctx; (void) first; (void) last; +} + +#endif /* unused */ + +/* Return pointer to accelerated points function */ +extern tnl_points_func choose_points_function( GLcontext* ctx ) +{ + (void) ctx; + return NULL; +} + +#if 0 /* unused */ + +static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, + GLuint v1, GLuint pv ) +{ + (void) ctx; (void) v0; (void) v1; (void) pv; +} + +static tnl_line_func choose_line_function( GLcontext* ctx ) +{ + (void) ctx; +} + +#endif /* unused */ + +/**********************************************************************/ +/***** 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; + (void) ctx; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; iScreenMem+FLIP(y)*Current->ScanWidth+x; + (void) ctx; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; iScreenMem+FLIP(y)*Current->ScanWidth+x; + (void) ctx; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; irgb_flag==GL_TRUE) + { + GLuint i; + /*HDC DC=DD_GETDC;*/ + y=FLIP(y); + if (mask) { + for (i=0; iScreenMem+y*Current->ScanWidth+x; + y = FLIP(y); + if (mask) { + for (i=0; ihPal, + RGB(rgba[i][RCOMP], + rgba[i][GCOMP], + rgba[i][BCOMP])); + } + else { + for (i=0; ihPal, + 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; + (void) ctx; + + if (pwc->rgb_flag==GL_TRUE) + { + GLuint i; + /*HDC DC=DD_GETDC;*/ + y=FLIP(y); + if (mask) { + for (i=0; iScreenMem+y*Current->ScanWidth+x; + y = FLIP(y); + if (mask) { + for (i=0; ihPal, + RGB(rgb[i][RCOMP], + rgb[i][GCOMP], + rgb[i][BCOMP])); + } + else { + for (i=0; ihPal, + 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; + (void) ctx; + assert(Current->rgb_flag==GL_TRUE); + y=FLIP(y); + if(Current->rgb_flag==GL_TRUE) + { + for (i=0; irgb_flag==GL_FALSE); + for (i=0; iScreenMem+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; + (void) ctx; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; iScreenMem+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;*/ + (void) ctx; + assert(Current->rgb_flag==GL_TRUE); + for (i=0; irgb_flag==GL_TRUE); + for (i=0; iScreenMem+FLIP(y)*Current->ScanWidth+x; + (void) ctx; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; irgb_flag==GL_FALSE); + for (i=0; iScreenMem+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; + (void) ctx; + assert(Current->rgb_flag==GL_TRUE); + y = Current->height - y - 1; + for (i=0; irgb_flag==GL_TRUE); + for (i=0; iheight - 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) +{ + (void) ctx; + if (name == GL_RENDERER) { + return (GLubyte *) "Mesa Windows"; + } + else { + return NULL; + } +} + +static void wmesa_update_state( GLcontext *ctx, GLuint new_state ); + +static void SetFunctionPointers( struct dd_function_table *functions ) +{ + functions->GetString = get_string; + functions->UpdateState = wmesa_update_state; + functions->ResizeBuffers = _swrast_alloc_buffers; + functions->GetBufferSize = buffer_size; + + functions->Clear = clear; + + functions->Flush = flush; + functions->ClearIndex = clear_index; + functions->ClearColor = clear_color; + functions->Enable = enable; +} + + +static void SetSWrastPointers(GLcontext *ctx) +{ + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx ); + 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->Driver); + SetSWrastPointers(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 *****/ +/**********************************************************************/ + +#if 0 /* unused */ + +#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; + Palette.Version = 0x300; + Palette.NumberOfEntries = 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 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; + } + + _mesa_init_driver_functions(&functions); + SetFunctionPointers(&functions); + + /* allocate a new Mesa context */ + c->gl_ctx = _mesa_create_context( c->gl_visual, NULL, + &functions, (void *) c ); + + 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);*/ + SetSWrastPointers(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; + (void) hDC; + (void) pbmi; + + 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), + (void **)&(pwc->pbPixels), + pwc->dib.hFileMap, + 0); +#else + pwc->hbmDIB = CreateDIBSection(hic, + &(pwc->bmi), + (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS), + (void **)&(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; + + if (Current==0 || Current->hwnd != hwnd) + wc=FindContext(hwnd); + else + wc=Current; + + + 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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; + 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;iDriverCtx; + 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;iColorPtr->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;xxColorPtr->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;xxColorPtr->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 ***********************/ + +#if 0 /* unused */ + +static tnl_triangle_func choose_triangle_function( GLcontext *ctx ) +{ + (void) 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 +} + +#endif /* unused */ + +/* + * 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 ) +{ + (void) ctx; (void) x; (void) y; (void) width; (void) 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 index 0000000..3c267aa --- /dev/null +++ b/src/mesa/drivers/windows/gdi/wmesadef.h @@ -0,0 +1,175 @@ +/* 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 +#include +#include "context.h" +#ifdef DDRAW +#define DIRECTDRAW_VERSION 0x0100 + #include +#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 +struct wmesa_context; +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 diff --git a/src/mesa/drivers/windows/gldirect/ddlog.c b/src/mesa/drivers/windows/gldirect/ddlog.c new file mode 100644 index 0000000..4ae79e2 --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/ddlog.c @@ -0,0 +1,192 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Logging functions. +* +****************************************************************************/ + +#define STRICT +#include + +#include "ddlog.h" +#include "gld_driver.h" + +// *********************************************************************** + +static char ddlogbuf[256]; +static FILE* fpDDLog = NULL; // Log file pointer +static char szDDLogName[_MAX_PATH] = {"gldirect.log"}; // Filename of the log +static DDLOG_loggingMethodType ddlogLoggingMethod = DDLOG_NONE; // Default to No Logging +static DDLOG_severityType ddlogDebugLevel; +static BOOL bUIWarning = FALSE; // MessageBox warning ? + +// *********************************************************************** + +void ddlogOpen( + DDLOG_loggingMethodType LoggingMethod, + DDLOG_severityType Severity) +{ + if (fpDDLog != NULL) { + // Tried to re-open the log + ddlogMessage(DDLOG_WARN, "Tried to re-open the log file\n"); + return; + } + + ddlogLoggingMethod = LoggingMethod; + ddlogDebugLevel = Severity; + + if (ddlogLoggingMethod == DDLOG_NORMAL) { + fpDDLog = fopen(szDDLogName, "wt"); + if (fpDDLog == NULL) + return; + } + + ddlogMessage(DDLOG_SYSTEM, "\n"); + ddlogMessage(DDLOG_SYSTEM, "-> Logging Started\n"); +} + +// *********************************************************************** + +void ddlogClose() +{ + // Determine whether the log is already closed + if (fpDDLog == NULL && ddlogLoggingMethod == DDLOG_NORMAL) + return; // Nothing to do. + + ddlogMessage(DDLOG_SYSTEM, "<- Logging Ended\n"); + + if (ddlogLoggingMethod == DDLOG_NORMAL) { + fclose(fpDDLog); + fpDDLog = NULL; + } +} + +// *********************************************************************** + +void ddlogMessage( + DDLOG_severityType severity, + LPSTR message) +{ + char buf[256]; + + // Bail if logging is disabled + if (ddlogLoggingMethod == DDLOG_NONE) + return; + + if (ddlogLoggingMethod == DDLOG_CRASHPROOF) + fpDDLog = fopen(szDDLogName, "at"); + + if (fpDDLog == NULL) + return; + + if (severity >= ddlogDebugLevel) { + sprintf(buf, "DDLog: (%s) %s", ddlogSeverityMessages[severity], message); + fputs(buf, fpDDLog); // Write string to file + OutputDebugString(buf); // Echo to debugger + } + + if (ddlogLoggingMethod == DDLOG_CRASHPROOF) { + fflush(fpDDLog); // Write info to disk + fclose(fpDDLog); + fpDDLog = NULL; + } + + // Popup message box if critical error + if (bUIWarning && severity == DDLOG_CRITICAL) { + MessageBox(NULL, buf, "GLDirect", MB_OK | MB_ICONWARNING | MB_TASKMODAL); + } +} + +// *********************************************************************** + +// Write a string value to the log file +void ddlogError( + DDLOG_severityType severity, + LPSTR message, + HRESULT hResult) +{ +#ifdef _USE_GLD3_WGL + char dxErrStr[1024]; + _gldDriver.GetDXErrorString(hResult, &dxErrStr[0], sizeof(dxErrStr)); + if (FAILED(hResult)) { + sprintf(ddlogbuf, "DDLog: %s %8x:[ %s ]\n", message, hResult, dxErrStr); + } else + sprintf(ddlogbuf, "DDLog: %s\n", message); +#else + if (FAILED(hResult)) { + sprintf(ddlogbuf, "DDLog: %s %8x:[ %s ]\n", message, hResult, DDErrorToString(hResult)); + } else + sprintf(ddlogbuf, "DDLog: %s\n", message); +#endif + ddlogMessage(severity, ddlogbuf); +} + +// *********************************************************************** + +void ddlogPrintf( + DDLOG_severityType severity, + LPSTR message, + ...) +{ + va_list args; + + va_start(args, message); + vsprintf(ddlogbuf, message, args); + va_end(args); + + lstrcat(ddlogbuf, "\n"); + + ddlogMessage(severity, ddlogbuf); +} + +// *********************************************************************** + +void ddlogWarnOption( + BOOL bWarnOption) +{ + bUIWarning = bWarnOption; +} + +// *********************************************************************** + +void ddlogPathOption( + LPSTR szPath) +{ + char szPathName[_MAX_PATH]; + + strcpy(szPathName, szPath); + strcat(szPathName, "\\"); + strcat(szPathName, szDDLogName); + strcpy(szDDLogName, szPathName); +} + +// *********************************************************************** diff --git a/src/mesa/drivers/windows/gldirect/ddlog.h b/src/mesa/drivers/windows/gldirect/ddlog.h new file mode 100644 index 0000000..d64067e --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/ddlog.h @@ -0,0 +1,109 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Logging functions. +* +****************************************************************************/ + +#ifndef __DDLOG_H +#define __DDLOG_H + +#include + +#ifndef _USE_GLD3_WGL +#include "dderrstr.h" // ddraw/d3d error string +#endif + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef enum { + DDLOG_NONE = 0, // No log output + DDLOG_NORMAL = 1, // Log is kept open + DDLOG_CRASHPROOF = 2, // Log is closed and flushed + DDLOG_METHOD_FORCE_DWORD = 0x7fffffff, +} DDLOG_loggingMethodType; + +// Denotes type of message sent to the logging functions +typedef enum { + DDLOG_INFO = 0, // Information only + DDLOG_WARN = 1, // Warning only + DDLOG_ERROR = 2, // Notify user of an error + DDLOG_CRITICAL = 3, // Exceptionally severe error + DDLOG_SYSTEM = 4, // System message. Not an error + // but must always be printed. + DDLOG_SEVERITY_FORCE_DWORD = 0x7fffffff, // Make enum dword +} DDLOG_severityType; + +#ifdef _USE_GLD3_WGL +// Synomyms +#define GLDLOG_INFO DDLOG_INFO +#define GLDLOG_WARN DDLOG_WARN +#define GLDLOG_ERROR DDLOG_ERROR +#define GLDLOG_CRITICAL DDLOG_CRITICAL +#define GLDLOG_SYSTEM DDLOG_SYSTEM +#endif + +// The message that will be output to the log +static const char *ddlogSeverityMessages[] = { + "INFO", + "WARN", + "ERROR", + "*CRITICAL*", + "System", +}; + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +void ddlogOpen(DDLOG_loggingMethodType LoggingMethod, DDLOG_severityType Severity); +void ddlogClose(); +void ddlogMessage(DDLOG_severityType severity, LPSTR message); +void ddlogError(DDLOG_severityType severity, LPSTR message, HRESULT hResult); +void ddlogPrintf(DDLOG_severityType severity, LPSTR message, ...); +void ddlogWarnOption(BOOL bWarnOption); +void ddlogPathOption(LPSTR szPath); + +#ifdef _USE_GLD3_WGL +// Synomyms +#define gldLogMessage ddlogMessage +#define gldLogError ddlogError +#define gldLogPrintf ddlogPrintf +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mesa/drivers/windows/gldirect/dglcontext.c b/src/mesa/drivers/windows/gldirect/dglcontext.c new file mode 100644 index 0000000..c504be5 --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/dglcontext.c @@ -0,0 +1,2213 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Context handling. +* +****************************************************************************/ + +#include "dglcontext.h" + +// Get compile errors without this. KeithH +#include "scitech.h" // ibool, etc. + +#ifdef _USE_GLD3_WGL +#include "gld_driver.h" + +extern void _gld_mesa_warning(GLcontext *, char *); +extern void _gld_mesa_fatal(GLcontext *, char *); +#endif // _USE_GLD3_WGL + +// TODO: Clean out old DX6-specific code from GLD 2.x CAD driver +// if it is no longer being built as part of GLDirect. (DaveM) + +// *********************************************************************** + +#define GLDERR_NONE 0 +#define GLDERR_MEM 1 +#define GLDERR_DDRAW 2 +#define GLDERR_D3D 3 +#define GLDERR_BPP 4 + +char szResourceWarning[] = +"GLDirect does not have enough video memory resources\n" +"to support the requested OpenGL rendering context.\n\n" +"You may have to reduce the current display resolution\n" +"to obtain satisfactory OpenGL performance.\n"; + +char szDDrawWarning[] = +"GLDirect is unable to initialize DirectDraw for the\n" +"requested OpenGL rendering context.\n\n" +"You will have to check the DirectX control panel\n" +"for further information.\n"; + +char szD3DWarning[] = +"GLDirect is unable to initialize Direct3D for the\n" +"requested OpenGL rendering context.\n\n" +"You may have to change the display mode resolution\n" +"color depth or check the DirectX control panel for\n" +"further information.\n"; + +char szBPPWarning[] = +"GLDirect is unable to use the selected color depth for\n" +"the requested OpenGL rendering context.\n\n" +"You will have to change the display mode resolution\n" +"color depth with the Display Settings control panel.\n"; + +int nContextError = GLDERR_NONE; + +// *********************************************************************** + +#define VENDORID_ATI 0x1002 + +static DWORD devATIRagePro[] = { + 0x4742, // 3D RAGE PRO BGA AGP 1X/2X + 0x4744, // 3D RAGE PRO BGA AGP 1X only + 0x4749, // 3D RAGE PRO BGA PCI 33 MHz + 0x4750, // 3D RAGE PRO PQFP PCI 33 MHz + 0x4751, // 3D RAGE PRO PQFP PCI 33 MHz limited 3D + 0x4C42, // 3D RAGE LT PRO BGA-312 AGP 133 MHz + 0x4C44, // 3D RAGE LT PRO BGA-312 AGP 66 MHz + 0x4C49, // 3D RAGE LT PRO BGA-312 PCI 33 MHz + 0x4C50, // 3D RAGE LT PRO BGA-256 PCI 33 MHz + 0x4C51, // 3D RAGE LT PRO BGA-256 PCI 33 MHz limited 3D +}; + +static DWORD devATIRageIIplus[] = { + 0x4755, // 3D RAGE II+ + 0x4756, // 3D RAGE IIC PQFP PCI + 0x4757, // 3D RAGE IIC BGA AGP + 0x475A, // 3D RAGE IIC PQFP AGP + 0x4C47, // 3D RAGE LT-G +}; + +// *********************************************************************** + +#ifndef _USE_GLD3_WGL +extern DGL_mesaFuncs mesaFuncs; +#endif + +extern DWORD dwLogging; + +#ifdef GLD_THREADS +#pragma message("compiling DGLCONTEXT.C vars for multi-threaded support") +CRITICAL_SECTION CriticalSection; // for serialized access +DWORD dwTLSCurrentContext = 0xFFFFFFFF; // TLS index for current context +DWORD dwTLSPixelFormat = 0xFFFFFFFF; // TLS index for current pixel format +#endif +HGLRC iCurrentContext = 0; // Index of current context (static) +BOOL bContextReady = FALSE; // Context state ready ? + +DGL_ctx ctxlist[DGL_MAX_CONTEXTS]; // Context list + +// *********************************************************************** + +static BOOL bHaveWin95 = FALSE; +static BOOL bHaveWinNT = FALSE; +static BOOL bHaveWin2K = FALSE; + +/**************************************************************************** +REMARKS: +Detect the installed OS type. +****************************************************************************/ +static void DetectOS(void) +{ + OSVERSIONINFO VersionInformation; + LPOSVERSIONINFO lpVersionInformation = &VersionInformation; + + VersionInformation.dwOSVersionInfoSize = sizeof(VersionInformation); + + GetVersionEx(lpVersionInformation); + + switch (VersionInformation.dwPlatformId) { + case VER_PLATFORM_WIN32_WINDOWS: + bHaveWin95 = TRUE; + bHaveWinNT = FALSE; + bHaveWin2K = FALSE; + break; + case VER_PLATFORM_WIN32_NT: + bHaveWin95 = FALSE; + if (VersionInformation.dwMajorVersion <= 4) { + bHaveWinNT = TRUE; + bHaveWin2K = FALSE; + } + else { + bHaveWinNT = FALSE; + bHaveWin2K = TRUE; + } + break; + case VER_PLATFORM_WIN32s: + bHaveWin95 = FALSE; + bHaveWinNT = FALSE; + bHaveWin2K = FALSE; + break; + } +} + +// *********************************************************************** + +HWND hWndEvent = NULL; // event monitor window +HWND hWndLastActive = NULL; // last active client window +LONG __stdcall GLD_EventWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam); + +// *********************************************************************** + +// Checks if the HGLRC is valid in range of context list. +BOOL dglIsValidContext( + HGLRC a) +{ + return ((int)a > 0 && (int)a <= DGL_MAX_CONTEXTS); +} + +// *********************************************************************** + +// Convert a HGLRC to a pointer into the context list. +DGL_ctx* dglGetContextAddress( + const HGLRC a) +{ + if (dglIsValidContext(a)) + return &ctxlist[(int)a-1]; + return NULL; +} + +// *********************************************************************** + +// Return the current HGLRC (however it may be stored for multi-threading). +HGLRC dglGetCurrentContext(void) +{ +#ifdef GLD_THREADS + HGLRC hGLRC; + // load from thread-specific instance + if (glb.bMultiThreaded) { + // protect against calls from arbitrary threads + __try { + hGLRC = (HGLRC)TlsGetValue(dwTLSCurrentContext); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + hGLRC = iCurrentContext; + } + } + // load from global static var + else { + hGLRC = iCurrentContext; + } + return hGLRC; +#else + return iCurrentContext; +#endif +} + +// *********************************************************************** + +// Set the current HGLRC (however it may be stored for multi-threading). +void dglSetCurrentContext(HGLRC hGLRC) +{ +#ifdef GLD_THREADS + // store in thread-specific instance + if (glb.bMultiThreaded) { + // protect against calls from arbitrary threads + __try { + TlsSetValue(dwTLSCurrentContext, (LPVOID)hGLRC); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + iCurrentContext = hGLRC; + } + } + // store in global static var + else { + iCurrentContext = hGLRC; + } +#else + iCurrentContext = hGLRC; +#endif +} + +// *********************************************************************** + +// Return the current HDC only for a currently active HGLRC. +HDC dglGetCurrentDC(void) +{ + HGLRC hGLRC; + DGL_ctx* lpCtx; + + hGLRC = dglGetCurrentContext(); + if (hGLRC) { + lpCtx = dglGetContextAddress(hGLRC); + return lpCtx->hDC; + } + return 0; +} + +// *********************************************************************** + +void dglInitContextState() +{ + int i; + WNDCLASS wc; + +#ifdef GLD_THREADS + // Allocate thread local storage indexes for current context and pixel format + dwTLSCurrentContext = TlsAlloc(); + dwTLSPixelFormat = TlsAlloc(); +#endif + + dglSetCurrentContext(NULL); // No current rendering context + + // Clear all context data + ZeroMemory(ctxlist, sizeof(ctxlist[0]) * DGL_MAX_CONTEXTS); + + for (i=0; ilpfnWndProc; + break; + } + } + // Not one of ours... + if (!lpfnWndProc) + return DefWindowProc(hwnd, msg, wParam, lParam); + + // Intercept messages amd process *before* passing on to window + switch (msg) { +#ifdef _USE_GLD3_WGL + case WM_DISPLAYCHANGE: + glb.bPixelformatsDirty = TRUE; + break; +#endif + case WM_ACTIVATEAPP: + glb.bAppActive = (BOOL)wParam; + ddlogPrintf(DDLOG_INFO, "Calling app has been %s", glb.bAppActive ? "activated" : "de-activated"); + break; + case WM_ERASEBKGND: + // Eat the GDI erase event for the GL window + if (!lpCtx || !lpCtx->bHasBeenCurrent) + break; + lpCtx->bGDIEraseBkgnd = TRUE; + return TRUE; + case WM_PAINT: + // Eat the invalidated update region if render scene is in progress + if (!lpCtx || !lpCtx->bHasBeenCurrent) + break; + if (lpCtx->bFrameStarted) { + if (GetUpdateRect(hwnd, &rect, FALSE)) { + BeginPaint(hwnd, &ps); + EndPaint(hwnd, &ps); + ValidateRect(hwnd, &rect); + return TRUE; + } + } + break; + } + // Call the appropriate window message handler + rc = CallWindowProc((WNDPROC)lpfnWndProc, hwnd, msg, wParam, lParam); + + // Intercept messages and process *after* passing on to window + switch (msg) { + case WM_QUIT: + case WM_DESTROY: + bQuit = TRUE; + if (lpCtx && lpCtx->bAllocated) { + ddlogPrintf(DDLOG_WARN, "WM_DESTROY detected for HWND=%X, HDC=%X, HGLRC=%d", hwnd, lpCtx->hDC, i+1); + dglDeleteContext((HGLRC)(i+1)); + } + break; +#if 0 + case WM_SIZE: + // Resize surfaces to fit window but not viewport (in case app did not bother) + if (!lpCtx || !lpCtx->bHasBeenCurrent) + break; + w = LOWORD(lParam); + h = HIWORD(lParam); + if (lpCtx->dwWidth < w || lpCtx->dwHeight < h) { + if (!dglWglResizeBuffers(lpCtx->glCtx, TRUE)) + dglWglResizeBuffers(lpCtx->glCtx, FALSE); + } + break; +#endif + } + + // If the main window is quitting, then so should we... + if (bMain && bQuit) { + ddlogPrintf(DDLOG_SYSTEM, "shutting down after WM_DESTROY detected for main HWND=%X", hwnd); + dglDeleteContextState(); + dglExitDriver(); + } + + return rc; +} + +// *********************************************************************** + +// Driver Window message handler +static LONG __stdcall GLD_EventWndProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam) +{ + switch (msg) { + // May be sent by splash screen dialog on exit + case WM_ACTIVATE: + if (LOWORD(wParam) == WA_ACTIVE && glb.hWndActive) { + SetForegroundWindow(glb.hWndActive); + return 0; + } + break; + } + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +// *********************************************************************** + +// Intercepted Keyboard handler for detecting hot keys. +LRESULT CALLBACK dglKeyProc( + int code, + WPARAM wParam, + LPARAM lParam) +{ + HWND hWnd, hWndFrame; + HGLRC hGLRC = NULL; + DGL_ctx* lpCtx = NULL; + int cmd = 0, dx1 = 0, dx2 = 0, i; + static ibool bAltPressed = false; + static ibool bCtrlPressed = false; + static ibool bShiftPressed = false; + RECT r, rf, rc; + POINT pt; + ibool bForceReshape = false; + + return CallNextHookEx(hKeyHook, code, wParam, lParam); +} + +// *********************************************************************** + +HWND hWndMatch; + +// Window handle enumeration procedure. +BOOL CALLBACK dglEnumChildProc( + HWND hWnd, + LPARAM lParam) +{ + RECT rect; + + // Find window handle with matching client rect. + GetClientRect(hWnd, &rect); + if (EqualRect(&rect, (RECT*)lParam)) { + hWndMatch = hWnd; + return FALSE; + } + // Continue with next child window. + return TRUE; +} + +// *********************************************************************** + +// Find window handle with matching client rect. +HWND dglFindWindowRect( + RECT* pRect) +{ + hWndMatch = NULL; + EnumChildWindows(GetForegroundWindow(), dglEnumChildProc, (LPARAM)pRect); + return hWndMatch; +} + +// *********************************************************************** +#ifndef _USE_GLD3_WGL +void dglChooseDisplayMode( + DGL_ctx *lpCtx) +{ + // Note: Choose an exact match if possible. + + int i; + DWORD area; + DWORD bestarea; + DDSURFACEDESC2 *lpDDSD = NULL; // Mode list pointer + DDSURFACEDESC2 *lpBestDDSD = NULL; // Pointer to best + + lpDDSD = glb.lpDisplayModes; + for (i=0; idwWidth == lpCtx->dwWidth) && + (lpDDSD->dwHeight == lpCtx->dwHeight)) + goto matched; // Mode has been exactly matched + // Choose modes that are larger in both dimensions than + // the window, but smaller in area than the current best. + if ( (lpDDSD->dwWidth >= lpCtx->dwWidth) && + (lpDDSD->dwHeight >= lpCtx->dwHeight)) + { + if (lpBestDDSD == NULL) { + lpBestDDSD = lpDDSD; + bestarea = lpDDSD->dwWidth * lpDDSD->dwHeight; + continue; + } + area = lpDDSD->dwWidth * lpDDSD->dwHeight; + if (area < bestarea) { + lpBestDDSD = lpDDSD; + bestarea = area; + } + } + } + + // Safety check + if (lpBestDDSD == NULL) { + ddlogMessage(DDLOG_CRITICAL, "dglChooseDisplayMode"); + return; + } + + lpCtx->dwModeWidth = lpBestDDSD->dwWidth; + lpCtx->dwModeHeight = lpBestDDSD->dwHeight; +matched: + ddlogPrintf(DDLOG_INFO, "Matched (%ldx%ld) to (%ldx%ld)", + lpCtx->dwWidth, lpCtx->dwHeight, lpCtx->dwModeWidth, lpCtx->dwModeHeight); +} +#endif // _USE_GLD3_WGL +// *********************************************************************** + +static BOOL IsDevice( + DWORD *lpDeviceIdList, + DWORD dwDeviceId, + int count) +{ + int i; + + for (i=0; ilpDD4 == NULL) { + // Testing for broken cards is sensitive area, so we don't want + // anything saying "broken cards" in the error message. ;) + ddlogMessage(DDLOG_ERROR, "Null DD4 passed to TFBC\n"); + return; + } + + // Microsoft really fucked up with the GetDeviceIdentifier function + // on Windows 2000, since it locks up on stock driers on the CD. Updated + // drivers from vendors appear to work, but we can't identify the drivers + // without this function!!! For now we skip these tests on Windows 2000. + if ((GetVersion() & 0x80000000UL) == 0) + return; + + // Obtain device info + if (FAILED(IDirectDraw4_GetDeviceIdentifier(lpCtx->lpDD4, &dddi, 0))) + return; + + // Useful info. Log it. + ddlogPrintf(DDLOG_INFO, "DirectDraw: VendorId=0x%x, DeviceId=0x%x", dddi.dwVendorId, dddi.dwDeviceId); + + // Vendor 1: ATI + if (dddi.dwVendorId == VENDORID_ATI) { + // Test A: ATI Rage PRO + if (IsDevice(devATIRagePro, dddi.dwDeviceId, sizeof(devATIRagePro))) + glb.bUseMipmaps = FALSE; + // Test B: ATI Rage II+ + if (IsDevice(devATIRageIIplus, dddi.dwDeviceId, sizeof(devATIRageIIplus))) + glb.bEmulateAlphaTest = TRUE; + } + + // Vendor 2: Matrox + if (dddi.dwVendorId == 0x102B) { + // Test: Matrox G400 stencil buffer support does not work for AutoCAD + if (dddi.dwDeviceId == 0x0525) { + lpCtx->lpPF->pfd.cStencilBits = 0; + if (lpCtx->lpPF->iZBufferPF != -1) { + glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwStencilBitDepth = 0; + glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwStencilBitMask = 0; + glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwFlags &= ~DDPF_STENCILBUFFER; + } + } + } +#endif // _GLD3 +} + +// *********************************************************************** + +BOOL dglCreateContextBuffers( + HDC a, + DGL_ctx *lpCtx, + BOOL bFallback) +{ + HRESULT hResult; + + int i; +// HGLRC hGLRC; +// DGL_ctx* lpCtx; + +#ifndef _USE_GLD3_WGL + DWORD dwFlags; + DDSURFACEDESC2 ddsd2; + DDSCAPS2 ddscaps2; + LPDIRECTDRAWCLIPPER lpddClipper; + D3DDEVICEDESC D3DHWDevDesc; // Direct3D Hardware description + D3DDEVICEDESC D3DHELDevDesc; // Direct3D Hardware Emulation Layer +#endif // _USE_GLD3_WGL + + float inv_aspect; + + GLenum bDoubleBuffer; // TRUE if double buffer required + GLenum bDepthBuffer; // TRUE if depth buffer required + + const PIXELFORMATDESCRIPTOR *lpPFD = &lpCtx->lpPF->pfd; + + // Vars for Mesa visual + DWORD dwDepthBits = 0; + DWORD dwStencilBits = 0; + DWORD dwAlphaBits = 0; + DWORD bAlphaSW = GL_FALSE; + DWORD bDouble = GL_FALSE; + + DDSURFACEDESC2 ddsd2DisplayMode; + BOOL bFullScrnWin = FALSE; // fullscreen-size window ? + DDBLTFX ddbltfx; + DWORD dwMemoryType = (bFallback) ? DDSCAPS_SYSTEMMEMORY : glb.dwMemoryType; + BOOL bBogusWindow = FALSE; // non-drawable window ? + DWORD dwColorRef = 0; // GDI background color + RECT rcDst; // GDI window rect + POINT pt; // GDI window point + + // Palette used for creating default global palette + PALETTEENTRY ppe[256]; + +#ifndef _USE_GLD3_WGL + // Vertex buffer description. Used for creation of vertex buffers + D3DVERTEXBUFFERDESC vbufdesc; +#endif // _USE_GLD3_WGL + +#define DDLOG_CRITICAL_OR_WARN (bFallback ? DDLOG_CRITICAL : DDLOG_WARN) + + ddlogPrintf(DDLOG_SYSTEM, "dglCreateContextBuffers for HDC=%X", a); + nContextError = GLDERR_NONE; + +#ifdef GLD_THREADS + // Serialize access to DirectDraw object creation or DDS start + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + + // Check for back buffer + bDoubleBuffer = GL_TRUE; //(lpPFD->dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE; + // Since we always do back buffering, check if we emulate front buffering + lpCtx->EmulateSingle = + (lpPFD->dwFlags & PFD_DOUBLEBUFFER) ? FALSE : TRUE; +#if 0 // Don't have to mimic MS OpenGL behavior for front-buffering (DaveM) + lpCtx->EmulateSingle |= + (lpPFD->dwFlags & PFD_SUPPORT_GDI) ? TRUE : FALSE; +#endif + + // Check for depth buffer + bDepthBuffer = (lpPFD->cDepthBits) ? GL_TRUE : GL_FALSE; + + lpCtx->bDoubleBuffer = bDoubleBuffer; + lpCtx->bDepthBuffer = bDepthBuffer; + + // Set the Fullscreen flag for the context. +// lpCtx->bFullscreen = glb.bFullscreen; + + // Obtain the dimensions of the rendering window + lpCtx->hDC = a; // Cache DC + lpCtx->hWnd = WindowFromDC(lpCtx->hDC); + // Check for non-window DC = memory DC ? + if (lpCtx->hWnd == NULL) { + // bitmap memory contexts are always single-buffered + lpCtx->EmulateSingle = TRUE; + bBogusWindow = TRUE; + ddlogPrintf(DDLOG_INFO, "Non-Window Memory Device Context"); + if (GetClipBox(lpCtx->hDC, &lpCtx->rcScreenRect) == ERROR) { + ddlogMessage(DDLOG_WARN, "GetClipBox failed in dglCreateContext\n"); + SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0); + } + } + else if (!GetClientRect(lpCtx->hWnd, &lpCtx->rcScreenRect)) { + bBogusWindow = TRUE; + ddlogMessage(DDLOG_WARN, "GetClientRect failed in dglCreateContext\n"); + SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0); + } + lpCtx->dwWidth = lpCtx->rcScreenRect.right - lpCtx->rcScreenRect.left; + lpCtx->dwHeight = lpCtx->rcScreenRect.bottom - lpCtx->rcScreenRect.top; + + ddlogPrintf(DDLOG_INFO, "Input window %X: w=%i, h=%i", + lpCtx->hWnd, lpCtx->dwWidth, lpCtx->dwHeight); + + // What if app only zeroes one dimension instead of both? (DaveM) + if ( (lpCtx->dwWidth == 0) || (lpCtx->dwHeight == 0) ) { + // Make the buffer size something sensible + lpCtx->dwWidth = 8; + lpCtx->dwHeight = 8; + } + + // Set defaults + lpCtx->dwModeWidth = lpCtx->dwWidth; + lpCtx->dwModeHeight = lpCtx->dwHeight; +/* + // Find best display mode for fullscreen + if (glb.bFullscreen || !glb.bPrimary) { + dglChooseDisplayMode(lpCtx); + } +*/ + // Misc initialisation + lpCtx->bCanRender = FALSE; // No rendering allowed yet + lpCtx->bSceneStarted = FALSE; + lpCtx->bFrameStarted = FALSE; + + // Detect OS (specifically 'Windows 2000' or 'Windows XP') + DetectOS(); + + // NOTE: WinNT not supported + ddlogPrintf(DDLOG_INFO, "OS: %s", bHaveWin95 ? "Win9x" : (bHaveWin2K ? "Win2000/XP" : "Unsupported") ); + + // Test for Fullscreen + if (bHaveWin95) { // Problems with fullscreen on Win2K/XP + if ((GetSystemMetrics(SM_CXSCREEN) == lpCtx->dwWidth) && + (GetSystemMetrics(SM_CYSCREEN) == lpCtx->dwHeight)) + { + // Workaround for some apps that crash when going fullscreen. + //lpCtx->bFullscreen = TRUE; + } + + } + +#ifdef _USE_GLD3_WGL + _gldDriver.CreateDrawable(lpCtx, glb.bDirectDrawPersistant, glb.bPersistantBuffers); +#else + // Check if DirectDraw has already been created by original GLRC (DaveM) + if (glb.bDirectDrawPersistant && glb.bDirectDraw) { + lpCtx->lpDD4 = glb.lpDD4; + IDirectDraw4_AddRef(lpCtx->lpDD4); + goto SkipDirectDrawCreate; + } + + // Create DirectDraw object + if (glb.bPrimary) + hResult = DirectDrawCreate(NULL, &lpCtx->lpDD1, NULL); + else { + // A non-primary device is to be used. + // Force context to be Fullscreen, secondary adaptors can not + // be used in a window. + hResult = DirectDrawCreate(&glb.ddGuid, &lpCtx->lpDD1, NULL); + lpCtx->bFullscreen = TRUE; + } + if (FAILED(hResult)) { + MessageBox(NULL, "Unable to initialize DirectDraw", "GLDirect", MB_OK); + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create DirectDraw interface", hResult); + nContextError = GLDERR_DDRAW; + goto return_with_error; + } + + // Query for DX6 IDirectDraw4. + hResult = IDirectDraw_QueryInterface(lpCtx->lpDD1, + &IID_IDirectDraw4, + (void**)&lpCtx->lpDD4); + if (FAILED(hResult)) { + MessageBox(NULL, "GLDirect requires DirectX 6.0 or above", "GLDirect", MB_OK); + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create DirectDraw4 interface", hResult); + nContextError = GLDERR_DDRAW; + goto return_with_error; + } + + // Cache DirectDraw interface for subsequent GLRCs + if (glb.bDirectDrawPersistant && !glb.bDirectDraw) { + glb.lpDD4 = lpCtx->lpDD4; + IDirectDraw4_AddRef(glb.lpDD4); + glb.bDirectDraw = TRUE; + } +SkipDirectDrawCreate: + + // Now we have a DD4 interface we can check for broken cards + dglTestForBrokenCards(lpCtx); + + // Test if primary device can use flipping instead of blitting + ZeroMemory(&ddsd2DisplayMode, sizeof(ddsd2DisplayMode)); + ddsd2DisplayMode.dwSize = sizeof(ddsd2DisplayMode); + hResult = IDirectDraw4_GetDisplayMode( + lpCtx->lpDD4, + &ddsd2DisplayMode); + if (SUCCEEDED(hResult)) { + if ( (lpCtx->dwWidth == ddsd2DisplayMode.dwWidth) && + (lpCtx->dwHeight == ddsd2DisplayMode.dwHeight) ) { + // We have a fullscreen-size window + bFullScrnWin = TRUE; + // OK to use DirectDraw fullscreen mode ? + if (glb.bPrimary && !glb.bFullscreenBlit && !lpCtx->EmulateSingle && !glb.bDirectDrawPersistant) { + lpCtx->bFullscreen = TRUE; + ddlogMessage(DDLOG_INFO, "Primary upgraded to page flipping.\n"); + } + } + // Cache the display mode dimensions + lpCtx->dwModeWidth = ddsd2DisplayMode.dwWidth; + lpCtx->dwModeHeight = ddsd2DisplayMode.dwHeight; + } + + // Clamp the effective window dimensions to primary surface. + // We need to do this for D3D viewport dimensions even if wide + // surfaces are supported. This also is a good idea for handling + // whacked-out window dimensions passed for non-drawable windows + // like Solid Edge. (DaveM) + if (lpCtx->dwWidth > ddsd2DisplayMode.dwWidth) + lpCtx->dwWidth = ddsd2DisplayMode.dwWidth; + if (lpCtx->dwHeight > ddsd2DisplayMode.dwHeight) + lpCtx->dwHeight = ddsd2DisplayMode.dwHeight; + + // Check for non-RGB desktop resolution + if (!lpCtx->bFullscreen && ddsd2DisplayMode.ddpfPixelFormat.dwRGBBitCount <= 8) { + ddlogPrintf(DDLOG_CRITICAL_OR_WARN, "Desktop color depth %d bpp not supported", + ddsd2DisplayMode.ddpfPixelFormat.dwRGBBitCount); + nContextError = GLDERR_BPP; + goto return_with_error; + } +#endif // _USE_GLD3_WGL + + ddlogPrintf(DDLOG_INFO, "Window: w=%i, h=%i (%s)", + lpCtx->dwWidth, + lpCtx->dwHeight, + lpCtx->bFullscreen ? "fullscreen" : "windowed"); + +#ifndef _USE_GLD3_WGL + // Obtain ddraw caps + ZeroMemory(&lpCtx->ddCaps, sizeof(DDCAPS)); + lpCtx->ddCaps.dwSize = sizeof(DDCAPS); + if (glb.bHardware) { + // Get HAL caps + IDirectDraw4_GetCaps(lpCtx->lpDD4, &lpCtx->ddCaps, NULL); + } else { + // Get HEL caps + IDirectDraw4_GetCaps(lpCtx->lpDD4, NULL, &lpCtx->ddCaps); + } + + // If this flag is present then we can't default to Mesa + // SW rendering between BeginScene() and EndScene(). + if (lpCtx->ddCaps.dwCaps2 & DDCAPS2_NO2DDURING3DSCENE) { + ddlogMessage(DDLOG_INFO, + "Warning : No 2D allowed during 3D scene.\n"); + } + + // Query for DX6 Direct3D3 interface + hResult = IDirectDraw4_QueryInterface(lpCtx->lpDD4, + &IID_IDirect3D3, + (void**)&lpCtx->lpD3D3); + if (FAILED(hResult)) { + MessageBox(NULL, "Unable to initialize Direct3D", "GLDirect", MB_OK); + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D interface", hResult); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // Context creation + if (lpCtx->bFullscreen) { + // FULLSCREEN + + // Disable warning popups when in fullscreen mode + ddlogWarnOption(FALSE); + + // Have to release persistant primary surface if fullscreen mode + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) { + RELEASE(glb.lpPrimary4); + glb.bDirectDrawPrimary = FALSE; + } + + dwFlags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT; + if (glb.bFastFPU) + dwFlags |= DDSCL_FPUSETUP; // fast FPU setup optional (DaveM) + hResult = IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, lpCtx->hWnd, dwFlags); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to set Exclusive Fullscreen mode", hResult); + goto return_with_error; + } + + hResult = IDirectDraw4_SetDisplayMode(lpCtx->lpDD4, + lpCtx->dwModeWidth, + lpCtx->dwModeHeight, + lpPFD->cColorBits, + 0, + 0); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "SetDisplayMode failed", hResult); + goto return_with_error; + } + + // ** The display mode has changed, so dont use MessageBox! ** + + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + + if (bDoubleBuffer) { + // Double buffered + // Primary surface + ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | + DDSCAPS_FLIP | + DDSCAPS_COMPLEX | + DDSCAPS_3DDEVICE | + dwMemoryType; + ddsd2.dwBackBufferCount = 1; + + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (primary) failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + + // Render target surface + ZeroMemory(&ddscaps2, sizeof(ddscaps2)); // Clear the entire struct. + ddscaps2.dwCaps = DDSCAPS_BACKBUFFER; + hResult = IDirectDrawSurface4_GetAttachedSurface(lpCtx->lpFront4, &ddscaps2, &lpCtx->lpBack4); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "GetAttachedSurface failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + } else { + // Single buffered + // Primary surface + ddsd2.dwFlags = DDSD_CAPS; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | + //DDSCAPS_3DDEVICE | + dwMemoryType; + + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (primary) failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + + lpCtx->lpBack4 = NULL; + } + } else { + // WINDOWED + + // OK to enable warning popups in windowed mode + ddlogWarnOption(glb.bMessageBoxWarnings); + + dwFlags = DDSCL_NORMAL; + if (glb.bMultiThreaded) + dwFlags |= DDSCL_MULTITHREADED; + if (glb.bFastFPU) + dwFlags |= DDSCL_FPUSETUP; // fast FPU setup optional (DaveM) + hResult = IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, + lpCtx->hWnd, + dwFlags); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to set Normal coop level", hResult); + goto return_with_error; + } + // Has Primary surface already been created for original GLRC ? + // Note this can only be applicable for windowed modes + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) { + lpCtx->lpFront4 = glb.lpPrimary4; + IDirectDrawSurface4_AddRef(lpCtx->lpFront4); + // Update the window on the default clipper + IDirectDrawSurface4_GetClipper(lpCtx->lpFront4, &lpddClipper); + IDirectDrawClipper_SetHWnd(lpddClipper, 0, lpCtx->hWnd); + IDirectDrawClipper_Release(lpddClipper); + goto SkipPrimaryCreate; + } + + // Primary surface + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (primary) failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + + // Cache Primary surface for subsequent GLRCs + // Note this can only be applicable to subsequent windowed modes + if (glb.bDirectDrawPersistant && !glb.bDirectDrawPrimary) { + glb.lpPrimary4 = lpCtx->lpFront4; + IDirectDrawSurface4_AddRef(glb.lpPrimary4); + glb.bDirectDrawPrimary = TRUE; + } + + // Clipper object + hResult = DirectDrawCreateClipper(0, &lpddClipper, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateClipper failed", hResult); + goto return_with_error; + } + hResult = IDirectDrawClipper_SetHWnd(lpddClipper, 0, lpCtx->hWnd); + if (FAILED(hResult)) { + RELEASE(lpddClipper); + ddlogError(DDLOG_CRITICAL_OR_WARN, "SetHWnd failed", hResult); + goto return_with_error; + } + hResult = IDirectDrawSurface4_SetClipper(lpCtx->lpFront4, lpddClipper); + RELEASE(lpddClipper); // We have finished with it. + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "SetClipper failed", hResult); + goto return_with_error; + } +SkipPrimaryCreate: + + if (bDoubleBuffer) { + // Render target surface + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd2.dwWidth = lpCtx->dwWidth; + ddsd2.dwHeight = lpCtx->dwHeight; + ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | + DDSCAPS_OFFSCREENPLAIN | + dwMemoryType; + + // Reserve the entire desktop size for persistant buffers option + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers) { + ddsd2.dwWidth = ddsd2DisplayMode.dwWidth; + ddsd2.dwHeight = ddsd2DisplayMode.dwHeight; + } + // Re-use original back buffer if persistant buffers exist + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpBack4) + hResult = IDirectDrawSurface4_AddRef(lpCtx->lpBack4 = glb.lpBack4); + else + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpBack4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "Create Backbuffer failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && !glb.lpBack4) + IDirectDrawSurface4_AddRef(glb.lpBack4 = lpCtx->lpBack4); + } else { + lpCtx->lpBack4 = NULL; + } + } + + // + // Now create the Z-buffer + // + lpCtx->bStencil = FALSE; // Default to no stencil buffer + if (bDepthBuffer && (lpCtx->lpPF->iZBufferPF != -1)) { + // Get z-buffer dimensions from the render target + // Setup the surface desc for the z-buffer. + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | dwMemoryType; + ddsd2.dwWidth = lpCtx->dwWidth; + ddsd2.dwHeight = lpCtx->dwHeight; + memcpy(&ddsd2.ddpfPixelFormat, + &glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF], + sizeof(DDPIXELFORMAT) ); + + // Reserve the entire desktop size for persistant buffers option + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers) { + ddsd2.dwWidth = ddsd2DisplayMode.dwWidth; + ddsd2.dwHeight = ddsd2DisplayMode.dwHeight; + } + + // Create a z-buffer + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpDepth4) + hResult = IDirectDrawSurface4_AddRef(lpCtx->lpDepth4 = glb.lpDepth4); + else + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpDepth4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (ZBuffer) failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && !glb.lpDepth4) + IDirectDrawSurface4_AddRef(glb.lpDepth4 = lpCtx->lpDepth4); + else if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpDepth4 && glb.lpBack4) + IDirectDrawSurface4_DeleteAttachedSurface(glb.lpBack4, 0, glb.lpDepth4); + + // Attach Zbuffer to render target + TRY(IDirectDrawSurface4_AddAttachedSurface( + bDoubleBuffer ? lpCtx->lpBack4 : lpCtx->lpFront4, + lpCtx->lpDepth4), + "dglCreateContext: Attach Zbuffer"); + if (glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwFlags & DDPF_STENCILBUFFER) { + lpCtx->bStencil = TRUE; + ddlogMessage(DDLOG_INFO, "Depth buffer has stencil\n"); + } + } + + // Clear all back buffers and Z-buffers in case of memory recycling. + ZeroMemory(&ddbltfx, sizeof(ddbltfx)); + ddbltfx.dwSize = sizeof(ddbltfx); + IDirectDrawSurface4_Blt(lpCtx->lpBack4, NULL, NULL, NULL, + DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); + if (lpCtx->lpDepth4) + IDirectDrawSurface4_Blt(lpCtx->lpDepth4, NULL, NULL, NULL, + DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); + + // Now that we have a Z-buffer we can create the 3D device + hResult = IDirect3D3_CreateDevice(lpCtx->lpD3D3, + &glb.d3dGuid, + bDoubleBuffer ? lpCtx->lpBack4 : lpCtx->lpFront4, + &lpCtx->lpDev3, + NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D device", hResult); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // We must do this as soon as the device is created + dglInitStateCaches(lpCtx); + + // Obtain the D3D Device Description + D3DHWDevDesc.dwSize = D3DHELDevDesc.dwSize = sizeof(D3DDEVICEDESC); + TRY(IDirect3DDevice3_GetCaps(lpCtx->lpDev3, + &D3DHWDevDesc, + &D3DHELDevDesc), + "dglCreateContext: GetCaps failed"); + + // Choose the relevant description and cache it in the context. + // We will use this description later for caps checking + memcpy( &lpCtx->D3DDevDesc, + glb.bHardware ? &D3DHWDevDesc : &D3DHELDevDesc, + sizeof(D3DDEVICEDESC)); + + // Now we can examine the texture formats + if (!dglBuildTextureFormatList(lpCtx->lpDev3)) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "dglBuildTextureFormatList failed\n"); + goto return_with_error; + } + + // Get the pixel format of the back buffer + lpCtx->ddpfRender.dwSize = sizeof(lpCtx->ddpfRender); + if (bDoubleBuffer) + hResult = IDirectDrawSurface4_GetPixelFormat( + lpCtx->lpBack4, + &lpCtx->ddpfRender); + else + hResult = IDirectDrawSurface4_GetPixelFormat( + lpCtx->lpFront4, + &lpCtx->ddpfRender); + + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "GetPixelFormat failed", hResult); + goto return_with_error; + } + // Find a pixel packing function suitable for this surface + pxClassifyPixelFormat(&lpCtx->ddpfRender, + &lpCtx->fnPackFunc, + &lpCtx->fnUnpackFunc, + &lpCtx->fnPackSpanFunc); + + // Viewport + hResult = IDirect3D3_CreateViewport(lpCtx->lpD3D3, &lpCtx->lpViewport3, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateViewport failed", hResult); + goto return_with_error; + } + + hResult = IDirect3DDevice3_AddViewport(lpCtx->lpDev3, lpCtx->lpViewport3); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "AddViewport failed", hResult); + goto return_with_error; + } + + // Initialise the viewport + // Note screen coordinates are used for viewport clipping since D3D + // transform operations are not used in the GLD CAD driver. (DaveM) + inv_aspect = (float)lpCtx->dwHeight/(float)lpCtx->dwWidth; + + lpCtx->d3dViewport.dwSize = sizeof(lpCtx->d3dViewport); + lpCtx->d3dViewport.dwX = 0; + lpCtx->d3dViewport.dwY = 0; + lpCtx->d3dViewport.dwWidth = lpCtx->dwWidth; + lpCtx->d3dViewport.dwHeight = lpCtx->dwHeight; + lpCtx->d3dViewport.dvClipX = 0; // -1.0f; + lpCtx->d3dViewport.dvClipY = 0; // inv_aspect; + lpCtx->d3dViewport.dvClipWidth = lpCtx->dwWidth; // 2.0f; + lpCtx->d3dViewport.dvClipHeight = lpCtx->dwHeight; // 2.0f * inv_aspect; + lpCtx->d3dViewport.dvMinZ = 0.0f; + lpCtx->d3dViewport.dvMaxZ = 1.0f; + TRY(IDirect3DViewport3_SetViewport2(lpCtx->lpViewport3, &lpCtx->d3dViewport), "dglCreateContext: SetViewport2"); + + hResult = IDirect3DDevice3_SetCurrentViewport(lpCtx->lpDev3, lpCtx->lpViewport3); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "SetCurrentViewport failed", hResult); + goto return_with_error; + } + + lpCtx->dwBPP = lpPFD->cColorBits; + lpCtx->iZBufferPF = lpCtx->lpPF->iZBufferPF; + + // Set last texture to NULL + for (i=0; iColorOp[i] = D3DTOP_DISABLE; + lpCtx->AlphaOp[i] = D3DTOP_DISABLE; + lpCtx->tObj[i] = NULL; + } + + // Default to perspective correct texture mapping + dglSetRenderState(lpCtx, D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE, "TexturePersp"); + + // Set the default culling mode + lpCtx->cullmode = D3DCULL_NONE; + dglSetRenderState(lpCtx, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE, "CullMode"); + + // Disable specular + dglSetRenderState(lpCtx, D3DRENDERSTATE_SPECULARENABLE, FALSE, "SpecularEnable"); + // Disable subpixel correction +// dglSetRenderState(lpCtx, D3DRENDERSTATE_SUBPIXEL, FALSE, "SubpixelEnable"); + // Disable dithering + dglSetRenderState(lpCtx, D3DRENDERSTATE_DITHERENABLE, FALSE, "DitherEnable"); + + // Initialise the primitive caches +// lpCtx->dwNextLineVert = 0; +// lpCtx->dwNextTriVert = 0; + + // Init the global texture palette + lpCtx->lpGlobalPalette = NULL; + + // Init the HW/SW usage counters +// lpCtx->dwHWUsageCount = lpCtx->dwSWUsageCount = 0L; + + // + // Create two D3D vertex buffers. + // One will hold the pre-transformed data with the other one + // being used to hold the post-transformed & clipped verts. + // +#if 0 // never used (DaveM) + vbufdesc.dwSize = sizeof(D3DVERTEXBUFFERDESC); + vbufdesc.dwCaps = D3DVBCAPS_WRITEONLY; + if (glb.bHardware == FALSE) + vbufdesc.dwCaps = D3DVBCAPS_SYSTEMMEMORY; + vbufdesc.dwNumVertices = 32768; // For the time being + + // Source vertex buffer + vbufdesc.dwFVF = DGL_LVERTEX; + hResult = IDirect3D3_CreateVertexBuffer(lpCtx->lpD3D3, &vbufdesc, &lpCtx->m_vbuf, 0, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateVertexBuffer(src) failed", hResult); + goto return_with_error; + } + + // Destination vertex buffer + vbufdesc.dwFVF = (glb.bMultitexture == FALSE) ? D3DFVF_TLVERTEX : (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX2); + hResult = IDirect3D3_CreateVertexBuffer(lpCtx->lpD3D3, &vbufdesc, &lpCtx->m_pvbuf, 0, NULL); + if(FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateVertexBuffer(dst) failed", hResult); + goto return_with_error; + } +#endif + +#endif _USE_GLD3_WGL + + // + // Now create the Mesa context + // + + // Create the Mesa visual + if (lpPFD->cDepthBits) + dwDepthBits = 16; + if (lpPFD->cStencilBits) + dwStencilBits = 8; + if (lpPFD->cAlphaBits) { + dwAlphaBits = 8; + bAlphaSW = GL_TRUE; + } + if (lpPFD->dwFlags & PFD_DOUBLEBUFFER) + bDouble = GL_TRUE; +// lpCtx->EmulateSingle = +// (lpPFD->dwFlags & PFD_DOUBLEBUFFER) ? FALSE : TRUE; + +#ifdef _USE_GLD3_WGL + lpCtx->glVis = _mesa_create_visual( + GL_TRUE, // RGB mode + bDouble, /* double buffer */ + GL_FALSE, // stereo + lpPFD->cRedBits, + lpPFD->cGreenBits, + lpPFD->cBlueBits, + dwAlphaBits, + 0, // index bits + dwDepthBits, + dwStencilBits, + lpPFD->cAccumRedBits, // accum bits + lpPFD->cAccumGreenBits, // accum bits + lpPFD->cAccumBlueBits, // accum bits + lpPFD->cAccumAlphaBits, // accum alpha bits + 1 // num samples + ); +#else // _USE_GLD3_WGL + lpCtx->glVis = (*mesaFuncs.gl_create_visual)( + GL_TRUE, // RGB mode + bAlphaSW, // Is an alpha buffer required? + bDouble, // Is an double-buffering required? + GL_FALSE, // stereo + dwDepthBits, // depth_size + dwStencilBits, // stencil_size + lpPFD->cAccumBits, // accum_size + 0, // colour-index bits + lpPFD->cRedBits, // Red bit count + lpPFD->cGreenBits, // Green bit count + lpPFD->cBlueBits, // Blue bit count + dwAlphaBits // Alpha bit count + ); +#endif // _USE_GLD3_WGL + + if (lpCtx->glVis == NULL) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "gl_create_visual failed\n"); + goto return_with_error; + } + +#ifdef _USE_GLD3_WGL + lpCtx->glCtx = _mesa_create_context(lpCtx->glVis, NULL, (void *)lpCtx, GL_TRUE); +#else + // Create the Mesa context + lpCtx->glCtx = (*mesaFuncs.gl_create_context)( + lpCtx->glVis, // Mesa visual + NULL, // share list context + (void *)lpCtx, // Pointer to our driver context + GL_TRUE // Direct context flag + ); +#endif // _USE_GLD3_WGL + + if (lpCtx->glCtx == NULL) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "gl_create_context failed\n"); + goto return_with_error; + } + + // Create the Mesa framebuffer +#ifdef _USE_GLD3_WGL + lpCtx->glBuffer = _mesa_create_framebuffer( + lpCtx->glVis, + lpCtx->glVis->depthBits > 0, + lpCtx->glVis->stencilBits > 0, + lpCtx->glVis->accumRedBits > 0, + GL_FALSE //swalpha + ); +#else + lpCtx->glBuffer = (*mesaFuncs.gl_create_framebuffer)(lpCtx->glVis); +#endif // _USE_GLD3_WGL + + if (lpCtx->glBuffer == NULL) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "gl_create_framebuffer failed\n"); + goto return_with_error; + } + +#ifdef _USE_GLD3_WGL + // Init Mesa internals + _swrast_CreateContext( lpCtx->glCtx ); + _ac_CreateContext( lpCtx->glCtx ); + _tnl_CreateContext( lpCtx->glCtx ); + _swsetup_CreateContext( lpCtx->glCtx ); + + _gldDriver.InitialiseMesa(lpCtx); + + lpCtx->glCtx->imports.warning = _gld_mesa_warning; + lpCtx->glCtx->imports.fatal = _gld_mesa_fatal; + +#else + // Tell Mesa how many texture stages we have + glb.wMaxSimultaneousTextures = lpCtx->D3DDevDesc.wMaxSimultaneousTextures; + // Only use as many Units as the spec requires + if (glb.wMaxSimultaneousTextures > MAX_TEXTURE_UNITS) + glb.wMaxSimultaneousTextures = MAX_TEXTURE_UNITS; + lpCtx->glCtx->Const.MaxTextureUnits = glb.wMaxSimultaneousTextures; + ddlogPrintf(DDLOG_INFO, "Texture stages : %d", glb.wMaxSimultaneousTextures); + + // Set the max texture size. + // NOTE: clamped to a max of 1024 for extra performance! + lpCtx->dwMaxTextureSize = (lpCtx->D3DDevDesc.dwMaxTextureWidth <= 1024) ? lpCtx->D3DDevDesc.dwMaxTextureWidth : 1024; + +// Texture resize takes place elsewhere. KH +// NOTE: This was added to workaround an issue with the Intel app. +#if 0 + lpCtx->glCtx->Const.MaxTextureSize = lpCtx->dwMaxTextureSize; +#else + lpCtx->glCtx->Const.MaxTextureSize = 1024; +#endif + + // Setup the Display Driver pointers + dglSetupDDPointers(lpCtx->glCtx); + + // Initialise all the Direct3D renderstates + dglInitStateD3D(lpCtx->glCtx); + +#if 0 + // Signal a reload of texture state on next glBegin + lpCtx->m_texHandleValid = FALSE; + lpCtx->m_mtex = FALSE; + lpCtx->m_texturing = FALSE; +#else + // Set default texture unit state +// dglSetTexture(lpCtx, 0, NULL); +// dglSetTexture(lpCtx, 1, NULL); +#endif + + // + // Set the global texture palette to default values. + // + + // Clear the entire palette + ZeroMemory(ppe, sizeof(PALETTEENTRY) * 256); + + // Fill the palette with a default colour. + // A garish colour is used to catch bugs. Here Magenta is used. + for (i=0; i < 256; i++) { + ppe[i].peRed = 255; + ppe[i].peGreen = 0; + ppe[i].peBlue = 255; + } + + RELEASE(lpCtx->lpGlobalPalette); + + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpGlobalPalette) + hResult = IDirectDrawPalette_AddRef(lpCtx->lpGlobalPalette = glb.lpGlobalPalette); + else + hResult = IDirectDraw4_CreatePalette( + lpCtx->lpDD4, + DDPCAPS_INITIALIZE | DDPCAPS_8BIT | DDPCAPS_ALLOW256, + ppe, + &(lpCtx->lpGlobalPalette), + NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_ERROR, "Default CreatePalette failed\n", hResult); + lpCtx->lpGlobalPalette = NULL; + goto return_with_error; + } + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && !glb.lpGlobalPalette) + IDirectDrawPalette_AddRef(glb.lpGlobalPalette = lpCtx->lpGlobalPalette); + +#endif // _USE_GLD3_WGL + + // ** If we have made it to here then we can enable rendering ** + lpCtx->bCanRender = TRUE; + +// ddlogMessage(DDLOG_SYSTEM, "dglCreateContextBuffers succeded\n"); + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return TRUE; + +return_with_error: + // Clean up before returning. + // This is critical for secondary devices. + + lpCtx->bCanRender = FALSE; + +#ifdef _USE_GLD3_WGL + // Destroy the Mesa context + if (lpCtx->glBuffer) + _mesa_destroy_framebuffer(lpCtx->glBuffer); + if (lpCtx->glCtx) + _mesa_destroy_context(lpCtx->glCtx); + if (lpCtx->glVis) + _mesa_destroy_visual(lpCtx->glVis); + + // Destroy driver data + _gldDriver.DestroyDrawable(lpCtx); +#else + // Destroy the Mesa context + if (lpCtx->glBuffer) + (*mesaFuncs.gl_destroy_framebuffer)(lpCtx->glBuffer); + if (lpCtx->glCtx) + (*mesaFuncs.gl_destroy_context)(lpCtx->glCtx); + if (lpCtx->glVis) + (*mesaFuncs.gl_destroy_visual)(lpCtx->glVis); + + RELEASE(lpCtx->m_pvbuf); // Release D3D vertex buffer + RELEASE(lpCtx->m_vbuf); // Release D3D vertex buffer + + if (lpCtx->lpViewport3) { + if (lpCtx->lpDev3) IDirect3DDevice3_DeleteViewport(lpCtx->lpDev3, lpCtx->lpViewport3); + RELEASE(lpCtx->lpViewport3); + lpCtx->lpViewport3 = NULL; + } + + RELEASE(lpCtx->lpDev3); + if (lpCtx->lpDepth4) { + if (lpCtx->lpBack4) + IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpBack4, 0L, lpCtx->lpDepth4); + else + IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpFront4, 0L, lpCtx->lpDepth4); + RELEASE(lpCtx->lpDepth4); + lpCtx->lpDepth4 = NULL; + } + RELEASE(lpCtx->lpBack4); + RELEASE(lpCtx->lpFront4); + else + if (lpCtx->bFullscreen) { + IDirectDraw4_RestoreDisplayMode(lpCtx->lpDD4); + IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, NULL, DDSCL_NORMAL); + } + RELEASE(lpCtx->lpD3D3); + RELEASE(lpCtx->lpDD4); + RELEASE(lpCtx->lpDD1); +#endif // _USE_GLD3_WGL + + lpCtx->bAllocated = FALSE; + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return FALSE; + +#undef DDLOG_CRITICAL_OR_WARN +} + +// *********************************************************************** + +HGLRC dglCreateContext( + HDC a, + const DGL_pixelFormat *lpPF) +{ + int i; + HGLRC hGLRC; + DGL_ctx* lpCtx; + static BOOL bWarnOnce = TRUE; + DWORD dwThreadId = GetCurrentThreadId(); + char szMsg[256]; + HWND hWnd; + LONG lpfnWndProc; + + // Validate license + if (!dglValidate()) + return NULL; + + // Is context state ready ? + if (!bContextReady) + return NULL; + + ddlogPrintf(DDLOG_SYSTEM, "dglCreateContext for HDC=%X, ThreadId=%X", a, dwThreadId); + + // Find next free context. + // Also ensure that only one Fullscreen context is created at any one time. + hGLRC = 0; // Default to Not Found + for (i=0; ibAllocated = TRUE; + // Flag that buffers need creating on next wglMakeCurrent call. + lpCtx->bHasBeenCurrent = FALSE; + lpCtx->lpPF = (DGL_pixelFormat *)lpPF; // cache pixel format + lpCtx->bCanRender = FALSE; + + // Create all the internal resources here, not in dglMakeCurrent(). + // We do a re-size check in dglMakeCurrent in case of re-allocations. (DaveM) + // We now try context allocations twice, first with video memory, + // then again with system memory. This is similar to technique + // used for dglWglResizeBuffers(). (DaveM) + if (lpCtx->bHasBeenCurrent == FALSE) { + if (!dglCreateContextBuffers(a, lpCtx, FALSE)) { + if (glb.bMessageBoxWarnings && bWarnOnce && dwLogging) { + bWarnOnce = FALSE; + switch (nContextError) { + case GLDERR_DDRAW: strcpy(szMsg, szDDrawWarning); break; + case GLDERR_D3D: strcpy(szMsg, szD3DWarning); break; + case GLDERR_MEM: strcpy(szMsg, szResourceWarning); break; + case GLDERR_BPP: strcpy(szMsg, szBPPWarning); break; + default: strcpy(szMsg, ""); + } + if (strlen(szMsg)) + MessageBox(NULL, szMsg, "GLDirect", MB_OK | MB_ICONWARNING); + } + // Only need to try again if memory error + if (nContextError == GLDERR_MEM) { + ddlogPrintf(DDLOG_WARN, "dglCreateContext failed 1st time with video memory"); + } + else { + ddlogPrintf(DDLOG_ERROR, "dglCreateContext failed"); + return NULL; + } + } + } + + // Now that we have a hWnd, we can intercept the WindowProc. + hWnd = lpCtx->hWnd; + if (hWnd) { + // Only hook individual window handler once if not hooked before. + lpfnWndProc = GetWindowLong(hWnd, GWL_WNDPROC); + if (lpfnWndProc != (LONG)dglWndProc) { + lpCtx->lpfnWndProc = lpfnWndProc; + SetWindowLong(hWnd, GWL_WNDPROC, (LONG)dglWndProc); + } + // Find the parent window of the app too. + if (glb.hWndActive == NULL) { + while (hWnd != NULL) { + glb.hWndActive = hWnd; + hWnd = GetParent(hWnd); + } + // Hook the parent window too. + lpfnWndProc = GetWindowLong(glb.hWndActive, GWL_WNDPROC); + if (glb.hWndActive == lpCtx->hWnd) + glb.lpfnWndProc = lpCtx->lpfnWndProc; + else if (lpfnWndProc != (LONG)dglWndProc) + glb.lpfnWndProc = lpfnWndProc; + if (glb.lpfnWndProc) + SetWindowLong(glb.hWndActive, GWL_WNDPROC, (LONG)dglWndProc); + } + } + + ddlogPrintf(DDLOG_SYSTEM, "dglCreateContext succeeded for HGLRC=%d", (int)hGLRC); + + return hGLRC; +} + +// *********************************************************************** +// Make a DirectGL context current +// Used by wgl functions and dgl functions +BOOL dglMakeCurrent( + HDC a, + HGLRC b) +{ + int context; + DGL_ctx* lpCtx; + HWND hWnd; + BOOL bNeedResize = FALSE; + BOOL bWindowChanged, bContextChanged; + LPDIRECTDRAWCLIPPER lpddClipper; + DWORD dwThreadId = GetCurrentThreadId(); + LONG lpfnWndProc; + + // Validate license + if (!dglValidate()) + return FALSE; + + // Is context state ready ? + if (!bContextReady) + return FALSE; + + context = (int)b; // This is as a result of STRICT! + ddlogPrintf(DDLOG_SYSTEM, "dglMakeCurrent: HDC=%X, HGLRC=%d, ThreadId=%X", a, context, dwThreadId); + + // If the HGLRC is NULL then make no context current; + // Ditto if the HDC is NULL either. (DaveM) + if (context == 0 || a == 0) { + // Corresponding Mesa operation +#ifdef _USE_GLD3_WGL + _mesa_make_current(NULL, NULL); +#else + (*mesaFuncs.gl_make_current)(NULL, NULL); +#endif + dglSetCurrentContext(0); + return TRUE; + } + + // Make sure the HGLRC is in range + if ((context > DGL_MAX_CONTEXTS) || (context < 0)) { + ddlogMessage(DDLOG_ERROR, "dglMakeCurrent: HGLRC out of range\n"); + return FALSE; + } + + // Find address of context and make sure that it has been allocated + lpCtx = dglGetContextAddress(b); + if (!lpCtx->bAllocated) { + ddlogMessage(DDLOG_ERROR, "dglMakeCurrent: Context not allocated\n"); +// return FALSE; + return TRUE; // HACK: Shuts up "WebLab Viewer Pro". KeithH + } + +#ifdef GLD_THREADS + // Serialize access to DirectDraw or DDS operations + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + + // Check if window has changed + hWnd = (a != lpCtx->hDC) ? WindowFromDC(a) : lpCtx->hWnd; + bWindowChanged = (hWnd != lpCtx->hWnd) ? TRUE : FALSE; + bContextChanged = (b != dglGetCurrentContext()) ? TRUE : FALSE; + + // If the window has changed, make sure the clipper is updated. (DaveM) + if (glb.bDirectDrawPersistant && !lpCtx->bFullscreen && (bWindowChanged || bContextChanged)) { + lpCtx->hWnd = hWnd; +#ifndef _USE_GLD3_WGL + IDirectDrawSurface4_GetClipper(lpCtx->lpFront4, &lpddClipper); + IDirectDrawClipper_SetHWnd(lpddClipper, 0, lpCtx->hWnd); + IDirectDrawClipper_Release(lpddClipper); +#endif // _USE_GLD3_WGL + } + + // Make sure hDC and hWnd is current. (DaveM) + // Obtain the dimensions of the rendering window + lpCtx->hDC = a; // Cache DC + lpCtx->hWnd = hWnd; + hWndLastActive = hWnd; + + // Check for non-window DC = memory DC ? + if (hWnd == NULL) { + if (GetClipBox(a, &lpCtx->rcScreenRect) == ERROR) { + ddlogMessage(DDLOG_WARN, "GetClipBox failed in dglMakeCurrent\n"); + SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0); + } + } + else if (!GetClientRect(lpCtx->hWnd, &lpCtx->rcScreenRect)) { + ddlogMessage(DDLOG_WARN, "GetClientRect failed in dglMakeCurrent\n"); + SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0); + } + // Check if buffers need to be re-sized; + // If so, wait until Mesa GL stuff is setup before re-sizing; + if (lpCtx->dwWidth != lpCtx->rcScreenRect.right - lpCtx->rcScreenRect.left || + lpCtx->dwHeight != lpCtx->rcScreenRect.bottom - lpCtx->rcScreenRect.top) + bNeedResize = TRUE; + + // Now we can update our globals + dglSetCurrentContext(b); + + // Corresponding Mesa operation +#ifdef _USE_GLD3_WGL + _mesa_make_current(lpCtx->glCtx, lpCtx->glBuffer); + lpCtx->glCtx->Driver.UpdateState(lpCtx->glCtx, _NEW_ALL); + if (bNeedResize) { + // Resize buffers (Note Mesa GL needs to be setup beforehand); + // Resize Mesa internal buffer too via glViewport() command, + // which subsequently calls dglWglResizeBuffers() too. + lpCtx->glCtx->Driver.Viewport(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); + lpCtx->bHasBeenCurrent = TRUE; + } +#else + (*mesaFuncs.gl_make_current)(lpCtx->glCtx, lpCtx->glBuffer); + + dglSetupDDPointers(lpCtx->glCtx); + + // Insure DirectDraw surfaces fit current window DC + if (bNeedResize) { + // Resize buffers (Note Mesa GL needs to be setup beforehand); + // Resize Mesa internal buffer too via glViewport() command, + // which subsequently calls dglWglResizeBuffers() too. + (*mesaFuncs.gl_Viewport)(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); + lpCtx->bHasBeenCurrent = TRUE; + } +#endif // _USE_GLD3_WGL + ddlogPrintf(DDLOG_SYSTEM, "dglMakeCurrent: width = %d, height = %d", lpCtx->dwWidth, lpCtx->dwHeight); + + // We have to clear D3D back buffer and render state if emulated front buffering + // for different window (but not context) like in Solid Edge. + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers + && (bWindowChanged /* || bContextChanged */) && lpCtx->EmulateSingle) { +#ifdef _USE_GLD3_WGL +// IDirect3DDevice8_EndScene(lpCtx->pDev); +// lpCtx->bSceneStarted = FALSE; + lpCtx->glCtx->Driver.Clear(lpCtx->glCtx, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, + GL_TRUE, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); +#else + IDirect3DDevice3_EndScene(lpCtx->lpDev3); + lpCtx->bSceneStarted = FALSE; + dglClearD3D(lpCtx->glCtx, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, + GL_TRUE, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); +#endif // _USE_GLD3_WGL + } + + // The first time we call MakeCurrent we set the initial viewport size + if (lpCtx->bHasBeenCurrent == FALSE) +#ifdef _USE_GLD3_WGL + lpCtx->glCtx->Driver.Viewport(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); +#else + (*mesaFuncs.gl_Viewport)(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); +#endif // _USE_GLD3_WGL + lpCtx->bHasBeenCurrent = TRUE; + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return TRUE; +} + +// *********************************************************************** + +BOOL dglDeleteContext( + HGLRC a) +{ + DGL_ctx* lpCtx; + DWORD dwThreadId = GetCurrentThreadId(); + char argstr[256]; + +#if 0 // We have enough trouble throwing exceptions as it is... (DaveM) + // Validate license + if (!dglValidate()) + return FALSE; +#endif + + // Is context state ready ? + if (!bContextReady) + return FALSE; + + ddlogPrintf(DDLOG_SYSTEM, "dglDeleteContext: Deleting context HGLRC=%d, ThreadId=%X", (int)a, dwThreadId); + + // Make sure the HGLRC is in range + if (((int) a> DGL_MAX_CONTEXTS) || ((int)a < 0)) { + ddlogMessage(DDLOG_ERROR, "dglDeleteCurrent: HGLRC out of range\n"); + return FALSE; + } + + // Make sure context is valid + lpCtx = dglGetContextAddress(a); + if (!lpCtx->bAllocated) { + ddlogPrintf(DDLOG_WARN, "Tried to delete unallocated context HGLRC=%d", (int)a); +// return FALSE; + return TRUE; // HACK: Shuts up "WebLab Viewer Pro". KeithH + } + + // Make sure context is de-activated + if (a == dglGetCurrentContext()) { + ddlogPrintf(DDLOG_WARN, "dglDeleteContext: context HGLRC=%d still active", (int)a); + dglMakeCurrent(NULL, NULL); + } + +#ifdef GLD_THREADS + // Serialize access to DirectDraw or DDS operations + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + + // We are about to destroy all Direct3D objects. + // Therefore we must disable rendering + lpCtx->bCanRender = FALSE; + + // This exception handler was installed to catch some + // particularly nasty apps. Console apps that call exit() + // fall into this catagory (i.e. Win32 Glut). + + // VC cannot successfully implement multiple exception handlers + // if more than one exception occurs. Therefore reverting back to + // single exception handler as Keith originally had it. (DaveM) + +#define WARN_MESSAGE(p) strcpy(argstr, (#p)); +#define SAFE_RELEASE(p) WARN_MESSAGE(p); RELEASE(p); + +__try { +#ifdef _USE_GLD3_WGL + WARN_MESSAGE(gl_destroy_framebuffer); + if (lpCtx->glBuffer) + _mesa_destroy_framebuffer(lpCtx->glBuffer); + WARN_MESSAGE(gl_destroy_context); + if (lpCtx->glCtx) + _mesa_destroy_context(lpCtx->glCtx); + WARN_MESSAGE(gl_destroy_visual); + if (lpCtx->glVis) + _mesa_destroy_visual(lpCtx->glVis); + + _gldDriver.DestroyDrawable(lpCtx); +#else + // Destroy the Mesa context + WARN_MESSAGE(gl_destroy_framebuffer); + if (lpCtx->glBuffer) + (*mesaFuncs.gl_destroy_framebuffer)(lpCtx->glBuffer); + WARN_MESSAGE(gl_destroy_context); + if (lpCtx->glCtx) + (*mesaFuncs.gl_destroy_context)(lpCtx->glCtx); + WARN_MESSAGE(gl_destroy_visual); + if (lpCtx->glVis) + (*mesaFuncs.gl_destroy_visual)(lpCtx->glVis); + + SAFE_RELEASE(lpCtx->m_pvbuf); // release D3D vertex buffer + SAFE_RELEASE(lpCtx->m_vbuf); // release D3D vertex buffer + + // Delete the global palette + SAFE_RELEASE(lpCtx->lpGlobalPalette); + + // Clean up. + if (lpCtx->lpViewport3) { + if (lpCtx->lpDev3) IDirect3DDevice3_DeleteViewport(lpCtx->lpDev3, lpCtx->lpViewport3); + SAFE_RELEASE(lpCtx->lpViewport3); + lpCtx->lpViewport3 = NULL; + } + + SAFE_RELEASE(lpCtx->lpDev3); + if (lpCtx->lpDepth4) { + if (lpCtx->lpBack4) + IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpBack4, 0L, lpCtx->lpDepth4); + else + IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpFront4, 0L, lpCtx->lpDepth4); + SAFE_RELEASE(lpCtx->lpDepth4); + lpCtx->lpDepth4 = NULL; + } + SAFE_RELEASE(lpCtx->lpBack4); + SAFE_RELEASE(lpCtx->lpFront4); + if (lpCtx->bFullscreen) { + IDirectDraw4_RestoreDisplayMode(lpCtx->lpDD4); + IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, NULL, DDSCL_NORMAL); + } + SAFE_RELEASE(lpCtx->lpD3D3); + SAFE_RELEASE(lpCtx->lpDD4); + SAFE_RELEASE(lpCtx->lpDD1); +#endif // _ULSE_GLD3_WGL + +} +__except(EXCEPTION_EXECUTE_HANDLER) { + ddlogPrintf(DDLOG_WARN, "Exception raised in dglDeleteContext: %s", argstr); +} + + // Restore the window message handler because this context may be used + // again by another window with a *different* message handler. (DaveM) + if (lpCtx->lpfnWndProc) { + SetWindowLong(lpCtx->hWnd, GWL_WNDPROC, (LONG)lpCtx->lpfnWndProc); + lpCtx->lpfnWndProc = (LONG)NULL; + } + + lpCtx->bAllocated = FALSE; // This context is now free for use + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return TRUE; +} + +// *********************************************************************** + +BOOL dglSwapBuffers( + HDC hDC) +{ + RECT rSrcRect; // Source rectangle + RECT rDstRect; // Destination rectangle + POINT pt; + HRESULT hResult; + + DDBLTFX bltFX; + DWORD dwBlitFlags; + DDBLTFX *lpBltFX; + +// DWORD dwThreadId = GetCurrentThreadId(); + HGLRC hGLRC = dglGetCurrentContext(); + DGL_ctx *lpCtx = dglGetContextAddress(hGLRC); + HWND hWnd; + + HDC hDCAux; // for memory DC + int x,y,w,h; // for memory DC BitBlt + +#if 0 // Perhaps not a good idea. Called too often. KH + // Validate license + if (!dglValidate()) + return FALSE; +#endif + + if (!lpCtx) { + return TRUE; //FALSE; // No current context + } + + if (!lpCtx->bCanRender) { + // Don't return false else some apps will bail. + return TRUE; + } + + hWnd = lpCtx->hWnd; + if (hDC != lpCtx->hDC) { + ddlogPrintf(DDLOG_WARN, "dglSwapBuffers: HDC=%X does not match HDC=%X for HGLRC=%d", hDC, lpCtx->hDC, hGLRC); + hWnd = WindowFromDC(hDC); + } + +#ifndef _USE_GLD3_WGL + // Ensure that the surfaces exist before we tell + // the device to render to them. + IDirectDraw4_RestoreAllSurfaces(lpCtx->lpDD4); + + // Make sure that the vertex caches have been emptied +// dglStateChange(lpCtx); + + // Some OpenGL programs don't issue a glFinish - check for it here. + if (lpCtx->bSceneStarted) { + IDirect3DDevice3_EndScene(lpCtx->lpDev3); + lpCtx->bSceneStarted = FALSE; + } +#endif + +#if 0 + // If the calling app is not active then we don't need to Blit/Flip. + // We can therefore simply return TRUE. + if (!glb.bAppActive) + return TRUE; + // Addendum: This is WRONG! We should bail if the app is *minimized*, + // not merely if the app is just plain 'not active'. + // KeithH, 27/May/2000. +#endif + + // Check for non-window DC = memory DC ? + if (hWnd == NULL) { + if (GetClipBox(hDC, &rSrcRect) == ERROR) + return TRUE; + // Use GDI BitBlt instead from compatible DirectDraw DC + x = rSrcRect.left; + y = rSrcRect.top; + w = rSrcRect.right - rSrcRect.left; + h = rSrcRect.bottom - rSrcRect.top; + + // Ack. DX8 does not have a GetDC() function... + // TODO: Defer to DX7 or DX9 drivers... (DaveM) + return TRUE; + } + + // Bail if window client region is not drawable, like in Solid Edge + if (!IsWindow(hWnd) /* || !IsWindowVisible(hWnd) */ || !GetClientRect(hWnd, &rSrcRect)) + return TRUE; + +#ifdef GLD_THREADS + // Serialize access to DirectDraw or DDS operations + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + +#ifdef _USE_GLD3_WGL + // Notify Mesa of impending swap, so Mesa can flush internal buffers. + _mesa_notifySwapBuffers(lpCtx->glCtx); + // Now perform driver buffer swap + _gldDriver.SwapBuffers(lpCtx, hDC, hWnd); +#else + if (lpCtx->bFullscreen) { + // Sync with retrace if required + if (glb.bWaitForRetrace) { + IDirectDraw4_WaitForVerticalBlank( + lpCtx->lpDD4, + DDWAITVB_BLOCKBEGIN, + 0); + } + + // Perform the fullscreen flip + TRY(IDirectDrawSurface4_Flip( + lpCtx->lpFront4, + NULL, + DDFLIP_WAIT), + "dglSwapBuffers: Flip"); + } else { + // Calculate current window position and size + pt.x = pt.y = 0; + ClientToScreen(hWnd, &pt); + GetClientRect(hWnd, &rDstRect); + if (rDstRect.right > lpCtx->dwModeWidth) + rDstRect.right = lpCtx->dwModeWidth; + if (rDstRect.bottom > lpCtx->dwModeHeight) + rDstRect.bottom = lpCtx->dwModeHeight; + OffsetRect(&rDstRect, pt.x, pt.y); + rSrcRect.left = rSrcRect.top = 0; + rSrcRect.right = lpCtx->dwWidth; + rSrcRect.bottom = lpCtx->dwHeight; + if (rSrcRect.right > lpCtx->dwModeWidth) + rSrcRect.right = lpCtx->dwModeWidth; + if (rSrcRect.bottom > lpCtx->dwModeHeight) + rSrcRect.bottom = lpCtx->dwModeHeight; + + if (glb.bWaitForRetrace) { + // Sync the blit to the vertical retrace + ZeroMemory(&bltFX, sizeof(bltFX)); + bltFX.dwSize = sizeof(bltFX); + bltFX.dwDDFX = DDBLTFX_NOTEARING; + dwBlitFlags = DDBLT_WAIT | DDBLT_DDFX; + lpBltFX = &bltFX; + } else { + dwBlitFlags = DDBLT_WAIT; + lpBltFX = NULL; + } + + // Perform the actual blit + TRY(IDirectDrawSurface4_Blt( + lpCtx->lpFront4, + &rDstRect, + lpCtx->lpBack4, // Blit source + &rSrcRect, + dwBlitFlags, + lpBltFX), + "dglSwapBuffers: Blt"); + } +#endif // _USE_GLD3_WGL + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + // TODO: Re-instate rendering bitmap snapshot feature??? (DaveM) + + // Render frame is completed + ValidateRect(hWnd, NULL); + lpCtx->bFrameStarted = FALSE; + + return TRUE; +} + +// *********************************************************************** diff --git a/src/mesa/drivers/windows/gldirect/dglcontext.h b/src/mesa/drivers/windows/gldirect/dglcontext.h new file mode 100644 index 0000000..5c433b8 --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/dglcontext.h @@ -0,0 +1,281 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: OpenGL context handling. +* +****************************************************************************/ + +#ifndef __DGLCONTEXT_H +#define __DGLCONTEXT_H + +// Disable compiler complaints about DLL linkage +#pragma warning (disable:4273) + +// Macros to control compilation +#ifndef STRICT +#define STRICT +#endif // STRICT +#define WIN32_LEAN_AND_MEAN +#include +#include + +#ifdef _USE_GLD3_WGL + #include "dglmacros.h" + #include "dglglobals.h" + #include "pixpack.h" + #include "ddlog.h" + #include "dglpf.h" + #include "context.h" // Mesa context +#else + #include + #include + + #include "dglmacros.h" + #include "dglglobals.h" + #include "pixpack.h" + #include "ddlog.h" + #include "dglpf.h" + #include "d3dvertex.h" + + #include "DirectGL.h" + + #include "context.h" // Mesa context + #include "vb.h" // Mesa vertex buffer +#endif // _USE_GLD3_WGL + +/*---------------------- Macros and type definitions ----------------------*/ + +// TODO: Use a list instead of this constant! +#define DGL_MAX_CONTEXTS 32 + +// Structure for describing an OpenGL context +#ifdef _USE_GLD3_WGL +typedef struct { + BOOL bHasBeenCurrent; + DGL_pixelFormat *lpPF; + + // Pointer to private driver data (this also contains the drawable). + void *glPriv; + + // Mesa vars: + GLcontext *glCtx; // The core Mesa context + GLvisual *glVis; // Describes the color buffer + GLframebuffer *glBuffer; // Ancillary buffers + + GLuint ClearIndex; + GLuint CurrentIndex; + GLubyte ClearColor[4]; + GLubyte CurrentColor[4]; + + BOOL EmulateSingle; // Emulate single-buffering + BOOL bDoubleBuffer; + BOOL bDepthBuffer; + + // Shared driver vars: + BOOL bAllocated; + BOOL bFullscreen; // Is this a fullscreen context? + BOOL bSceneStarted; // Has a lpDev->BeginScene been issued? + BOOL bCanRender; // Flag: states whether rendering is OK + BOOL bFrameStarted; // Has frame update started at all? + BOOL bStencil; // TRUE if this context has stencil + BOOL bGDIEraseBkgnd; // GDI Erase Background command + + // Window information + HWND hWnd; // Window handle + HDC hDC; // Windows' Device Context of the window + DWORD dwWidth; // Window width + DWORD dwHeight; // Window height + DWORD dwBPP; // Window bits-per-pixel; + RECT rcScreenRect; // Screen rectangle + DWORD dwModeWidth; // Display mode width + DWORD dwModeHeight; // Display mode height + float dvClipX; + float dvClipY; + LONG lpfnWndProc; // window message handler function + +} DGL_ctx; + +#define GLD_context DGL_ctx +#define GLD_GET_CONTEXT(c) (GLD_context*)(c)->DriverCtx + +#else // _USE_GLD3_WGL + +typedef struct { + BOOL bHasBeenCurrent; + DGL_pixelFormat *lpPF; + // + // Mesa context vars: + // + GLcontext *glCtx; // The core Mesa context + GLvisual *glVis; // Describes the color buffer + GLframebuffer *glBuffer; // Ancillary buffers + + GLuint ClearIndex; + GLuint CurrentIndex; + GLubyte ClearColor[4]; + GLubyte CurrentColor[4]; + + BOOL EmulateSingle; // Emulate single-buffering + BOOL bDoubleBuffer; + BOOL bDepthBuffer; + int iZBufferPF; // Index of Zbuffer pixel format + + // Vertex buffer: one-to-one correlation with Mesa's vertex buffer. + // This will be filled by our setup function (see d3dvsetup.c) + DGL_TLvertex gWin[VB_SIZE]; // Transformed and lit vertices +// DGL_Lvertex gObj[VB_SIZE]; // Lit vertices in object coordinates. + + // Indices for DrawIndexedPrimitive. + // Clipped quads are drawn seperately, so use VB_SIZE. + // 6 indices are needed to make 2 triangles for each possible quad +// WORD wIndices[(VB_SIZE / 4) * 6]; + WORD wIndices[32768]; + + // + // Device driver vars: + // + BOOL bAllocated; + BOOL bFullscreen; // Is this a fullscreen context? + BOOL bSceneStarted; // Has a lpDev->BeginScene been issued? + BOOL bCanRender; // Flag: states whether rendering is OK + BOOL bFrameStarted; // Has frame update started at all? + + // DirectX COM interfaces, postfixed with the interface number + IDirectDraw *lpDD1; + IDirectDraw4 *lpDD4; + IDirect3D3 *lpD3D3; + IDirect3DDevice3 *lpDev3; + IDirect3DViewport3 *lpViewport3; + IDirectDrawSurface4 *lpFront4; + IDirectDrawSurface4 *lpBack4; + IDirectDrawSurface4 *lpDepth4; + + // Vertex buffers + BOOL bD3DPipeline; // True if using D3D geometry pipeline + IDirect3DVertexBuffer *m_vbuf; // Unprocessed vertices + IDirect3DVertexBuffer *m_pvbuf; // Processed vertices ready to be rendered + + D3DTEXTUREOP ColorOp[MAX_TEXTURE_UNITS]; // Used for re-enabling texturing + D3DTEXTUREOP AlphaOp[MAX_TEXTURE_UNITS]; // Used for re-enabling texturing + struct gl_texture_object *tObj[MAX_TEXTURE_UNITS]; + + DDCAPS ddCaps; // DirectDraw caps + D3DDEVICEDESC D3DDevDesc; // Direct3D Device description + + DDPIXELFORMAT ddpfRender; // Pixel format of the render buffer + DDPIXELFORMAT ddpfDepth; // Pixel format of the depth buffer + + BOOL bStencil; // TRUE is this context has stencil + + PX_packFunc fnPackFunc; // Pixel packing function for SW + PX_unpackFunc fnUnpackFunc; // Pixel unpacking function for SW + PX_packSpanFunc fnPackSpanFunc; // Pixel span packer + + D3DVIEWPORT2 d3dViewport; // D3D Viewport object + + D3DCULL cullmode; // Direct3D cull mode + D3DCOLOR curcolor; // Current color + DWORD dwColorPF; // Current color, in format of target surface + D3DCOLOR d3dClearColor; // Clear color + D3DCOLOR ConstantColor; // For flat shading + DWORD dwClearColorPF; // Clear color, in format of target surface + BOOL bGDIEraseBkgnd; // GDI Erase Background command + + // Primitive caches +// DGL_vertex LineCache[DGL_MAX_LINE_VERTS]; +// DGL_vertex TriCache[DGL_MAX_TRI_VERTS]; +// DWORD dwNextLineVert; +// DWORD dwNextTriVert; + + // Window information + HWND hWnd; // Window handle + HDC hDC; // Windows' Device Context of the window + DWORD dwWidth; // Window width + DWORD dwHeight; // Window height + DWORD dwBPP; // Window bits-per-pixel; + RECT rcScreenRect; // Screen rectangle + DWORD dwModeWidth; // Display mode width + DWORD dwModeHeight; // Display mode height + float dvClipX; + float dvClipY; + LONG lpfnWndProc; // window message handler function + + // Shared texture palette + IDirectDrawPalette *lpGlobalPalette; + + // Usage counters. + // One of these counters will be incremented when we choose + // between hardware and software rendering functions. +// DWORD dwHWUsageCount; // Hardware usage count +// DWORD dwSWUsageCount; // Software usage count + + // Texture state flags. +// BOOL m_texturing; // TRUE is texturing +// BOOL m_mtex; // TRUE if multitexture +// BOOL m_texHandleValid; // TRUE if tex state valid + + // Renderstate caches to ensure no redundant state changes + DWORD dwRS[256]; // Renderstates + DWORD dwTSS[2][24]; // Texture-stage states + LPDIRECT3DTEXTURE2 lpTex[2]; // Texture (1 per stage) + + DWORD dwMaxTextureSize; // Max texture size: + // clamped to 1024. + +} DGL_ctx; +#endif // _USE_GLD3_WGL + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +HHOOK hKeyHook; +LRESULT CALLBACK dglKeyProc(int code,WPARAM wParam,LPARAM lParam); + +void dglInitContextState(); +void dglDeleteContextState(); +BOOL dglIsValidContext(HGLRC a); +DGL_ctx* dglGetContextAddress(const HGLRC a); +HDC dglGetCurrentDC(void); +HGLRC dglGetCurrentContext(void); +HGLRC dglCreateContext(HDC a, const DGL_pixelFormat *lpPF); +BOOL dglMakeCurrent(HDC a, HGLRC b); +BOOL dglDeleteContext(HGLRC a); +BOOL dglSwapBuffers(HDC hDC); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mesa/drivers/windows/gldirect/dglglobals.c b/src/mesa/drivers/windows/gldirect/dglglobals.c new file mode 100644 index 0000000..c633e3b --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/dglglobals.c @@ -0,0 +1,149 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Global variables. +* +****************************************************************************/ + +#include "dglglobals.h" + +// ======================================================================= +// Global Variables +// ======================================================================= + +char szCopyright[] = "Copyright (c) 1998 SciTech Software, Inc."; +char szDllName[] = "Scitech GLDirect"; +char szErrorTitle[] = "GLDirect Error"; + +DGL_globals glb; + +// Shared result variable +HRESULT hResult; + +// *********************************************************************** + +// Patch function for missing function in Mesa +int finite( + double x) +{ + return _finite(x); +}; + +// *********************************************************************** + +void dglInitGlobals() +{ + // Zero all fields just in case + memset(&glb, 0, sizeof(glb)); + + // Set the global defaults + glb.bPrimary = FALSE; // Not the primary device + glb.bHardware = FALSE; // Not a hardware device +// glb.bFullscreen = FALSE; // Not running fullscreen + glb.bSquareTextures = FALSE; // Device does not need sq + glb.bPAL8 = FALSE; // Device cannot do 8bit + glb.dwMemoryType = DDSCAPS_SYSTEMMEMORY; + glb.dwRendering = DGL_RENDER_D3D; + + glb.bWaitForRetrace = TRUE; // Sync to vertical retrace + glb.bFullscreenBlit = FALSE; + + glb.nPixelFormatCount = 0; + glb.lpPF = NULL; // Pixel format list +#ifndef _USE_GLD3_WGL + glb.nZBufferPFCount = 0; + glb.lpZBufferPF = NULL; + glb.nDisplayModeCount = 0; + glb.lpDisplayModes = NULL; + glb.nTextureFormatCount = 0; + glb.lpTextureFormat = NULL; +#endif // _USE_GLD3_WGL + + glb.wMaxSimultaneousTextures = 1; + + // Enable support for multitexture, if available. + glb.bMultitexture = TRUE; + + // Enable support for mipmapping + glb.bUseMipmaps = TRUE; + + // Alpha emulation via chroma key + glb.bEmulateAlphaTest = FALSE; + + // Use Mesa pipeline always (for compatibility) + glb.bForceMesaPipeline = FALSE; + + // Init support for multiple GLRCs + glb.bDirectDraw = FALSE; + glb.bDirectDrawPrimary = FALSE; + glb.bDirect3D = FALSE; + glb.bDirect3DDevice = FALSE; + glb.bDirectDrawStereo = FALSE; + glb.iDirectDrawStereo = 0; + glb.hWndActive = NULL; + // Init DirectX COM interfaces for multiple GLRCs +// glb.lpDD4 = NULL; +// glb.lpPrimary4 = NULL; +// glb.lpBack4 = NULL; +// glb.lpDepth4 = NULL; +// glb.lpGlobalPalette = NULL; + + // Init special support options + glb.bMessageBoxWarnings = TRUE; + glb.bDirectDrawPersistant = FALSE; + glb.bPersistantBuffers = FALSE; + + // Do not assume single-precision-only FPU (for compatibility) + glb.bFastFPU = FALSE; + + // Allow hot-key support + glb.bHotKeySupport = TRUE; + + // Default to single-threaded support (for simplicity) + glb.bMultiThreaded = FALSE; + + // Use application-specific customizations (for end-user convenience) + glb.bAppCustomizations = TRUE; + +#ifdef _USE_GLD3_WGL + // Registry/ini-file settings for GLDirect 3.x + glb.dwAdapter = 0; // Primary DX8 adapter + glb.dwTnL = 1; // MesaSW TnL + glb.dwMultisample = 0; // Multisample Off + glb.dwDriver = 2; // Direct3D HW + + // Signal a pixelformat list rebuild + glb.bPixelformatsDirty = TRUE; +#endif +} + +// *********************************************************************** diff --git a/src/mesa/drivers/windows/gldirect/dglglobals.h b/src/mesa/drivers/windows/gldirect/dglglobals.h new file mode 100644 index 0000000..995f1cd --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/dglglobals.h @@ -0,0 +1,198 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Globals. +* +****************************************************************************/ + +#ifndef __DGLGLOBALS_H +#define __DGLGLOBALS_H + +#include "dglcontext.h" +#include "dglpf.h" // Pixel format +#ifndef _USE_GLD3_WGL +#include "d3dtexture.h" +#endif + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef enum { + DGL_RENDER_MESASW = 0, + DGL_RENDER_D3D = 1, + DGL_RENDER_FORCE_DWORD = 0x7ffffff, +} DGL_renderType; + +#ifdef _USE_GLD3_WGL + +// Same as DGL_renderType? KeithH +typedef enum { + GLDS_DRIVER_MESA_SW = 0, // Mesa SW rendering + GLDS_DRIVER_REF = 1, // Direct3D Reference Rasteriser + GLDS_DRIVER_HAL = 2, // Direct3D HW rendering +} GLDS_DRIVER; + +typedef enum { + GLDS_TNL_DEFAULT = 0, // Choose best TnL method + GLDS_TNL_MESA = 1, // Mesa TnL + GLDS_TNL_D3DSW = 2, // D3D Software TnL + GLDS_TNL_D3DHW = 3, // D3D Hardware TnL +} GLDS_TNL; + +typedef enum { + GLDS_MULTISAMPLE_NONE = 0, + GLDS_MULTISAMPLE_FASTEST = 1, + GLDS_MULTISAMPLE_NICEST = 2, +} GLDS_MULTISAMPLE; +#endif + +typedef struct { + // Registry settings + char szDDName[MAX_DDDEVICEID_STRING]; // DirectDraw device name + char szD3DName[MAX_DDDEVICEID_STRING]; // Direct3D driver name + BOOL bPrimary; // Is ddraw device the Primary device? + BOOL bHardware; // Is the d3d driver a Hardware driver? +#ifndef _USE_GLD3_WGL + GUID ddGuid; // GUID of the ddraw device + GUID d3dGuid; // GUID of the direct3d driver +#endif // _USE_GLD3_WGL +// BOOL bFullscreen; // Force fullscreen - only useful for primary adaptors. + BOOL bSquareTextures; // Does this driver require square textures? + DWORD dwRendering; // Type of rendering required + + BOOL bWaitForRetrace; // Sync to vertical retrace + BOOL bFullscreenBlit; // Use Blt instead of Flip in fullscreen modes + + // Multitexture + BOOL bMultitexture; + + BOOL bUseMipmaps; + + DWORD dwMemoryType; // Sysmem or Vidmem + + // Global palette + BOOL bPAL8; + DDPIXELFORMAT ddpfPAL8; + + // Multitexture + WORD wMaxSimultaneousTextures; + + // Win32 internals + BOOL bAppActive; // Keep track of Alt-Tab + LONG lpfnWndProc; // WndProc of calling app + + // Pixel Format Descriptior list. + int nPixelFormatCount; + DGL_pixelFormat *lpPF; +#ifndef _USE_GLD3_WGL + // ZBuffer pixel formats + int nZBufferPFCount; // Count of Zbuffer pixel formats + DDPIXELFORMAT *lpZBufferPF; // ZBuffer pixel formats + + // Display modes (for secondary devices) + int nDisplayModeCount; + DDSURFACEDESC2 *lpDisplayModes; + + // Texture pixel formats + int nTextureFormatCount; + DGL_textureFormat *lpTextureFormat; +#endif // _USE_GLD3_WGL + // Alpha emulation via chroma key + BOOL bEmulateAlphaTest; + + // Geom pipeline override. + // If this is set TRUE then the D3D pipeline will never be used, + // and the Mesa pipline will always be used. + BOOL bForceMesaPipeline; + +#ifdef _USE_GLD3_WGL + BOOL bPixelformatsDirty; // Signal a list rebuild +#endif + + // Additional globals to support multiple GL rendering contexts, GLRCs + BOOL bDirectDraw; // DirectDraw interface exists ? + BOOL bDirectDrawPrimary; // DirectDraw primary surface exists ? + BOOL bDirect3D; // Direct3D interface exists ? + BOOL bDirect3DDevice; // Direct3D device exists ? + + BOOL bDirectDrawStereo; // DirectDraw Stereo driver started ? + int iDirectDrawStereo; // DirectDraw Stereo driver reference count + HWND hWndActive; // copy of active window + + // Copies of DirectX COM interfaces for re-referencing across multiple GLRCs +// IDirectDraw4 *lpDD4; // copy of DirectDraw interface +// IDirectDrawSurface4 *lpPrimary4; // copy of DirectDraw primary surface +// IDirectDrawSurface4 *lpBack4; +// IDirectDrawSurface4 *lpDepth4; +// IDirectDrawPalette *lpGlobalPalette; + + // Aids for heavy-duty MFC-windowed OGL apps, like AutoCAD + BOOL bMessageBoxWarnings; // popup message box warning + BOOL bDirectDrawPersistant; // DirectDraw is persisitant + BOOL bPersistantBuffers; // DirectDraw buffers persisitant + + // FPU setup option for CAD precision (AutoCAD) vs GAME speed (Quake) + BOOL bFastFPU; // single-precision-only FPU ? + + // Hot-Key support, like for real-time stereo parallax adjustments + BOOL bHotKeySupport; // hot-key support ? + + // Multi-threaded support, for apps like 3DStudio + BOOL bMultiThreaded; // multi-threaded ? + + // Detect and use app-specific customizations for apps like 3DStudio + BOOL bAppCustomizations; // app customizations ? + +#ifdef _USE_GLD3_WGL + DWORD dwAdapter; // Primary DX8 adapter + DWORD dwTnL; // MesaSW TnL + DWORD dwMultisample; // Multisample Off + DWORD dwDriver; // Direct3D HW + void *pDrvPrivate; // Driver-specific data +#endif + +} DGL_globals; + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +DGL_globals glb; + +void dglInitGlobals(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mesa/drivers/windows/gldirect/dglmacros.h b/src/mesa/drivers/windows/gldirect/dglmacros.h new file mode 100644 index 0000000..aed0f21 --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/dglmacros.h @@ -0,0 +1,91 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Useful generic macros. +* +****************************************************************************/ + +#ifndef __DGLMACROS_H +#define __DGLMACROS_H + +#include + +// Define the relevant RELEASE macro depending on C or C++ +#if !defined(__cplusplus) || defined(CINTERFACE) + // Standard C version + #define RELEASE(x) if (x!=NULL) { x->lpVtbl->Release(x); x=NULL; } +#else + // C++ version + #define RELEASE(x) if (x!=NULL) { x->Release(); x=NULL; } +#endif + +// We don't want a message *every* time we call an unsupported function +#define UNSUPPORTED(x) \ + { \ + static BOOL bFirstTime = TRUE; \ + if (bFirstTime) { \ + bFirstTime = FALSE; \ + ddlogError(DDLOG_WARN, (x), DDERR_CURRENTLYNOTAVAIL); \ + } \ + } + +#define DGL_CHECK_CONTEXT \ + if (ctx == NULL) return; + +// Don't render if bCanRender is not TRUE. +#define DGL_CHECK_RENDER \ + if (!dgl->bCanRender) return; + +#if 0 +#define TRY(a,b) (a) +#define TRY_ERR(a,b) (a) +#else +// hResult should be defined in the function +// Return codes should be checked via SUCCEDDED and FAILED macros +#define TRY(a,b) \ + { \ + if (FAILED(hResult=(a))) \ + ddlogError(DDLOG_ERROR, (b), hResult); \ + } + +// hResult is a global +// The label exit_with_error should be defined within the calling scope +#define TRY_ERR(a,b) \ + { \ + if (FAILED(hResult=(a))) { \ + ddlogError(DDLOG_ERROR, (b), hResult); \ + goto exit_with_error; \ + } \ + } +#endif // #if 1 + +#endif diff --git a/src/mesa/drivers/windows/gldirect/dglpf.c b/src/mesa/drivers/windows/gldirect/dglpf.c new file mode 100644 index 0000000..65e389d --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/dglpf.c @@ -0,0 +1,620 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Pixel Formats. +* +****************************************************************************/ + +#include "dglpf.h" + +#ifdef _USE_GLD3_WGL +#include "gld_driver.h" +#endif + +// *********************************************************************** + +char szColorDepthWarning[] = +"GLDirect does not support the current desktop\n\ +color depth.\n\n\ +You may need to change the display resolution to\n\ +16 bits per pixel or higher color depth using\n\ +the Windows Display Settings control panel\n\ +before running this OpenGL application.\n"; + +// *********************************************************************** +// This pixel format will be used as a template when compiling the list +// of pixel formats supported by the hardware. Many fields will be +// filled in at runtime. +// PFD flag defaults are upgraded to match ChoosePixelFormat() -- DaveM +DGL_pixelFormat pfTemplateHW = +{ + { + sizeof(PIXELFORMATDESCRIPTOR), // Size of the data structure + 1, // Structure version - should be 1 + // Flags: + PFD_DRAW_TO_WINDOW | // The buffer can draw to a window or device surface. + PFD_DRAW_TO_BITMAP | // The buffer can draw to a bitmap. (DaveM) + PFD_SUPPORT_GDI | // The buffer supports GDI drawing. (DaveM) + PFD_SUPPORT_OPENGL | // The buffer supports OpenGL drawing. + PFD_DOUBLEBUFFER | // The buffer is double-buffered. + 0, // Placeholder for easy commenting of above flags + PFD_TYPE_RGBA, // Pixel type RGBA. + 16, // Total colour bitplanes (excluding alpha bitplanes) + 5, 0, // Red bits, shift + 5, 5, // Green bits, shift + 5, 10, // Blue bits, shift + 0, 0, // Alpha bits, shift (destination alpha) + 0, // Accumulator bits (total) + 0, 0, 0, 0, // Accumulator bits: Red, Green, Blue, Alpha + 0, // Depth bits + 0, // Stencil bits + 0, // Number of auxiliary buffers + 0, // Layer type + 0, // Specifies the number of overlay and underlay planes. + 0, // Layer mask + 0, // Specifies the transparent color or index of an underlay plane. + 0 // Damage mask + }, + -1, // No depth/stencil buffer +}; + +// *********************************************************************** +// Return the count of the number of bits in a Bit Mask. +int BitCount( + DWORD dw) +{ + int i; + + if (dw == 0) + return 0; // account for non-RGB mode + + for (i=0; dw; dw=dw>>1) + i += (dw & 1); + return i; +} + +// *********************************************************************** + +DWORD BitShift( + DWORD dwMaskIn) +{ + DWORD dwShift, dwMask; + + if (dwMaskIn == 0) + return 0; // account for non-RGB mode + + for (dwShift=0, dwMask=dwMaskIn; !(dwMask&1); dwShift++, dwMask>>=1); + + return dwShift; +} + +// *********************************************************************** + +BOOL IsValidPFD(int iPFD) +{ + DGL_pixelFormat *lpPF; + + // Validate license + if (!dglValidate()) + return FALSE; + + if ((glb.lpPF == NULL) || + (glb.nPixelFormatCount == 0)) + return FALSE; + + // Check PFD range + if ( (iPFD < 1) || (iPFD > glb.nPixelFormatCount) ) { + ddlogMessage(DDLOG_ERROR, "PFD out of range\n"); + return FALSE; // PFD is invalid + } + + // Make a pointer to the pixel format + lpPF = &glb.lpPF[iPFD-1]; + + // Check size + if (lpPF->pfd.nSize != sizeof(PIXELFORMATDESCRIPTOR)) { + ddlogMessage(DDLOG_ERROR, "Bad PFD size\n"); + return FALSE; // PFD is invalid + } + + // Check version + if (lpPF->pfd.nVersion != 1) { + ddlogMessage(DDLOG_ERROR, "PFD is not Version 1\n"); + return FALSE; // PFD is invalid + } + + return TRUE; // PFD is valid +} + +// *********************************************************************** + +#ifndef _USE_GLD3_WGL + +int iEnumCount; // Enumeration count +DWORD dwDisplayBitDepth; // Bit depth of current display mode + +// *********************************************************************** + +HRESULT WINAPI EnumDisplayModesCallback( + DDSURFACEDESC2* pddsd, + void *pvContext) +{ + DWORD dwModeDepth; + DDSURFACEDESC2 *lpDisplayMode; + char buf[32]; + + // Check parameters + if (pddsd == NULL) + return DDENUMRET_CANCEL; + + dwModeDepth = pddsd->ddpfPixelFormat.dwRGBBitCount; + lpDisplayMode = (DDSURFACEDESC2 *)pvContext; + + // Check mode for compatability with device. + if (dwModeDepth != dwDisplayBitDepth) + return DDENUMRET_OK; + + if (lpDisplayMode != NULL) { + memcpy(&lpDisplayMode[iEnumCount], pddsd, sizeof(DDSURFACEDESC2)); + sprintf(buf, TEXT("Mode: %ld x %ld x %ld\n"), + pddsd->dwWidth, pddsd->dwHeight, dwModeDepth); + ddlogMessage(DDLOG_INFO, buf); + } + + iEnumCount++; + + return DDENUMRET_OK; +} + +// *********************************************************************** + +HRESULT CALLBACK d3dEnumZBufferFormatsCallback( + DDPIXELFORMAT* pddpf, + VOID* lpZBufferPF ) +{ + char buf[64]; + + if(pddpf == NULL) + return D3DENUMRET_CANCEL; + + if (pddpf->dwFlags & DDPF_ZBUFFER) { + if (lpZBufferPF == NULL) { + // Pass 1. Merely counting the PF + glb.nZBufferPFCount++; + } else { + // Pass 2. Save the PF + if (pddpf->dwFlags & DDPF_STENCILBUFFER) { + sprintf(buf, " %d: Z=%d S=%d\n", + iEnumCount, + pddpf->dwZBufferBitDepth, + pddpf->dwStencilBitDepth); + } else { + sprintf(buf, " %d: Z=%d S=0\n", + iEnumCount, + pddpf->dwZBufferBitDepth); + } + ddlogMessage(DDLOG_INFO, buf); + + memcpy(&glb.lpZBufferPF[iEnumCount++], + pddpf, + sizeof(DDPIXELFORMAT)); + } + } + + return D3DENUMRET_OK; +} +#endif // _USE_GLD3_WGL + +// *********************************************************************** + +BOOL IsStencilSupportBroken(LPDIRECTDRAW4 lpDD4) +{ + DDDEVICEIDENTIFIER dddi; // DX6 device identifier + BOOL bBroken = FALSE; + + // Microsoft really fucked up with the GetDeviceIdentifier function + // on Windows 2000, since it locks up on stock driers on the CD. Updated + // drivers from vendors appear to work, but we can't identify the drivers + // without this function!!! For now we skip these tests on Windows 2000. + if ((GetVersion() & 0x80000000UL) == 0) + return FALSE; + + // Obtain device info + if (FAILED(IDirectDraw4_GetDeviceIdentifier(lpDD4, &dddi, 0))) + return FALSE; + + // Matrox G400 stencil buffer support does not draw anything in AutoCAD, + // but ordinary Z buffers draw shaded models fine. (DaveM) + if (dddi.dwVendorId == 0x102B) { // Matrox + if (dddi.dwDeviceId == 0x0525) { // G400 + bBroken = TRUE; + } + } + + return bBroken; +} + +// *********************************************************************** + +void dglBuildPixelFormatList() +{ + int i; + char buf[128]; + char cat[8]; + HRESULT hRes; + DGL_pixelFormat *lpPF; + +#ifdef _USE_GLD3_WGL + _gldDriver.BuildPixelformatList(); +#else + IDirectDraw *lpDD1 = NULL; + IDirectDraw4 *lpDD4 = NULL; + IDirect3D3 *lpD3D3 = NULL; + DDSURFACEDESC2 ddsdDisplayMode; + + DWORD dwRb, dwGb, dwBb, dwAb; // Bit counts + DWORD dwRs, dwGs, dwBs, dwAs; // Bit shifts + DWORD dwPixelType; // RGB or color index + + // Set defaults + glb.nPixelFormatCount = 0; + glb.lpPF = NULL; + glb.nZBufferPFCount = 0; + glb.lpZBufferPF = NULL; + glb.nDisplayModeCount = 0; + glb.lpDisplayModes = NULL; + + // + // Examine the hardware for depth and stencil + // + + if (glb.bPrimary) + hRes = DirectDrawCreate(NULL, &lpDD1, NULL); + else + hRes = DirectDrawCreate(&glb.ddGuid, &lpDD1, NULL); + + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: DirectDrawCreate failed", hRes); + return; + } + + // Query for DX6 IDirectDraw4. + hRes = IDirectDraw_QueryInterface( + lpDD1, + &IID_IDirectDraw4, + (void**)&lpDD4); + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: QueryInterface (DD4) failed", hRes); + goto clean_up; + } + + + // Retrieve caps of current display mode + ZeroMemory(&ddsdDisplayMode, sizeof(ddsdDisplayMode)); + ddsdDisplayMode.dwSize = sizeof(ddsdDisplayMode); + hRes = IDirectDraw4_GetDisplayMode(lpDD4, &ddsdDisplayMode); + if (FAILED(hRes)) + goto clean_up; + + dwDisplayBitDepth = ddsdDisplayMode.ddpfPixelFormat.dwRGBBitCount; + dwPixelType = (dwDisplayBitDepth <= 8) ? PFD_TYPE_COLORINDEX : PFD_TYPE_RGBA; + dwRb = BitCount(ddsdDisplayMode.ddpfPixelFormat.dwRBitMask); + dwGb = BitCount(ddsdDisplayMode.ddpfPixelFormat.dwGBitMask); + dwBb = BitCount(ddsdDisplayMode.ddpfPixelFormat.dwBBitMask); + dwRs = BitShift(ddsdDisplayMode.ddpfPixelFormat.dwRBitMask); + dwGs = BitShift(ddsdDisplayMode.ddpfPixelFormat.dwGBitMask); + dwBs = BitShift(ddsdDisplayMode.ddpfPixelFormat.dwBBitMask); + + if (BitCount(ddsdDisplayMode.ddpfPixelFormat.dwRGBAlphaBitMask)) { + dwAb = BitCount(ddsdDisplayMode.ddpfPixelFormat.dwRGBAlphaBitMask); + dwAs = BitShift(ddsdDisplayMode.ddpfPixelFormat.dwRGBAlphaBitMask); + } else { + dwAb = 0; + dwAs = 0; + } + + // Query for available display modes + ddlogMessage(DDLOG_INFO, "\n"); + ddlogMessage(DDLOG_INFO, "Display Modes:\n"); + + // Pass 1: Determine count + iEnumCount = 0; + hRes = IDirectDraw4_EnumDisplayModes( + lpDD4, + 0, + NULL, + NULL, + EnumDisplayModesCallback); + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: EnumDisplayModes failed", hRes); + goto clean_up; + } + if (iEnumCount == 0) { + ddlogMessage(DDLOG_ERROR, "dglBPFL: No display modes found"); + goto clean_up; + } + glb.lpDisplayModes = (DDSURFACEDESC2 *)calloc(iEnumCount, + sizeof(DDSURFACEDESC2)); + if (glb.lpDisplayModes == NULL) { + ddlogMessage(DDLOG_ERROR, "dglBPFL: DDSURFACEDESC2 calloc failed"); + goto clean_up; + } + glb.nDisplayModeCount = iEnumCount; + // Pass 2: Save modes + iEnumCount = 0; + hRes = IDirectDraw4_EnumDisplayModes( + lpDD4, + 0, + NULL, + (void *)glb.lpDisplayModes, + EnumDisplayModesCallback); + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: EnumDisplayModes failed", hRes); + goto clean_up; + } + // Query for IDirect3D3 interface + hRes = IDirectDraw4_QueryInterface( + lpDD4, + &IID_IDirect3D3, + (void**)&lpD3D3); + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: QueryInterface (D3D3) failed", hRes); + goto clean_up; + } + + ddlogMessage(DDLOG_INFO, "\n"); + ddlogMessage(DDLOG_INFO, "ZBuffer formats:\n"); + + // Pass 1. Count the ZBuffer pixel formats + hRes = IDirect3D3_EnumZBufferFormats( + lpD3D3, + &glb.d3dGuid, + d3dEnumZBufferFormatsCallback, + NULL); + + if (FAILED(hRes)) + goto clean_up; + + if (glb.nZBufferPFCount) { + glb.lpZBufferPF = (DDPIXELFORMAT *)calloc(glb.nZBufferPFCount, + sizeof(DDPIXELFORMAT)); + if(glb.lpZBufferPF == NULL) + goto clean_up; + + // Pass 2. Cache the ZBuffer pixel formats + iEnumCount = 0; // (Used by the enum function) + hRes = IDirect3D3_EnumZBufferFormats( + lpD3D3, + &glb.d3dGuid, + d3dEnumZBufferFormatsCallback, + glb.lpZBufferPF); + + if (FAILED(hRes)) + goto clean_up; + } + + // Remove stencil support for boards which don't work for AutoCAD; + // Matrox G400 does not work, but NVidia TNT2 and ATI Rage128 do... (DaveM) + if (IsStencilSupportBroken(lpDD4)) { + for (i=0; iiZBufferPF = i-1; + lpPF->pfd.cDepthBits = glb.lpZBufferPF[i-1].dwZBufferBitDepth; + lpPF->pfd.cStencilBits = glb.lpZBufferPF[i-1].dwStencilBitDepth; + } + } + // Fill in the single-buffered pixel formats + for (i=0; i<(glb.nZBufferPFCount + 1); i++, lpPF++) { + memcpy(lpPF, &pfTemplateHW, sizeof(DGL_pixelFormat)); + if (i) { + lpPF->iZBufferPF = i-1; + lpPF->pfd.cDepthBits = glb.lpZBufferPF[i-1].dwZBufferBitDepth; + lpPF->pfd.cStencilBits = glb.lpZBufferPF[i-1].dwStencilBitDepth; + } + // Remove double-buffer flag. Could use XOR instead... + lpPF->pfd.dwFlags &= (~(PFD_DOUBLEBUFFER)); + // Insert GDI flag for single buffered format only. + lpPF->pfd.dwFlags |= PFD_SUPPORT_GDI; + } +#endif // _USE_GLD3_WGL + + // Lets dump the list to the log + // ** Based on "wglinfo" by Nate Robins ** + ddlogMessage(DDLOG_INFO, "\n"); + ddlogMessage(DDLOG_INFO, "Pixel Formats:\n"); + ddlogMessage(DDLOG_INFO, + " visual x bf lv rg d st r g b a ax dp st accum buffs ms\n"); + ddlogMessage(DDLOG_INFO, + " id dep cl sp sz l ci b ro sz sz sz sz bf th cl r g b a ns b\n"); + ddlogMessage(DDLOG_INFO, + "-----------------------------------------------------------------\n"); + for (i=0, lpPF = glb.lpPF; ipfd.cColorBits); + strcat(buf, cat); + if(lpPF->pfd.dwFlags & PFD_DRAW_TO_WINDOW) sprintf(cat, "wn "); + else if(lpPF->pfd.dwFlags & PFD_DRAW_TO_BITMAP) sprintf(cat, "bm "); + else sprintf(cat, ". "); + strcat(buf, cat); + + /* should find transparent pixel from LAYERPLANEDESCRIPTOR */ + sprintf(cat, " . "); + strcat(buf, cat); + + sprintf(cat, "%2d ", lpPF->pfd.cColorBits); + strcat(buf, cat); + + /* bReserved field indicates number of over/underlays */ + if(lpPF->pfd.bReserved) sprintf(cat, " %d ", lpPF->pfd.bReserved); + else sprintf(cat, " . "); + strcat(buf, cat); + + sprintf(cat, " %c ", lpPF->pfd.iPixelType == PFD_TYPE_RGBA ? 'r' : 'c'); + strcat(buf, cat); + + sprintf(cat, "%c ", lpPF->pfd.dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.'); + strcat(buf, cat); + + sprintf(cat, " %c ", lpPF->pfd.dwFlags & PFD_STEREO ? 'y' : '.'); + strcat(buf, cat); + + if(lpPF->pfd.cRedBits && lpPF->pfd.iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", lpPF->pfd.cRedBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cGreenBits && lpPF->pfd.iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", lpPF->pfd.cGreenBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cBlueBits && lpPF->pfd.iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", lpPF->pfd.cBlueBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAlphaBits && lpPF->pfd.iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", lpPF->pfd.cAlphaBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAuxBuffers) sprintf(cat, "%2d ", lpPF->pfd.cAuxBuffers); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cDepthBits) sprintf(cat, "%2d ", lpPF->pfd.cDepthBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cStencilBits) sprintf(cat, "%2d ", lpPF->pfd.cStencilBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAccumRedBits) sprintf(cat, "%2d ", lpPF->pfd.cAccumRedBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAccumGreenBits) sprintf(cat, "%2d ", lpPF->pfd.cAccumGreenBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAccumBlueBits) sprintf(cat, "%2d ", lpPF->pfd.cAccumBlueBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAccumAlphaBits) sprintf(cat, "%2d ", lpPF->pfd.cAccumAlphaBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + /* no multisample in Win32 */ + sprintf(cat, " . .\n"); + strcat(buf, cat); + + ddlogMessage(DDLOG_INFO, buf); + } + ddlogMessage(DDLOG_INFO, + "-----------------------------------------------------------------\n"); + ddlogMessage(DDLOG_INFO, "\n"); + +#ifndef _USE_GLD3_WGL +clean_up: + // Release COM objects + RELEASE(lpD3D3); + RELEASE(lpDD4); + RELEASE(lpDD1); + + // Popup warning message if non RGB color mode + if (dwDisplayBitDepth <= 8) { + ddlogPrintf(DDLOG_WARN, "Current Color Depth %d bpp is not supported", dwDisplayBitDepth); + MessageBox(NULL, szColorDepthWarning, "GLDirect", MB_OK | MB_ICONWARNING); + } +#endif // _USE_GLD3_WGL +} + +// *********************************************************************** + +void dglReleasePixelFormatList() +{ + glb.nPixelFormatCount = 0; + if (glb.lpPF) { + free(glb.lpPF); + glb.lpPF = NULL; + } +#ifndef _USE_GLD3_WGL + glb.nZBufferPFCount = 0; + if (glb.lpZBufferPF) { + free(glb.lpZBufferPF); + glb.lpZBufferPF = NULL; + } + glb.nDisplayModeCount = 0; + if (glb.lpDisplayModes) { + free(glb.lpDisplayModes); + glb.lpDisplayModes = NULL; + } +#endif // _USE_GLD3_WGL +} + +// *********************************************************************** diff --git a/src/mesa/drivers/windows/gldirect/dglpf.h b/src/mesa/drivers/windows/gldirect/dglpf.h new file mode 100644 index 0000000..8a7e38c --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/dglpf.h @@ -0,0 +1,77 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Pixel Formats. +* +****************************************************************************/ + +#ifndef __DGLPF_H +#define __DGLPF_H + +#ifndef STRICT +#define STRICT +#endif // STRICT +#define WIN32_LEAN_AND_MEAN + +#include + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef struct { + PIXELFORMATDESCRIPTOR pfd; // Win32 Pixel Format Descriptor +#ifdef _USE_GLD3_WGL + // Driver-specific data. + // Example: The DX8 driver uses this to hold an index into a + // list of depth-stencil descriptions. + DWORD dwDriverData; +#else + int iZBufferPF; // Index of depth buffer pixel format +#endif +} DGL_pixelFormat; + +#include "dglglobals.h" + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +BOOL IsValidPFD(int iPFD); +void dglBuildPixelFormatList(); +void dglReleasePixelFormatList(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mesa/drivers/windows/gldirect/dglwgl.c b/src/mesa/drivers/windows/gldirect/dglwgl.c new file mode 100644 index 0000000..a1b7e5d --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/dglwgl.c @@ -0,0 +1,2958 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: OpenGL window functions (wgl*). +* +****************************************************************************/ + +#include "dglwgl.h" +#ifdef _USE_GLD3_WGL +#include "gld_driver.h" +#endif + +#include "glu.h" // MUST USE MICROSOFT'S GLU32! + +#ifndef _USE_GLD3_WGL +extern DGL_mesaFuncs mesaFuncs; +#endif + +// Need to export wgl* functions if using GLD3, +// otherwise export GLD2 DGL_* functions. +#ifdef _USE_GLD3_WGL +#define _GLD_WGL_EXPORT(a) wgl##a +#else +#define _GLD_WGL_EXPORT(a) DGL_##a +#endif + +// Calls into Mesa 4.x are different +#ifdef _USE_GLD3_WGL +#include "dlist.h" +#include "drawpix.h" +#include "get.h" +#include "matrix.h" +// NOTE: All the _GLD* macros now call the gl* functions direct. +// This ensures that the correct internal pathway is taken. KeithH +#define _GLD_glNewList glNewList +#define _GLD_glBitmap glBitmap +#define _GLD_glEndList glEndList +#define _GLD_glDeleteLists glDeleteLists +#define _GLD_glGetError glGetError +#define _GLD_glTranslatef glTranslatef +#define _GLD_glBegin glBegin +#define _GLD_glVertex2fv glVertex2fv +#define _GLD_glEnd glEnd +#define _GLD_glNormal3f glNormal3f +#define _GLD_glVertex3f glVertex3f +#define _GLD_glVertex3fv glVertex3fv +#else // _USE_GLD3_WGL +#define _GLD_glNewList (*mesaFuncs.glNewList) +#define _GLD_glBitmap (*mesaFuncs.glBitmap) +#define _GLD_glEndList (*mesaFuncs.glEndList) +#define _GLD_glDeleteLists (*mesaFuncs.glDeleteLists) +#define _GLD_glGetError (*mesaFuncs.glGetError) +#define _GLD_glTranslatef (*mesaFuncs.glTranslatef) +#define _GLD_glBegin (*mesaFuncs.glBegin) +#define _GLD_glVertex2fv (*mesaFuncs.glVertex2fv) +#define _GLD_glEnd (*mesaFuncs.glEnd) +#define _GLD_glNormal3f (*mesaFuncs.glNormal3f) +#define _GLD_glVertex3f (*mesaFuncs.glVertex3f) +#define _GLD_glVertex3fv (*mesaFuncs.glVertex3fv) +#endif // _USE_GLD3_WGL + +// *********************************************************************** + +// Emulate SGI DDK calls. +#define __wglMalloc(a) GlobalAlloc(GPTR, (a)) +#define __wglFree(a) GlobalFree((a)) + +// *********************************************************************** + +// Mesa glu.h and MS glu.h call these different things... +//#define GLUtesselator GLUtriangulatorObj +//#define GLU_TESS_VERTEX_DATA GLU_VERTEX_DATA + +// For wglFontOutlines + +typedef GLUtesselator *(APIENTRY *gluNewTessProto)(void); +typedef void (APIENTRY *gluDeleteTessProto)(GLUtesselator *tess); +typedef void (APIENTRY *gluTessBeginPolygonProto)(GLUtesselator *tess, void *polygon_data); +typedef void (APIENTRY *gluTessBeginContourProto)(GLUtesselator *tess); +typedef void (APIENTRY *gluTessVertexProto)(GLUtesselator *tess, GLdouble coords[3], void *data); +typedef void (APIENTRY *gluTessEndContourProto)(GLUtesselator *tess); +typedef void (APIENTRY *gluTessEndPolygonProto)(GLUtesselator *tess); +typedef void (APIENTRY *gluTessPropertyProto)(GLUtesselator *tess, GLenum which, GLdouble value); +typedef void (APIENTRY *gluTessNormalProto)(GLUtesselator *tess, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRY *gluTessCallbackProto)(GLUtesselator *tess, GLenum which, void (CALLBACK *)()); + +static HINSTANCE gluModuleHandle; +static gluNewTessProto gluNewTessProc; +static gluDeleteTessProto gluDeleteTessProc; +static gluTessBeginPolygonProto gluTessBeginPolygonProc; +static gluTessBeginContourProto gluTessBeginContourProc; +static gluTessVertexProto gluTessVertexProc; +static gluTessEndContourProto gluTessEndContourProc; +static gluTessEndPolygonProto gluTessEndPolygonProc; +static gluTessPropertyProto gluTessPropertyProc; +static gluTessNormalProto gluTessNormalProc; +static gluTessCallbackProto gluTessCallbackProc; + +static HFONT hNewFont, hOldFont; +static FLOAT ScaleFactor; + +#define LINE_BUF_QUANT 4000 +#define VERT_BUF_QUANT 4000 + +static FLOAT* LineBuf; +static DWORD LineBufSize; +static DWORD LineBufIndex; +static FLOAT* VertBuf; +static DWORD VertBufSize; +static DWORD VertBufIndex; +static GLenum TessErrorOccurred; + +static int AppendToLineBuf( + FLOAT value); + +static int AppendToVertBuf( + FLOAT value); + +static int DrawGlyph( + UCHAR* glyphBuf, + DWORD glyphSize, + FLOAT chordalDeviation, + FLOAT extrusion, + INT format); + +static void FreeLineBuf(void); + +static void FreeVertBuf(void); + +static long GetWord( + UCHAR** p); + +static long GetDWord( + UCHAR** p); + +static double GetFixed( + UCHAR** p); + +static int InitLineBuf(void); + +static int InitVertBuf(void); + +static HFONT CreateHighResolutionFont( + HDC hDC); + +static int MakeDisplayListFromGlyph( + DWORD listName, + UCHAR* glyphBuf, + DWORD glyphSize, + LPGLYPHMETRICSFLOAT glyphMetricsFloat, + FLOAT chordalDeviation, + FLOAT extrusion, + INT format); + +static BOOL LoadGLUTesselator(void); +static BOOL UnloadGLUTesselator(void); + +static int MakeLinesFromArc( + FLOAT x0, + FLOAT y0, + FLOAT x1, + FLOAT y1, + FLOAT x2, + FLOAT y2, + DWORD vertexCountIndex, + FLOAT chordalDeviationSquared); + +static int MakeLinesFromGlyph( UCHAR* glyphBuf, + DWORD glyphSize, + FLOAT chordalDeviation); + +static int MakeLinesFromTTLine( UCHAR** pp, + DWORD vertexCountIndex, + WORD pointCount); + +static int MakeLinesFromTTPolycurve( UCHAR** pp, + DWORD vertexCountIndex, + FLOAT chordalDeviation); + +static int MakeLinesFromTTPolygon( UCHAR** pp, + FLOAT chordalDeviation); + +static int MakeLinesFromTTQSpline( UCHAR** pp, + DWORD vertexCountIndex, + WORD pointCount, + FLOAT chordalDeviation); + +static void CALLBACK TessCombine( double coords[3], + void* vertex_data[4], + FLOAT weight[4], + void** outData); + +static void CALLBACK TessError( GLenum error); + +static void CALLBACK TessVertexOutData( FLOAT p[3], + GLfloat z); + +// *********************************************************************** + +#ifdef GLD_THREADS +#pragma message("compiling DGLWGL.C vars for multi-threaded support") +extern CRITICAL_SECTION CriticalSection; +extern DWORD dwTLSPixelFormat; // TLS index for current pixel format +#endif +int curPFD = 0; // Current PFD (static) + +// *********************************************************************** + +int dglGetPixelFormat(void) +{ +#ifdef GLD_THREADS + int iPixelFormat; + // get thread-specific instance + if (glb.bMultiThreaded) { + __try { + iPixelFormat = (int)TlsGetValue(dwTLSPixelFormat); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + iPixelFormat = curPFD; + } + } + // get global static var + else { + iPixelFormat = curPFD; + } + return iPixelFormat; +#else + return curPFD; +#endif +} + +// *********************************************************************** + +void dglSetPixelFormat(int iPixelFormat) +{ +#ifdef GLD_THREADS + // set thread-specific instance + if (glb.bMultiThreaded) { + __try { + TlsSetValue(dwTLSPixelFormat, (LPVOID)iPixelFormat); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + curPFD = iPixelFormat; + } + } + // set global static var + else { + curPFD = iPixelFormat; + } +#else + curPFD = iPixelFormat; +#endif +} + +// *********************************************************************** + +int APIENTRY _GLD_WGL_EXPORT(ChoosePixelFormat)( + HDC a, + CONST PIXELFORMATDESCRIPTOR *ppfd) +{ + DGL_pixelFormat *lpPF = glb.lpPF; + + PIXELFORMATDESCRIPTOR ppfdBest; + int i; + int bestIndex = -1; + int numPixelFormats; + DWORD dwFlags; + + char buf[128]; + char cat[8]; + + DWORD dwAllFlags = + PFD_DRAW_TO_WINDOW | + PFD_DRAW_TO_BITMAP | + PFD_SUPPORT_GDI | + PFD_SUPPORT_OPENGL | + PFD_GENERIC_FORMAT | + PFD_NEED_PALETTE | + PFD_NEED_SYSTEM_PALETTE | + PFD_DOUBLEBUFFER | + PFD_STEREO | + /*PFD_SWAP_LAYER_BUFFERS |*/ + PFD_DOUBLEBUFFER_DONTCARE | + PFD_STEREO_DONTCARE | + PFD_SWAP_COPY | + PFD_SWAP_EXCHANGE | + PFD_GENERIC_ACCELERATED | + 0; + + // Validate license + if (!dglValidate()) + return 0; + + // List may not be built until dglValidate() is called! KeithH + lpPF = glb.lpPF; + + // + // Lets print the input pixel format to the log + // ** Based on "wglinfo" by Nate Robins ** + // + ddlogMessage(DDLOG_SYSTEM, "ChoosePixelFormat:\n"); + ddlogMessage(DDLOG_INFO, "Input pixel format for ChoosePixelFormat:\n"); + ddlogMessage(DDLOG_INFO, + " visual x bf lv rg d st r g b a ax dp st accum buffs ms\n"); + ddlogMessage(DDLOG_INFO, + " id dep cl sp sz l ci b ro sz sz sz sz bf th cl r g b a ns b\n"); + ddlogMessage(DDLOG_INFO, + "-----------------------------------------------------------------\n"); + sprintf(buf, " . "); + + sprintf(cat, "%2d ", ppfd->cColorBits); + strcat(buf, cat); + if(ppfd->dwFlags & PFD_DRAW_TO_WINDOW) sprintf(cat, "wn "); + else if(ppfd->dwFlags & PFD_DRAW_TO_BITMAP) sprintf(cat, "bm "); + else sprintf(cat, ". "); + strcat(buf, cat); + + /* should find transparent pixel from LAYERPLANEDESCRIPTOR */ + sprintf(cat, " . "); + strcat(buf, cat); + + sprintf(cat, "%2d ", ppfd->cColorBits); + strcat(buf, cat); + + /* bReserved field indicates number of over/underlays */ + if(ppfd->bReserved) sprintf(cat, " %d ", ppfd->bReserved); + else sprintf(cat, " . "); + strcat(buf, cat); + + sprintf(cat, " %c ", ppfd->iPixelType == PFD_TYPE_RGBA ? 'r' : 'c'); + strcat(buf, cat); + + sprintf(cat, "%c ", ppfd->dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.'); + strcat(buf, cat); + + sprintf(cat, " %c ", ppfd->dwFlags & PFD_STEREO ? 'y' : '.'); + strcat(buf, cat); + + if(ppfd->cRedBits && ppfd->iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", ppfd->cRedBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cGreenBits && ppfd->iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", ppfd->cGreenBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cBlueBits && ppfd->iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", ppfd->cBlueBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cAlphaBits && ppfd->iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", ppfd->cAlphaBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cAuxBuffers) sprintf(cat, "%2d ", ppfd->cAuxBuffers); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cDepthBits) sprintf(cat, "%2d ", ppfd->cDepthBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cStencilBits) sprintf(cat, "%2d ", ppfd->cStencilBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cAccumRedBits) sprintf(cat, "%2d ", ppfd->cAccumRedBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cAccumGreenBits) sprintf(cat, "%2d ", ppfd->cAccumGreenBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cAccumBlueBits) sprintf(cat, "%2d ", ppfd->cAccumBlueBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cAccumAlphaBits) sprintf(cat, "%2d ", ppfd->cAccumAlphaBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + /* no multisample in Win32 */ + sprintf(cat, " . .\n"); + strcat(buf, cat); + + ddlogMessage(DDLOG_INFO, buf); + ddlogMessage(DDLOG_INFO, + "-----------------------------------------------------------------\n"); + ddlogMessage(DDLOG_INFO, "\n"); + + // + // Examine the flags for correctness + // + dwFlags = ppfd->dwFlags; + if (dwFlags != (dwFlags & dwAllFlags)) + { + /* error: bad dwFlags */ + ddlogPrintf(DDLOG_WARN, + "ChoosePixelFormat: bad flags (0x%x)", + dwFlags & (~dwAllFlags)); + // Mask illegal flags and continue + dwFlags = dwFlags & dwAllFlags; + } + + switch (ppfd->iPixelType) { + case PFD_TYPE_RGBA: + case PFD_TYPE_COLORINDEX: + break; + default: + /* error: bad iPixelType */ + ddlogMessage(DDLOG_WARN, "ChoosePixelFormat: bad pixel type\n"); + return 0; + } + + switch (ppfd->iLayerType) { + case PFD_MAIN_PLANE: + case PFD_OVERLAY_PLANE: + case PFD_UNDERLAY_PLANE: + break; + default: + /* error: bad iLayerType */ + ddlogMessage(DDLOG_WARN, "ChoosePixelFormat: bad layer type\n"); + return 0; + } + + numPixelFormats = glb.nPixelFormatCount; + + /* loop through candidate pixel format descriptors */ + for (i=0; iiPixelType != ppfdCandidate.iPixelType) { + continue; + } + + if (ppfd->iLayerType != ppfdCandidate.iLayerType) { + continue; + } + + if (((dwFlags ^ ppfdCandidate.dwFlags) & dwFlags) & + (PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | + PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL)) + { + continue; + } + + if (!(dwFlags & PFD_DOUBLEBUFFER_DONTCARE)) { + if ((dwFlags & PFD_DOUBLEBUFFER) != + (ppfdCandidate.dwFlags & PFD_DOUBLEBUFFER)) + { + continue; + } + } + +// if (!(dwFlags & PFD_STEREO_DONTCARE)) { + if ((dwFlags & PFD_STEREO) != + (ppfdCandidate.dwFlags & PFD_STEREO)) + { + continue; + } +// } + + if (ppfd->iPixelType==PFD_TYPE_RGBA + && ppfd->cAlphaBits && !ppfdCandidate.cAlphaBits) { + continue; + } + + if (ppfd->iPixelType==PFD_TYPE_RGBA + && ppfd->cAccumBits && !ppfdCandidate.cAccumBits) { + continue; + } + + if (ppfd->cDepthBits && !ppfdCandidate.cDepthBits) { + continue; + } + + if (ppfd->cStencilBits && !ppfdCandidate.cStencilBits) { + continue; + } + + if (ppfd->cAuxBuffers && !ppfdCandidate.cAuxBuffers) { + continue; + } + + /* + ** See if candidate is better than the previous best choice + */ + if (bestIndex == -1) { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + + if ((ppfd->cColorBits > ppfdBest.cColorBits && + ppfdCandidate.cColorBits > ppfdBest.cColorBits) || + (ppfd->cColorBits <= ppfdCandidate.cColorBits && + ppfdCandidate.cColorBits < ppfdBest.cColorBits)) + { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + + if (ppfd->iPixelType==PFD_TYPE_RGBA + && ppfd->cAlphaBits + && ppfdCandidate.cAlphaBits > ppfdBest.cAlphaBits) + { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + + if (ppfd->iPixelType==PFD_TYPE_RGBA + && ppfd->cAccumBits + && ppfdCandidate.cAccumBits > ppfdBest.cAccumBits) + { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + + if ((ppfd->cDepthBits > ppfdBest.cDepthBits && + ppfdCandidate.cDepthBits > ppfdBest.cDepthBits) || + (ppfd->cDepthBits <= ppfdCandidate.cDepthBits && + ppfdCandidate.cDepthBits < ppfdBest.cDepthBits)) + { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + + if (ppfd->cStencilBits && + ppfdCandidate.cStencilBits > ppfdBest.cStencilBits) + { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + + if (ppfd->cAuxBuffers && + ppfdCandidate.cAuxBuffers > ppfdBest.cAuxBuffers) + { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + } + + if (bestIndex != -1) { + ddlogPrintf(DDLOG_SYSTEM, "Pixel Format %d chosen as best match", bestIndex+1); + return bestIndex + 1; + } + + // Return the pixelformat that has the most capabilities. + // ** NOTE: This is only possible due to the way the list + // of pixelformats is built. ** + // Now picks best pixelformat. KeithH + bestIndex = numPixelFormats; // most capable double buffer format + ddlogPrintf(DDLOG_SYSTEM, "Pixel Format %d chosen by default", bestIndex); + return (bestIndex); +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(CopyContext)( + HGLRC a, + HGLRC b, + UINT c) +{ + // Validate license + if (!dglValidate()) + return FALSE; + UNSUPPORTED("wglCopyContext") + return FALSE; // Failed +} + +// *********************************************************************** + +HGLRC APIENTRY _GLD_WGL_EXPORT(CreateContext)( + HDC a) +{ + int ipf; + + // Validate license + if (!dglValidate()) + return 0; + + // Check that the current PFD is valid + ipf = dglGetPixelFormat(); + if (!IsValidPFD(ipf)) + return (HGLRC)0; + + return dglCreateContext(a, &glb.lpPF[ipf-1]); +} + +// *********************************************************************** + +HGLRC APIENTRY _GLD_WGL_EXPORT(CreateLayerContext)( + HDC a, + int b) +{ + // Validate license + if (!dglValidate()) + return 0; + + UNSUPPORTED("wglCreateLayerContext") + return NULL; // Failed +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(DeleteContext)( + HGLRC a) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + return dglDeleteContext(a); +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(DescribeLayerPlane)( + HDC hDC, + int iPixelFormat, + int iLayerPlane, + UINT nBytes, + LPLAYERPLANEDESCRIPTOR plpd) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + UNSUPPORTED("DGL_DescribeLayerPlane") + +// gldLogPrintf(GLDLOG_INFO, "DescribeLayerPlane: %d, %d", iPixelFormat, iLayerPlane); + + return FALSE; +} + +// *********************************************************************** + +int APIENTRY _GLD_WGL_EXPORT(DescribePixelFormat)( + HDC a, + int b, + UINT c, + LPPIXELFORMATDESCRIPTOR d) +{ + UINT nSize; + + // Validate license + if (!dglValidate()) + return 0; + + if (d == NULL) // Calling app requires max number of PF's + return glb.nPixelFormatCount; + + // The supplied buffer may be larger than the info that we + // will be copying. + if (c > sizeof(PIXELFORMATDESCRIPTOR)) + nSize = sizeof(PIXELFORMATDESCRIPTOR); + else + nSize = c; + + // Setup an empty PFD before doing validation check + memset(d, 0, nSize); + d->nSize = nSize; + d->nVersion = 1; + + if (!IsValidPFD(b)) + return 0; // Bail if PFD index is invalid + + memcpy(d, &glb.lpPF[b-1].pfd, nSize); + + return glb.nPixelFormatCount; +} + +// *********************************************************************** + +HGLRC APIENTRY _GLD_WGL_EXPORT(GetCurrentContext)(void) +{ + // Validate license + if (!dglValidate()) + return 0; + + return dglGetCurrentContext(); +} + +// *********************************************************************** + +HDC APIENTRY _GLD_WGL_EXPORT(GetCurrentDC)(void) +{ + // Validate license + if (!dglValidate()) + return 0; + + return dglGetCurrentDC(); +} + +// *********************************************************************** + +PROC APIENTRY _GLD_WGL_EXPORT(GetDefaultProcAddress)( + LPCSTR a) +{ + // Validate license + if (!dglValidate()) + return NULL; + + UNSUPPORTED("DGL_GetDefaultProcAddress") + return NULL; +} + +// *********************************************************************** + +int APIENTRY _GLD_WGL_EXPORT(GetLayerPaletteEntries)( + HDC a, + int b, + int c, + int d, + COLORREF *e) +{ + // Validate license + if (!dglValidate()) + return 0; + + UNSUPPORTED("DGL_GetLayerPaletteEntries") + return 0; +} + +// *********************************************************************** + +int APIENTRY _GLD_WGL_EXPORT(GetPixelFormat)( + HDC a) +{ + // Validate license + if (!dglValidate()) + return 0; + + return dglGetPixelFormat(); +} + +// *********************************************************************** + +PROC APIENTRY _GLD_WGL_EXPORT(GetProcAddress)( + LPCSTR a) +{ + PROC dglGetProcAddressD3D(LPCSTR a); + + // Validate license + if (!dglValidate()) + return NULL; + +#ifdef _USE_GLD3_WGL + return _gldDriver.wglGetProcAddress(a); +#else + return dglGetProcAddressD3D(a); +#endif +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(MakeCurrent)( + HDC a, + HGLRC b) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + return dglMakeCurrent(a, b); +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(RealizeLayerPalette)( + HDC a, + int b, + BOOL c) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + UNSUPPORTED("DGL_RealizeLayerPalette") + return FALSE; +} + +// *********************************************************************** + +int APIENTRY _GLD_WGL_EXPORT(SetLayerPaletteEntries)( + HDC a, + int b, + int c, + int d, + CONST COLORREF *e) +{ + // Validate license + if (!dglValidate()) + return 0; + + UNSUPPORTED("DGL_SetLayerPaletteEntries") + return 0; +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(SetPixelFormat)( + HDC a, + int b, + CONST PIXELFORMATDESCRIPTOR *c) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + if (IsValidPFD(b)) { + ddlogPrintf(DDLOG_SYSTEM, "SetPixelFormat: PixelFormat %d has been set", b); + dglSetPixelFormat(b); + return TRUE; + } else { + ddlogPrintf(DDLOG_ERROR, + "SetPixelFormat: PixelFormat %d is invalid and cannot be set", b); + return FALSE; + } +} + +// *********************************************************************** +/* + * Share lists between two gl_context structures. + * This was added for WIN32 WGL function support, since wglShareLists() + * must be called *after* wglCreateContext() with valid GLRCs. (DaveM) + */ +// +// Copied from GLD2.x. KeithH +// +static GLboolean _gldShareLists( + GLcontext *ctx1, + GLcontext *ctx2) +{ + /* Sanity check context pointers */ + if (ctx1 == NULL || ctx2 == NULL) + return GL_FALSE; + /* Sanity check shared list pointers */ + if (ctx1->Shared == NULL || ctx2->Shared == NULL) + return GL_FALSE; + /* Decrement reference count on sharee to release previous list */ + ctx2->Shared->RefCount--; +#if 0 /* 3DStudio exits on this memory release */ + if (ctx2->Shared->RefCount == 0) + free_shared_state(ctx2, ctx2->Shared); +#endif + /* Re-assign list from sharer to sharee and increment reference count */ + ctx2->Shared = ctx1->Shared; + ctx1->Shared->RefCount++; + return GL_TRUE; +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(ShareLists)( + HGLRC a, + HGLRC b) +{ + DGL_ctx *dgl1, *dgl2; + + // Validate license + if (!dglValidate()) + return FALSE; + + // Mesa supports shared lists, but you need to supply the shared + // GL context info when calling gl_create_context(). An auxiliary + // function gl_share_lists() has been added to update the shared + // list info after the GL contexts have been created. (DaveM) + dgl1 = dglGetContextAddress(a); + dgl2 = dglGetContextAddress(b); + if (dgl1->bAllocated && dgl2->bAllocated) { +#ifdef _USE_GLD3_WGL + return _gldShareLists(dgl1->glCtx, dgl2->glCtx); +#else + return (*mesaFuncs.gl_share_lists)(dgl1->glCtx, dgl2->glCtx); +#endif + } + return FALSE; +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(SwapBuffers)( + HDC a) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + return dglSwapBuffers(a); +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(SwapLayerBuffers)( + HDC a, + UINT b) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + return dglSwapBuffers(a); +} + +// *********************************************************************** + +// *********************************************************************** +// Note: This ResizeBuffers() function may be called from +// either MESA glViewport() or GLD wglMakeCurrent(). + +BOOL dglWglResizeBuffers( + GLcontext *ctx, + BOOL bDefaultDriver) +{ + DGL_ctx *dgl = NULL; + RECT rcScreenRect; + DWORD dwWidth; + DWORD dwHeight; + DDSURFACEDESC2 ddsd2; + DDSCAPS2 ddscaps2; + IDirectDrawClipper *lpddClipper = NULL; + DWORD dwFlags; + HRESULT hResult; + + DWORD dwMemoryType; + + int i; + struct gl_texture_object *tObj; + struct gl_texture_image *image; + + BOOL bWasFullscreen; + BOOL bSaveDesktop; + BOOL bFullScrnWin = FALSE; + DDSURFACEDESC2 ddsd2DisplayMode; + + DDBLTFX ddbltfx; + POINT pt; + RECT rcDst; +#ifdef _USE_GLD3_WGL + GLD_displayMode glddm; +#endif + +#define DDLOG_CRITICAL_OR_WARN (bDefaultDriver ? DDLOG_WARN : DDLOG_CRITICAL) + + // Validate license + if (!dglValidate()) + return FALSE; + + // Sanity checks + if (ctx == NULL) + return FALSE; + dgl = ctx->DriverCtx; + if (dgl == NULL) + return FALSE; + + // Get the window size and calculate its dimensions + if (dgl->hWnd == NULL) { + // Check for non-window DC = memory DC ? + if (GetClipBox(dgl->hDC, &rcScreenRect) == ERROR) + SetRect(&rcScreenRect, 0, 0, 0, 0); + } + else if (!GetClientRect(dgl->hWnd, &rcScreenRect)) + SetRect(&rcScreenRect, 0, 0, 0, 0); + dwWidth = rcScreenRect.right - rcScreenRect.left; + dwHeight = rcScreenRect.bottom - rcScreenRect.top; + CopyRect(&dgl->rcScreenRect, &rcScreenRect); + + // This will occur on Alt-Tab + if ((dwWidth == 0) && (dwHeight == 0)) { + //dgl->bCanRender = FALSE; + return TRUE; // No resize possible! + } + + // Some apps zero only 1 dimension for non-visible window... (DaveM) + if ((dwWidth == 0) || (dwHeight == 0)) { + dwWidth = 8; + dwHeight = 8; + } + + // Test to see if a resize is required. + // Note that the dimensions will be the same if a prior resize attempt failed. + if ((dwWidth == dgl->dwWidth) && (dwHeight == dgl->dwHeight) && bDefaultDriver) { + return TRUE; // No resize required + } + + ddlogPrintf(DDLOG_SYSTEM, "dglResize: %dx%d", dwWidth, dwHeight); +#ifndef _USE_GLD3_WGL + // Work out where we want our surfaces created + dwMemoryType = (bDefaultDriver) ? glb.dwMemoryType : DDSCAPS_SYSTEMMEMORY; +#endif // _USE_GLD3_WGL + + // Note previous fullscreen vs window display status + bWasFullscreen = dgl->bFullscreen; + +#ifdef _USE_GLD3_WGL + if (_gldDriver.GetDisplayMode(dgl, &glddm)) { + if ( (dwWidth == glddm.Width) && + (dwHeight == glddm.Height) ) { + bFullScrnWin = TRUE; + } + if (bFullScrnWin && glb.bPrimary && !glb.bFullscreenBlit && !glb.bDirectDrawPersistant) { + dgl->bFullscreen = TRUE; + ddlogMessage(DDLOG_INFO, "Fullscreen window after resize.\n"); + } + else { + dgl->bFullscreen = FALSE; + ddlogMessage(DDLOG_INFO, "Non-Fullscreen window after resize.\n"); + } + // Cache the display mode dimensions + dgl->dwModeWidth = glddm.Width; + dgl->dwModeHeight = glddm.Height; + } + + // Clamp the effective window dimensions to primary surface. + // We need to do this for D3D viewport dimensions even if wide + // surfaces are supported. This also is a good idea for handling + // whacked-out window dimensions passed for non-drawable windows + // like Solid Edge. (DaveM) + if (dgl->dwWidth > glddm.Width) + dgl->dwWidth = glddm.Width; + if (dgl->dwHeight > glddm.Height) + dgl->dwHeight = glddm.Height; +#else // _USE_GLD3_WGL + // Window resize may have changed to fullscreen + ZeroMemory(&ddsd2DisplayMode, sizeof(ddsd2DisplayMode)); + ddsd2DisplayMode.dwSize = sizeof(ddsd2DisplayMode); + hResult = IDirectDraw4_GetDisplayMode( + dgl->lpDD4, + &ddsd2DisplayMode); + if (SUCCEEDED(hResult)) { + if ( (dwWidth == ddsd2DisplayMode.dwWidth) && + (dwHeight == ddsd2DisplayMode.dwHeight) ) { + bFullScrnWin = TRUE; + } + if (bFullScrnWin && glb.bPrimary && !glb.bFullscreenBlit && !glb.bDirectDrawPersistant) { + dgl->bFullscreen = TRUE; + ddlogMessage(DDLOG_INFO, "Fullscreen window after resize.\n"); + } + else { + dgl->bFullscreen = FALSE; + ddlogMessage(DDLOG_INFO, "Non-Fullscreen window after resize.\n"); + } + // Cache the display mode dimensions + dgl->dwModeWidth = ddsd2DisplayMode.dwWidth; + dgl->dwModeHeight = ddsd2DisplayMode.dwHeight; + } + + // Clamp the effective window dimensions to primary surface. + // We need to do this for D3D viewport dimensions even if wide + // surfaces are supported. This also is a good idea for handling + // whacked-out window dimensions passed for non-drawable windows + // like Solid Edge. (DaveM) + if (dgl->dwWidth > ddsd2DisplayMode.dwWidth) + dgl->dwWidth = ddsd2DisplayMode.dwWidth; + if (dgl->dwHeight > ddsd2DisplayMode.dwHeight) + dgl->dwHeight = ddsd2DisplayMode.dwHeight; +#endif // _USE_GLD3_WGL + + // Note if fullscreen vs window display has changed? + bSaveDesktop = (!bWasFullscreen && !dgl->bFullscreen) ? TRUE : FALSE; + // Save the desktop primary surface from being destroyed + // whenever remaining in windowed mode, since the stereo mode + // switches are expensive... + +#ifndef _USE_GLD3_WGL + // Don't need to re-allocate persistant buffers. (DaveM) + // Though we should clear the back buffers to hide artifacts. + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers) { + dgl->dwWidth = dwWidth; + dgl->dwHeight = dwHeight; + ZeroMemory(&ddbltfx, sizeof(ddbltfx)); + ddbltfx.dwSize = sizeof(ddbltfx); + ddbltfx.dwFillColor = dgl->dwClearColorPF; + IDirectDrawSurface4_Blt(dgl->lpBack4, &rcScreenRect, NULL, NULL, + DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); + return TRUE; + } + + // Ensure all rendering is complete + if (ctx->Driver.Finish) + (*ctx->Driver.Finish)(ctx); + if (dgl->bSceneStarted == TRUE) { + IDirect3DDevice3_EndScene(dgl->lpDev3); + dgl->bSceneStarted = FALSE; + } +#endif // _USE_GLD3_WGL + dgl->bCanRender = FALSE; + +#ifdef GLD_THREADS + // Serialize access to DirectDraw and DDS operations + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + +#ifndef _USE_GLD3_WGL + // Release existing surfaces + RELEASE(dgl->lpDev3); + RELEASE(dgl->lpDepth4); + RELEASE(dgl->lpBack4); + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) + ; + else + RELEASE(dgl->lpFront4); +#endif // _USE_GLD3_WGL + dgl->dwWidth = dwWidth; + dgl->dwHeight = dwHeight; + + // Set defaults + dgl->dwModeWidth = dgl->dwWidth; + dgl->dwModeHeight = dgl->dwHeight; + +#ifdef _USE_GLD3_WGL + if (!_gldDriver.ResizeDrawable(dgl, bDefaultDriver, glb.bDirectDrawPersistant, glb.bPersistantBuffers)) + goto cleanup_and_return_with_error; +#else // _USE_GLD3_WGL + + if (dgl->bFullscreen) { + // + // FULLSCREEN + // + + // Disable warning popups when in fullscreen mode + ddlogWarnOption(FALSE); + + // Have to release the persistant DirectDraw primary surface + // if switching to fullscreen mode. So if application wants + // persistant display in fullscreen mode, a fullscreen-size + // window should be used instead via fullscreen-blit option. + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) { + RELEASE(glb.lpPrimary4); + glb.bDirectDrawPrimary = FALSE; + } + + dwFlags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT; + if (glb.bFastFPU) + dwFlags |= DDSCL_FPUSETUP; // optional + hResult = IDirectDraw4_SetCooperativeLevel(dgl->lpDD4, dgl->hWnd, dwFlags); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Unable to set Exclusive Fullscreen mode", hResult); + goto cleanup_and_return_with_error; + } + + hResult = IDirectDraw4_SetDisplayMode(dgl->lpDD4, + dgl->dwModeWidth, + dgl->dwModeHeight, + dgl->dwBPP, + 0, + 0); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetDisplayMode failed", hResult); + goto cleanup_and_return_with_error; + } + + // ** The display mode has changed, so dont use MessageBox! ** + + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + + if (dgl->bDoubleBuffer) { + // Double buffered + // Primary surface + ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | + DDSCAPS_FLIP | + DDSCAPS_COMPLEX | + DDSCAPS_3DDEVICE | + dwMemoryType; + ddsd2.dwBackBufferCount = 1; + hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (primary) failed", hResult); + goto cleanup_and_return_with_error; + } + // Render target surface + ZeroMemory(&ddscaps2, sizeof(ddscaps2)); // Clear the entire struct. + ddscaps2.dwCaps = DDSCAPS_BACKBUFFER; + hResult = IDirectDrawSurface4_GetAttachedSurface(dgl->lpFront4, &ddscaps2, &dgl->lpBack4); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: GetAttachedSurface failed", hResult); + goto cleanup_and_return_with_error; + } + } else { + // Single buffered + // Primary surface + ddsd2.dwFlags = DDSD_CAPS; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | + //DDSCAPS_3DDEVICE | + dwMemoryType; + + hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (primary) failed", hResult); + goto cleanup_and_return_with_error; + } + + dgl->lpBack4 = NULL; + } + } else { + // WINDOWED + + // OK to enable warning popups in windowed mode + ddlogWarnOption(glb.bMessageBoxWarnings); + + // Ditto if persistant DirectDraw primary + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) + goto DoClipperOnly; + + // WINDOWED + dwFlags = DDSCL_NORMAL; + if (glb.bMultiThreaded) + dwFlags |= DDSCL_MULTITHREADED; + if (glb.bFastFPU) + dwFlags |= DDSCL_FPUSETUP; // optional + hResult = IDirectDraw4_SetCooperativeLevel(dgl->lpDD4, + dgl->hWnd, + dwFlags); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Unable to set Normal coop level", hResult); + goto cleanup_and_return_with_error; + } + // Primary surface + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (primary) failed", hResult); + goto cleanup_and_return_with_error; + } + + // Cache the primary surface for persistant DirectDraw state + if (glb.bDirectDrawPersistant && !glb.bDirectDrawPrimary) { + glb.lpPrimary4 = dgl->lpFront4; + IDirectDrawSurface4_AddRef(glb.lpPrimary4); + glb.bDirectDrawPrimary = TRUE; + } + + // Clipper object + hResult = DirectDrawCreateClipper(0, &lpddClipper, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateClipper failed", hResult); + goto cleanup_and_return_with_error; + } + hResult = IDirectDrawClipper_SetHWnd(lpddClipper, 0, dgl->hWnd); + if (FAILED(hResult)) { + RELEASE(lpddClipper); + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetHWnd failed", hResult); + goto cleanup_and_return_with_error; + } + hResult = IDirectDrawSurface4_SetClipper(dgl->lpFront4, lpddClipper); + RELEASE(lpddClipper); // We have finished with it. + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetClipper failed", hResult); + goto cleanup_and_return_with_error; + } +DoClipperOnly: + // Update the window for the original clipper + if ((glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) || bSaveDesktop) { + IDirectDrawSurface4_GetClipper(dgl->lpFront4, &lpddClipper); + IDirectDrawClipper_SetHWnd(lpddClipper, 0, dgl->hWnd); + RELEASE(lpddClipper); + } + + if (dgl->bDoubleBuffer) { + // Render target surface + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd2.dwWidth = dgl->dwWidth; + ddsd2.dwHeight = dgl->dwHeight; + ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | + DDSCAPS_OFFSCREENPLAIN | + dwMemoryType; + hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpBack4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Create Backbuffer failed", hResult); + goto cleanup_and_return_with_error; + } + + } else { + dgl->lpBack4 = NULL; + } + } + + // + // Now create the Zbuffer + // + if (dgl->bDepthBuffer) { + // Get z-buffer dimensions from the render target + // Setup the surface desc for the z-buffer. + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | dwMemoryType; + ddsd2.dwWidth = dgl->dwWidth; + ddsd2.dwHeight = dgl->dwHeight; + memcpy(&ddsd2.ddpfPixelFormat, + &glb.lpZBufferPF[dgl->iZBufferPF], + sizeof(DDPIXELFORMAT) ); + + // Create a z-buffer + hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpDepth4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (ZBuffer) failed", hResult); + goto cleanup_and_return_with_error; + } + + // Attach Zbuffer to render target + TRY(IDirectDrawSurface4_AddAttachedSurface( + dgl->bDoubleBuffer ? dgl->lpBack4 : dgl->lpFront4, + dgl->lpDepth4), + "dglResize: Attach Zbuffer"); + + } + + // Clear the newly resized back buffers for the window client area. + ZeroMemory(&ddbltfx, sizeof(ddbltfx)); + ddbltfx.dwSize = sizeof(ddbltfx); + ddbltfx.dwFillColor = dgl->dwClearColorPF; + IDirectDrawSurface4_Blt(dgl->lpBack4, &rcScreenRect, NULL, NULL, + DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); + + // + // Now that we have a zbuffer we can create the 3D device + // + hResult = IDirect3D3_CreateDevice(dgl->lpD3D3, + bDefaultDriver ? &glb.d3dGuid : &IID_IDirect3DRGBDevice, + dgl->bDoubleBuffer ? dgl->lpBack4 : dgl->lpFront4, + &dgl->lpDev3, + NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Could not create Direct3D device", hResult); + goto cleanup_and_return_with_error; + } + + // We must do this as soon as the device is created + dglInitStateCaches(dgl); + + // + // Viewport + // + hResult = IDirect3DDevice3_AddViewport(dgl->lpDev3, dgl->lpViewport3); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: AddViewport failed", hResult); + goto cleanup_and_return_with_error; + } + + // Initialise the viewport + dgl->d3dViewport.dwSize = sizeof(dgl->d3dViewport); + dgl->d3dViewport.dwX = 0; + dgl->d3dViewport.dwY = 0; + dgl->d3dViewport.dwWidth = dgl->dwWidth; + dgl->d3dViewport.dwHeight = dgl->dwHeight; + dgl->d3dViewport.dvClipX = 0; + dgl->d3dViewport.dvClipY = 0; + dgl->d3dViewport.dvClipWidth = dgl->dwWidth; + dgl->d3dViewport.dvClipHeight = dgl->dwHeight; +// dgl->d3dViewport.dvMinZ = 0.0f; +// dgl->d3dViewport.dvMaxZ = 1.0f; + TRY(IDirect3DViewport3_SetViewport2(dgl->lpViewport3, &dgl->d3dViewport), + "dglResize: SetViewport2"); + + hResult = IDirect3DDevice3_SetCurrentViewport(dgl->lpDev3, dgl->lpViewport3); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetCurrentViewport failed", hResult); + goto cleanup_and_return_with_error; + } + + // (Re)Initialise all the Direct3D renderstates + dglInitStateD3D(ctx); + + // Now we have to recreate all of our textures (+ mipmaps). + // Luckily, Mesa has a list of them. + tObj = ctx->Shared->TexObjectList; + while (tObj != NULL) { + if (tObj->DriverData) { + // We could call our TexImage function directly, but it's + // safer to use the driver pointer. + for (i=0; iImage[i]; + if (image) { + switch (tObj->Dimensions){ + case 1: + if (ctx->Driver.TexImage) + (*ctx->Driver.TexImage)(ctx, GL_TEXTURE_1D, tObj, i, image->Format, image); + break; + case 2: + if (ctx->Driver.TexImage) + (*ctx->Driver.TexImage)(ctx, GL_TEXTURE_2D, tObj, i, image->Format, image); + break; + default: + break; + } + } + } + } + tObj = tObj->Next; + } + + // Re-Bind each texture Unit + for (i=0; iTexture.Unit[i].Current; + if (tObj) { + DGL_texture *lpTex = (DGL_texture *)tObj->DriverData; + hResult = dglSetTexture(dgl, i, lpTex ? lpTex->lpTexture : NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_ERROR, "dglResize: SetTexture failed", hResult); + } + } + } +#endif // _USE_GLD3_WGL + + dgl->bCanRender = TRUE; + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + // SUCCESS. + return TRUE; + +cleanup_and_return_with_error: + // Relase all interfaces before returning. +#ifdef _USE_GLD3_WGL + _gldDriver.DestroyDrawable(dgl); +#else // _USE_GLD3_WGL + RELEASE(dgl->lpDev3); + RELEASE(dgl->lpDepth4); + RELEASE(dgl->lpBack4); + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) + ; + else + RELEASE(dgl->lpFront4); + +#undef DDLOG_CRITICAL_OR_WARN +#endif // _USE_GLD3_WGL + + // Mark context as not being able to render + dgl->bCanRender = FALSE; + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return FALSE; +} + +// *********************************************************************** +// *********************************************************************** +// Support for bitmap fonts. +// *********************************************************************** +// *********************************************************************** + +/***************************************************************************** +** +** InvertGlyphBitmap. +** +** Invert the bitmap so that it suits OpenGL's representation. +** Each row starts on a double word boundary. +** +*****************************************************************************/ + +static void InvertGlyphBitmap( + int w, + int h, + DWORD *fptr, + DWORD *tptr) +{ + int dWordsInRow = (w+31)/32; + int i, j; + DWORD *tmp = tptr; + + if (w <= 0 || h <= 0) { + return; + } + + tptr += ((h-1)*dWordsInRow); + for (i = 0; i < h; i++) { + for (j = 0; j < dWordsInRow; j++) { + *(tptr + j) = *(fptr + j); + } + tptr -= dWordsInRow; + fptr += dWordsInRow; + } +} + +// *********************************************************************** + +/***************************************************************************** + * wglUseFontBitmaps + * + * Converts a subrange of the glyphs in a GDI font to OpenGL display + * lists. + * + * Extended to support any GDI font, not just TrueType fonts. (DaveM) + * + *****************************************************************************/ + +BOOL APIENTRY _GLD_WGL_EXPORT(UseFontBitmapsA)( + HDC hDC, + DWORD first, + DWORD count, + DWORD listBase) +{ + int i, ox, oy, ix, iy; + int w, h; + int iBufSize, iCurBufSize = 0; + DWORD *bitmapBuffer = NULL; + DWORD *invertedBitmapBuffer = NULL; + BOOL bSuccessOrFail = TRUE; + BOOL bTrueType = FALSE; + TEXTMETRIC tm; + GLYPHMETRICS gm; + RASTERIZER_STATUS rs; + MAT2 mat; + SIZE size; + RECT rect; + HDC hDCMem; + HBITMAP hBitmap; + BITMAPINFO bmi; + HFONT hFont; + + // Validate SciTech DirectGL license + if (!dglValidate()) + return FALSE; + + // Set up a unity matrix. + ZeroMemory(&mat, sizeof(mat)); + mat.eM11.value = 1; + mat.eM22.value = 1; + + // Test to see if selected font is TrueType or not + ZeroMemory(&tm, sizeof(tm)); + if (!GetTextMetrics(hDC, &tm)) { + ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Font metrics error\n"); + return (FALSE); + } + bTrueType = (tm.tmPitchAndFamily & TMPF_TRUETYPE) ? TRUE : FALSE; + + // Test to see if TRUE-TYPE capabilities are installed + // (only necessary if TrueType font selected) + ZeroMemory(&rs, sizeof(rs)); + if (bTrueType) { + if (!GetRasterizerCaps (&rs, sizeof (RASTERIZER_STATUS))) { + ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Raster caps error\n"); + return (FALSE); + } + if (!(rs.wFlags & TT_ENABLED)) { + ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: No TrueType caps\n"); + return (FALSE); + } + } + + // Trick to get the current font handle + hFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); + SelectObject(hDC, hFont); + + // Have memory device context available for holding bitmaps of font glyphs + hDCMem = CreateCompatibleDC(hDC); + SelectObject(hDCMem, hFont); + SetTextColor(hDCMem, RGB(0xFF, 0xFF, 0xFF)); + SetBkColor(hDCMem, 0); + + for (i = first; (DWORD) i < (first + count); i++) { + // Find out how much space is needed for the bitmap so we can + // Set the buffer size correctly. + if (bTrueType) { + // Use TrueType support to get bitmap size of glyph + iBufSize = GetGlyphOutline(hDC, i, GGO_BITMAP, &gm, + 0, NULL, &mat); + if (iBufSize == GDI_ERROR) { + bSuccessOrFail = FALSE; + break; + } + } + else { + // Use generic GDI support to compute bitmap size of glyph + w = tm.tmMaxCharWidth; + h = tm.tmHeight; + if (GetTextExtentPoint32(hDC, (LPCTSTR)&i, 1, &size)) { + w = size.cx; + h = size.cy; + } + iBufSize = w * h; + // Use DWORD multiple for compatibility + iBufSize += 3; + iBufSize /= 4; + iBufSize *= 4; + } + + // If we need to allocate Larger Buffers, then do so - but allocate + // An extra 50 % so that we don't do too many mallocs ! + if (iBufSize > iCurBufSize) { + if (bitmapBuffer) { + __wglFree(bitmapBuffer); + } + if (invertedBitmapBuffer) { + __wglFree(invertedBitmapBuffer); + } + + iCurBufSize = iBufSize * 2; + bitmapBuffer = (DWORD *) __wglMalloc(iCurBufSize); + invertedBitmapBuffer = (DWORD *) __wglMalloc(iCurBufSize); + + if (bitmapBuffer == NULL || invertedBitmapBuffer == NULL) { + bSuccessOrFail = FALSE; + break; + } + } + + // If we fail to get the Glyph data, delete the display lists + // Created so far and return FALSE. + if (bTrueType) { + // Use TrueType support to get bitmap of glyph + if (GetGlyphOutline(hDC, i, GGO_BITMAP, &gm, + iBufSize, bitmapBuffer, &mat) == GDI_ERROR) { + bSuccessOrFail = FALSE; + break; + } + + // Setup glBitmap parameters for current font glyph + w = gm.gmBlackBoxX; + h = gm.gmBlackBoxY; + ox = gm.gmptGlyphOrigin.x; + oy = gm.gmptGlyphOrigin.y; + ix = gm.gmCellIncX; + iy = gm.gmCellIncY; + } + else { + // Use generic GDI support to create bitmap of glyph + ZeroMemory(bitmapBuffer, iBufSize); + + if (i >= tm.tmFirstChar && i <= tm.tmLastChar) { + // Only create bitmaps for actual font glyphs + hBitmap = CreateBitmap(w, h, 1, 1, NULL); + SelectObject(hDCMem, hBitmap); + // Make bitmap of current font glyph + SetRect(&rect, 0, 0, w, h); + DrawText(hDCMem, (LPCTSTR)&i, 1, &rect, + DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_NOCLIP); + // Make copy of bitmap in our local buffer + ZeroMemory(&bmi, sizeof(bmi)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = w; + bmi.bmiHeader.biHeight = -h; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 1; + bmi.bmiHeader.biCompression = BI_RGB; + GetDIBits(hDCMem, hBitmap, 0, h, bitmapBuffer, &bmi, 0); + DeleteObject(hBitmap); + } + else { + // Otherwise use empty display list for non-existing glyph + iBufSize = 0; + } + + // Setup glBitmap parameters for current font glyph + ox = 0; + oy = tm.tmDescent; + ix = w; + iy = 0; + } + + // Create an OpenGL display list. + _GLD_glNewList((listBase + i), GL_COMPILE); + + // Some fonts have no data for the space character, yet advertise + // a non-zero size. + if (0 == iBufSize) { + _GLD_glBitmap(0, 0, 0.0f, 0.0f, (GLfloat) ix, (GLfloat) iy, NULL); + } else { + // Invert the Glyph data. + InvertGlyphBitmap(w, h, bitmapBuffer, invertedBitmapBuffer); + + // Render an OpenGL bitmap and invert the origin. + _GLD_glBitmap(w, h, + (GLfloat) ox, (GLfloat) (h-oy), + (GLfloat) ix, (GLfloat) iy, + (GLubyte *) invertedBitmapBuffer); + } + + // Close this display list. + _GLD_glEndList(); + } + + if (bSuccessOrFail == FALSE) { + ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Get glyph failed\n"); + _GLD_glDeleteLists((i+listBase), (i-first)); + } + + // Release resources used + DeleteObject(hFont); + DeleteDC(hDCMem); + + if (bitmapBuffer) + __wglFree(bitmapBuffer); + if (invertedBitmapBuffer) + __wglFree(invertedBitmapBuffer); + + return(bSuccessOrFail); +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(UseFontBitmapsW)( + HDC a, + DWORD b, + DWORD c, + DWORD d) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + return _GLD_WGL_EXPORT(UseFontBitmapsA)(a, b, c, d); +} + +// *********************************************************************** +// *********************************************************************** +// Support for outline TrueType fonts. +// *********************************************************************** +// *********************************************************************** + +void * __wglRealloc( + void *oldPtr, + size_t newSize) +{ + void *newPtr = NULL; + + if (newSize != 0) { + newPtr = (void *) GlobalAlloc(GPTR, newSize); + if (oldPtr && newPtr) { + DWORD oldSize = GlobalSize(oldPtr); + + memcpy(newPtr, oldPtr, (oldSize <= newSize ? oldSize : newSize)); + GlobalFree(oldPtr); + } + } else if (oldPtr) { + GlobalFree(oldPtr); + } + if (newPtr == NULL) { + return NULL; /* XXX out of memory error */ + } + return newPtr; +} + +// *********************************************************************** + + +/***************************************************************************** + * wglUseFontOutlinesW + * + * Converts a subrange of the glyphs in a TrueType font to OpenGL display + * lists. + *****************************************************************************/ + +BOOL APIENTRY _GLD_WGL_EXPORT(UseFontOutlinesW)( + IN HDC hDC, + IN DWORD first, + IN DWORD count, + IN DWORD listBase, + IN FLOAT chordalDeviation, + IN FLOAT extrusion, + IN INT format, + OUT LPGLYPHMETRICSFLOAT lpgmf) +{ + return _GLD_WGL_EXPORT(UseFontOutlinesA)(hDC, first, count, listBase, + chordalDeviation, extrusion, format, lpgmf); +} + +/***************************************************************************** + * wglUseFontOutlinesA + * + * Converts a subrange of the glyphs in a TrueType font to OpenGL display + * lists. + *****************************************************************************/ + +BOOL APIENTRY _GLD_WGL_EXPORT(UseFontOutlinesA)( + IN HDC hDC, + IN DWORD first, + IN DWORD count, + IN DWORD listBase, + IN FLOAT chordalDeviation, + IN FLOAT extrusion, + IN INT format, + OUT LPGLYPHMETRICSFLOAT glyphMetricsFloatArray) + { + DWORD glyphIndex; + UCHAR* glyphBuf; + DWORD glyphBufSize; + + + /* + * Flush any previous OpenGL errors. This allows us to check for + * new errors so they can be reported via the function return value. + */ + while (_GLD_glGetError() != GL_NO_ERROR) + ; + + /* + * Make sure that the current font can be sampled accurately. + */ + hNewFont = CreateHighResolutionFont(hDC); + if (!hNewFont) + return FALSE; + + hOldFont = SelectObject(hDC, hNewFont); + if (!hOldFont) + return FALSE; + + /* + * Preallocate a buffer for the outline data, and track its size: + */ + glyphBuf = (UCHAR*) __wglMalloc(glyphBufSize = 10240); + if (!glyphBuf) + return FALSE; /*WGL_STATUS_NOT_ENOUGH_MEMORY*/ + + /* + * Process each glyph in the given range: + */ + for (glyphIndex = first; glyphIndex - first < count; ++glyphIndex) + { + GLYPHMETRICS glyphMetrics; + DWORD glyphSize; + static MAT2 matrix = + { + {0, 1}, {0, 0}, + {0, 0}, {0, 1} + }; + LPGLYPHMETRICSFLOAT glyphMetricsFloat = + &glyphMetricsFloatArray[glyphIndex - first]; + + + /* + * Determine how much space is needed to store the glyph's + * outlines. If our glyph buffer isn't large enough, + * resize it. + */ + glyphSize = GetGlyphOutline( hDC, + glyphIndex, + GGO_NATIVE, + &glyphMetrics, + 0, + NULL, + &matrix + ); + if (glyphSize < 0) + return FALSE; /*WGL_STATUS_FAILURE*/ + if (glyphSize > glyphBufSize) + { + __wglFree(glyphBuf); + glyphBuf = (UCHAR*) __wglMalloc(glyphBufSize = glyphSize); + if (!glyphBuf) + return FALSE; /*WGL_STATUS_NOT_ENOUGH_MEMORY*/ + } + + + /* + * Get the glyph's outlines. + */ + if (GetGlyphOutline( hDC, + glyphIndex, + GGO_NATIVE, + &glyphMetrics, + glyphBufSize, + glyphBuf, + &matrix + ) < 0) + { + __wglFree(glyphBuf); + return FALSE; /*WGL_STATUS_FAILURE*/ + } + + glyphMetricsFloat->gmfBlackBoxX = + (FLOAT) glyphMetrics.gmBlackBoxX * ScaleFactor; + glyphMetricsFloat->gmfBlackBoxY = + (FLOAT) glyphMetrics.gmBlackBoxY * ScaleFactor; + glyphMetricsFloat->gmfptGlyphOrigin.x = + (FLOAT) glyphMetrics.gmptGlyphOrigin.x * ScaleFactor; + glyphMetricsFloat->gmfptGlyphOrigin.y = + (FLOAT) glyphMetrics.gmptGlyphOrigin.y * ScaleFactor; + glyphMetricsFloat->gmfCellIncX = + (FLOAT) glyphMetrics.gmCellIncX * ScaleFactor; + glyphMetricsFloat->gmfCellIncY = + (FLOAT) glyphMetrics.gmCellIncY * ScaleFactor; + + /* + * Turn the glyph into a display list: + */ + if (!MakeDisplayListFromGlyph( (glyphIndex - first) + listBase, + glyphBuf, + glyphSize, + glyphMetricsFloat, + chordalDeviation + ScaleFactor, + extrusion, + format)) + { + __wglFree(glyphBuf); + return FALSE; /*WGL_STATUS_FAILURE*/ + } + } + + + /* + * Clean up temporary storage and return. If an error occurred, + * clear all OpenGL error flags and return FAILURE status; + * otherwise just return SUCCESS. + */ + __wglFree(glyphBuf); + + SelectObject(hDC, hOldFont); + + if (_GLD_glGetError() == GL_NO_ERROR) + return TRUE; /*WGL_STATUS_SUCCESS*/ + else + { + while (_GLD_glGetError() != GL_NO_ERROR) + ; + return FALSE; /*WGL_STATUS_FAILURE*/ + } + } + + + +/***************************************************************************** + * CreateHighResolutionFont + * + * Gets metrics for the current font and creates an equivalent font + * scaled to the design units of the font. + * + *****************************************************************************/ + +static HFONT +CreateHighResolutionFont(HDC hDC) + { + UINT otmSize; + OUTLINETEXTMETRIC *otm; + LONG fontHeight, fontWidth, fontUnits; + LOGFONT logFont; + + otmSize = GetOutlineTextMetrics(hDC, 0, NULL); + if (otmSize == 0) + return NULL; + + otm = (OUTLINETEXTMETRIC *) __wglMalloc(otmSize); + if (otm == NULL) + return NULL; + + otm->otmSize = otmSize; + if (GetOutlineTextMetrics(hDC, otmSize, otm) == 0) + return NULL; + + fontHeight = otm->otmTextMetrics.tmHeight - + otm->otmTextMetrics.tmInternalLeading; + fontWidth = otm->otmTextMetrics.tmAveCharWidth; + fontUnits = (LONG) otm->otmEMSquare; + + ScaleFactor = 1.0F / (FLOAT) fontUnits; + + logFont.lfHeight = - ((LONG) fontUnits); + logFont.lfWidth = (LONG) + ((FLOAT) (fontWidth * fontUnits) / (FLOAT) fontHeight); + logFont.lfEscapement = 0; + logFont.lfOrientation = 0; + logFont.lfWeight = otm->otmTextMetrics.tmWeight; + logFont.lfItalic = otm->otmTextMetrics.tmItalic; + logFont.lfUnderline = otm->otmTextMetrics.tmUnderlined; + logFont.lfStrikeOut = otm->otmTextMetrics.tmStruckOut; + logFont.lfCharSet = otm->otmTextMetrics.tmCharSet; + logFont.lfOutPrecision = OUT_OUTLINE_PRECIS; + logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + logFont.lfQuality = DEFAULT_QUALITY; + logFont.lfPitchAndFamily = + otm->otmTextMetrics.tmPitchAndFamily & 0xf0; + strcpy(logFont.lfFaceName, + (char *)otm + (int)otm->otmpFaceName); + + hNewFont = CreateFontIndirect(&logFont); + if (hNewFont == NULL) + return NULL; + + __wglFree(otm); + + return hNewFont; + } + + + +/***************************************************************************** + * MakeDisplayListFromGlyph + * + * Converts the outline of a glyph to an OpenGL display list. + * + * Return value is nonzero for success, zero for failure. + * + * Does not check for OpenGL errors, so if the caller needs to know about them, + * it should call glGetError(). + *****************************************************************************/ + +static int +MakeDisplayListFromGlyph( IN DWORD listName, + IN UCHAR* glyphBuf, + IN DWORD glyphSize, + IN LPGLYPHMETRICSFLOAT glyphMetricsFloat, + IN FLOAT chordalDeviation, + IN FLOAT extrusion, + IN INT format) + { + int status; + + _GLD_glNewList(listName, GL_COMPILE); + status = DrawGlyph( glyphBuf, + glyphSize, + chordalDeviation, + extrusion, + format); + + _GLD_glTranslatef(glyphMetricsFloat->gmfCellIncX, + glyphMetricsFloat->gmfCellIncY, + 0.0F); + _GLD_glEndList(); + + return status; + } + + + +/***************************************************************************** + * DrawGlyph + * + * Converts the outline of a glyph to OpenGL drawing primitives, tessellating + * as needed, and then draws the glyph. Tessellation of the quadratic splines + * in the outline is controlled by "chordalDeviation", and the drawing + * primitives (lines or polygons) are selected by "format". + * + * Return value is nonzero for success, zero for failure. + * + * Does not check for OpenGL errors, so if the caller needs to know about them, + * it should call glGetError(). + *****************************************************************************/ + +static int +DrawGlyph( IN UCHAR* glyphBuf, + IN DWORD glyphSize, + IN FLOAT chordalDeviation, + IN FLOAT extrusion, + IN INT format) + { + INT status = 0; + FLOAT* p; + DWORD loop; + DWORD point; + GLUtesselator* tess = NULL; + + + /* + * Initialize the global buffer into which we place the outlines: + */ + if (!InitLineBuf()) + goto exit; + + + /* + * Convert the glyph outlines to a set of polyline loops. + * (See MakeLinesFromGlyph() for the format of the loop data + * structure.) + */ + if (!MakeLinesFromGlyph(glyphBuf, glyphSize, chordalDeviation)) + goto exit; + p = LineBuf; + + + /* + * Now draw the loops in the appropriate format: + */ + if (format == WGL_FONT_LINES) + { + /* + * This is the easy case. Just draw the outlines. + */ + for (loop = (DWORD) *p++; loop; --loop) + { + _GLD_glBegin(GL_LINE_LOOP); + for (point = (DWORD) *p++; point; --point) + { + _GLD_glVertex2fv(p); + p += 2; + } + _GLD_glEnd(); + } + status = 1; + } + + else if (format == WGL_FONT_POLYGONS) + { + double v[3]; + FLOAT *save_p = p; + GLfloat z_value; + + /* + * This is the hard case. We have to set up a tessellator + * to convert the outlines into a set of polygonal + * primitives, which the tessellator passes to some + * auxiliary routines for drawing. + */ + if (!LoadGLUTesselator()) + goto exit; + if (!InitVertBuf()) + goto exit; + if (!(tess = gluNewTessProc())) + goto exit; + gluTessCallbackProc(tess, GLU_BEGIN, (void(CALLBACK *)()) _GLD_glBegin); + gluTessCallbackProc(tess, GLU_TESS_VERTEX_DATA, + (void(CALLBACK *)()) TessVertexOutData); + gluTessCallbackProc(tess, GLU_END, (void(CALLBACK *)()) _GLD_glEnd); + gluTessCallbackProc(tess, GLU_ERROR, (void(CALLBACK *)()) TessError); + gluTessCallbackProc(tess, GLU_TESS_COMBINE, (void(CALLBACK *)()) TessCombine); + gluTessNormalProc(tess, 0.0F, 0.0F, 1.0F); + + TessErrorOccurred = 0; + _GLD_glNormal3f(0.0f, 0.0f, 1.0f); + v[2] = 0.0; + z_value = 0.0f; + + gluTessBeginPolygonProc(tess, (void *)*(int *)&z_value); + for (loop = (DWORD) *p++; loop; --loop) + { + gluTessBeginContourProc(tess); + + for (point = (DWORD) *p++; point; --point) + { + v[0] = p[0]; + v[1] = p[1]; + gluTessVertexProc(tess, v, p); + p += 2; + } + + gluTessEndContourProc(tess); + } + gluTessEndPolygonProc(tess); + + status = !TessErrorOccurred; + + /* Extrusion code */ + if (extrusion) { + DWORD loops; + GLfloat thickness = (GLfloat) -extrusion; + FLOAT *vert, *vert2; + DWORD count; + + p = save_p; + loops = (DWORD) *p++; + + for (loop = 0; loop < loops; loop++) { + GLfloat dx, dy, len; + DWORD last; + + count = (DWORD) *p++; + _GLD_glBegin(GL_QUAD_STRIP); + + /* Check if the first and last vertex are identical + * so we don't draw the same quad twice. + */ + vert = p + (count-1)*2; + last = (p[0] == vert[0] && p[1] == vert[1]) ? count-1 : count; + + for (point = 0; point <= last; point++) { + vert = p + 2 * (point % last); + vert2 = p + 2 * ((point+1) % last); + + dx = vert[0] - vert2[0]; + dy = vert[1] - vert2[1]; + len = (GLfloat)sqrt(dx * dx + dy * dy); + + _GLD_glNormal3f(dy / len, -dx / len, 0.0f); + _GLD_glVertex3f((GLfloat) vert[0], + (GLfloat) vert[1], thickness); + _GLD_glVertex3f((GLfloat) vert[0], + (GLfloat) vert[1], 0.0f); + } + + _GLD_glEnd(); + p += count*2; + } + + /* Draw the back face */ + p = save_p; + v[2] = thickness; + _GLD_glNormal3f(0.0f, 0.0f, -1.0f); + gluTessNormalProc(tess, 0.0F, 0.0F, -1.0F); + + gluTessBeginPolygonProc(tess, (void *)*(int *)&thickness); + + for (loop = (DWORD) *p++; loop; --loop) + { + count = (DWORD) *p++; + + gluTessBeginContourProc(tess); + + for (point = 0; point < count; point++) + { + vert = p + ((count-point-1)<<1); + v[0] = vert[0]; + v[1] = vert[1]; + gluTessVertexProc(tess, v, vert); + } + p += count*2; + + gluTessEndContourProc(tess); + } + gluTessEndPolygonProc(tess); + } + +#if DEBUG + if (TessErrorOccurred) + printf("Tessellation error %s\n", + gluErrorString(TessErrorOccurred)); +#endif + } + + +exit: + FreeLineBuf(); + if (tess) + gluDeleteTessProc(tess); + // UnloadGLUTesselator(); + FreeVertBuf(); + return status; + } + + + +/***************************************************************************** + * LoadGLUTesselator + * + * Maps the glu32.dll module and gets function pointers for the + * tesselator functions. + *****************************************************************************/ + +static BOOL +LoadGLUTesselator(void) + { + if (gluModuleHandle != NULL) + return TRUE; + + { + extern HINSTANCE hInstanceOpenGL; + char *gluName = "GLU32.DLL"; +// char name[256]; +// char *ptr; +// int len; + +/* + len = GetModuleFileName(hInstanceOpenGL, name, 255); + if (len != 0) + { + ptr = name+len-1; + while (ptr > name && *ptr != '\\') + ptr--; + if (*ptr == '\\') + ptr++; + if (!stricmp(ptr, "cosmogl.dll")) + { + gluName = "COSMOGLU.DLL"; + } + else if (!stricmp(ptr, "opengl32.dll")) + { + gluName = "GLU32.DLL"; + } + } +*/ + if ((gluModuleHandle = LoadLibrary(gluName)) == NULL) + return FALSE; + } + + if ((gluNewTessProc = (gluNewTessProto) + GetProcAddress(gluModuleHandle, "gluNewTess")) == NULL) + return FALSE; + + if ((gluDeleteTessProc = (gluDeleteTessProto) + GetProcAddress(gluModuleHandle, "gluDeleteTess")) == NULL) + return FALSE; + + if ((gluTessBeginPolygonProc = (gluTessBeginPolygonProto) + GetProcAddress(gluModuleHandle, "gluTessBeginPolygon")) == NULL) + return FALSE; + + if ((gluTessBeginContourProc = (gluTessBeginContourProto) + GetProcAddress(gluModuleHandle, "gluTessBeginContour")) == NULL) + return FALSE; + + if ((gluTessVertexProc = (gluTessVertexProto) + GetProcAddress(gluModuleHandle, "gluTessVertex")) == NULL) + return FALSE; + + if ((gluTessEndContourProc = (gluTessEndContourProto) + GetProcAddress(gluModuleHandle, "gluTessEndContour")) == NULL) + return FALSE; + + if ((gluTessEndPolygonProc = (gluTessEndPolygonProto) + GetProcAddress(gluModuleHandle, "gluTessEndPolygon")) == NULL) + return FALSE; + + if ((gluTessPropertyProc = (gluTessPropertyProto) + GetProcAddress(gluModuleHandle, "gluTessProperty")) == NULL) + return FALSE; + + if ((gluTessNormalProc = (gluTessNormalProto) + GetProcAddress(gluModuleHandle, "gluTessNormal")) == NULL) + return FALSE; + + if ((gluTessCallbackProc = (gluTessCallbackProto) + GetProcAddress(gluModuleHandle, "gluTessCallback")) == NULL) + return FALSE; + + return TRUE; + } + + + +/***************************************************************************** + * UnloadGLUTesselator + * + * Unmaps the glu32.dll module. + *****************************************************************************/ + +static BOOL +UnloadGLUTesselator(void) + { + if (gluModuleHandle != NULL) + if (FreeLibrary(gluModuleHandle) == FALSE) + return FALSE; + gluModuleHandle = NULL; + } + + + +/***************************************************************************** + * TessVertexOut + * + * Used by tessellator to handle output vertexes. + *****************************************************************************/ + +static void CALLBACK +TessVertexOut(FLOAT p[3]) + { + GLfloat v[2]; + + v[0] = p[0] * ScaleFactor; + v[1] = p[1] * ScaleFactor; + _GLD_glVertex2fv(v); + } + +static void CALLBACK +TessVertexOutData(FLOAT p[3], GLfloat z) +{ + GLfloat v[3]; + + v[0] = (GLfloat) p[0]; + v[1] = (GLfloat) p[1]; + v[2] = z; + _GLD_glVertex3fv(v); +} + + +/***************************************************************************** + * TessCombine + * + * Used by tessellator to handle self-intersecting contours and degenerate + * geometry. + *****************************************************************************/ + +static void CALLBACK +TessCombine(double coords[3], + void* vertex_data[4], + FLOAT weight[4], + void** outData) + { + if (!AppendToVertBuf((FLOAT) coords[0]) + || !AppendToVertBuf((FLOAT) coords[1]) + || !AppendToVertBuf((FLOAT) coords[2])) + TessErrorOccurred = GL_OUT_OF_MEMORY; + *outData = VertBuf + (VertBufIndex - 3); + } + + + +/***************************************************************************** + * TessError + * + * Saves the last tessellator error code in the global TessErrorOccurred. + *****************************************************************************/ + +static void CALLBACK +TessError(GLenum error) + { + TessErrorOccurred = error; + } + + + +/***************************************************************************** + * MakeLinesFromGlyph + * + * Converts the outline of a glyph from the TTPOLYGON format to a simple + * array of floating-point values containing one or more loops. + * + * The first element of the output array is a count of the number of loops. + * The loop data follows this count. Each loop consists of a count of the + * number of vertices it contains, followed by the vertices. Each vertex + * is an X and Y coordinate. For example, a single triangle might be + * described by this array: + * + * 1., 3., 0., 0., 1., 0., 0., 1. + * ^ ^ ^ ^ ^ ^ ^ ^ + * #loops #verts x1 y1 x2 y2 x3 y3 + * + * A two-loop glyph would look like this: + * + * 2., 3., 0.,0., 1.,0., 0.,1., 3., .2,.2, .4,.2, .2,.4 + * + * Line segments from the TTPOLYGON are transferred to the output array in + * the obvious way. Quadratic splines in the TTPOLYGON are converted to + * collections of line segments + *****************************************************************************/ + +static int +MakeLinesFromGlyph(IN UCHAR* glyphBuf, + IN DWORD glyphSize, + IN FLOAT chordalDeviation) + { + UCHAR* p; + int status = 0; + + + /* + * Pick up all the polygons (aka loops) that make up the glyph: + */ + if (!AppendToLineBuf(0.0F)) /* loop count at LineBuf[0] */ + goto exit; + + p = glyphBuf; + while (p < glyphBuf + glyphSize) + { + if (!MakeLinesFromTTPolygon(&p, chordalDeviation)) + goto exit; + LineBuf[0] += 1.0F; /* increment loop count */ + } + + status = 1; + +exit: + return status; + } + + + +/***************************************************************************** + * MakeLinesFromTTPolygon + * + * Converts a TTPOLYGONHEADER and its associated curve structures into a + * single polyline loop in the global LineBuf. + *****************************************************************************/ + +static int +MakeLinesFromTTPolygon( IN OUT UCHAR** pp, + IN FLOAT chordalDeviation) + { + DWORD polySize; + UCHAR* polyStart; + DWORD vertexCountIndex; + + /* + * Record where the polygon data begins, and where the loop's + * vertex count resides: + */ + polyStart = *pp; + vertexCountIndex = LineBufIndex; + if (!AppendToLineBuf(0.0F)) + return 0; + + /* + * Extract relevant data from the TTPOLYGONHEADER: + */ + polySize = GetDWord(pp); + if (GetDWord(pp) != TT_POLYGON_TYPE) /* polygon type */ + return 0; + if (!AppendToLineBuf((FLOAT) GetFixed(pp))) /* first X coord */ + return 0; + if (!AppendToLineBuf((FLOAT) GetFixed(pp))) /* first Y coord */ + return 0; + LineBuf[vertexCountIndex] += 1.0F; + + /* + * Process each of the TTPOLYCURVE structures in the polygon: + */ + while (*pp < polyStart + polySize) + if (!MakeLinesFromTTPolycurve( pp, + vertexCountIndex, + chordalDeviation)) + return 0; + + return 1; + } + + + +/***************************************************************************** + * MakeLinesFromTTPolyCurve + * + * Converts the lines and splines in a single TTPOLYCURVE structure to points + * in the global LineBuf. + *****************************************************************************/ + +static int +MakeLinesFromTTPolycurve( IN OUT UCHAR** pp, + IN DWORD vertexCountIndex, + IN FLOAT chordalDeviation) + { + WORD type; + WORD pointCount; + + + /* + * Pick up the relevant fields of the TTPOLYCURVE structure: + */ + type = (WORD) GetWord(pp); + pointCount = (WORD) GetWord(pp); + + /* + * Convert the "curve" to line segments: + */ + if (type == TT_PRIM_LINE) + return MakeLinesFromTTLine( pp, + vertexCountIndex, + pointCount); + else if (type == TT_PRIM_QSPLINE) + return MakeLinesFromTTQSpline( pp, + vertexCountIndex, + pointCount, + chordalDeviation); + else + return 0; + } + + + +/***************************************************************************** + * MakeLinesFromTTLine + * + * Converts points from the polyline in a TT_PRIM_LINE structure to + * equivalent points in the global LineBuf. + *****************************************************************************/ +static int +MakeLinesFromTTLine( IN OUT UCHAR** pp, + IN DWORD vertexCountIndex, + IN WORD pointCount) + { + /* + * Just copy the line segments into the line buffer (converting + * type as we go): + */ + LineBuf[vertexCountIndex] += pointCount; + while (pointCount--) + { + if (!AppendToLineBuf((FLOAT) GetFixed(pp)) /* X coord */ + || !AppendToLineBuf((FLOAT) GetFixed(pp))) /* Y coord */ + return 0; + } + + return 1; + } + + + +/***************************************************************************** + * MakeLinesFromTTQSpline + * + * Converts points from the poly quadratic spline in a TT_PRIM_QSPLINE + * structure to polyline points in the global LineBuf. + *****************************************************************************/ + +static int +MakeLinesFromTTQSpline( IN OUT UCHAR** pp, + IN DWORD vertexCountIndex, + IN WORD pointCount, + IN FLOAT chordalDeviation) + { + FLOAT x0, y0, x1, y1, x2, y2; + WORD point; + + /* + * Process each of the non-interpolated points in the outline. + * To do this, we need to generate two interpolated points (the + * start and end of the arc) for each non-interpolated point. + * The first interpolated point is always the one most recently + * stored in LineBuf, so we just extract it from there. The + * second interpolated point is either the average of the next + * two points in the QSpline, or the last point in the QSpline + * if only one remains. + */ + for (point = 0; point < pointCount - 1; ++point) + { + x0 = LineBuf[LineBufIndex - 2]; + y0 = LineBuf[LineBufIndex - 1]; + + x1 = (FLOAT) GetFixed(pp); + y1 = (FLOAT) GetFixed(pp); + + if (point == pointCount - 2) + { + /* + * This is the last arc in the QSpline. The final + * point is the end of the arc. + */ + x2 = (FLOAT) GetFixed(pp); + y2 = (FLOAT) GetFixed(pp); + } + else + { + /* + * Peek at the next point in the input to compute + * the end of the arc: + */ + x2 = 0.5F * (x1 + (FLOAT) GetFixed(pp)); + y2 = 0.5F * (y1 + (FLOAT) GetFixed(pp)); + /* + * Push the point back onto the input so it will + * be reused as the next off-curve point: + */ + *pp -= 8; + } + + if (!MakeLinesFromArc( x0, y0, + x1, y1, + x2, y2, + vertexCountIndex, + chordalDeviation * chordalDeviation)) + return 0; + } + + return 1; + } + + + +/***************************************************************************** + * MakeLinesFromArc + * + * Subdivides one arc of a quadratic spline until the chordal deviation + * tolerance requirement is met, then places the resulting set of line + * segments in the global LineBuf. + *****************************************************************************/ + +static int +MakeLinesFromArc( IN FLOAT x0, + IN FLOAT y0, + IN FLOAT x1, + IN FLOAT y1, + IN FLOAT x2, + IN FLOAT y2, + IN DWORD vertexCountIndex, + IN FLOAT chordalDeviationSquared) + { + FLOAT x01; + FLOAT y01; + FLOAT x12; + FLOAT y12; + FLOAT midPointX; + FLOAT midPointY; + FLOAT deltaX; + FLOAT deltaY; + + /* + * Calculate midpoint of the curve by de Casteljau: + */ + x01 = 0.5F * (x0 + x1); + y01 = 0.5F * (y0 + y1); + x12 = 0.5F * (x1 + x2); + y12 = 0.5F * (y1 + y2); + midPointX = 0.5F * (x01 + x12); + midPointY = 0.5F * (y01 + y12); + + + /* + * Estimate chordal deviation by the distance from the midpoint + * of the curve to its non-interpolated control point. If this + * distance is greater than the specified chordal deviation + * constraint, then subdivide. Otherwise, generate polylines + * from the three control points. + */ + deltaX = midPointX - x1; + deltaY = midPointY - y1; + if (deltaX * deltaX + deltaY * deltaY > chordalDeviationSquared) + { + MakeLinesFromArc( x0, y0, + x01, y01, + midPointX, midPointY, + vertexCountIndex, + chordalDeviationSquared); + + MakeLinesFromArc( midPointX, midPointY, + x12, y12, + x2, y2, + vertexCountIndex, + chordalDeviationSquared); + } + else + { + /* + * The "pen" is already at (x0, y0), so we don't need to + * add that point to the LineBuf. + */ + if (!AppendToLineBuf(x1) + || !AppendToLineBuf(y1) + || !AppendToLineBuf(x2) + || !AppendToLineBuf(y2)) + return 0; + LineBuf[vertexCountIndex] += 2.0F; + } + + return 1; + } + + + +/***************************************************************************** + * InitLineBuf + * + * Initializes the global LineBuf and its associated size and current-element + * counters. + *****************************************************************************/ + +static int +InitLineBuf(void) + { + if (!(LineBuf = (FLOAT*) + __wglMalloc((LineBufSize = LINE_BUF_QUANT) * sizeof(FLOAT)))) + return 0; + LineBufIndex = 0; + return 1; + } + + + +/***************************************************************************** + * InitVertBuf + * + * Initializes the global VertBuf and its associated size and current-element + * counters. + *****************************************************************************/ + +static int +InitVertBuf(void) + { + if (!(VertBuf = (FLOAT*) + __wglMalloc((VertBufSize = VERT_BUF_QUANT) * sizeof(FLOAT)))) + return 0; + VertBufIndex = 0; + return 1; + } + + + +/***************************************************************************** + * AppendToLineBuf + * + * Appends one floating-point value to the global LineBuf array. Return value + * is non-zero for success, zero for failure. + *****************************************************************************/ + +static int +AppendToLineBuf(FLOAT value) + { + if (LineBufIndex >= LineBufSize) + { + FLOAT* f; + + f = (FLOAT*) __wglRealloc(LineBuf, + (LineBufSize += LINE_BUF_QUANT) * sizeof(FLOAT)); + if (!f) + return 0; + LineBuf = f; + } + LineBuf[LineBufIndex++] = value; + return 1; + } + + + +/***************************************************************************** + * AppendToVertBuf + * + * Appends one floating-point value to the global VertBuf array. Return value + * is non-zero for success, zero for failure. + * + * Note that we can't realloc this one, because the tessellator is using + * pointers into it. + *****************************************************************************/ + +static int +AppendToVertBuf(FLOAT value) + { + if (VertBufIndex >= VertBufSize) + return 0; + VertBuf[VertBufIndex++] = value; + return 1; + } + + + +/***************************************************************************** + * FreeLineBuf + * + * Cleans up vertex buffer structure. + *****************************************************************************/ + +static void +FreeLineBuf(void) + { + if (LineBuf) + { + __wglFree(LineBuf); + LineBuf = NULL; + } + } + + + +/***************************************************************************** + * FreeVertBuf + * + * Cleans up vertex buffer structure. + *****************************************************************************/ + +static void +FreeVertBuf(void) + { + if (VertBuf) + { + __wglFree(VertBuf); + VertBuf = NULL; + } + } + + + +/***************************************************************************** + * GetWord + * + * Fetch the next 16-bit word from a little-endian byte stream, and increment + * the stream pointer to the next unscanned byte. + *****************************************************************************/ + +static long GetWord(UCHAR** p) + { + long value; + + value = ((*p)[1] << 8) + (*p)[0]; + *p += 2; + return value; + } + + + +/***************************************************************************** + * GetDWord + * + * Fetch the next 32-bit word from a little-endian byte stream, and increment + * the stream pointer to the next unscanned byte. + *****************************************************************************/ + +static long GetDWord(UCHAR** p) + { + long value; + + value = ((*p)[3] << 24) + ((*p)[2] << 16) + ((*p)[1] << 8) + (*p)[0]; + *p += 4; + return value; + } + + + + +/***************************************************************************** + * GetFixed + * + * Fetch the next 32-bit fixed-point value from a little-endian byte stream, + * convert it to floating-point, and increment the stream pointer to the next + * unscanned byte. + *****************************************************************************/ + +static double GetFixed( + UCHAR** p) +{ + long hiBits, loBits; + double value; + + loBits = GetWord(p); + hiBits = GetWord(p); + value = (double) ((hiBits << 16) | loBits) / 65536.0; + + return value * ScaleFactor; +} + +// *********************************************************************** + diff --git a/src/mesa/drivers/windows/gldirect/dglwgl.h b/src/mesa/drivers/windows/gldirect/dglwgl.h new file mode 100644 index 0000000..c488ff9 --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/dglwgl.h @@ -0,0 +1,102 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: OpenGL window functions (wgl*). +* +****************************************************************************/ + +#ifndef __DGLWGL_H +#define __DGLWGL_H + +// Disable compiler complaints about DLL linkage +#pragma warning (disable:4273) + +// Macros to control compilation +#define STRICT +#define WIN32_LEAN_AND_MEAN + +#include +#include + +#include "dglcontext.h" +#include "dglglobals.h" +#include "dglmacros.h" +#include "ddlog.h" +#include "dglpf.h" + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef struct { + PROC proc; + char *name; +} DGL_extension; + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _USE_GLD3_WGL +int APIENTRY DGL_ChoosePixelFormat(HDC a, CONST PIXELFORMATDESCRIPTOR *ppfd); +BOOL APIENTRY DGL_CopyContext(HGLRC a, HGLRC b, UINT c); +HGLRC APIENTRY DGL_CreateContext(HDC a); +HGLRC APIENTRY DGL_CreateLayerContext(HDC a, int b); +BOOL APIENTRY DGL_DeleteContext(HGLRC a); +BOOL APIENTRY DGL_DescribeLayerPlane(HDC a, int b, int c, UINT d, LPLAYERPLANEDESCRIPTOR e); +int APIENTRY DGL_DescribePixelFormat(HDC a, int b, UINT c, LPPIXELFORMATDESCRIPTOR d); +HGLRC APIENTRY DGL_GetCurrentContext(void); +HDC APIENTRY DGL_GetCurrentDC(void); +PROC APIENTRY DGL_GetDefaultProcAddress(LPCSTR a); +int APIENTRY DGL_GetLayerPaletteEntries(HDC a, int b, int c, int d, COLORREF *e); +int APIENTRY DGL_GetPixelFormat(HDC a); +PROC APIENTRY DGL_GetProcAddress(LPCSTR a); +BOOL APIENTRY DGL_MakeCurrent(HDC a, HGLRC b); +BOOL APIENTRY DGL_RealizeLayerPalette(HDC a, int b, BOOL c); +int APIENTRY DGL_SetLayerPaletteEntries(HDC a, int b, int c, int d, CONST COLORREF *e); +BOOL APIENTRY DGL_SetPixelFormat(HDC a, int b, CONST PIXELFORMATDESCRIPTOR *c); +BOOL APIENTRY DGL_ShareLists(HGLRC a, HGLRC b); +BOOL APIENTRY DGL_SwapBuffers(HDC a); +BOOL APIENTRY DGL_SwapLayerBuffers(HDC a, UINT b); +BOOL APIENTRY DGL_UseFontBitmapsA(HDC a, DWORD b, DWORD c, DWORD d); +BOOL APIENTRY DGL_UseFontBitmapsW(HDC a, DWORD b, DWORD c, DWORD d); +BOOL APIENTRY DGL_UseFontOutlinesA(HDC a, DWORD b, DWORD c, DWORD d, FLOAT e, FLOAT f, int g, LPGLYPHMETRICSFLOAT h); +BOOL APIENTRY DGL_UseFontOutlinesW(HDC a, DWORD b, DWORD c, DWORD d, FLOAT e, FLOAT f, int g, LPGLYPHMETRICSFLOAT h); +#endif //_USE_GLD3_WGL + +BOOL dglWglResizeBuffers(GLcontext *ctx, BOOL bDefaultDriver); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mesa/drivers/windows/gldirect/dll_main.c b/src/mesa/drivers/windows/gldirect/dll_main.c new file mode 100644 index 0000000..04f6466 --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/dll_main.c @@ -0,0 +1,816 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Win32 DllMain functions. +* +****************************************************************************/ + +// INITGUID must only be defined once. +// Don't put it in a shared header file! +// GLD3 uses dxguid.lib, so INITGUID must *not* be used! +#ifndef _USE_GLD3_WGL +#define INITGUID +#endif // _USE_GLD3_WGL + +#include "dllmain.h" + +#include "snap/graphics.h" +#include "drvlib/os/os.h" + +#ifdef _USE_GLD3_WGL +typedef void (APIENTRY *LPDGLSPLASHSCREEN)(int, int, char*); +#include "gld_driver.h" +#endif + +// *********************************************************************** + +BOOL bInitialized = FALSE; // callback driver initialized? +BOOL bExited = FALSE; // callback driver exited this instance? +HINSTANCE hInstanceDll = NULL; // DLL instance handle + +static BOOL bDriverValidated = FALSE; // prior validation status +static BOOL bSplashScreen = TRUE; // Splash Screen ? +static BOOL bValidINIFound = FALSE; // Have we found a valid INI file? + +HHOOK hKeyHook = NULL; // global keyboard handler hook + +// Multi-threaded support needs to be reflected in Mesa code. (DaveM) +int _gld_bMultiThreaded = FALSE; + +// *********************************************************************** + +DWORD dwLogging = 0; // Logging flag +DWORD dwDebugLevel = 0; // Log debug level + +char szLogPath[_MAX_PATH] = {"\0"}; // Log file path +char szSNAPPath[_MAX_PATH] = {"\0"}; // SNAP driver path + +#ifndef _USE_GLD3_WGL +DGL_wglFuncs wglFuncs = { + sizeof(DGL_wglFuncs), + DGL_ChoosePixelFormat, + DGL_CopyContext, + DGL_CreateContext, + DGL_CreateLayerContext, + DGL_DeleteContext, + DGL_DescribeLayerPlane, + DGL_DescribePixelFormat, + DGL_GetCurrentContext, + DGL_GetCurrentDC, + DGL_GetDefaultProcAddress, + DGL_GetLayerPaletteEntries, + DGL_GetPixelFormat, + DGL_GetProcAddress, + DGL_MakeCurrent, + DGL_RealizeLayerPalette, + DGL_SetLayerPaletteEntries, + DGL_SetPixelFormat, + DGL_ShareLists, + DGL_SwapBuffers, + DGL_SwapLayerBuffers, + DGL_UseFontBitmapsA, + DGL_UseFontBitmapsW, + DGL_UseFontOutlinesA, + DGL_UseFontOutlinesW, +}; + +DGL_mesaFuncs mesaFuncs = { + sizeof(DGL_mesaFuncs), +}; +#endif // _USE_GLD3_WGL + +// *********************************************************************** + +typedef struct { + DWORD dwDriver; // 0=SciTech SW, 1=Direct3D SW, 2=Direct3D HW + BOOL bMipmapping; // 0=off, 1=on + BOOL bMultitexture; // 0=off, 1=on + BOOL bWaitForRetrace; // 0=off, 1=on + BOOL bFullscreenBlit; // 0=off, 1=on + BOOL bFastFPU; // 0=off, 1=on + BOOL bDirectDrawPersistant;// 0=off, 1=on + BOOL bPersistantBuffers; // 0=off, 1=on + DWORD dwLogging; // 0=off, 1=normal, 2=crash-proof + DWORD dwLoggingSeverity; // 0=all, 1=warnings+errors, 2=errors only + BOOL bMessageBoxWarnings;// 0=off, 1=on + BOOL bMultiThreaded; // 0=off, 1=on + BOOL bAppCustomizations; // 0=off, 1=on + BOOL bHotKeySupport; // 0=off, 1=on + BOOL bSplashScreen; // 0=off, 1=on + +#ifdef _USE_GLD3_WGL + // + // New for GLDirect 3.0 + // + DWORD dwAdapter; // DX8 adpater ordinal + DWORD dwTnL; // Transform & Lighting type + DWORD dwMultisample; // DX8 multisample type +#endif // _USE_GLD3_WGL +} INI_settings; + +static INI_settings ini; + +// *********************************************************************** + +BOOL APIENTRY DGL_initDriver( +#ifdef _USE_GLD3_WGL + void) +{ +#else + DGL_wglFuncs *lpWglFuncs, + DGL_mesaFuncs *lpMesaFuncs) +{ + // Check for valid pointers + if ((lpWglFuncs == NULL) || (lpMesaFuncs == NULL)) + return FALSE; + + // Check for valid structs + if (lpWglFuncs->dwSize != sizeof(DGL_wglFuncs)) { + return FALSE; + } + + // Check for valid structs + if (lpMesaFuncs->dwSize != sizeof(DGL_mesaFuncs)) { + return FALSE; + } + + // Copy the Mesa functions + memcpy(&mesaFuncs, lpMesaFuncs, sizeof(DGL_mesaFuncs)); + + // Pass back the wgl functions + memcpy(lpWglFuncs, &wglFuncs, sizeof(DGL_wglFuncs)); +#endif // _USE_GLD3_WGL + + // Finally initialize the callback driver + if (!dglInitDriver()) + return FALSE; + + return TRUE; +}; + +// *********************************************************************** + +BOOL ReadINIFile( + HINSTANCE hInstance) +{ + char szModuleFilename[MAX_PATH]; + char szSystemDirectory[MAX_PATH]; + const char szSectionName[] = "Config"; + char szINIFile[MAX_PATH]; + int pos; + + // Now using the DLL module handle. KeithH, 24/May/2000. + // Addendum: GetModuleFileName(NULL, ... returns process filename, + // GetModuleFileName(hModule, ... returns DLL filename, + + // Get the dll path and filename. + GetModuleFileName(hInstance, &szModuleFilename[0], MAX_PATH); // NULL for current process + // Get the System directory. + GetSystemDirectory(&szSystemDirectory[0], MAX_PATH); + + // Test to see if DLL is in system directory. + if (strnicmp(szModuleFilename, szSystemDirectory, strlen(szSystemDirectory))==0) { + // DLL *is* in system directory. + // Return FALSE to indicate that registry keys should be read. + return FALSE; + } + + // Compose filename of INI file + strcpy(szINIFile, szModuleFilename); + pos = strlen(szINIFile); + while (szINIFile[pos] != '\\') { + pos--; + } + szINIFile[pos+1] = '\0'; + // Use run-time DLL path for log file too + strcpy(szLogPath, szINIFile); + szLogPath[pos] = '\0'; + // Complete full INI file path + strcat(szINIFile, "gldirect.ini"); + + // Read settings from private INI file. + // Note that defaults are contained in the calls. + ini.dwDriver = GetPrivateProfileInt(szSectionName, "dwDriver", 2, szINIFile); + ini.bMipmapping = GetPrivateProfileInt(szSectionName, "bMipmapping", 1, szINIFile); + ini.bMultitexture = GetPrivateProfileInt(szSectionName, "bMultitexture", 1, szINIFile); + ini.bWaitForRetrace = GetPrivateProfileInt(szSectionName, "bWaitForRetrace", 0, szINIFile); + ini.bFullscreenBlit = GetPrivateProfileInt(szSectionName, "bFullscreenBlit", 0, szINIFile); + ini.bFastFPU = GetPrivateProfileInt(szSectionName, "bFastFPU", 1, szINIFile); + ini.bDirectDrawPersistant = GetPrivateProfileInt(szSectionName, "bPersistantDisplay", 0, szINIFile); + ini.bPersistantBuffers = GetPrivateProfileInt(szSectionName, "bPersistantResources", 0, szINIFile); + ini.dwLogging = GetPrivateProfileInt(szSectionName, "dwLogging", 0, szINIFile); + ini.dwLoggingSeverity = GetPrivateProfileInt(szSectionName, "dwLoggingSeverity", 0, szINIFile); + ini.bMessageBoxWarnings = GetPrivateProfileInt(szSectionName, "bMessageBoxWarnings", 0, szINIFile); + ini.bMultiThreaded = GetPrivateProfileInt(szSectionName, "bMultiThreaded", 0, szINIFile); + ini.bAppCustomizations = GetPrivateProfileInt(szSectionName, "bAppCustomizations", 1, szINIFile); + ini.bHotKeySupport = GetPrivateProfileInt(szSectionName, "bHotKeySupport", 0, szINIFile); + ini.bSplashScreen = GetPrivateProfileInt(szSectionName, "bSplashScreen", 1, szINIFile); + +#ifdef _USE_GLD3_WGL + // New for GLDirect 3.x + ini.dwAdapter = GetPrivateProfileInt(szSectionName, "dwAdapter", 0, szINIFile); + // dwTnL now defaults to zero (chooses TnL at runtime). KeithH + ini.dwTnL = GetPrivateProfileInt(szSectionName, "dwTnL", 0, szINIFile); + ini.dwMultisample = GetPrivateProfileInt(szSectionName, "dwMultisample", 0, szINIFile); +#endif + + return TRUE; +} + +// *********************************************************************** + +BOOL dllReadRegistry( + HINSTANCE hInstance) +{ + // Read settings from INI file, if available + bValidINIFound = FALSE; + if (ReadINIFile(hInstance)) { + const char *szRendering[3] = { + "SciTech Software Renderer", + "Direct3D MMX Software Renderer", + "Direct3D Hardware Renderer" + }; + // Set globals + glb.bPrimary = 1; + glb.bHardware = (ini.dwDriver == 2) ? 1 : 0; +#ifndef _USE_GLD3_WGL + memset(&glb.ddGuid, 0, sizeof(glb.ddGuid)); + glb.d3dGuid = (ini.dwDriver == 2) ? IID_IDirect3DHALDevice : IID_IDirect3DRGBDevice; +#endif // _USE_GLD3_WGL + strcpy(glb.szDDName, "Primary"); + strcpy(glb.szD3DName, szRendering[ini.dwDriver]); + glb.dwRendering = ini.dwDriver; + glb.bUseMipmaps = ini.bMipmapping; + glb.bMultitexture = ini.bMultitexture; + glb.bWaitForRetrace = ini.bWaitForRetrace; + glb.bFullscreenBlit = ini.bFullscreenBlit; + glb.bFastFPU = ini.bFastFPU; + glb.bDirectDrawPersistant = ini.bDirectDrawPersistant; + glb.bPersistantBuffers = ini.bPersistantBuffers; + dwLogging = ini.dwLogging; + dwDebugLevel = ini.dwLoggingSeverity; + glb.bMessageBoxWarnings = ini.bMessageBoxWarnings; + glb.bMultiThreaded = ini.bMultiThreaded; + glb.bAppCustomizations = ini.bAppCustomizations; + glb.bHotKeySupport = ini.bHotKeySupport; + bSplashScreen = ini.bSplashScreen; +#ifdef _USE_GLD3_WGL + // New for GLDirect 3.x + glb.dwAdapter = ini.dwAdapter; + glb.dwDriver = ini.dwDriver; + glb.dwTnL = ini.dwTnL; + glb.dwMultisample = ini.dwMultisample; +#endif + bValidINIFound = TRUE; + return TRUE; + } + // Read settings from registry + else { + HKEY hReg; + DWORD cbValSize; + DWORD dwType = REG_SZ; // Registry data type for strings + BOOL bRegistryError; + BOOL bSuccess; + +#define REG_READ_DWORD(a, b) \ + cbValSize = sizeof(b); \ + if (ERROR_SUCCESS != RegQueryValueEx( hReg, (a), \ + NULL, NULL, (LPBYTE)&(b), &cbValSize )) \ + bRegistryError = TRUE; + +#define REG_READ_DEVICEID(a, b) \ + cbValSize = MAX_DDDEVICEID_STRING; \ + if(ERROR_SUCCESS != RegQueryValueEx(hReg, (a), 0, &dwType, \ + (LPBYTE)&(b), &cbValSize)) \ + bRegistryError = TRUE; + +#define REG_READ_STRING(a, b) \ + cbValSize = sizeof((b)); \ + if(ERROR_SUCCESS != RegQueryValueEx(hReg, (a), 0, &dwType, \ + (LPBYTE)&(b), &cbValSize)) \ + bRegistryError = TRUE; + + // Read settings from the registry. + + // Open the registry key for the current user if it exists. + bSuccess = (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, + DIRECTGL_REG_SETTINGS_KEY, + 0, + KEY_READ, + &hReg)); + // Otherwise open the registry key for the local machine. + if (!bSuccess) + bSuccess = (ERROR_SUCCESS == RegOpenKeyEx(DIRECTGL_REG_KEY_ROOT, + DIRECTGL_REG_SETTINGS_KEY, + 0, + KEY_READ, + &hReg)); + if (!bSuccess) + return FALSE; + + bRegistryError = FALSE; + + REG_READ_DWORD(DIRECTGL_REG_SETTING_PRIMARY, glb.bPrimary); + REG_READ_DWORD(DIRECTGL_REG_SETTING_D3D_HW, glb.bHardware); +#ifndef _USE_GLD3_WGL + REG_READ_DWORD(DIRECTGL_REG_SETTING_DD_GUID, glb.ddGuid); + REG_READ_DWORD(DIRECTGL_REG_SETTING_D3D_GUID, glb.d3dGuid); +#endif // _USE_GLD3_WGL + REG_READ_DWORD(DIRECTGL_REG_SETTING_LOGGING, dwLogging); + REG_READ_DWORD(DIRECTGL_REG_SETTING_DEBUGLEVEL, dwDebugLevel); + REG_READ_DWORD(DIRECTGL_REG_SETTING_RENDERING, glb.dwRendering); + REG_READ_DWORD(DIRECTGL_REG_SETTING_MULTITEXTURE, glb.bMultitexture); + REG_READ_DWORD(DIRECTGL_REG_SETTING_WAITFORRETRACE, glb.bWaitForRetrace); + REG_READ_DWORD(DIRECTGL_REG_SETTING_FULLSCREENBLIT, glb.bFullscreenBlit); + REG_READ_DWORD(DIRECTGL_REG_SETTING_USEMIPMAPS, glb.bUseMipmaps); + + REG_READ_DEVICEID(DIRECTGL_REG_SETTING_DD_NAME, glb.szDDName); + REG_READ_DEVICEID(DIRECTGL_REG_SETTING_D3D_NAME, glb.szD3DName); + + REG_READ_DWORD(DIRECTGL_REG_SETTING_MSGBOXWARNINGS, glb.bMessageBoxWarnings); + REG_READ_DWORD(DIRECTGL_REG_SETTING_PERSISTDISPLAY, glb.bDirectDrawPersistant); + REG_READ_DWORD(DIRECTGL_REG_SETTING_PERSISTBUFFERS, glb.bPersistantBuffers); + REG_READ_DWORD(DIRECTGL_REG_SETTING_FASTFPU, glb.bFastFPU); + REG_READ_DWORD(DIRECTGL_REG_SETTING_HOTKEYS, glb.bHotKeySupport); + REG_READ_DWORD(DIRECTGL_REG_SETTING_MULTITHREAD, glb.bMultiThreaded); + REG_READ_DWORD(DIRECTGL_REG_SETTING_APPCUSTOM, glb.bAppCustomizations); + REG_READ_DWORD(DIRECTGL_REG_SETTING_SPLASHSCREEN, bSplashScreen); + +#ifdef _USE_GLD3_WGL + // New for GLDirect 3.x + glb.dwDriver = glb.dwRendering; + REG_READ_DWORD(DIRECTGL_REG_SETTING_ADAPTER, glb.dwAdapter); + REG_READ_DWORD(DIRECTGL_REG_SETTING_TNL, glb.dwTnL); + REG_READ_DWORD(DIRECTGL_REG_SETTING_MULTISAMPLE, glb.dwMultisample); +#endif + + RegCloseKey(hReg); + + // Open the global registry key for GLDirect + bSuccess = (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, + DIRECTGL_REG_SETTINGS_KEY, + 0, + KEY_READ, + &hReg)); + if (bSuccess) { + // Read the installation path for GLDirect + REG_READ_STRING("InstallLocation",szLogPath); + RegCloseKey(hReg); + } + + if (bRegistryError || !bSuccess) + return FALSE; + else + return TRUE; + +#undef REG_READ_DWORD +#undef REG_READ_DEVICEID +#undef REG_READ_STRING + } +} + +// *********************************************************************** + +BOOL dllWriteRegistry( + void ) +{ + HKEY hReg; + DWORD dwCreateDisposition, cbValSize; + BOOL bRegistryError = FALSE; + +#define REG_WRITE_DWORD(a, b) \ + cbValSize = sizeof(b); \ + if (ERROR_SUCCESS != RegSetValueEx( hReg, (a), \ + 0, REG_DWORD, (LPBYTE)&(b), cbValSize )) \ + bRegistryError = TRUE; + + if (ERROR_SUCCESS == RegCreateKeyEx( DIRECTGL_REG_KEY_ROOT, DIRECTGL_REG_SETTINGS_KEY, + 0, NULL, 0, KEY_WRITE, NULL, &hReg, + &dwCreateDisposition )) { + RegFlushKey(hReg); // Make sure keys are written to disk + RegCloseKey(hReg); + hReg = NULL; + } + + if (bRegistryError) + return FALSE; + else + return TRUE; + +#undef REG_WRITE_DWORD +} + +// *********************************************************************** + +void dglInitHotKeys(HINSTANCE hInstance) +{ + // Hot-Key support at all? + if (!glb.bHotKeySupport) + return; + + // Install global keyboard interceptor + hKeyHook = SetWindowsHookEx(WH_KEYBOARD, dglKeyProc, hInstance, 0); +} + +// *********************************************************************** + +void dglExitHotKeys(void) +{ + // Hot-Key support at all? + if (!glb.bHotKeySupport) + return; + + // Remove global keyboard interceptor + if (hKeyHook) + UnhookWindowsHookEx(hKeyHook); + hKeyHook = NULL; +} + +// *********************************************************************** + +// Note: This app-customization step must be performed in both the main +// OpenGL32 driver and the callback driver DLLs for multithreading option. +void dglSetAppCustomizations(void) +{ + char szModuleFileName[MAX_PATH]; + int iSize = MAX_PATH; + + // Get the currently loaded EXE filename. + GetModuleFileName(NULL, &szModuleFileName[0], MAX_PATH); // NULL for current process + strupr(szModuleFileName); + iSize = strlen(szModuleFileName); + + // Check for specific EXEs and adjust global settings accordingly + + // NOTE: In GLD3.x "bDirectDrawPersistant" corresponds to IDirect3D8 and + // "bPersistantBuffers" corresponds to IDirect3DDevice8. KeithH + + // Case 1: 3DStudio must be multi-threaded + // Added: Discreet GMAX (3DStudio MAX 4 for gamers. KeithH) + if (strstr(szModuleFileName, "3DSMAX.EXE") + || strstr(szModuleFileName, "3DSVIZ.EXE") + || strstr(szModuleFileName, "GMAX.EXE")) { + glb.bMultiThreaded = TRUE; + glb.bDirectDrawPersistant = FALSE; + glb.bPersistantBuffers = FALSE; + return; + } + + // Case 2: Solid Edge must use pre-allocated resources for all GLRCs + if (strstr(szModuleFileName, "PART.EXE") + || strstr(szModuleFileName, "ASSEMBL.EXE") + || strstr(szModuleFileName, "DRAFT.EXE") + || strstr(szModuleFileName, "SMARTVW.EXE") + || strstr(szModuleFileName, "SMETAL.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = FALSE; + return; + } + + // Case 3: Sudden Depth creates and destroys GLRCs on paint commands + if (strstr(szModuleFileName, "SUDDEPTH.EXE") + || strstr(szModuleFileName, "SUDDEMO.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = TRUE; + glb.bFullscreenBlit = TRUE; + return; + } + + // Case 4: StereoGraphics test apps create and destroy GLRCs on paint commands + if (strstr(szModuleFileName, "REDBLUE.EXE") + || strstr(szModuleFileName, "DIAGNOSE.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = TRUE; + return; + } + + // Case 5: Pipes screen savers share multiple GLRCs for same window + if (strstr(szModuleFileName, "PIPES.SCR") + || (strstr(szModuleFileName, "PIPES") && strstr(szModuleFileName, ".SCR"))) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = TRUE; + return; + } + + // Case 6: AutoVue uses sub-viewport ops which are temporarily broken in stereo window + if (strstr(szModuleFileName, "AVWIN.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = TRUE; + return; + } + // Case 7: Quake3 is waiting for DDraw objects to be released at exit + if (strstr(szModuleFileName, "QUAKE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = FALSE; + glb.bPersistantBuffers = FALSE; + glb.bFullscreenBlit = FALSE; + return; + } + // Case 8: Reflection GLX server is unable to switch contexts at run-time + if (strstr(szModuleFileName, "RX.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bMessageBoxWarnings = FALSE; + return; + } + // Case 9: Original AutoCAD 2000 must share DDraw objects across GLRCs + if (strstr(szModuleFileName, "ACAD.EXE")) { + glb.bFastFPU = FALSE; + if (GetModuleHandle("wopengl6.hdi") != NULL) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = FALSE; + } + return; + } +} + +// *********************************************************************** + +BOOL dglInitDriver(void) +{ + UCHAR szExeName[MAX_PATH]; + const char *szRendering[] = { + "Mesa Software", + "Direct3D RGB SW", + "Direct3D HW", + }; + static ibool bWarnOnce = false; + + // Already initialized? + if (bInitialized) + return TRUE; + + // Moved from DllMain DLL_PROCESS_ATTACH: + + // (Re-)Init defaults + dglInitGlobals(); + + // Read registry or INI file settings + if (!dllReadRegistry(hInstanceDll)) { + if (!bWarnOnce) + MessageBox( NULL, "GLDirect has not been configured.\n\n" + "Please run the configuration program\n" + "before using GLDirect with applications.\n", + "GLDirect", MB_OK | MB_ICONWARNING); + bWarnOnce = true; + return FALSE; + } + +#ifdef _USE_GLD3_WGL + // Must do this as early as possible. + // Need to read regkeys/ini-file first though. + gldInitDriverPointers(glb.dwDriver); + + // Create private driver globals + _gldDriver.CreatePrivateGlobals(); +#endif + // Overide settings with application customizations + if (glb.bAppCustomizations) + dglSetAppCustomizations(); + +//#ifndef _USE_GLD3_WGL + // Set the global memory type to either sysmem or vidmem + glb.dwMemoryType = glb.bHardware ? DDSCAPS_VIDEOMEMORY : DDSCAPS_SYSTEMMEMORY; +//#endif + + // Multi-threaded support overides persistant display support + if (glb.bMultiThreaded) + glb.bDirectDrawPersistant = glb.bPersistantBuffers = FALSE; + + // Multi-threaded support needs to be reflected in Mesa code. (DaveM) + _gld_bMultiThreaded = glb.bMultiThreaded; + + // Start logging + ddlogPathOption(szLogPath); + ddlogWarnOption(glb.bMessageBoxWarnings); + ddlogOpen((DDLOG_loggingMethodType)dwLogging, + (DDLOG_severityType)dwDebugLevel); + + // Obtain the name of the calling app + ddlogMessage(DDLOG_SYSTEM, "Driver : SciTech GLDirect 4.0\n"); + GetModuleFileName(NULL, szExeName, sizeof(szExeName)); + ddlogPrintf(DDLOG_SYSTEM, "Executable : %s", szExeName); + + ddlogPrintf(DDLOG_SYSTEM, "DirectDraw device: %s", glb.szDDName); + ddlogPrintf(DDLOG_SYSTEM, "Direct3D driver : %s", glb.szD3DName); + + ddlogPrintf(DDLOG_SYSTEM, "Rendering type : %s", szRendering[glb.dwRendering]); + + ddlogPrintf(DDLOG_SYSTEM, "Multithreaded : %s", glb.bMultiThreaded ? "Enabled" : "Disabled"); + ddlogPrintf(DDLOG_SYSTEM, "Display resources: %s", glb.bDirectDrawPersistant ? "Persistant" : "Instanced"); + ddlogPrintf(DDLOG_SYSTEM, "Buffer resources : %s", glb.bPersistantBuffers ? "Persistant" : "Instanced"); + + dglInitContextState(); + dglBuildPixelFormatList(); + //dglBuildTextureFormatList(); + + // D3D callback driver is now successfully initialized + bInitialized = TRUE; + // D3D callback driver is now ready to be exited + bExited = FALSE; + + return TRUE; +} + +// *********************************************************************** + +void dglExitDriver(void) +{ + + // Only need to clean up once per instance: + // May be called implicitly from DLL_PROCESS_DETACH, + // or explicitly from DGL_exitDriver(). + if (bExited) + return; + bExited = TRUE; + + // DDraw objects may be invalid when DLL unloads. +__try { + + // Clean-up sequence (moved from DLL_PROCESS_DETACH) +#ifndef _USE_GLD3_WGL + dglReleaseTextureFormatList(); +#endif + dglReleasePixelFormatList(); + dglDeleteContextState(); + +#ifdef _USE_GLD3_WGL + _gldDriver.DestroyPrivateGlobals(); +#endif + +} +__except(EXCEPTION_EXECUTE_HANDLER) { + ddlogPrintf(DDLOG_WARN, "Exception raised in dglExitDriver."); +} + + // Close the log file + ddlogClose(); +} + +// *********************************************************************** + +int WINAPI DllMain( + HINSTANCE hInstance, + DWORD fdwReason, + PVOID pvReserved) +{ + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + // Cache DLL instance handle + hInstanceDll = hInstance; + + // Flag that callback driver has yet to be initialized + bInitialized = bExited = FALSE; + +#ifndef _USE_GLD3_WGL + // Init internal Mesa function pointers + memset(&mesaFuncs, 0, sizeof(DGL_mesaFuncs)); +#endif // _USE_GLD3_WGL + + // Init defaults + dglInitGlobals(); + + // Defer rest of DLL initialization to 1st WGL function call + break; + + case DLL_PROCESS_DETACH: + // Call exit clean-up sequence + dglExitDriver(); + break; + } + + return TRUE; +} + +// *********************************************************************** + +void APIENTRY DGL_exitDriver(void) +{ + // Call exit clean-up sequence + dglExitDriver(); +} + +// *********************************************************************** + +void APIENTRY DGL_reinitDriver(void) +{ + // Force init sequence again + bInitialized = bExited = FALSE; + dglInitDriver(); +} + +// *********************************************************************** + +int WINAPI DllInitialize( + HINSTANCE hInstance, + DWORD fdwReason, + PVOID pvReserved) +{ + // Some Watcom compiled executables require this. + return DllMain(hInstance, fdwReason, pvReserved); +} + +// *********************************************************************** + +void DGL_LoadSplashScreen(int piReg, char* pszUser) +{ + HINSTANCE hSplashDll = NULL; + LPDGLSPLASHSCREEN dglSplashScreen = NULL; + static BOOL bOnce = FALSE; + static int iReg = 0; + static char szUser[255] = {"\0"}; + + // Display splash screen at all? + if (!bSplashScreen) + return; + + // Only display splash screen once + if (bOnce) + return; + bOnce = TRUE; + + // Make local copy of string for passing to DLL + if (pszUser) + strcpy(szUser, pszUser); + iReg = piReg; + + // Load Splash Screen DLL + // (If it fails to load for any reason, we don't care...) + hSplashDll = LoadLibrary("gldsplash.dll"); + if (hSplashDll) { + // Execute the Splash Screen function + dglSplashScreen = (LPDGLSPLASHSCREEN)GetProcAddress(hSplashDll, "GLDSplashScreen"); + if (dglSplashScreen) + (*dglSplashScreen)(1, iReg, szUser); + // Don't unload the DLL since splash screen dialog is modeless now + } +} + +// *********************************************************************** + +BOOL dglValidate() +{ + char *szCaption = "SciTech GLDirect Driver"; + UINT uType = MB_OK | MB_ICONEXCLAMATION; + +#ifdef _USE_GLD3_WGL + // (Re)build pixelformat list + if (glb.bPixelformatsDirty) + _gldDriver.BuildPixelformatList(); +#endif + + // Check to see if we have already validated + if (bDriverValidated && bInitialized) + return TRUE; + + // Since all (most) the WGL functions must be validated at this point, + // this also insure that the callback driver is completely initialized. + if (!bInitialized) + if (!dglInitDriver()) { + MessageBox(NULL, + "The GLDirect driver could not initialize.\n\n" + "Please run the configuration program to\n" + "properly configure the driver, or else\n" + "re-run the installation program.", szCaption, uType); + _exit(1); // Bail + } + + return TRUE; +} + +// *********************************************************************** + diff --git a/src/mesa/drivers/windows/gldirect/dllmain.h b/src/mesa/drivers/windows/gldirect/dllmain.h new file mode 100644 index 0000000..d898c31 --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/dllmain.h @@ -0,0 +1,64 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Win32 DllMain functions. +* +****************************************************************************/ + +#ifndef __DLLMAIN_H +#define __DLLMAIN_H + +// Macros to control compilation +#define STRICT +#define WIN32_LEAN_AND_MEAN + +#include + +#ifndef _USE_GLD3_WGL +#include "DirectGL.h" +#endif // _USE_GLD3_WGL + +#include "gldirect/regkeys.h" +#include "dglglobals.h" +#include "ddlog.h" +#ifndef _USE_GLD3_WGL +#include "d3dtexture.h" +#endif // _USE_GLD3_WGL + +#include "dglwgl.h" + +extern BOOL bInitialized; + +BOOL dglInitDriver(void); +void dglExitDriver(void); + +#endif diff --git a/src/mesa/drivers/windows/gldirect/gld_debug_clip.c b/src/mesa/drivers/windows/gldirect/gld_debug_clip.c new file mode 100644 index 0000000..1eb19ca --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/gld_debug_clip.c @@ -0,0 +1,40 @@ +/* $Id: gld_debug_clip.c,v 1.1 2004/04/20 11:13:11 alanh Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Gareth Hughes + */ + +#ifdef DEBUG /* This code only used for debugging */ + +// Stub to enable Mesa to build. KeithH +#pragma message("NOTE: Using gld_debug_clip.c HACK") + +void _math_test_all_cliptest_functions( char *description ) +{ +} + + +#endif /* DEBUG */ diff --git a/src/mesa/drivers/windows/gldirect/gld_debug_norm.c b/src/mesa/drivers/windows/gldirect/gld_debug_norm.c new file mode 100644 index 0000000..00c428b --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/gld_debug_norm.c @@ -0,0 +1,40 @@ +/* $Id: gld_debug_norm.c,v 1.1 2004/04/20 11:13:11 alanh Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Gareth Hughes + */ + +#ifdef DEBUG /* This code only used for debugging */ + +// Stub to enable Mesa to build. KeithH +#pragma message("NOTE: Using gld_debug_norm.c HACK") + +void _math_test_all_normal_transform_functions( char *description ) +{ +} + + +#endif /* DEBUG */ diff --git a/src/mesa/drivers/windows/gldirect/gld_debug_xform.c b/src/mesa/drivers/windows/gldirect/gld_debug_xform.c new file mode 100644 index 0000000..d6e64b8 --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/gld_debug_xform.c @@ -0,0 +1,42 @@ +/* $Id: gld_debug_xform.c,v 1.1 2004/04/20 11:13:11 alanh Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Updated for P6 architecture by Gareth Hughes. + */ + + +#ifdef DEBUG /* This code only used for debugging */ + +// Stub to enable Mesa to build. KeithH +#pragma message("NOTE: Using gld_debug_xform.c HACK") + +void _math_test_all_transform_functions( char *description ) +{ +} + + +#endif /* DEBUG */ diff --git a/src/mesa/drivers/windows/gldirect/gld_dispatch.c b/src/mesa/drivers/windows/gldirect/gld_dispatch.c new file mode 100644 index 0000000..e05d767 --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/gld_dispatch.c @@ -0,0 +1,73 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Thread-aware dispatch table. +* +****************************************************************************/ + +#include "glheader.h" +#include "glapi.h" +#include "glapitable.h" +#include "mtypes.h" +#include "context.h" + +#define KEYWORD1 +#define KEYWORD2 GLAPIENTRY +#if defined(USE_MGL_NAMESPACE) + #define NAME(func) mgl##func +#else + #define NAME(func) gl##func +#endif + +#if 0 +// Altered these to get the dispatch table from +// the current context of the calling thread. +#define DISPATCH(FUNC, ARGS, MESSAGE) \ + GET_CURRENT_CONTEXT(gc); \ + (gc->CurrentDispatch->FUNC) ARGS +#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ + GET_CURRENT_CONTEXT(gc); \ + return (gc->CurrentDispatch->FUNC) ARGS +#else // #if 0 +#define DISPATCH(FUNC, ARGS, MESSAGE) \ + GET_CURRENT_CONTEXT(gc); \ + (_glapi_Dispatch->FUNC) ARGS +#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ + GET_CURRENT_CONTEXT(gc); \ + return (_glapi_Dispatch->FUNC) ARGS +#endif // #if 0 + +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#include "glapitemp.h" diff --git a/src/mesa/drivers/windows/gldirect/gld_driver.c b/src/mesa/drivers/windows/gldirect/gld_driver.c new file mode 100644 index 0000000..f7c5756 --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/gld_driver.c @@ -0,0 +1,279 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Driver functions and interfaces +* +****************************************************************************/ + +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include + +#include "gld_driver.h" +#include "ddlog.h" +#include "glheader.h" + +// For glGetString(). +#include "common_x86_asm.h" + +//--------------------------------------------------------------------------- + +static char *szDriverError = "Driver used before initialisation!"; + +// This holds our dynamically created OpenGL renderer string. +// 256 chars should be plenty - remember that some apps display this. +static char _gldRendererString[256]; + +static char *szVendor = "SciTech Software, Inc."; + +//--------------------------------------------------------------------------- + +extern BOOL gldGetDXErrorString_DX(HRESULT hr, char *buf, int nBufSize); + +extern BOOL gldCreateDrawable_MesaSW(DGL_ctx *ctx, BOOL bPersistantInterface, BOOL bPersistantBuffers); +extern BOOL gldResizeDrawable_MesaSW(DGL_ctx *ctx, BOOL bDefaultDriver, BOOL bPersistantInterface, BOOL bPersistantBuffers); +extern BOOL gldDestroyDrawable_MesaSW(DGL_ctx *ctx); +extern BOOL gldCreatePrivateGlobals_MesaSW(void); +extern BOOL gldDestroyPrivateGlobals_MesaSW(void); +extern BOOL gldBuildPixelformatList_MesaSW(void); +extern BOOL gldInitialiseMesa_MesaSW(DGL_ctx *ctx); +extern BOOL gldSwapBuffers_MesaSW(DGL_ctx *ctx, HDC hDC, HWND hWnd); +extern PROC gldGetProcAddress_MesaSW(LPCSTR a); +extern BOOL gldGetDisplayMode_MesaSW(DGL_ctx *ctx, GLD_displayMode *glddm); + +extern BOOL gldCreateDrawable_DX(DGL_ctx *ctx, BOOL bPersistantInterface, BOOL bPersistantBuffers); +extern BOOL gldResizeDrawable_DX(DGL_ctx *ctx, BOOL bDefaultDriver, BOOL bPersistantInterface, BOOL bPersistantBuffers); +extern BOOL gldDestroyDrawable_DX(DGL_ctx *ctx); +extern BOOL gldCreatePrivateGlobals_DX(void); +extern BOOL gldDestroyPrivateGlobals_DX(void); +extern BOOL gldBuildPixelformatList_DX(void); +extern BOOL gldInitialiseMesa_DX(DGL_ctx *ctx); +extern BOOL gldSwapBuffers_DX(DGL_ctx *ctx, HDC hDC, HWND hWnd); +extern PROC gldGetProcAddress_DX(LPCSTR a); +extern BOOL gldGetDisplayMode_DX(DGL_ctx *ctx, GLD_displayMode *glddm); + +//--------------------------------------------------------------------------- +// NOP functions. Called if proper driver functions are not set. +//--------------------------------------------------------------------------- + +static BOOL _gldDriverError(void) +{ + ddlogMessage(DDLOG_CRITICAL, szDriverError); + return FALSE; +} + +//--------------------------------------------------------------------------- + +static BOOL _GetDXErrorString_ERROR( + HRESULT hr, + char *buf, + int nBufSize) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _CreateDrawable_ERROR( + DGL_ctx *ctx, + BOOL bPersistantInterface, + BOOL bPersistantBuffers) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _ResizeDrawable_ERROR( + DGL_ctx *ctx, + BOOL bDefaultDriver, + BOOL bPersistantInterface, + BOOL bPersistantBuffers) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _DestroyDrawable_ERROR( + DGL_ctx *ctx) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _CreatePrivateGlobals_ERROR(void) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _DestroyPrivateGlobals_ERROR(void) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _BuildPixelformatList_ERROR(void) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + + +static BOOL _InitialiseMesa_ERROR( + DGL_ctx *ctx) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _SwapBuffers_ERROR( + DGL_ctx *ctx, + HDC hDC, + HWND hWnd) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static PROC _GetProcAddress_ERROR( + LPCSTR a) +{ + _gldDriverError(); + return NULL; +} + +//--------------------------------------------------------------------------- + +static BOOL _GetDisplayMode_ERROR( + DGL_ctx *ctx, + GLD_displayMode *glddm) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- +// Functions useful to all drivers +//--------------------------------------------------------------------------- + +const GLubyte* _gldGetStringGeneric( + GLcontext *ctx, + GLenum name) +{ + if (!ctx) + return NULL; + + switch (name) { + case GL_RENDERER: + sprintf(_gldRendererString, "GLDirect 4.0 %s%s%s%s (%s %s)", + _mesa_x86_cpu_features ? "/x86" : "", + cpu_has_mmx ? "/MMX" : "", + cpu_has_3dnow ? "/3DNow!" : "", + cpu_has_xmm ? "/SSE" : "", + __DATE__, __TIME__); + return (const GLubyte *) _gldRendererString; + case GL_VENDOR: + return (const GLubyte *) szVendor; + default: + return NULL; + } +} + +//--------------------------------------------------------------------------- +// Global driver function pointers, initially set to functions that +// will report an error when called. +//--------------------------------------------------------------------------- + +GLD_driver _gldDriver = { + _GetDXErrorString_ERROR, + _CreateDrawable_ERROR, + _ResizeDrawable_ERROR, + _DestroyDrawable_ERROR, + _CreatePrivateGlobals_ERROR, + _DestroyPrivateGlobals_ERROR, + _BuildPixelformatList_ERROR, + _InitialiseMesa_ERROR, + _SwapBuffers_ERROR, + _GetProcAddress_ERROR, + _GetDisplayMode_ERROR +}; + +//--------------------------------------------------------------------------- +// Init function. Should be called as soon as regkeys/ini-settings are read. +//--------------------------------------------------------------------------- + +BOOL gldInitDriverPointers( + DWORD dwDriver) +{ + _gldDriver.GetDXErrorString = gldGetDXErrorString_DX; + + if (dwDriver == GLDS_DRIVER_MESA_SW) { + // Mesa Software driver + _gldDriver.CreateDrawable = gldCreateDrawable_MesaSW; + _gldDriver.ResizeDrawable = gldResizeDrawable_MesaSW; + _gldDriver.DestroyDrawable = gldDestroyDrawable_MesaSW; + _gldDriver.CreatePrivateGlobals = gldCreatePrivateGlobals_MesaSW; + _gldDriver.DestroyPrivateGlobals = gldDestroyPrivateGlobals_MesaSW; + _gldDriver.BuildPixelformatList = gldBuildPixelformatList_MesaSW; + _gldDriver.InitialiseMesa = gldInitialiseMesa_MesaSW; + _gldDriver.SwapBuffers = gldSwapBuffers_MesaSW; + _gldDriver.wglGetProcAddress = gldGetProcAddress_MesaSW; + _gldDriver.GetDisplayMode = gldGetDisplayMode_MesaSW; + return TRUE; + } + + if ((dwDriver == GLDS_DRIVER_REF) || (dwDriver == GLDS_DRIVER_HAL)) { + // Direct3D driver, either HW or SW + _gldDriver.CreateDrawable = gldCreateDrawable_DX; + _gldDriver.ResizeDrawable = gldResizeDrawable_DX; + _gldDriver.DestroyDrawable = gldDestroyDrawable_DX; + _gldDriver.CreatePrivateGlobals = gldCreatePrivateGlobals_DX; + _gldDriver.DestroyPrivateGlobals = gldDestroyPrivateGlobals_DX; + _gldDriver.BuildPixelformatList = gldBuildPixelformatList_DX; + _gldDriver.InitialiseMesa = gldInitialiseMesa_DX; + _gldDriver.SwapBuffers = gldSwapBuffers_DX; + _gldDriver.wglGetProcAddress = gldGetProcAddress_DX; + _gldDriver.GetDisplayMode = gldGetDisplayMode_DX; + return TRUE; + }; + + return FALSE; +} + +//--------------------------------------------------------------------------- diff --git a/src/mesa/drivers/windows/gldirect/gld_driver.h b/src/mesa/drivers/windows/gldirect/gld_driver.h new file mode 100644 index 0000000..01a46a8 --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/gld_driver.h @@ -0,0 +1,90 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Driver functions and interfaces +* +****************************************************************************/ + +#ifndef _GLD_DRIVER_H +#define _GLD_DRIVER_H + +// This file is only useful is we're using the new GLD3 WGL code. +#ifdef _USE_GLD3_WGL + +#include "dglcontext.h" + +// Same as DX8 D3DDISPLAYMODE +typedef struct { + DWORD Width; + DWORD Height; + DWORD Refresh; + DWORD BPP; +} GLD_displayMode; + +typedef struct { + // Returns a string for a given HRESULT error code. + BOOL (*GetDXErrorString)(HRESULT hr, char *buf, int nBufSize); + + // Driver functions for managing drawables. + // Functions must respect persistant buffers / persistant interface. + // NOTE: Persistant interface is: DirectDraw, pre-DX8; Direct3D, DX8 and above. + BOOL (*CreateDrawable)(DGL_ctx *ctx, BOOL bPersistantInterface, BOOL bPersistantBuffers); + BOOL (*ResizeDrawable)(DGL_ctx *ctx, BOOL bDefaultDriver, BOOL bPersistantInterface, BOOL bPersistantBuffers); + BOOL (*DestroyDrawable)(DGL_ctx *ctx); + + // Create/Destroy private globals belonging to driver + BOOL (*CreatePrivateGlobals)(void); + BOOL (*DestroyPrivateGlobals)(void); + + // Build pixelformat list + BOOL (*BuildPixelformatList)(void); + + // Initialise Mesa's driver pointers + BOOL (*InitialiseMesa)(DGL_ctx *ctx); + + // Swap buffers + BOOL (*SwapBuffers)(DGL_ctx *ctx, HDC hDC, HWND hWnd); + + // wglGetProcAddress() + PROC (*wglGetProcAddress)(LPCSTR a); + + BOOL (*GetDisplayMode)(DGL_ctx *ctx, GLD_displayMode *glddm); +} GLD_driver; + +extern GLD_driver _gldDriver; + +BOOL gldInitDriverPointers(DWORD dwDriver); +const GLubyte* _gldGetStringGeneric(GLcontext *ctx, GLenum name); + +#endif // _USE_GLD3_WGL + +#endif // _GLD_DRIVER_H diff --git a/src/mesa/drivers/windows/gldirect/gldlame8.c b/src/mesa/drivers/windows/gldirect/gldlame8.c new file mode 100644 index 0000000..5ac519c --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/gldlame8.c @@ -0,0 +1,181 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: GLDirect utility for determining lame boards/drivers. +* +****************************************************************************/ + +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include + +/* +Ack. Broken out from gldlame.c because of broken D3D headers. KeithH +*/ + +/**************************************************************************** +REMARKS: +Scans list of DirectDraw devices for specific device IDs. +****************************************************************************/ + +#define VENDORID_ATI 0x1002 + +static DWORD devATIRagePro[] = { + 0x4742, // 3D RAGE PRO BGA AGP 1X/2X + 0x4744, // 3D RAGE PRO BGA AGP 1X only + 0x4749, // 3D RAGE PRO BGA PCI 33 MHz + 0x4750, // 3D RAGE PRO PQFP PCI 33 MHz + 0x4751, // 3D RAGE PRO PQFP PCI 33 MHz limited 3D + 0x4C42, // 3D RAGE LT PRO BGA-312 AGP 133 MHz + 0x4C44, // 3D RAGE LT PRO BGA-312 AGP 66 MHz + 0x4C49, // 3D RAGE LT PRO BGA-312 PCI 33 MHz + 0x4C50, // 3D RAGE LT PRO BGA-256 PCI 33 MHz + 0x4C51, // 3D RAGE LT PRO BGA-256 PCI 33 MHz limited 3D +}; + +static DWORD devATIRageIIplus[] = { + 0x4755, // 3D RAGE II+ + 0x4756, // 3D RAGE IIC PQFP PCI + 0x4757, // 3D RAGE IIC BGA AGP + 0x475A, // 3D RAGE IIC PQFP AGP + 0x4C47, // 3D RAGE LT-G +}; + +static __inline BOOL IsDevice( + DWORD *lpDeviceIdList, + DWORD dwDeviceId, + int count) +{ + int i; + + for (i=0; i 1 ) && + (d3dCaps.MaxSimultaneousTextures > 1 ) && + (d3dCaps.TextureOpCaps & D3DTEXOPCAPS_MODULATE )) ) + return TRUE; + + return FALSE; // Not lame +} diff --git a/src/mesa/drivers/windows/gldirect/opengl32.def b/src/mesa/drivers/windows/gldirect/opengl32.def new file mode 100644 index 0000000..b213b6e --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/opengl32.def @@ -0,0 +1,488 @@ +;**************************************************************************** +;* +;* Mesa 3-D graphics library +;* Direct3D Driver Interface +;* +;* ======================================================================== +;* +;* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +;* +;* Permission is hereby granted, free of charge, to any person obtaining a +;* copy of this software and associated documentation files (the "Software"), +;* to deal in the Software without restriction, including without limitation +;* the rights to use, copy, modify, merge, publish, distribute, sublicense, +;* and/or sell copies of the Software, and to permit persons to whom the +;* Software is furnished to do so, subject to the following conditions: +;* +;* The above copyright notice and this permission notice shall be included +;* in all copies or substantial portions of the Software. +;* +;* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +;* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;* SOFTWARE. +;* +;* ====================================================================== +;* +;* Language: ANSI C +;* Environment: Windows 9x/2000/XP/XBox (Win32) +;* +;* Description: DLL Module definition file +;* +;****************************************************************************/ + +DESCRIPTION 'GLDirect' + +VERSION 3.0 + +EXPORTS + glAccum=glAccum @1 + glAlphaFunc=glAlphaFunc @2 + glAreTexturesResident=glAreTexturesResident @3 + glArrayElement=glArrayElement @4 + glBegin=glBegin @5 + glBindTexture=glBindTexture @6 + glBitmap=glBitmap @7 + glBlendFunc=glBlendFunc @8 + glCallList=glCallList @9 + glCallLists=glCallLists @10 + glClear=glClear @11 + glClearAccum=glClearAccum @12 + glClearIndex=glClearIndex @13 + glClearColor=glClearColor @14 + glClearDepth=glClearDepth @15 + glClearStencil=glClearStencil @16 + glClipPlane=glClipPlane @17 + glColor3b=glColor3b @18 + glColor3d=glColor3d @19 + glColor3f=glColor3f @20 + glColor3i=glColor3i @21 + glColor3s=glColor3s @22 + glColor3ub=glColor3ub @23 + glColor3ui=glColor3ui @24 + glColor3us=glColor3us @25 + glColor4b=glColor4b @26 + glColor4d=glColor4d @27 + glColor4f=glColor4f @28 + glColor4i=glColor4i @29 + glColor4s=glColor4s @30 + glColor4ub=glColor4ub @31 + glColor4ui=glColor4ui @32 + glColor4us=glColor4us @33 + glColor3bv=glColor3bv @34 + glColor3dv=glColor3dv @35 + glColor3fv=glColor3fv @36 + glColor3iv=glColor3iv @37 + glColor3sv=glColor3sv @38 + glColor3ubv=glColor3ubv @39 + glColor3uiv=glColor3uiv @40 + glColor3usv=glColor3usv @41 + glColor4bv=glColor4bv @42 + glColor4dv=glColor4dv @43 + glColor4fv=glColor4fv @44 + glColor4iv=glColor4iv @45 + glColor4sv=glColor4sv @46 + glColor4ubv=glColor4ubv @47 + glColor4uiv=glColor4uiv @48 + glColor4usv=glColor4usv @49 + glColorMask=glColorMask @50 + glColorMaterial=glColorMaterial @51 + glColorPointer=glColorPointer @52 + glColorTableEXT=glColorTableEXT @53 + glColorSubTableEXT=glColorSubTableEXT @54 + glCopyPixels=glCopyPixels @55 + glCopyTexImage1D=glCopyTexImage1D @56 + glCopyTexImage2D=glCopyTexImage2D @57 + glCopyTexSubImage1D=glCopyTexSubImage1D @58 + glCopyTexSubImage2D=glCopyTexSubImage2D @59 + glCullFace=glCullFace @60 + glDepthFunc=glDepthFunc @61 + glDepthMask=glDepthMask @62 + glDepthRange=glDepthRange @63 + glDeleteLists=glDeleteLists @64 + glDeleteTextures=glDeleteTextures @65 + glDisable=glDisable @66 + glDisableClientState=glDisableClientState @67 + glDrawArrays=glDrawArrays @68 + glDrawBuffer=glDrawBuffer @69 + glDrawElements=glDrawElements @70 + glDrawPixels=glDrawPixels @71 + glEnable=glEnable @72 + glEnableClientState=glEnableClientState @73 + glEnd=glEnd @74 + glEndList=glEndList @75 + glEvalCoord1d=glEvalCoord1d @76 + glEvalCoord1f=glEvalCoord1f @77 + glEvalCoord1dv=glEvalCoord1dv @78 + glEvalCoord1fv=glEvalCoord1fv @79 + glEvalCoord2d=glEvalCoord2d @80 + glEvalCoord2f=glEvalCoord2f @81 + glEvalCoord2dv=glEvalCoord2dv @82 + glEvalCoord2fv=glEvalCoord2fv @83 + glEvalPoint1=glEvalPoint1 @84 + glEvalPoint2=glEvalPoint2 @85 + glEvalMesh1=glEvalMesh1 @86 + glEdgeFlag=glEdgeFlag @87 + glEdgeFlagv=glEdgeFlagv @88 + glEdgeFlagPointer=glEdgeFlagPointer @89 + glEvalMesh2=glEvalMesh2 @90 + glFeedbackBuffer=glFeedbackBuffer @91 + glFinish=glFinish @92 + glFlush=glFlush @93 + glFogf=glFogf @94 + glFogi=glFogi @95 + glFogfv=glFogfv @96 + glFogiv=glFogiv @97 + glFrontFace=glFrontFace @98 + glFrustum=glFrustum @99 + glGenLists=glGenLists @100 + glGenTextures=glGenTextures @101 + glGetBooleanv=glGetBooleanv @102 + glGetClipPlane=glGetClipPlane @103 + glGetColorTableEXT=glGetColorTableEXT @104 + glGetColorTableParameterivEXT=glGetColorTableParameterivEXT @105 + glGetColorTableParameterfvEXT=glGetColorTableParameterfvEXT @106 + glGetDoublev=glGetDoublev @107 + glGetError=glGetError @108 + glGetFloatv=glGetFloatv @109 + glGetIntegerv=glGetIntegerv @110 + glGetLightfv=glGetLightfv @111 + glGetLightiv=glGetLightiv @112 + glGetMapdv=glGetMapdv @113 + glGetMapfv=glGetMapfv @114 + glGetMapiv=glGetMapiv @115 + glGetMaterialfv=glGetMaterialfv @116 + glGetMaterialiv=glGetMaterialiv @117 + glGetPixelMapfv=glGetPixelMapfv @118 + glGetPixelMapuiv=glGetPixelMapuiv @119 + glGetPixelMapusv=glGetPixelMapusv @120 + glGetPointerv=glGetPointerv @121 + glGetPolygonStipple=glGetPolygonStipple @122 + glGetString=glGetString @123 + glGetTexEnvfv=glGetTexEnvfv @124 + glGetTexEnviv=glGetTexEnviv @125 + glGetTexGeniv=glGetTexGeniv @126 + glGetTexGendv=glGetTexGendv @127 + glGetTexGenfv=glGetTexGenfv @128 + glGetTexImage=glGetTexImage @129 + glGetTexLevelParameterfv=glGetTexLevelParameterfv @130 + glGetTexLevelParameteriv=glGetTexLevelParameteriv @131 + glGetTexParameterfv=glGetTexParameterfv @132 + glGetTexParameteriv=glGetTexParameteriv @133 + glHint=glHint @134 + glIndexd=glIndexd @135 + glIndexf=glIndexf @136 + glIndexi=glIndexi @137 + glIndexs=glIndexs @138 + glIndexub=glIndexub @139 + glIndexdv=glIndexdv @140 + glIndexfv=glIndexfv @141 + glIndexiv=glIndexiv @142 + glIndexsv=glIndexsv @143 + glIndexubv=glIndexubv @144 + glIndexMask=glIndexMask @145 + glIndexPointer=glIndexPointer @146 + glInterleavedArrays=glInterleavedArrays @147 + glInitNames=glInitNames @148 + glIsList=glIsList @149 + glIsTexture=glIsTexture @150 + glLightf=glLightf @151 + glLighti=glLighti @152 + glLightfv=glLightfv @153 + glLightiv=glLightiv @154 + glLightModelf=glLightModelf @155 + glLightModeli=glLightModeli @156 + glLightModelfv=glLightModelfv @157 + glLightModeliv=glLightModeliv @158 + glLineWidth=glLineWidth @159 + glLineStipple=glLineStipple @160 + glListBase=glListBase @161 + glLoadIdentity=glLoadIdentity @162 + glLoadMatrixd=glLoadMatrixd @163 + glLoadMatrixf=glLoadMatrixf @164 + glLoadName=glLoadName @165 + glLogicOp=glLogicOp @166 + glMap1d=glMap1d @167 + glMap1f=glMap1f @168 + glMap2d=glMap2d @169 + glMap2f=glMap2f @170 + glMapGrid1d=glMapGrid1d @171 + glMapGrid1f=glMapGrid1f @172 + glMapGrid2d=glMapGrid2d @173 + glMapGrid2f=glMapGrid2f @174 + glMaterialf=glMaterialf @175 + glMateriali=glMateriali @176 + glMaterialfv=glMaterialfv @177 + glMaterialiv=glMaterialiv @178 + glMatrixMode=glMatrixMode @179 + glMultMatrixd=glMultMatrixd @180 + glMultMatrixf=glMultMatrixf @181 + glNewList=glNewList @182 + glNormal3b=glNormal3b @183 + glNormal3d=glNormal3d @184 + glNormal3f=glNormal3f @185 + glNormal3i=glNormal3i @186 + glNormal3s=glNormal3s @187 + glNormal3bv=glNormal3bv @188 + glNormal3dv=glNormal3dv @189 + glNormal3fv=glNormal3fv @190 + glNormal3iv=glNormal3iv @191 + glNormal3sv=glNormal3sv @192 + glNormalPointer=glNormalPointer @193 + glOrtho=glOrtho @194 + glPassThrough=glPassThrough @195 + glPixelMapfv=glPixelMapfv @196 + glPixelMapuiv=glPixelMapuiv @197 + glPixelMapusv=glPixelMapusv @198 + glPixelStoref=glPixelStoref @199 + glPixelStorei=glPixelStorei @200 + glPixelTransferf=glPixelTransferf @201 + glPixelTransferi=glPixelTransferi @202 + glPixelZoom=glPixelZoom @203 + glPointSize=glPointSize @204 + glPolygonMode=glPolygonMode @205 + glPolygonOffset=glPolygonOffset @206 + glPolygonOffsetEXT=glPolygonOffsetEXT @207 + glPolygonStipple=glPolygonStipple @208 + glPopAttrib=glPopAttrib @209 + glPopClientAttrib=glPopClientAttrib @210 + glPopMatrix=glPopMatrix @211 + glPopName=glPopName @212 + glPrioritizeTextures=glPrioritizeTextures @213 + glPushMatrix=glPushMatrix @214 + glRasterPos2d=glRasterPos2d @215 + glRasterPos2f=glRasterPos2f @216 + glRasterPos2i=glRasterPos2i @217 + glRasterPos2s=glRasterPos2s @218 + glRasterPos3d=glRasterPos3d @219 + glRasterPos3f=glRasterPos3f @220 + glRasterPos3i=glRasterPos3i @221 + glRasterPos3s=glRasterPos3s @222 + glRasterPos4d=glRasterPos4d @223 + glRasterPos4f=glRasterPos4f @224 + glRasterPos4i=glRasterPos4i @225 + glRasterPos4s=glRasterPos4s @226 + glRasterPos2dv=glRasterPos2dv @227 + glRasterPos2fv=glRasterPos2fv @228 + glRasterPos2iv=glRasterPos2iv @229 + glRasterPos2sv=glRasterPos2sv @230 + glRasterPos3dv=glRasterPos3dv @231 + glRasterPos3fv=glRasterPos3fv @232 + glRasterPos3iv=glRasterPos3iv @233 + glRasterPos3sv=glRasterPos3sv @234 + glRasterPos4dv=glRasterPos4dv @235 + glRasterPos4fv=glRasterPos4fv @236 + glRasterPos4iv=glRasterPos4iv @237 + glRasterPos4sv=glRasterPos4sv @238 + glReadBuffer=glReadBuffer @239 + glReadPixels=glReadPixels @240 + glRectd=glRectd @241 + glRectf=glRectf @242 + glRecti=glRecti @243 + glRects=glRects @244 + glRectdv=glRectdv @245 + glRectfv=glRectfv @246 + glRectiv=glRectiv @247 + glRectsv=glRectsv @248 + glScissor=glScissor @249 + glIsEnabled=glIsEnabled @250 + glPushAttrib=glPushAttrib @251 + glPushClientAttrib=glPushClientAttrib @252 + glPushName=glPushName @253 + glRenderMode=glRenderMode @254 + glRotated=glRotated @255 + glRotatef=glRotatef @256 + glSelectBuffer=glSelectBuffer @257 + glScaled=glScaled @258 + glScalef=glScalef @259 + glShadeModel=glShadeModel @260 + glStencilFunc=glStencilFunc @261 + glStencilMask=glStencilMask @262 + glStencilOp=glStencilOp @263 + glTexCoord1d=glTexCoord1d @264 + glTexCoord1f=glTexCoord1f @265 + glTexCoord1i=glTexCoord1i @266 + glTexCoord1s=glTexCoord1s @267 + glTexCoord2d=glTexCoord2d @268 + glTexCoord2f=glTexCoord2f @269 + glTexCoord2i=glTexCoord2i @270 + glTexCoord2s=glTexCoord2s @271 + glTexCoord3d=glTexCoord3d @272 + glTexCoord3f=glTexCoord3f @273 + glTexCoord3i=glTexCoord3i @274 + glTexCoord3s=glTexCoord3s @275 + glTexCoord4d=glTexCoord4d @276 + glTexCoord4f=glTexCoord4f @277 + glTexCoord4i=glTexCoord4i @278 + glTexCoord4s=glTexCoord4s @279 + glTexCoord1dv=glTexCoord1dv @280 + glTexCoord1fv=glTexCoord1fv @281 + glTexCoord1iv=glTexCoord1iv @282 + glTexCoord1sv=glTexCoord1sv @283 + glTexCoord2dv=glTexCoord2dv @284 + glTexCoord2fv=glTexCoord2fv @285 + glTexCoord2iv=glTexCoord2iv @286 + glTexCoord2sv=glTexCoord2sv @287 + glTexCoord3dv=glTexCoord3dv @288 + glTexCoord3fv=glTexCoord3fv @289 + glTexCoord3iv=glTexCoord3iv @290 + glTexCoord3sv=glTexCoord3sv @291 + glTexCoord4dv=glTexCoord4dv @292 + glTexCoord4fv=glTexCoord4fv @293 + glTexCoord4iv=glTexCoord4iv @294 + glTexCoord4sv=glTexCoord4sv @295 + glTexCoordPointer=glTexCoordPointer @296 + glTexGend=glTexGend @297 + glTexGenf=glTexGenf @298 + glTexGeni=glTexGeni @299 + glTexGendv=glTexGendv @300 + glTexGeniv=glTexGeniv @301 + glTexGenfv=glTexGenfv @302 + glTexEnvf=glTexEnvf @303 + glTexEnvi=glTexEnvi @304 + glTexEnvfv=glTexEnvfv @305 + glTexEnviv=glTexEnviv @306 + glTexImage1D=glTexImage1D @307 + glTexImage2D=glTexImage2D @308 + glTexParameterf=glTexParameterf @309 + glTexParameteri=glTexParameteri @310 + glTexParameterfv=glTexParameterfv @311 + glTexParameteriv=glTexParameteriv @312 + glTexSubImage1D=glTexSubImage1D @313 + glTexSubImage2D=glTexSubImage2D @314 + glTranslated=glTranslated @315 + glTranslatef=glTranslatef @316 + glVertex2d=glVertex2d @317 + glVertex2f=glVertex2f @318 + glVertex2i=glVertex2i @319 + glVertex2s=glVertex2s @320 + glVertex3d=glVertex3d @321 + glVertex3f=glVertex3f @322 + glVertex3i=glVertex3i @323 + glVertex3s=glVertex3s @324 + glVertex4d=glVertex4d @325 + glVertex4f=glVertex4f @326 + glVertex4i=glVertex4i @327 + glVertex4s=glVertex4s @328 + glVertex2dv=glVertex2dv @329 + glVertex2fv=glVertex2fv @330 + glVertex2iv=glVertex2iv @331 + glVertex2sv=glVertex2sv @332 + glVertex3dv=glVertex3dv @333 + glVertex3fv=glVertex3fv @334 + glVertex3iv=glVertex3iv @335 + glVertex3sv=glVertex3sv @336 + glVertex4dv=glVertex4dv @337 + glVertex4fv=glVertex4fv @338 + glVertex4iv=glVertex4iv @339 + glVertex4sv=glVertex4sv @340 + glVertexPointer=glVertexPointer @341 + glViewport=glViewport @342 + glBlendEquationEXT=glBlendEquationEXT @343 + glBlendColorEXT=glBlendColorEXT @344 + glVertexPointerEXT=glVertexPointerEXT @345 + glNormalPointerEXT=glNormalPointerEXT @346 + glColorPointerEXT=glColorPointerEXT @347 + glIndexPointerEXT=glIndexPointerEXT @348 + glTexCoordPointerEXT=glTexCoordPointerEXT @349 + glEdgeFlagPointerEXT=glEdgeFlagPointerEXT @350 + glGetPointervEXT=glGetPointervEXT @351 + glArrayElementEXT=glArrayElementEXT @352 + glDrawArraysEXT=glDrawArraysEXT @353 + glBindTextureEXT=glBindTextureEXT @354 + glDeleteTexturesEXT=glDeleteTexturesEXT @355 + glGenTexturesEXT=glGenTexturesEXT @356 + glPrioritizeTexturesEXT=glPrioritizeTexturesEXT @357 + glCopyTexSubImage3DEXT=glCopyTexSubImage3DEXT @358 + glTexImage3DEXT=glTexImage3DEXT @359 + glTexSubImage3DEXT=glTexSubImage3DEXT @360 + glWindowPos4fMESA=glWindowPos4fMESA @361 + glWindowPos2iMESA=glWindowPos2iMESA @362 + glWindowPos2sMESA=glWindowPos2sMESA @363 + glWindowPos2fMESA=glWindowPos2fMESA @364 + glWindowPos2dMESA=glWindowPos2dMESA @365 + glWindowPos2ivMESA=glWindowPos2ivMESA @366 + glWindowPos2svMESA=glWindowPos2svMESA @367 + glWindowPos2fvMESA=glWindowPos2fvMESA @368 + glWindowPos2dvMESA=glWindowPos2dvMESA @369 + glWindowPos3iMESA=glWindowPos3iMESA @370 + glWindowPos3sMESA=glWindowPos3sMESA @371 + glWindowPos3fMESA=glWindowPos3fMESA @372 + glWindowPos3dMESA=glWindowPos3dMESA @373 + glWindowPos3ivMESA=glWindowPos3ivMESA @374 + glWindowPos3svMESA=glWindowPos3svMESA @375 + glWindowPos3fvMESA=glWindowPos3fvMESA @376 + glWindowPos3dvMESA=glWindowPos3dvMESA @377 + glWindowPos4iMESA=glWindowPos4iMESA @378 + glWindowPos4sMESA=glWindowPos4sMESA @379 + glWindowPos4dMESA=glWindowPos4dMESA @380 + glWindowPos4ivMESA=glWindowPos4ivMESA @381 + glWindowPos4svMESA=glWindowPos4svMESA @382 + glWindowPos4fvMESA=glWindowPos4fvMESA @383 + glWindowPos4dvMESA=glWindowPos4dvMESA @384 + glResizeBuffersMESA=glResizeBuffersMESA @385 + wglCopyContext=wglCopyContext @386 + wglCreateContext=wglCreateContext @387 + wglCreateLayerContext=wglCreateLayerContext @388 + wglDeleteContext=wglDeleteContext @389 + wglDescribeLayerPlane=wglDescribeLayerPlane @390 + wglGetCurrentContext=wglGetCurrentContext @391 + wglGetCurrentDC=wglGetCurrentDC @392 + wglGetLayerPaletteEntries=wglGetLayerPaletteEntries @393 + wglGetProcAddress=wglGetProcAddress @394 + wglMakeCurrent=wglMakeCurrent @395 + wglRealizeLayerPalette=wglRealizeLayerPalette @396 + wglSetLayerPaletteEntries=wglSetLayerPaletteEntries @397 + wglShareLists=wglShareLists @398 + wglSwapLayerBuffers=wglSwapLayerBuffers @399 + wglUseFontBitmapsA=wglUseFontBitmapsA @400 + wglUseFontBitmapsW=wglUseFontBitmapsW @401 + wglUseFontOutlinesA=wglUseFontOutlinesA @402 + wglUseFontOutlinesW=wglUseFontOutlinesW @403 + ChoosePixelFormat=ChoosePixelFormat @404 + DescribePixelFormat=DescribePixelFormat @405 + GetPixelFormat=GetPixelFormat @406 + SetPixelFormat=SetPixelFormat @407 + SwapBuffers=SwapBuffers @408 + wglChoosePixelFormat=wglChoosePixelFormat @409 + wglDescribePixelFormat=wglDescribePixelFormat @410 + wglGetPixelFormat=wglGetPixelFormat @411 + wglSetPixelFormat=wglSetPixelFormat @412 + wglSwapBuffers=wglSwapBuffers @413 + glActiveTextureARB=glActiveTextureARB @414 + glClientActiveTextureARB=glClientActiveTextureARB @415 + glMultiTexCoord1dARB=glMultiTexCoord1dARB @416 + glMultiTexCoord1dvARB=glMultiTexCoord1dvARB @417 + glMultiTexCoord1fARB=glMultiTexCoord1fARB @418 + glMultiTexCoord1fvARB=glMultiTexCoord1fvARB @419 + glMultiTexCoord1iARB=glMultiTexCoord1iARB @420 + glMultiTexCoord1ivARB=glMultiTexCoord1ivARB @421 + glMultiTexCoord1sARB=glMultiTexCoord1sARB @422 + glMultiTexCoord1svARB=glMultiTexCoord1svARB @423 + glMultiTexCoord2dARB=glMultiTexCoord2dARB @424 + glMultiTexCoord2dvARB=glMultiTexCoord2dvARB @425 + glMultiTexCoord2fARB=glMultiTexCoord2fARB @426 + glMultiTexCoord2fvARB=glMultiTexCoord2fvARB @427 + glMultiTexCoord2iARB=glMultiTexCoord2iARB @428 + glMultiTexCoord2ivARB=glMultiTexCoord2ivARB @429 + glMultiTexCoord2sARB=glMultiTexCoord2sARB @430 + glMultiTexCoord2svARB=glMultiTexCoord2svARB @431 + glMultiTexCoord3dARB=glMultiTexCoord3dARB @432 + glMultiTexCoord3dvARB=glMultiTexCoord3dvARB @433 + glMultiTexCoord3fARB=glMultiTexCoord3fARB @434 + glMultiTexCoord3fvARB=glMultiTexCoord3fvARB @435 + glMultiTexCoord3iARB=glMultiTexCoord3iARB @436 + glMultiTexCoord3ivARB=glMultiTexCoord3ivARB @437 + glMultiTexCoord3sARB=glMultiTexCoord3sARB @438 + glMultiTexCoord3svARB=glMultiTexCoord3svARB @439 + glMultiTexCoord4dARB=glMultiTexCoord4dARB @440 + glMultiTexCoord4dvARB=glMultiTexCoord4dvARB @441 + glMultiTexCoord4fARB=glMultiTexCoord4fARB @442 + glMultiTexCoord4fvARB=glMultiTexCoord4fvARB @443 + glMultiTexCoord4iARB=glMultiTexCoord4iARB @444 + glMultiTexCoord4ivARB=glMultiTexCoord4ivARB @445 + glMultiTexCoord4sARB=glMultiTexCoord4sARB @446 + glMultiTexCoord4svARB=glMultiTexCoord4svARB @447 diff --git a/src/mesa/drivers/windows/gldirect/pixpack.h b/src/mesa/drivers/windows/gldirect/pixpack.h new file mode 100644 index 0000000..ec848d4 --- /dev/null +++ b/src/mesa/drivers/windows/gldirect/pixpack.h @@ -0,0 +1,108 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Pixel packing functions. +* +****************************************************************************/ + +#ifndef __PIXPACK_H +#define __PIXPACK_H + +#include +#include + +#include "ddlog.h" + +/*---------------------- Macros and type definitions ----------------------*/ + +#define PXAPI + +// Typedef that can be used for pixel packing function pointers. +#define PX_PACK_FUNC(a) void PXAPI (a)(unsigned char *pixdata, void *dst, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2) +typedef void (PXAPI *PX_packFunc)(unsigned char *pixdata, void *dst, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2); + +// Typedef that can be used for pixel unpacking function pointers. +#define PX_UNPACK_FUNC(a) void PXAPI (a)(unsigned char *pixdata, void *src, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2) +typedef void (PXAPI *PX_unpackFunc)(unsigned char *pixdata, void *src, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2); + +// Typedef that can be used for pixel span packing function pointers. +#define PX_PACK_SPAN_FUNC(a) void PXAPI (a)(GLuint n, unsigned char *pixdata, unsigned char *dst, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2) +typedef void (PXAPI *PX_packSpanFunc)(GLuint n, unsigned char *pixdata, unsigned char *dst, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2); + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +// Function that examines a pixel format and returns the relevent +// pixel-packing function +void PXAPI pxClassifyPixelFormat(const LPDDPIXELFORMAT lpddpf, PX_packFunc *lpPackFn ,PX_unpackFunc *lpUnpackFn, PX_packSpanFunc *lpPackSpanFn); + +// Packing functions +PX_PACK_FUNC(pxPackGeneric); +PX_PACK_FUNC(pxPackRGB555); +PX_PACK_FUNC(pxPackARGB4444); +PX_PACK_FUNC(pxPackARGB1555); +PX_PACK_FUNC(pxPackRGB565); +PX_PACK_FUNC(pxPackRGB332); +PX_PACK_FUNC(pxPackRGB888); +PX_PACK_FUNC(pxPackARGB8888); +PX_PACK_FUNC(pxPackPAL8); + +// Unpacking functions +PX_UNPACK_FUNC(pxUnpackGeneric); +PX_UNPACK_FUNC(pxUnpackRGB555); +PX_UNPACK_FUNC(pxUnpackARGB4444); +PX_UNPACK_FUNC(pxUnpackARGB1555); +PX_UNPACK_FUNC(pxUnpackRGB565); +PX_UNPACK_FUNC(pxUnpackRGB332); +PX_UNPACK_FUNC(pxUnpackRGB888); +PX_UNPACK_FUNC(pxUnpackARGB8888); +PX_UNPACK_FUNC(pxUnpackPAL8); + +// Span Packing functions +PX_PACK_SPAN_FUNC(pxPackSpanGeneric); +PX_PACK_SPAN_FUNC(pxPackSpanRGB555); +PX_PACK_SPAN_FUNC(pxPackSpanARGB4444); +PX_PACK_SPAN_FUNC(pxPackSpanARGB1555); +PX_PACK_SPAN_FUNC(pxPackSpanRGB565); +PX_PACK_SPAN_FUNC(pxPackSpanRGB332); +PX_PACK_SPAN_FUNC(pxPackSpanRGB888); +PX_PACK_SPAN_FUNC(pxPackSpanARGB8888); +PX_PACK_SPAN_FUNC(pxPackSpanPAL8); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/mesa/drivers/windows/icd/icd.c b/src/mesa/drivers/windows/icd/icd.c new file mode 100644 index 0000000..969f530 --- /dev/null +++ b/src/mesa/drivers/windows/icd/icd.c @@ -0,0 +1,347 @@ +/* + * Mesa 3-D graphics library + * Version: 6.1 + * + * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * File name: icd.c + * Author: Gregor Anich + * + * ICD (Installable Client Driver) interface. + * Based on the windows GDI/WGL driver. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#define GL_GLEXT_PROTOTYPES +#include "GL/gl.h" +#include "GL/glext.h" + +#ifdef __cplusplus +} +#endif + +#include +#include +#include "../gdi/wmesadef.h" +#include "GL/wmesa.h" +#include "mtypes.h" +#include "glapi.h" + +#define MAX_MESA_ATTRS 20 + + +typedef struct _icdTable { + DWORD size; + PROC table[336]; +} ICDTABLE, *PICDTABLE; + +#ifdef USE_MGL_NAMESPACE +# define GL_FUNC(func) mgl##func +#else +# define GL_FUNC(func) gl##func +#endif + +static ICDTABLE icdTable = { 336, { +#define ICD_ENTRY(func) (PROC)GL_FUNC(func), +#include "icdlist.h" +#undef ICD_ENTRY +} }; + +struct __pixelformat__ +{ + PIXELFORMATDESCRIPTOR pfd; + GLboolean doubleBuffered; +}; + +struct __pixelformat__ pix[] = +{ + /* Double Buffer, alpha */ + { { sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|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_SUPPORT_GDI ? */ + 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_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_SUPPORT_GDI ? */ + 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 int ctx_current = -1; +static unsigned curPFD = 0; + +WGLAPI BOOL GLAPIENTRY DrvCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask) +{ + (void) hglrcSrc; (void) hglrcDst; (void) mask; + return(FALSE); +} + +WGLAPI HGLRC GLAPIENTRY DrvCreateContext(HDC hdc) +{ + HWND hWnd; + int i = 0; + + if(!(hWnd = WindowFromDC(hdc))) + { + SetLastError(0); + return(NULL); + } + if (!ctx_count) + { + for(i=0;i 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 DrvGetProcAddress(LPCSTR lpszProc) +{ + PROC p = (PROC) (int) _glapi_get_proc_address((const char *) lpszProc); + if (p) + return p; + + SetLastError(0); + return(NULL); +} + +WGLAPI BOOL GLAPIENTRY DrvSetPixelFormat(HDC hdc,int iPixelFormat) +{ + int qt_valid_pix; + (void) hdc; + + qt_valid_pix = qt_pix; + if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix) + { + SetLastError(0); + return(FALSE); + } + curPFD = iPixelFormat; + return(TRUE); +} + +WGLAPI BOOL GLAPIENTRY DrvSwapBuffers(HDC hdc) +{ + (void) hdc; + if (ctx_current < 0) + return FALSE; + + if(wgl_ctx[ctx_current].ctx == NULL) { + SetLastError(0); + return(FALSE); + } + WMesaSwapBuffers(); + return(TRUE); +} + +WGLAPI BOOL GLAPIENTRY DrvValidateVersion(DWORD version) +{ + (void) version; + return TRUE; +} diff --git a/src/mesa/drivers/windows/icd/icdlist.h b/src/mesa/drivers/windows/icd/icdlist.h new file mode 100644 index 0000000..1318804 --- /dev/null +++ b/src/mesa/drivers/windows/icd/icdlist.h @@ -0,0 +1,336 @@ +ICD_ENTRY(NewList) /* 0 */ +ICD_ENTRY(EndList) /* 1 */ +ICD_ENTRY(CallList) /* 2 */ +ICD_ENTRY(CallLists) /* 3 */ +ICD_ENTRY(DeleteLists) /* 4 */ +ICD_ENTRY(GenLists) /* 5 */ +ICD_ENTRY(ListBase) /* 6 */ +ICD_ENTRY(Begin) /* 7 */ +ICD_ENTRY(Bitmap) /* 8 */ +ICD_ENTRY(Color3b) /* 9 */ +ICD_ENTRY(Color3bv) /* 10 */ +ICD_ENTRY(Color3d) /* 11 */ +ICD_ENTRY(Color3dv) /* 12 */ +ICD_ENTRY(Color3f) /* 13 */ +ICD_ENTRY(Color3fv) /* 14 */ +ICD_ENTRY(Color3i) /* 15 */ +ICD_ENTRY(Color3iv) /* 16 */ +ICD_ENTRY(Color3s) /* 17 */ +ICD_ENTRY(Color3sv) /* 18 */ +ICD_ENTRY(Color3ub) /* 19 */ +ICD_ENTRY(Color3ubv) /* 20 */ +ICD_ENTRY(Color3ui) /* 21 */ +ICD_ENTRY(Color3uiv) /* 22 */ +ICD_ENTRY(Color3us) /* 23 */ +ICD_ENTRY(Color3usv) /* 24 */ +ICD_ENTRY(Color4b) /* 25 */ +ICD_ENTRY(Color4bv) /* 26 */ +ICD_ENTRY(Color4d) /* 27 */ +ICD_ENTRY(Color4dv) /* 28 */ +ICD_ENTRY(Color4f) /* 29 */ +ICD_ENTRY(Color4fv) /* 30 */ +ICD_ENTRY(Color4i) /* 31 */ +ICD_ENTRY(Color4iv) /* 32 */ +ICD_ENTRY(Color4s) /* 33 */ +ICD_ENTRY(Color4sv) /* 34 */ +ICD_ENTRY(Color4ub) /* 35 */ +ICD_ENTRY(Color4ubv) /* 36 */ +ICD_ENTRY(Color4ui) /* 37 */ +ICD_ENTRY(Color4uiv) /* 38 */ +ICD_ENTRY(Color4us) /* 39 */ +ICD_ENTRY(Color4usv) /* 40 */ +ICD_ENTRY(EdgeFlag) /* 41 */ +ICD_ENTRY(EdgeFlagv) /* 42 */ +ICD_ENTRY(End) /* 43 */ +ICD_ENTRY(Indexd) /* 44 */ +ICD_ENTRY(Indexdv) /* 45 */ +ICD_ENTRY(Indexf) /* 46 */ +ICD_ENTRY(Indexfv) /* 47 */ +ICD_ENTRY(Indexi) /* 48 */ +ICD_ENTRY(Indexiv) /* 49 */ +ICD_ENTRY(Indexs) /* 50 */ +ICD_ENTRY(Indexsv) /* 51 */ +ICD_ENTRY(Normal3b) /* 52 */ +ICD_ENTRY(Normal3bv) /* 53 */ +ICD_ENTRY(Normal3d) /* 54 */ +ICD_ENTRY(Normal3dv) /* 55 */ +ICD_ENTRY(Normal3f) /* 56 */ +ICD_ENTRY(Normal3fv) /* 57 */ +ICD_ENTRY(Normal3i) /* 58 */ +ICD_ENTRY(Normal3iv) /* 59 */ +ICD_ENTRY(Normal3s) /* 60 */ +ICD_ENTRY(Normal3sv) /* 61 */ +ICD_ENTRY(RasterPos2d) /* 62 */ +ICD_ENTRY(RasterPos2dv) /* 63 */ +ICD_ENTRY(RasterPos2f) /* 64 */ +ICD_ENTRY(RasterPos2fv) /* 65 */ +ICD_ENTRY(RasterPos2i) /* 66 */ +ICD_ENTRY(RasterPos2iv) /* 67 */ +ICD_ENTRY(RasterPos2s) /* 68 */ +ICD_ENTRY(RasterPos2sv) /* 69 */ +ICD_ENTRY(RasterPos3d) /* 70 */ +ICD_ENTRY(RasterPos3dv) /* 71 */ +ICD_ENTRY(RasterPos3f) /* 72 */ +ICD_ENTRY(RasterPos3fv) /* 73 */ +ICD_ENTRY(RasterPos3i) /* 74 */ +ICD_ENTRY(RasterPos3iv) /* 75 */ +ICD_ENTRY(RasterPos3s) /* 76 */ +ICD_ENTRY(RasterPos3sv) /* 77 */ +ICD_ENTRY(RasterPos4d) /* 78 */ +ICD_ENTRY(RasterPos4dv) /* 79 */ +ICD_ENTRY(RasterPos4f) /* 80 */ +ICD_ENTRY(RasterPos4fv) /* 81 */ +ICD_ENTRY(RasterPos4i) /* 82 */ +ICD_ENTRY(RasterPos4iv) /* 83 */ +ICD_ENTRY(RasterPos4s) /* 84 */ +ICD_ENTRY(RasterPos4sv) /* 85 */ +ICD_ENTRY(Rectd) /* 86 */ +ICD_ENTRY(Rectdv) /* 87 */ +ICD_ENTRY(Rectf) /* 88 */ +ICD_ENTRY(Rectfv) /* 89 */ +ICD_ENTRY(Recti) /* 90 */ +ICD_ENTRY(Rectiv) /* 91 */ +ICD_ENTRY(Rects) /* 92 */ +ICD_ENTRY(Rectsv) /* 93 */ +ICD_ENTRY(TexCoord1d) /* 94 */ +ICD_ENTRY(TexCoord1dv) /* 95 */ +ICD_ENTRY(TexCoord1f) /* 96 */ +ICD_ENTRY(TexCoord1fv) /* 97 */ +ICD_ENTRY(TexCoord1i) /* 98 */ +ICD_ENTRY(TexCoord1iv) /* 99 */ +ICD_ENTRY(TexCoord1s) /* 100 */ +ICD_ENTRY(TexCoord1sv) /* 101 */ +ICD_ENTRY(TexCoord2d) /* 102 */ +ICD_ENTRY(TexCoord2dv) /* 103 */ +ICD_ENTRY(TexCoord2f) /* 104 */ +ICD_ENTRY(TexCoord2fv) /* 105 */ +ICD_ENTRY(TexCoord2i) /* 106 */ +ICD_ENTRY(TexCoord2iv) /* 107 */ +ICD_ENTRY(TexCoord2s) /* 108 */ +ICD_ENTRY(TexCoord2sv) /* 109 */ +ICD_ENTRY(TexCoord3d) /* 110 */ +ICD_ENTRY(TexCoord3dv) /* 111 */ +ICD_ENTRY(TexCoord3f) /* 112 */ +ICD_ENTRY(TexCoord3fv) /* 113 */ +ICD_ENTRY(TexCoord3i) /* 114 */ +ICD_ENTRY(TexCoord3iv) /* 115 */ +ICD_ENTRY(TexCoord3s) /* 116 */ +ICD_ENTRY(TexCoord3sv) /* 117 */ +ICD_ENTRY(TexCoord4d) /* 118 */ +ICD_ENTRY(TexCoord4dv) /* 119 */ +ICD_ENTRY(TexCoord4f) /* 120 */ +ICD_ENTRY(TexCoord4fv) /* 121 */ +ICD_ENTRY(TexCoord4i) /* 122 */ +ICD_ENTRY(TexCoord4iv) /* 123 */ +ICD_ENTRY(TexCoord4s) /* 124 */ +ICD_ENTRY(TexCoord4sv) /* 125 */ +ICD_ENTRY(Vertex2d) /* 126 */ +ICD_ENTRY(Vertex2dv) /* 127 */ +ICD_ENTRY(Vertex2f) /* 128 */ +ICD_ENTRY(Vertex2fv) /* 129 */ +ICD_ENTRY(Vertex2i) /* 130 */ +ICD_ENTRY(Vertex2iv) /* 131 */ +ICD_ENTRY(Vertex2s) /* 132 */ +ICD_ENTRY(Vertex2sv) /* 133 */ +ICD_ENTRY(Vertex3d) /* 134 */ +ICD_ENTRY(Vertex3dv) /* 135 */ +ICD_ENTRY(Vertex3f) /* 136 */ +ICD_ENTRY(Vertex3fv) /* 137 */ +ICD_ENTRY(Vertex3i) /* 138 */ +ICD_ENTRY(Vertex3iv) /* 139 */ +ICD_ENTRY(Vertex3s) /* 140 */ +ICD_ENTRY(Vertex3sv) /* 141 */ +ICD_ENTRY(Vertex4d) /* 142 */ +ICD_ENTRY(Vertex4dv) /* 143 */ +ICD_ENTRY(Vertex4f) /* 144 */ +ICD_ENTRY(Vertex4fv) /* 145 */ +ICD_ENTRY(Vertex4i) /* 146 */ +ICD_ENTRY(Vertex4iv) /* 147 */ +ICD_ENTRY(Vertex4s) /* 148 */ +ICD_ENTRY(Vertex4sv) /* 149 */ +ICD_ENTRY(ClipPlane) /* 150 */ +ICD_ENTRY(ColorMaterial) /* 151 */ +ICD_ENTRY(CullFace) /* 152 */ +ICD_ENTRY(Fogf) /* 153 */ +ICD_ENTRY(Fogfv) /* 154 */ +ICD_ENTRY(Fogi) /* 155 */ +ICD_ENTRY(Fogiv) /* 156 */ +ICD_ENTRY(FrontFace) /* 157 */ +ICD_ENTRY(Hint) /* 158 */ +ICD_ENTRY(Lightf) /* 159 */ +ICD_ENTRY(Lightfv) /* 160 */ +ICD_ENTRY(Lighti) /* 161 */ +ICD_ENTRY(Lightiv) /* 162 */ +ICD_ENTRY(LightModelf) /* 163 */ +ICD_ENTRY(LightModelfv) /* 164 */ +ICD_ENTRY(LightModeli) /* 165 */ +ICD_ENTRY(LightModeliv) /* 166 */ +ICD_ENTRY(LineStipple) /* 167 */ +ICD_ENTRY(LineWidth) /* 168 */ +ICD_ENTRY(Materialf) /* 169 */ +ICD_ENTRY(Materialfv) /* 170 */ +ICD_ENTRY(Materiali) /* 171 */ +ICD_ENTRY(Materialiv) /* 172 */ +ICD_ENTRY(PointSize) /* 173 */ +ICD_ENTRY(PolygonMode) /* 174 */ +ICD_ENTRY(PolygonStipple) /* 175 */ +ICD_ENTRY(Scissor) /* 176 */ +ICD_ENTRY(ShadeModel) /* 177 */ +ICD_ENTRY(TexParameterf) /* 178 */ +ICD_ENTRY(TexParameterfv) /* 179 */ +ICD_ENTRY(TexParameteri) /* 180 */ +ICD_ENTRY(TexParameteriv) /* 181 */ +ICD_ENTRY(TexImage1D) /* 182 */ +ICD_ENTRY(TexImage2D) /* 183 */ +ICD_ENTRY(TexEnvf) /* 184 */ +ICD_ENTRY(TexEnvfv) /* 185 */ +ICD_ENTRY(TexEnvi) /* 186 */ +ICD_ENTRY(TexEnviv) /* 187 */ +ICD_ENTRY(TexGend) /* 188 */ +ICD_ENTRY(TexGendv) /* 189 */ +ICD_ENTRY(TexGenf) /* 190 */ +ICD_ENTRY(TexGenfv) /* 191 */ +ICD_ENTRY(TexGeni) /* 192 */ +ICD_ENTRY(TexGeniv) /* 193 */ +ICD_ENTRY(FeedbackBuffer) /* 194 */ +ICD_ENTRY(SelectBuffer) /* 195 */ +ICD_ENTRY(RenderMode) /* 196 */ +ICD_ENTRY(InitNames) /* 197 */ +ICD_ENTRY(LoadName) /* 198 */ +ICD_ENTRY(PassThrough) /* 199 */ +ICD_ENTRY(PopName) /* 200 */ +ICD_ENTRY(PushName) /* 201 */ +ICD_ENTRY(DrawBuffer) /* 202 */ +ICD_ENTRY(Clear) /* 203 */ +ICD_ENTRY(ClearAccum) /* 204 */ +ICD_ENTRY(ClearIndex) /* 205 */ +ICD_ENTRY(ClearColor) /* 206 */ +ICD_ENTRY(ClearStencil) /* 207 */ +ICD_ENTRY(ClearDepth) /* 208 */ +ICD_ENTRY(StencilMask) /* 209 */ +ICD_ENTRY(ColorMask) /* 210 */ +ICD_ENTRY(DepthMask) /* 211 */ +ICD_ENTRY(IndexMask) /* 212 */ +ICD_ENTRY(Accum) /* 213 */ +ICD_ENTRY(Disable) /* 214 */ +ICD_ENTRY(Enable) /* 215 */ +ICD_ENTRY(Finish) /* 216 */ +ICD_ENTRY(Flush) /* 217 */ +ICD_ENTRY(PopAttrib) /* 218 */ +ICD_ENTRY(PushAttrib) /* 219 */ +ICD_ENTRY(Map1d) /* 220 */ +ICD_ENTRY(Map1f) /* 221 */ +ICD_ENTRY(Map2d) /* 222 */ +ICD_ENTRY(Map2f) /* 223 */ +ICD_ENTRY(MapGrid1d) /* 224 */ +ICD_ENTRY(MapGrid1f) /* 225 */ +ICD_ENTRY(MapGrid2d) /* 226 */ +ICD_ENTRY(MapGrid2f) /* 227 */ +ICD_ENTRY(EvalCoord1d) /* 228 */ +ICD_ENTRY(EvalCoord1dv) /* 229 */ +ICD_ENTRY(EvalCoord1f) /* 230 */ +ICD_ENTRY(EvalCoord1fv) /* 231 */ +ICD_ENTRY(EvalCoord2d) /* 232 */ +ICD_ENTRY(EvalCoord2dv) /* 233 */ +ICD_ENTRY(EvalCoord2f) /* 234 */ +ICD_ENTRY(EvalCoord2fv) /* 235 */ +ICD_ENTRY(EvalMesh1) /* 236 */ +ICD_ENTRY(EvalPoint1) /* 237 */ +ICD_ENTRY(EvalMesh2) /* 238 */ +ICD_ENTRY(EvalPoint2) /* 239 */ +ICD_ENTRY(AlphaFunc) /* 240 */ +ICD_ENTRY(BlendFunc) /* 241 */ +ICD_ENTRY(LogicOp) /* 242 */ +ICD_ENTRY(StencilFunc) /* 243 */ +ICD_ENTRY(StencilOp) /* 244 */ +ICD_ENTRY(DepthFunc) /* 245 */ +ICD_ENTRY(PixelZoom) /* 246 */ +ICD_ENTRY(PixelTransferf) /* 247 */ +ICD_ENTRY(PixelTransferi) /* 248 */ +ICD_ENTRY(PixelStoref) /* 249 */ +ICD_ENTRY(PixelStorei) /* 250 */ +ICD_ENTRY(PixelMapfv) /* 251 */ +ICD_ENTRY(PixelMapuiv) /* 252 */ +ICD_ENTRY(PixelMapusv) /* 253 */ +ICD_ENTRY(ReadBuffer) /* 254 */ +ICD_ENTRY(CopyPixels) /* 255 */ +ICD_ENTRY(ReadPixels) /* 256 */ +ICD_ENTRY(DrawPixels) /* 257 */ +ICD_ENTRY(GetBooleanv) /* 258 */ +ICD_ENTRY(GetClipPlane) /* 259 */ +ICD_ENTRY(GetDoublev) /* 260 */ +ICD_ENTRY(GetError) /* 261 */ +ICD_ENTRY(GetFloatv) /* 262 */ +ICD_ENTRY(GetIntegerv) /* 263 */ +ICD_ENTRY(GetLightfv) /* 264 */ +ICD_ENTRY(GetLightiv) /* 265 */ +ICD_ENTRY(GetMapdv) /* 266 */ +ICD_ENTRY(GetMapfv) /* 267 */ +ICD_ENTRY(GetMapiv) /* 268 */ +ICD_ENTRY(GetMaterialfv) /* 269 */ +ICD_ENTRY(GetMaterialiv) /* 270 */ +ICD_ENTRY(GetPixelMapfv) /* 271 */ +ICD_ENTRY(GetPixelMapuiv) /* 272 */ +ICD_ENTRY(GetPixelMapusv) /* 273 */ +ICD_ENTRY(GetPolygonStipple) /* 274 */ +ICD_ENTRY(GetString) /* 275 */ +ICD_ENTRY(GetTexEnvfv) /* 276 */ +ICD_ENTRY(GetTexEnviv) /* 277 */ +ICD_ENTRY(GetTexGendv) /* 278 */ +ICD_ENTRY(GetTexGenfv) /* 279 */ +ICD_ENTRY(GetTexGeniv) /* 280 */ +ICD_ENTRY(GetTexImage) /* 281 */ +ICD_ENTRY(GetTexParameterfv) /* 282 */ +ICD_ENTRY(GetTexParameteriv) /* 283 */ +ICD_ENTRY(GetTexLevelParameterfv) /* 284 */ +ICD_ENTRY(GetTexLevelParameteriv) /* 285 */ +ICD_ENTRY(IsEnabled) /* 286 */ +ICD_ENTRY(IsList) /* 287 */ +ICD_ENTRY(DepthRange) /* 288 */ +ICD_ENTRY(Frustum) /* 289 */ +ICD_ENTRY(LoadIdentity) /* 290 */ +ICD_ENTRY(LoadMatrixf) /* 291 */ +ICD_ENTRY(LoadMatrixd) /* 292 */ +ICD_ENTRY(MatrixMode) /* 293 */ +ICD_ENTRY(MultMatrixf) /* 294 */ +ICD_ENTRY(MultMatrixd) /* 295 */ +ICD_ENTRY(Ortho) /* 296 */ +ICD_ENTRY(PopMatrix) /* 297 */ +ICD_ENTRY(PushMatrix) /* 298 */ +ICD_ENTRY(Rotated) /* 299 */ +ICD_ENTRY(Rotatef) /* 300 */ +ICD_ENTRY(Scaled) /* 301 */ +ICD_ENTRY(Scalef) /* 302 */ +ICD_ENTRY(Translated) /* 303 */ +ICD_ENTRY(Translatef) /* 304 */ +ICD_ENTRY(Viewport) /* 305 */ +ICD_ENTRY(ArrayElement) /* 306 */ +ICD_ENTRY(BindTexture) /* 307 */ +ICD_ENTRY(ColorPointer) /* 308 */ +ICD_ENTRY(DisableClientState) /* 309 */ +ICD_ENTRY(DrawArrays) /* 310 */ +ICD_ENTRY(DrawElements) /* 311 */ +ICD_ENTRY(EdgeFlagPointer) /* 312 */ +ICD_ENTRY(EnableClientState) /* 313 */ +ICD_ENTRY(IndexPointer) /* 314 */ +ICD_ENTRY(Indexub) /* 315 */ +ICD_ENTRY(Indexubv) /* 316 */ +ICD_ENTRY(InterleavedArrays) /* 317 */ +ICD_ENTRY(NormalPointer) /* 318 */ +ICD_ENTRY(PolygonOffset) /* 319 */ +ICD_ENTRY(TexCoordPointer) /* 320 */ +ICD_ENTRY(VertexPointer) /* 321 */ +ICD_ENTRY(AreTexturesResident) /* 322 */ +ICD_ENTRY(CopyTexImage1D) /* 323 */ +ICD_ENTRY(CopyTexImage2D) /* 324 */ +ICD_ENTRY(CopyTexSubImage1D) /* 325 */ +ICD_ENTRY(CopyTexSubImage2D) /* 326 */ +ICD_ENTRY(DeleteTextures) /* 327 */ +ICD_ENTRY(GenTextures) /* 328 */ +ICD_ENTRY(GetPointerv) /* 329 */ +ICD_ENTRY(IsTexture) /* 330 */ +ICD_ENTRY(PrioritizeTextures) /* 331 */ +ICD_ENTRY(TexSubImage1D) /* 332 */ +ICD_ENTRY(TexSubImage2D) /* 333 */ +ICD_ENTRY(PopClientAttrib) /* 334 */ +ICD_ENTRY(PushClientAttrib) /* 335 */ diff --git a/src/mesa/drivers/windows/icd/mesa.def b/src/mesa/drivers/windows/icd/mesa.def new file mode 100644 index 0000000..263b9d4 --- /dev/null +++ b/src/mesa/drivers/windows/icd/mesa.def @@ -0,0 +1,110 @@ +DESCRIPTION 'Mesa (OpenGL driver) for Win32' +VERSION 6.1 + +EXPORTS +; +; ICD API + DrvCopyContext + DrvCreateContext + DrvCreateLayerContext + DrvDeleteContext + DrvDescribeLayerPlane + DrvDescribePixelFormat + DrvGetLayerPaletteEntries + DrvGetProcAddress + DrvReleaseContext + DrvRealizeLayerPalette + DrvSetContext + DrvSetLayerPaletteEntries + DrvSetPixelFormat + DrvShareLists + DrvSwapBuffers + DrvSwapLayerBuffers + DrvValidateVersion + +; +; Mesa internals - mostly for OSMESA + _ac_CreateContext + _ac_DestroyContext + _ac_InvalidateState + _glapi_get_context + _glapi_get_proc_address + _mesa_buffer_data + _mesa_buffer_map + _mesa_buffer_subdata + _mesa_bzero + _mesa_calloc + _mesa_choose_tex_format + _mesa_compressed_texture_size + _mesa_create_framebuffer + _mesa_create_visual + _mesa_delete_buffer_object + _mesa_delete_texture_object + _mesa_destroy_framebuffer + _mesa_destroy_visual + _mesa_enable_1_3_extensions + _mesa_enable_1_4_extensions + _mesa_enable_1_5_extensions + _mesa_enable_sw_extensions + _mesa_error + _mesa_free + _mesa_free_context_data + _mesa_get_current_context + _mesa_init_default_imports + _mesa_init_driver_functions + _mesa_initialize_context + _mesa_make_current + _mesa_memcpy + _mesa_memset + _mesa_new_buffer_object + _mesa_new_texture_object + _mesa_problem + _mesa_ResizeBuffersMESA + _mesa_store_compressed_teximage1d + _mesa_store_compressed_teximage2d + _mesa_store_compressed_teximage3d + _mesa_store_compressed_texsubimage1d + _mesa_store_compressed_texsubimage2d + _mesa_store_compressed_texsubimage3d + _mesa_store_teximage1d + _mesa_store_teximage2d + _mesa_store_teximage3d + _mesa_store_texsubimage1d + _mesa_store_texsubimage2d + _mesa_store_texsubimage3d + _mesa_strcmp + _mesa_test_proxy_teximage + _mesa_Viewport + _swrast_Accum + _swrast_alloc_buffers + _swrast_Bitmap + _swrast_CopyPixels + _swrast_DrawBuffer + _swrast_DrawPixels + _swrast_GetDeviceDriverReference + _swrast_Clear + _swrast_choose_line + _swrast_choose_triangle + _swrast_CopyColorSubTable + _swrast_CopyColorTable + _swrast_CopyConvolutionFilter1D + _swrast_CopyConvolutionFilter2D + _swrast_copy_teximage1d + _swrast_copy_teximage2d + _swrast_copy_texsubimage1d + _swrast_copy_texsubimage2d + _swrast_copy_texsubimage3d + _swrast_CreateContext + _swrast_DestroyContext + _swrast_InvalidateState + _swrast_ReadPixels + _swrast_zbuffer_address + _swsetup_Wakeup + _swsetup_CreateContext + _swsetup_DestroyContext + _swsetup_InvalidateState + _tnl_CreateContext + _tnl_DestroyContext + _tnl_InvalidateState + _tnl_MakeCurrent + _tnl_run_pipeline -- cgit