Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1552 lines
45 KiB

  1. /*
  2. * (c) Copyright 1993, Silicon Graphics, Inc.
  3. * ALL RIGHTS RESERVED
  4. * Permission to use, copy, modify, and distribute this software for
  5. * any purpose and without fee is hereby granted, provided that the above
  6. * copyright notice appear in all copies and that both the copyright notice
  7. * and this permission notice appear in supporting documentation, and that
  8. * the name of Silicon Graphics, Inc. not be used in advertising
  9. * or publicity pertaining to distribution of the software without specific,
  10. * written prior permission.
  11. *
  12. * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13. * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14. * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15. * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
  16. * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17. * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18. * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19. * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20. * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
  21. * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22. * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23. * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24. *
  25. * US Government Users Restricted Rights
  26. * Use, duplication, or disclosure by the Government is subject to
  27. * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28. * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29. * clause at DFARS 252.227-7013 and/or in similar or successor
  30. * clauses in the FAR or the DOD or NASA FAR Supplement.
  31. * Unpublished-- rights reserved under the copyright laws of the
  32. * United States. Contractor/manufacturer is Silicon Graphics,
  33. * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
  34. *
  35. * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  36. */
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include "tk.h"
  41. #include "windows.h"
  42. #if defined(__cplusplus) || defined(c_plusplus)
  43. #define class c_class
  44. #endif
  45. #if DBG
  46. #define TKASSERT(x) \
  47. if ( !(x) ) { \
  48. PrintMessage("%s(%d) Assertion failed %s\n", \
  49. __FILE__, __LINE__, #x); \
  50. }
  51. #else
  52. #define TKASSERT(x)
  53. #endif /* DBG */
  54. /******************************************************************************/
  55. static struct _WINDOWINFO {
  56. int x, y;
  57. int width, height;
  58. GLenum type;
  59. BOOL bDefPos;
  60. } windInfo = {
  61. 0, 0, 100, 100, TK_INDEX | TK_SINGLE, TRUE
  62. };
  63. static HWND tkhwnd = NULL;
  64. static HDC tkhdc = NULL;
  65. static HGLRC tkhrc = NULL;
  66. static HPALETTE tkhpalette = NULL;
  67. static void (*ExposeFunc)(int, int) = NULL;
  68. static void (*ReshapeFunc)(int, int) = NULL;
  69. static void (*DisplayFunc)(void) = NULL;
  70. static GLenum (*KeyDownFunc)(int, GLenum) = NULL;
  71. static GLenum (*MouseDownFunc)(int, int, GLenum) = NULL;
  72. static GLenum (*MouseUpFunc)(int, int, GLenum) = NULL;
  73. static GLenum (*MouseMoveFunc)(int, int, GLenum) = NULL;
  74. static void (*IdleFunc)(void) = NULL;
  75. static char *lpszClassName = "tkLibWClass";
  76. static WCHAR *lpszClassNameW = L"tkLibWClass";
  77. static long tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam);
  78. static unsigned char ComponentFromIndex(int i, int nbits, int shift );
  79. static void PrintMessage( const char *Format, ... );
  80. static PALETTEENTRY *FillRgbPaletteEntries( PIXELFORMATDESCRIPTOR *Pfd, PALETTEENTRY *Entries, UINT Count );
  81. static HPALETTE CreateCIPalette( HDC Dc );
  82. static HPALETTE CreateRGBPalette( HDC hdc );
  83. static void DestroyThisWindow( HWND Window );
  84. static void CleanUp( void );
  85. static void DelayPaletteRealization( void );
  86. static BOOL RealizePaletteNow( HDC Dc, HPALETTE Palette );
  87. static void ForceRedraw( HWND Window );
  88. static BOOL FindPixelFormat(HDC hdc, GLenum type);
  89. static int PixelFormatDescriptorFromDc( HDC Dc, PIXELFORMATDESCRIPTOR *Pfd );
  90. static void *AllocateMemory( size_t Size );
  91. static void *AllocateZeroedMemory( size_t Size );
  92. static void FreeMemory( void *Chunk );
  93. /*
  94. * Prototypes for the debugging functions go here
  95. */
  96. #define DBGFUNC 0
  97. #if DBGFUNC
  98. static void DbgPrintf( const char *Format, ... );
  99. static void pwi( void );
  100. static void pwr(RECT *pr);
  101. static void ShowPixelFormat(HDC hdc);
  102. #endif
  103. static float colorMaps[] = {
  104. 0.000000F, 1.000000F, 0.000000F, 1.000000F, 0.000000F, 1.000000F,
  105. 0.000000F, 1.000000F, 0.333333F, 0.776471F, 0.443137F, 0.556863F,
  106. 0.443137F, 0.556863F, 0.219608F, 0.666667F, 0.666667F, 0.333333F,
  107. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  108. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  109. 0.666667F, 0.333333F, 0.039216F, 0.078431F, 0.117647F, 0.156863F,
  110. 0.200000F, 0.239216F, 0.278431F, 0.317647F, 0.356863F, 0.400000F,
  111. 0.439216F, 0.478431F, 0.517647F, 0.556863F, 0.600000F, 0.639216F,
  112. 0.678431F, 0.717647F, 0.756863F, 0.800000F, 0.839216F, 0.878431F,
  113. 0.917647F, 0.956863F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  114. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.247059F, 0.247059F,
  115. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  116. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  117. 0.498039F, 0.498039F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  118. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 1.000000F, 1.000000F,
  119. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  120. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  121. 0.000000F, 0.000000F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  122. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.498039F, 0.498039F,
  123. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  124. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  125. 0.749020F, 0.749020F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  126. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 0.000000F, 0.000000F,
  127. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  128. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  129. 0.247059F, 0.247059F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  130. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.749020F, 0.749020F,
  131. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  132. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  133. 1.000000F, 1.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  134. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.247059F, 0.247059F,
  135. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  136. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  137. 0.498039F, 0.498039F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  138. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 1.000000F, 1.000000F,
  139. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  140. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  141. 0.000000F, 0.000000F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  142. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.498039F, 0.498039F,
  143. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  144. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  145. 0.749020F, 0.749020F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  146. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 0.000000F, 0.000000F,
  147. 1.000000F, 1.000000F, 0.000000F, 0.000000F, 1.000000F, 1.000000F,
  148. 0.333333F, 0.443137F, 0.776471F, 0.556863F, 0.443137F, 0.219608F,
  149. 0.556863F, 0.666667F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  150. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  151. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  152. 0.039216F, 0.078431F, 0.117647F, 0.156863F, 0.200000F, 0.239216F,
  153. 0.278431F, 0.317647F, 0.356863F, 0.400000F, 0.439216F, 0.478431F,
  154. 0.517647F, 0.556863F, 0.600000F, 0.639216F, 0.678431F, 0.717647F,
  155. 0.756863F, 0.800000F, 0.839216F, 0.878431F, 0.917647F, 0.956863F,
  156. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  157. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  158. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  159. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  160. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  161. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  162. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  163. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  164. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  165. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  166. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  167. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  168. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  169. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  170. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  171. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  172. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  173. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  174. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  175. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  176. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  177. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  178. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  179. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  180. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  181. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  182. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  183. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  184. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  185. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  186. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  187. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  188. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  189. 0.854902F, 1.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  190. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 0.333333F, 0.443137F,
  191. 0.443137F, 0.219608F, 0.776471F, 0.556863F, 0.556863F, 0.666667F,
  192. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  193. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  194. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.039216F, 0.078431F,
  195. 0.117647F, 0.156863F, 0.200000F, 0.239216F, 0.278431F, 0.317647F,
  196. 0.356863F, 0.400000F, 0.439216F, 0.478431F, 0.517647F, 0.556863F,
  197. 0.600000F, 0.639216F, 0.678431F, 0.717647F, 0.756863F, 0.800000F,
  198. 0.839216F, 0.878431F, 0.917647F, 0.956863F, 0.000000F, 0.000000F,
  199. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  200. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  201. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  202. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  203. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  204. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  205. 0.000000F, 0.000000F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  206. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  207. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  208. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  209. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  210. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  211. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  212. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  213. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  214. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  215. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  216. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  217. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  218. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.749020F, 0.749020F,
  219. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  220. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  221. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  222. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  223. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  224. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  225. 0.749020F, 0.749020F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  226. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  227. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  228. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  229. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  230. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  231. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  232. };
  233. /* Default Palette */
  234. float auxRGBMap[20][3] = {
  235. { 0.0F, 0.0F, 0.0F }, /* 0: black */
  236. { 0x80/255.0F, 0.0F, 0.0F }, /* 1: Half red */
  237. { 0.0F, 0x80/255.0F, 0.0F }, /* 2: Half green */
  238. { 0x80/255.0F, 0x80/255.0F, 0.0F }, /* 3: Half yellow */
  239. { 0.0F, 0.0F, 0x80/255.0F }, /* 4: Half blue */
  240. { 0x80/255.0F, 0.0F, 0x80/255.0F }, /* 5: Half magenta */
  241. { 0.0F, 0x80/255.0F, 0x80/255.0F }, /* 6: Half cyan */
  242. { 0xC0/255.0F, 0xC0/255.0F, 0xC0/255.0F }, /* 7: Light gray */
  243. { 0xC0/255.0F, 0xDC/255.0F, 0xC0/255.0F }, /* 8: Green gray */
  244. { 0xA6/255.0F, 0xCA/255.0F, 0xF0/255.0F }, /* 9: Half gray */
  245. { 1.0F, 0xFB/255.0F, 0xF0/255.0F }, /* 10: Pale */
  246. { 0xA0/255.0F, 0xA0/255.0F, 0xA4/255.0F }, /* 11: Med gray */
  247. { 0x80/255.0F, 0x80/255.0F, 0x80/255.0F }, /* 12: Dark gray */
  248. { 1.0F, 0.0F, 0.0F }, /* 13: red */
  249. { 0.0F, 1.0F, 0.0F }, /* 14: green */
  250. { 1.0F, 1.0F, 0.0F }, /* 15: yellow */
  251. { 0.0F, 0.0F, 1.0F }, /* 16: blue */
  252. { 1.0F, 0.0F, 1.0F }, /* 17: magenta */
  253. { 0.0F, 1.0F, 1.0F }, /* 18: cyan */
  254. { 1.0F, 1.0F, 1.0F }, /* 19: white */
  255. };
  256. /***************************************************************
  257. * *
  258. * Exported Functions go here *
  259. * *
  260. ***************************************************************/
  261. void tkCloseWindow(void)
  262. {
  263. DestroyThisWindow(tkhwnd);
  264. }
  265. void tkExec(void)
  266. {
  267. MSG Message;
  268. /*
  269. * WM_SIZE gets delivered before we get here!
  270. */
  271. if (ReshapeFunc)
  272. {
  273. RECT ClientRect;
  274. GetClientRect(tkhwnd, &ClientRect);
  275. (*ReshapeFunc)(ClientRect.right, ClientRect.bottom);
  276. }
  277. while (GL_TRUE)
  278. {
  279. /*
  280. * Process all pending messages
  281. */
  282. while (PeekMessage(&Message, NULL, 0, 0, PM_NOREMOVE) == TRUE)
  283. {
  284. if (GetMessage(&Message, NULL, 0, 0) )
  285. {
  286. TranslateMessage(&Message);
  287. DispatchMessage(&Message);
  288. }
  289. else
  290. {
  291. /*
  292. * Nothing else to do here, just return
  293. */
  294. return;
  295. }
  296. }
  297. /*
  298. * If an idle function was defined, call it
  299. */
  300. if (IdleFunc)
  301. {
  302. (*IdleFunc)();
  303. }
  304. }
  305. }
  306. void tkExposeFunc(void (*Func)(int, int))
  307. {
  308. ExposeFunc = Func;
  309. }
  310. void tkReshapeFunc(void (*Func)(int, int))
  311. {
  312. ReshapeFunc = Func;
  313. }
  314. void tkDisplayFunc(void (*Func)(void))
  315. {
  316. DisplayFunc = Func;
  317. }
  318. void tkKeyDownFunc(GLenum (*Func)(int, GLenum))
  319. {
  320. KeyDownFunc = Func;
  321. }
  322. void tkMouseDownFunc(GLenum (*Func)(int, int, GLenum))
  323. {
  324. MouseDownFunc = Func;
  325. }
  326. void tkMouseUpFunc(GLenum (*Func)(int, int, GLenum))
  327. {
  328. MouseUpFunc = Func;
  329. }
  330. void tkMouseMoveFunc(GLenum (*Func)(int, int, GLenum))
  331. {
  332. MouseMoveFunc = Func;
  333. }
  334. void tkIdleFunc(void (*Func)(void))
  335. {
  336. IdleFunc = Func;
  337. }
  338. void tkInitPosition(int x, int y, int width, int height)
  339. {
  340. if (x == CW_USEDEFAULT)
  341. {
  342. x = 0;
  343. y = 0;
  344. windInfo.bDefPos = TRUE;
  345. }
  346. else
  347. windInfo.bDefPos = FALSE;
  348. windInfo.x = x + GetSystemMetrics(SM_CXFRAME);
  349. windInfo.y = y + GetSystemMetrics(SM_CYCAPTION)
  350. - GetSystemMetrics(SM_CYBORDER)
  351. + GetSystemMetrics(SM_CYFRAME);
  352. windInfo.width = width;
  353. windInfo.height = height;
  354. }
  355. void tkInitDisplayMode(GLenum type)
  356. {
  357. windInfo.type = type;
  358. }
  359. // Initialize a window, create a rendering context for that window
  360. GLenum tkInitWindow(char *title)
  361. {
  362. TKASSERT( NULL==tkhwnd );
  363. TKASSERT( NULL==tkhdc );
  364. TKASSERT( NULL==tkhrc );
  365. TKASSERT( NULL==tkhpalette );
  366. return tkInitWindowAW(title, FALSE);
  367. }
  368. GLenum tkInitWindowAW(char *title, BOOL bUnicode)
  369. {
  370. WNDCLASS wndclass;
  371. RECT WinRect;
  372. HANDLE hInstance;
  373. ATOM aRegister;
  374. GLenum Result = GL_FALSE;
  375. hInstance = GetModuleHandle(NULL);
  376. // Must not define CS_CS_PARENTDC style.
  377. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  378. wndclass.lpfnWndProc = (WNDPROC)tkWndProc;
  379. wndclass.cbClsExtra = 0;
  380. wndclass.cbWndExtra = 0;
  381. wndclass.hInstance = hInstance;
  382. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  383. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  384. wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
  385. wndclass.lpszMenuName = NULL;
  386. if (bUnicode)
  387. wndclass.lpszClassName = (LPCSTR)lpszClassNameW;
  388. else
  389. wndclass.lpszClassName = (LPCSTR)lpszClassName;
  390. if (bUnicode)
  391. {
  392. aRegister = RegisterClassW((CONST WNDCLASSW *)&wndclass);
  393. }
  394. else
  395. {
  396. aRegister = RegisterClass(&wndclass);
  397. }
  398. /*
  399. * If the window failed to register, then there's no
  400. * need to continue further.
  401. */
  402. if(0 == aRegister)
  403. {
  404. PrintMessage("Failed to register window class\n");
  405. return(Result);
  406. }
  407. /*
  408. * Make window large enough to hold a client area as large as windInfo
  409. */
  410. WinRect.left = windInfo.x;
  411. WinRect.right = windInfo.x + windInfo.width;
  412. WinRect.top = windInfo.y;
  413. WinRect.bottom = windInfo.y + windInfo.height;
  414. AdjustWindowRect(&WinRect, WS_OVERLAPPEDWINDOW, FALSE);
  415. /*
  416. * Must use WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles.
  417. */
  418. if (bUnicode)
  419. {
  420. tkhwnd = CreateWindowW(
  421. (LPCWSTR)lpszClassNameW,
  422. (LPCWSTR)title,
  423. WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  424. (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.left,
  425. (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.top,
  426. WinRect.right - WinRect.left,
  427. WinRect.bottom - WinRect.top,
  428. NULL,
  429. NULL,
  430. hInstance,
  431. NULL);
  432. }
  433. else
  434. {
  435. tkhwnd = CreateWindow(
  436. lpszClassName,
  437. title,
  438. WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  439. (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.left,
  440. (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.top,
  441. WinRect.right - WinRect.left,
  442. WinRect.bottom - WinRect.top,
  443. NULL,
  444. NULL,
  445. hInstance,
  446. NULL);
  447. }
  448. if ( NULL != tkhwnd )
  449. {
  450. // If default window positioning used, find out window position and fix
  451. // up the windInfo position info.
  452. if (windInfo.bDefPos)
  453. {
  454. GetWindowRect(tkhwnd, &WinRect);
  455. windInfo.x = WinRect.left + GetSystemMetrics(SM_CXFRAME);
  456. windInfo.y = WinRect.top + GetSystemMetrics(SM_CYCAPTION)
  457. - GetSystemMetrics(SM_CYBORDER)
  458. + GetSystemMetrics(SM_CYFRAME);
  459. }
  460. tkhdc = GetDC(tkhwnd);
  461. if ( NULL != tkhdc )
  462. {
  463. ShowWindow(tkhwnd, SW_SHOWDEFAULT);
  464. if ( FindPixelFormat(tkhdc, windInfo.type) )
  465. {
  466. /*
  467. * Create a Rendering Context
  468. */
  469. tkhrc = wglCreateContext(tkhdc);
  470. if ( NULL != tkhrc )
  471. {
  472. /*
  473. * Make it Current
  474. */
  475. if ( wglMakeCurrent(tkhdc, tkhrc) )
  476. {
  477. Result = GL_TRUE;
  478. }
  479. else
  480. {
  481. PrintMessage("wglMakeCurrent Failed\n");
  482. }
  483. }
  484. else
  485. {
  486. PrintMessage("wglCreateContext Failed\n");
  487. }
  488. }
  489. }
  490. else
  491. {
  492. PrintMessage("Could not get an HDC for window 0x%08lX\n", tkhwnd );
  493. }
  494. }
  495. else
  496. {
  497. PrintMessage("create window failed\n");
  498. }
  499. if ( GL_FALSE == Result )
  500. {
  501. DestroyThisWindow(tkhwnd); // Something Failed, Destroy this window
  502. }
  503. return( Result );
  504. }
  505. /******************************************************************************/
  506. /*
  507. * You cannot just call DestroyWindow() here. The programs do not expect
  508. * tkQuit() to return; DestroyWindow() just posts a WM_DESTROY message
  509. */
  510. void tkQuit(void)
  511. {
  512. DestroyThisWindow(tkhwnd);
  513. ExitProcess(0);
  514. }
  515. /******************************************************************************/
  516. void tkSetOneColor(int index, float r, float g, float b)
  517. {
  518. PALETTEENTRY PalEntry;
  519. HPALETTE Palette;
  520. if ( NULL != (Palette = CreateCIPalette( tkhdc )) )
  521. {
  522. PalEntry.peRed = (BYTE)(r*(float)255.0 + (float)0.5);
  523. PalEntry.peGreen = (BYTE)(g*(float)255.0 + (float)0.5);
  524. PalEntry.peBlue = (BYTE)(b*(float)255.0 + (float)0.5);
  525. PalEntry.peFlags = (BYTE)0;
  526. SetPaletteEntries( Palette, index, 1, &PalEntry);
  527. DelayPaletteRealization();
  528. }
  529. }
  530. void tkSetFogRamp(int density, int startIndex)
  531. {
  532. HPALETTE CurrentPal;
  533. PALETTEENTRY *pPalEntry;
  534. UINT n, i, j, k, intensity, fogValues, colorValues;
  535. if ( NULL != (CurrentPal = CreateCIPalette(tkhdc)) )
  536. {
  537. n = GetPaletteEntries( CurrentPal, 0, 0, NULL );
  538. pPalEntry = AllocateMemory( n * sizeof(PALETTEENTRY) );
  539. if ( NULL != pPalEntry)
  540. {
  541. fogValues = 1 << density;
  542. colorValues = 1 << startIndex;
  543. for (i = 0; i < colorValues; i++) {
  544. for (j = 0; j < fogValues; j++) {
  545. k = i * fogValues + j;
  546. intensity = i * fogValues + j * colorValues;
  547. //mf: not sure what they're trying to do here
  548. if (intensity > 0xFF) {
  549. intensity = 0xFF;
  550. }
  551. //intensity = (intensity << 8) | intensity; ???
  552. pPalEntry[k].peRed =
  553. pPalEntry[k].peGreen =
  554. pPalEntry[k].peBlue = (BYTE) intensity;
  555. pPalEntry[k].peFlags = 0;
  556. }
  557. }
  558. SetPaletteEntries(CurrentPal, 0, n, pPalEntry);
  559. FreeMemory( pPalEntry );
  560. DelayPaletteRealization();
  561. }
  562. }
  563. }
  564. void tkSetGreyRamp(void)
  565. {
  566. HPALETTE CurrentPal;
  567. PALETTEENTRY *Entries;
  568. UINT Count, i;
  569. float intensity;
  570. if ( NULL != (CurrentPal = CreateCIPalette( tkhdc )) )
  571. {
  572. Count = GetPaletteEntries( CurrentPal, 0, 0, NULL );
  573. Entries = AllocateMemory( Count * sizeof(PALETTEENTRY) );
  574. if ( NULL != Entries )
  575. {
  576. for (i = 0; i < Count; i++)
  577. {
  578. intensity = (float)(((double)i / (double)(Count-1)) * (double)255.0 + (double)0.5);
  579. Entries[i].peRed =
  580. Entries[i].peGreen =
  581. Entries[i].peBlue = (BYTE) intensity;
  582. Entries[i].peFlags = 0;
  583. }
  584. SetPaletteEntries( CurrentPal, 0, Count, Entries );
  585. FreeMemory( Entries );
  586. DelayPaletteRealization();
  587. }
  588. }
  589. }
  590. void tkSetRGBMap( int Size, float *Values )
  591. {
  592. HPALETTE CurrentPal;
  593. PIXELFORMATDESCRIPTOR Pfd, *pPfd;
  594. PALETTEENTRY *Entries;
  595. UINT Count;
  596. if ( NULL != (CurrentPal = CreateCIPalette( tkhdc )) )
  597. {
  598. pPfd = &Pfd;
  599. if ( PixelFormatDescriptorFromDc( tkhdc, pPfd ) )
  600. {
  601. Count = 1 << pPfd->cColorBits;
  602. Entries = AllocateMemory( Count * sizeof(PALETTEENTRY) );
  603. if ( NULL != Entries )
  604. {
  605. FillRgbPaletteEntries( pPfd, Entries, Count );
  606. SetPaletteEntries( CurrentPal, 0, Count, Entries );
  607. FreeMemory(Entries);
  608. RealizePaletteNow( tkhdc, tkhpalette );
  609. }
  610. }
  611. }
  612. }
  613. /******************************************************************************/
  614. void tkSwapBuffers(void)
  615. {
  616. SwapBuffers(tkhdc);
  617. }
  618. /******************************************************************************/
  619. GLint tkGetColorMapSize(void)
  620. {
  621. CreateCIPalette( tkhdc );
  622. if ( NULL == tkhpalette )
  623. return( 0 );
  624. return( GetPaletteEntries( tkhpalette, 0, 0, NULL ) );
  625. }
  626. void tkGetMouseLoc(int *x, int *y)
  627. {
  628. POINT Point;
  629. *x = 0;
  630. *y = 0;
  631. GetCursorPos(&Point);
  632. /*
  633. * GetCursorPos returns screen coordinates,
  634. * we want window coordinates
  635. */
  636. *x = Point.x - windInfo.x;
  637. *y = Point.y - windInfo.y;
  638. }
  639. HWND tkGetHWND(void)
  640. {
  641. return tkhwnd;
  642. }
  643. HDC tkGetHDC(void)
  644. {
  645. return tkhdc;
  646. }
  647. HGLRC tkGetHRC(void)
  648. {
  649. return tkhrc;
  650. }
  651. /***********************************************************************
  652. * *
  653. * The Following functions are for our own use only. (ie static) *
  654. * *
  655. ***********************************************************************/
  656. static long
  657. tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam)
  658. {
  659. int key;
  660. PAINTSTRUCT paint;
  661. HDC hdc;
  662. switch (message) {
  663. case WM_USER:
  664. if ( RealizePaletteNow( tkhdc, tkhpalette ) )
  665. {
  666. ForceRedraw( hWnd );
  667. }
  668. return(0);
  669. case WM_SIZE:
  670. windInfo.width = LOWORD(lParam);
  671. windInfo.height = HIWORD(lParam);
  672. if (ReshapeFunc)
  673. {
  674. (*ReshapeFunc)(windInfo.width, windInfo.height);
  675. ForceRedraw( hWnd );
  676. }
  677. return (0);
  678. case WM_MOVE:
  679. windInfo.x = LOWORD(lParam);
  680. windInfo.y = HIWORD(lParam);
  681. return (0);
  682. case WM_PAINT:
  683. /*
  684. * Validate the region even if there are no DisplayFunc.
  685. * Otherwise, USER will not stop sending WM_PAINT messages.
  686. */
  687. hdc = BeginPaint(tkhwnd, &paint);
  688. if (DisplayFunc)
  689. {
  690. (*DisplayFunc)();
  691. }
  692. EndPaint(tkhwnd, &paint);
  693. return (0);
  694. /*
  695. * WM_QUERYNEWPALETTE and WM_ACTIVATE were tried here.
  696. * They would not work all the time (except on fridays)
  697. * WM_NCACTIVATE seems more reliable
  698. */
  699. case WM_NCACTIVATE:
  700. if ( wParam )
  701. {
  702. if ( NULL != tkhpalette )
  703. {
  704. RealizePaletteNow( tkhdc, tkhpalette );
  705. }
  706. }
  707. /*
  708. * Pretend you didn't do anything let DefWindowProc() handle it.
  709. */
  710. break;
  711. case WM_MOUSEMOVE:
  712. if (MouseMoveFunc)
  713. {
  714. GLenum mask;
  715. mask = 0;
  716. if (wParam & MK_LBUTTON) {
  717. mask |= TK_LEFTBUTTON;
  718. }
  719. if (wParam & MK_MBUTTON) {
  720. mask |= TK_MIDDLEBUTTON;
  721. }
  722. if (wParam & MK_RBUTTON) {
  723. mask |= TK_RIGHTBUTTON;
  724. }
  725. if ((*MouseMoveFunc)( LOWORD(lParam), HIWORD(lParam), mask ))
  726. {
  727. ForceRedraw( hWnd );
  728. }
  729. }
  730. return (0);
  731. case WM_LBUTTONDOWN:
  732. SetCapture(hWnd);
  733. if (MouseDownFunc)
  734. {
  735. if ( (*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  736. TK_LEFTBUTTON) )
  737. {
  738. ForceRedraw( hWnd );
  739. }
  740. }
  741. return (0);
  742. case WM_LBUTTONUP:
  743. ReleaseCapture();
  744. if (MouseUpFunc)
  745. {
  746. if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam), TK_LEFTBUTTON))
  747. {
  748. ForceRedraw( hWnd );
  749. }
  750. }
  751. return (0);
  752. case WM_MBUTTONDOWN:
  753. SetCapture(hWnd);
  754. if (MouseDownFunc)
  755. {
  756. if ((*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  757. TK_MIDDLEBUTTON))
  758. {
  759. ForceRedraw( hWnd );
  760. }
  761. }
  762. return (0);
  763. case WM_MBUTTONUP:
  764. ReleaseCapture();
  765. if (MouseUpFunc)
  766. {
  767. if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
  768. TK_MIDDLEBUTTON))
  769. {
  770. ForceRedraw( hWnd );
  771. }
  772. }
  773. return (0);
  774. case WM_RBUTTONDOWN:
  775. SetCapture(hWnd);
  776. if (MouseDownFunc)
  777. {
  778. if ((*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  779. TK_RIGHTBUTTON))
  780. {
  781. ForceRedraw( hWnd );
  782. }
  783. }
  784. return (0);
  785. case WM_RBUTTONUP:
  786. ReleaseCapture();
  787. if (MouseUpFunc)
  788. {
  789. if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
  790. TK_RIGHTBUTTON))
  791. {
  792. ForceRedraw( hWnd );
  793. }
  794. }
  795. return (0);
  796. case WM_KEYDOWN:
  797. switch (wParam) {
  798. case VK_SPACE: key = TK_SPACE; break;
  799. case VK_RETURN: key = TK_RETURN; break;
  800. case VK_ESCAPE: key = TK_ESCAPE; break;
  801. case VK_LEFT: key = TK_LEFT; break;
  802. case VK_UP: key = TK_UP; break;
  803. case VK_RIGHT: key = TK_RIGHT; break;
  804. case VK_DOWN: key = TK_DOWN; break;
  805. default: key = GL_FALSE; break;
  806. }
  807. if (key && KeyDownFunc)
  808. {
  809. GLenum mask;
  810. mask = 0;
  811. if (GetKeyState(VK_CONTROL)) {
  812. mask |= TK_CONTROL;
  813. }
  814. if (GetKeyState(VK_SHIFT)) {
  815. mask |= TK_SHIFT;
  816. }
  817. if ( (*KeyDownFunc)(key, mask) )
  818. {
  819. ForceRedraw( hWnd );
  820. }
  821. }
  822. return (0);
  823. case WM_CHAR:
  824. if (('0' <= wParam && wParam <= '9') ||
  825. ('a' <= wParam && wParam <= 'z') ||
  826. ('A' <= wParam && wParam <= 'Z')) {
  827. key = wParam;
  828. } else {
  829. key = GL_FALSE;
  830. }
  831. if (key && KeyDownFunc) {
  832. GLenum mask;
  833. mask = 0;
  834. if (GetKeyState(VK_CONTROL)) {
  835. mask |= TK_CONTROL;
  836. }
  837. if (GetKeyState(VK_SHIFT)) {
  838. mask |= TK_SHIFT;
  839. }
  840. if ( (*KeyDownFunc)(key, mask) )
  841. {
  842. ForceRedraw( hWnd );
  843. }
  844. }
  845. return (0);
  846. case WM_CLOSE:
  847. DestroyWindow(tkhwnd);
  848. return(0);
  849. case WM_DESTROY:
  850. CleanUp();
  851. PostQuitMessage(TRUE);
  852. return 0;
  853. }
  854. return(DefWindowProc( hWnd, message, wParam, lParam));
  855. }
  856. #ifdef GAMMA_1_0
  857. static unsigned char threeto8[8] = {
  858. 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
  859. };
  860. static unsigned char twoto8[4] = {
  861. 0, 0x55, 0xaa, 0xff
  862. };
  863. static int defaultOverride[13] = {
  864. 0, 4, 32, 36, 128, 132, 160, 173, 181, 245, 247, 164, 156
  865. };
  866. #endif
  867. // The following tables use gamma 1.4
  868. static unsigned char threeto8[8] = {
  869. 0, 63, 104, 139, 171, 200, 229, 255
  870. };
  871. static unsigned char twoto8[4] = {
  872. 0, 116, 191, 255
  873. };
  874. static unsigned char oneto8[2] = {
  875. 0, 255
  876. };
  877. static int defaultOverride[13] = {
  878. 0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91
  879. };
  880. // These are the ones GMT (tarolli) calculated (note 247 vs 191)
  881. // 0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 191, 164, 91
  882. static unsigned char
  883. ComponentFromIndex(int i, int nbits, int shift)
  884. {
  885. unsigned char val;
  886. val = i >> shift;
  887. switch (nbits) {
  888. case 1:
  889. val &= 0x1;
  890. return oneto8[val];
  891. case 2:
  892. val &= 0x3;
  893. return twoto8[val];
  894. case 3:
  895. val &= 0x7;
  896. return threeto8[val];
  897. default:
  898. //PrintMessage("default case in Component from index, nbits %d\n", nbits);
  899. return 0;
  900. }
  901. }
  902. static PALETTEENTRY defaultPalEntry[20] = {
  903. { 0, 0, 0, 0 },
  904. { 0x80,0, 0, 0 },
  905. { 0, 0x80,0, 0 },
  906. { 0x80,0x80,0, 0 },
  907. { 0, 0, 0x80, 0 },
  908. { 0x80,0, 0x80, 0 },
  909. { 0, 0x80,0x80, 0 },
  910. { 0xC0,0xC0,0xC0, 0 },
  911. { 192, 220, 192, 0 },
  912. { 166, 202, 240, 0 },
  913. { 255, 251, 240, 0 },
  914. { 160, 160, 164, 0 },
  915. { 0x80,0x80,0x80, 0 },
  916. { 0xFF,0, 0, 0 },
  917. { 0, 0xFF,0, 0 },
  918. { 0xFF,0xFF,0, 0 },
  919. { 0, 0, 0xFF, 0 },
  920. { 0xFF,0, 0xFF, 0 },
  921. { 0, 0xFF,0xFF, 0 },
  922. { 0xFF,0xFF,0xFF, 0 }
  923. };
  924. static PALETTEENTRY *
  925. FillRgbPaletteEntries( PIXELFORMATDESCRIPTOR *Pfd,
  926. PALETTEENTRY *Entries,
  927. UINT Count
  928. )
  929. {
  930. PALETTEENTRY *Entry;
  931. UINT i;
  932. if ( NULL != Entries )
  933. {
  934. for ( i = 0, Entry = Entries ; i < Count ; i++, Entry++ )
  935. {
  936. Entry->peRed = ComponentFromIndex(i, Pfd->cRedBits,
  937. Pfd->cRedShift);
  938. Entry->peGreen = ComponentFromIndex(i, Pfd->cGreenBits,
  939. Pfd->cGreenShift);
  940. Entry->peBlue = ComponentFromIndex(i, Pfd->cBlueBits,
  941. Pfd->cBlueShift);
  942. Entry->peFlags = 0;
  943. }
  944. // XXX fix this up
  945. if ( (256 == Count) &&
  946. (3 == Pfd->cRedBits) && (0 == Pfd->cRedShift) &&
  947. (3 == Pfd->cGreenBits) && (3 == Pfd->cGreenShift) &&
  948. (2 == Pfd->cBlueBits) && (6 == Pfd->cBlueShift)
  949. )
  950. {
  951. for ( i = 1 ; i <= 12 ; i++)
  952. {
  953. Entries[defaultOverride[i]] = defaultPalEntry[i];
  954. }
  955. }
  956. }
  957. return( Entries );
  958. }
  959. static HPALETTE
  960. CreateRGBPalette( HDC Dc )
  961. {
  962. PIXELFORMATDESCRIPTOR Pfd, *pPfd;
  963. LOGPALETTE *LogPalette;
  964. UINT Count;
  965. if ( NULL == tkhpalette )
  966. {
  967. pPfd = &Pfd;
  968. if ( PixelFormatDescriptorFromDc( Dc, pPfd ) )
  969. {
  970. /*
  971. * Make sure we need a palette
  972. */
  973. if (pPfd->dwFlags & PFD_NEED_PALETTE)
  974. {
  975. Count = 1 << pPfd->cColorBits;
  976. LogPalette = AllocateMemory( sizeof(LOGPALETTE) +
  977. Count * sizeof(PALETTEENTRY));
  978. if ( NULL != LogPalette )
  979. {
  980. LogPalette->palVersion = 0x300;
  981. LogPalette->palNumEntries = Count;
  982. FillRgbPaletteEntries( pPfd,
  983. &LogPalette->palPalEntry[0], Count );
  984. tkhpalette = CreatePalette(LogPalette);
  985. FreeMemory(LogPalette);
  986. RealizePaletteNow( Dc, tkhpalette );
  987. }
  988. }
  989. }
  990. }
  991. return( tkhpalette );
  992. }
  993. static HPALETTE
  994. CreateCIPalette( HDC Dc )
  995. {
  996. PIXELFORMATDESCRIPTOR Pfd;
  997. LOGPALETTE *LogicalPalette;
  998. HPALETTE StockPalette;
  999. UINT PaletteSize, StockPaletteSize, EntriesToCopy;
  1000. if ( (Dc != NULL) && (NULL == tkhpalette) )
  1001. {
  1002. PixelFormatDescriptorFromDc( Dc, &Pfd );
  1003. if ( Pfd.iPixelType & PFD_TYPE_COLORINDEX )
  1004. {
  1005. /*
  1006. * Limit the size of the palette to 256 colors.
  1007. * Why? Because this is what was decided.
  1008. */
  1009. PaletteSize = (Pfd.cColorBits >= 8) ? 256 : (1 << Pfd.cColorBits);
  1010. LogicalPalette = AllocateZeroedMemory( sizeof(LOGPALETTE) +
  1011. (PaletteSize * sizeof(PALETTEENTRY)) );
  1012. if ( NULL != LogicalPalette )
  1013. {
  1014. LogicalPalette->palVersion = 0x300;
  1015. LogicalPalette->palNumEntries = PaletteSize;
  1016. StockPalette = GetStockObject(DEFAULT_PALETTE);
  1017. StockPaletteSize = GetPaletteEntries( StockPalette, 0, 0, NULL );
  1018. /*
  1019. * start by copying default palette into new one
  1020. */
  1021. EntriesToCopy = StockPaletteSize < PaletteSize ?
  1022. StockPaletteSize : PaletteSize;
  1023. GetPaletteEntries( StockPalette, 0, EntriesToCopy,
  1024. LogicalPalette->palPalEntry );
  1025. tkhpalette = CreatePalette(LogicalPalette);
  1026. FreeMemory(LogicalPalette);
  1027. RealizePaletteNow( Dc, tkhpalette );
  1028. }
  1029. }
  1030. }
  1031. return( tkhpalette );
  1032. }
  1033. static BOOL
  1034. FindPixelFormat(HDC hdc, GLenum type)
  1035. {
  1036. PIXELFORMATDESCRIPTOR pfd, *ppfd;
  1037. int PfdIndex;
  1038. BOOL Result = FALSE;
  1039. ppfd = &pfd;
  1040. ppfd->nSize = sizeof(pfd);
  1041. ppfd->nVersion = 1;
  1042. ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
  1043. ppfd->dwLayerMask = PFD_MAIN_PLANE;
  1044. if (TK_IS_DOUBLE(type)) {
  1045. ppfd->dwFlags |= PFD_DOUBLEBUFFER;
  1046. }
  1047. if (TK_IS_INDEX(type)) {
  1048. ppfd->iPixelType = PFD_TYPE_COLORINDEX;
  1049. ppfd->cColorBits = 8;
  1050. }
  1051. if (TK_IS_RGB(type)) {
  1052. ppfd->iPixelType = PFD_TYPE_RGBA;
  1053. ppfd->cColorBits = 24;
  1054. }
  1055. if (TK_HAS_ACCUM(type)) {
  1056. ppfd->cAccumBits = ppfd->cColorBits;
  1057. } else {
  1058. ppfd->cAccumBits = 0;
  1059. }
  1060. if (TK_HAS_DEPTH(type)) {
  1061. ppfd->cDepthBits = 24;
  1062. } else {
  1063. ppfd->cDepthBits = 0;
  1064. }
  1065. if (TK_HAS_STENCIL(type)) {
  1066. ppfd->cStencilBits = 8;
  1067. } else {
  1068. ppfd->cStencilBits = 0;
  1069. }
  1070. PfdIndex = ChoosePixelFormat(hdc, ppfd);
  1071. if ( PfdIndex )
  1072. {
  1073. if ( SetPixelFormat(hdc, PfdIndex, ppfd) )
  1074. {
  1075. /*
  1076. * If this pixel format requires a palette do it now.
  1077. * In colorindex mode, create a logical palette only
  1078. * if the application needs to modify it.
  1079. */
  1080. CreateRGBPalette( hdc );
  1081. Result = TRUE;
  1082. }
  1083. else
  1084. {
  1085. PrintMessage("SetPixelFormat failed\n");
  1086. }
  1087. }
  1088. else
  1089. {
  1090. PrintMessage("ChoosePixelFormat failed\n");
  1091. }
  1092. return(Result);
  1093. }
  1094. static void
  1095. PrintMessage( const char *Format, ... )
  1096. {
  1097. va_list ArgList;
  1098. char Buffer[256];
  1099. va_start(ArgList, Format);
  1100. vsprintf(Buffer, Format, ArgList);
  1101. va_end(ArgList);
  1102. MessageBox(NULL, Buffer, "Error", MB_OK);
  1103. }
  1104. static void
  1105. DelayPaletteRealization( void )
  1106. {
  1107. MSG Message;
  1108. TKASSERT(NULL!=tkhwnd);
  1109. /*
  1110. * Add a WM_USER message to the queue, if there isn't one there already.
  1111. */
  1112. if (!PeekMessage(&Message, tkhwnd, WM_USER, WM_USER, PM_NOREMOVE) )
  1113. {
  1114. PostMessage( tkhwnd, WM_USER, 0, 0);
  1115. }
  1116. }
  1117. static BOOL
  1118. RealizePaletteNow( HDC Dc, HPALETTE Palette )
  1119. {
  1120. BOOL Result = FALSE;
  1121. TKASSERT( NULL!=Dc );
  1122. TKASSERT( NULL!=Palette );
  1123. if ( NULL != SelectPalette( Dc, Palette, FALSE) )
  1124. {
  1125. if ( GDI_ERROR != RealizePalette( Dc ) )
  1126. {
  1127. Result = TRUE;
  1128. }
  1129. }
  1130. return( Result );
  1131. }
  1132. static void
  1133. ForceRedraw( HWND Window )
  1134. {
  1135. MSG Message;
  1136. if (!PeekMessage(&Message, Window, WM_PAINT, WM_PAINT, PM_NOREMOVE) )
  1137. {
  1138. InvalidateRect( Window, NULL, FALSE );
  1139. }
  1140. }
  1141. static int
  1142. PixelFormatDescriptorFromDc( HDC Dc, PIXELFORMATDESCRIPTOR *Pfd )
  1143. {
  1144. int PfdIndex;
  1145. if ( 0 < (PfdIndex = GetPixelFormat( Dc )) )
  1146. {
  1147. if ( 0 < DescribePixelFormat( Dc, PfdIndex, sizeof(*Pfd), Pfd ) )
  1148. {
  1149. return(PfdIndex);
  1150. }
  1151. else
  1152. {
  1153. PrintMessage("Could not get a description of pixel format %d\n",
  1154. PfdIndex );
  1155. }
  1156. }
  1157. else
  1158. {
  1159. PrintMessage("Could not get pixel format for Dc 0x%08lX\n", Dc );
  1160. }
  1161. return( 0 );
  1162. }
  1163. static void
  1164. DestroyThisWindow( HWND Window )
  1165. {
  1166. if ( NULL != Window )
  1167. {
  1168. DestroyWindow( Window );
  1169. }
  1170. }
  1171. /*
  1172. * This Should be called in response to a WM_DESTROY message
  1173. */
  1174. static void
  1175. CleanUp( void )
  1176. {
  1177. HPALETTE hStock;
  1178. if ( NULL != tkhrc )
  1179. {
  1180. wglMakeCurrent( tkhdc, NULL ); // No current context
  1181. wglDeleteContext(tkhrc); // Delete this context
  1182. }
  1183. if ( NULL != tkhdc )
  1184. {
  1185. ReleaseDC( tkhwnd, tkhdc );
  1186. }
  1187. if ( NULL != tkhpalette )
  1188. {
  1189. if(hStock = GetStockObject(DEFAULT_PALETTE))
  1190. SelectPalette(tkhdc,hStock,FALSE);
  1191. DeleteObject(tkhpalette);
  1192. }
  1193. /*
  1194. * Programs maybe using printf's
  1195. */
  1196. flushall();
  1197. tkhwnd = NULL;
  1198. tkhdc = NULL;
  1199. tkhrc = NULL;
  1200. tkhpalette = NULL;
  1201. ExposeFunc = NULL;
  1202. ReshapeFunc = NULL;
  1203. IdleFunc = NULL;
  1204. DisplayFunc = NULL;
  1205. KeyDownFunc = NULL;
  1206. MouseDownFunc = NULL;
  1207. MouseUpFunc = NULL;
  1208. MouseMoveFunc = NULL;
  1209. }
  1210. static void *
  1211. AllocateMemory( size_t Size )
  1212. {
  1213. return( LocalAlloc( LMEM_FIXED, Size ) );
  1214. }
  1215. static void *
  1216. AllocateZeroedMemory( size_t Size )
  1217. {
  1218. return( LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, Size ) );
  1219. }
  1220. static void
  1221. FreeMemory( void *Chunk )
  1222. {
  1223. TKASSERT( NULL!=Chunk );
  1224. LocalFree( Chunk );
  1225. }
  1226. /*******************************************************************
  1227. * *
  1228. * Debugging functions go here *
  1229. * *
  1230. *******************************************************************/
  1231. #if DBGFUNC
  1232. static void
  1233. DbgPrintf( const char *Format, ... )
  1234. {
  1235. va_list ArgList;
  1236. char Buffer[256];
  1237. va_start(ArgList, Format);
  1238. vsprintf(Buffer, Format, ArgList);
  1239. va_end(ArgList);
  1240. printf("%s", Buffer );
  1241. fflush(stdout);
  1242. }
  1243. static void
  1244. pwi( void )
  1245. {
  1246. DbgPrintf("windInfo: x %d, y %d, w %d, h %d\n", windInfo.x, windInfo.y, windInfo.width, windInfo.height);
  1247. }
  1248. static void
  1249. pwr(RECT *pr)
  1250. {
  1251. DbgPrintf("Rect: left %d, top %d, right %d, bottom %d\n", pr->left, pr->top, pr->right, pr->bottom);
  1252. }
  1253. static void
  1254. ShowPixelFormat(HDC hdc)
  1255. {
  1256. PIXELFORMATDESCRIPTOR pfd, *ppfd;
  1257. int format;
  1258. ppfd = &pfd;
  1259. format = PixelFormatDescriptorFromDc( hdc, ppfd );
  1260. DbgPrintf("Pixel format %d\n", format);
  1261. DbgPrintf(" dwFlags - 0x%x", ppfd->dwFlags);
  1262. if (ppfd->dwFlags & PFD_DOUBLEBUFFER) DbgPrintf("PFD_DOUBLEBUFFER ");
  1263. if (ppfd->dwFlags & PFD_STEREO) DbgPrintf("PFD_STEREO ");
  1264. if (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) DbgPrintf("PFD_DRAW_TO_WINDOW ");
  1265. if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) DbgPrintf("PFD_DRAW_TO_BITMAP ");
  1266. if (ppfd->dwFlags & PFD_SUPPORT_GDI) DbgPrintf("PFD_SUPPORT_GDI ");
  1267. if (ppfd->dwFlags & PFD_SUPPORT_OPENGL) DbgPrintf("PFD_SUPPORT_OPENGL ");
  1268. if (ppfd->dwFlags & PFD_GENERIC_FORMAT) DbgPrintf("PFD_GENERIC_FORMAT ");
  1269. if (ppfd->dwFlags & PFD_NEED_PALETTE) DbgPrintf("PFD_NEED_PALETTE ");
  1270. DbgPrintf("\n");
  1271. DbgPrintf(" iPixelType - %d", ppfd->iPixelType);
  1272. if (ppfd->iPixelType == PFD_TYPE_RGBA) DbgPrintf("PGD_TYPE_RGBA\n");
  1273. if (ppfd->iPixelType == PFD_TYPE_COLORINDEX) DbgPrintf("PGD_TYPE_COLORINDEX\n");
  1274. DbgPrintf(" cColorBits - %d\n", ppfd->cColorBits);
  1275. DbgPrintf(" cRedBits - %d\n", ppfd->cRedBits);
  1276. DbgPrintf(" cRedShift - %d\n", ppfd->cRedShift);
  1277. DbgPrintf(" cGreenBits - %d\n", ppfd->cGreenBits);
  1278. DbgPrintf(" cGreenShift - %d\n", ppfd->cGreenShift);
  1279. DbgPrintf(" cBlueBits - %d\n", ppfd->cBlueBits);
  1280. DbgPrintf(" cBlueShift - %d\n", ppfd->cBlueShift);
  1281. DbgPrintf(" cAlphaBits - %d\n", ppfd->cAlphaBits);
  1282. DbgPrintf(" cAlphaShift - 0x%x\n", ppfd->cAlphaShift);
  1283. DbgPrintf(" cAccumBits - %d\n", ppfd->cAccumBits);
  1284. DbgPrintf(" cAccumRedBits - %d\n", ppfd->cAccumRedBits);
  1285. DbgPrintf(" cAccumGreenBits - %d\n", ppfd->cAccumGreenBits);
  1286. DbgPrintf(" cAccumBlueBits - %d\n", ppfd->cAccumBlueBits);
  1287. DbgPrintf(" cAccumAlphaBits - %d\n", ppfd->cAccumAlphaBits);
  1288. DbgPrintf(" cDepthBits - %d\n", ppfd->cDepthBits);
  1289. DbgPrintf(" cStencilBits - %d\n", ppfd->cStencilBits);
  1290. DbgPrintf(" cAuxBuffers - %d\n", ppfd->cAuxBuffers);
  1291. DbgPrintf(" iLayerType - %d\n", ppfd->iLayerType);
  1292. DbgPrintf(" bReserved - %d\n", ppfd->bReserved);
  1293. DbgPrintf(" dwLayerMask - 0x%x\n", ppfd->dwLayerMask);
  1294. DbgPrintf(" dwVisibleMask - 0x%x\n", ppfd->dwVisibleMask);
  1295. DbgPrintf(" dwDamageMask - 0x%x\n", ppfd->dwDamageMask);
  1296. }
  1297. #endif /* DBG */