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.

2623 lines
80 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(WINVER < 0x0400)
  43. // Ordinarily not defined for versions before 4.00.
  44. #define COLOR_3DDKSHADOW 21
  45. #define COLOR_3DLIGHT 22
  46. #define COLOR_INFOTEXT 23
  47. #define COLOR_INFOBK 24
  48. #endif
  49. #define static
  50. #if defined(__cplusplus) || defined(c_plusplus)
  51. #define class c_class
  52. #endif
  53. #if DBG
  54. #define TKASSERT(x) \
  55. if ( !(x) ) { \
  56. PrintMessage("%s(%d) Assertion failed %s\n", \
  57. __FILE__, __LINE__, #x); \
  58. }
  59. #else
  60. #define TKASSERT(x)
  61. #endif /* DBG */
  62. /******************************************************************************/
  63. static struct _WINDOWINFO {
  64. int x, y;
  65. int width, height;
  66. GLenum type;
  67. GLenum dmPolicy;
  68. int ipfd;
  69. BOOL bDefPos;
  70. } windInfo = {
  71. 0, 0, 100, 100, TK_INDEX | TK_SINGLE, TK_MINIMUM_CRITERIA, 0, TRUE
  72. };
  73. HWND tkhwnd = NULL;
  74. HDC tkhdc = NULL;
  75. static HGLRC tkhrc = NULL;
  76. HPALETTE tkhpalette = NULL;
  77. static OSVERSIONINFO tkOSVerInfo;
  78. GLboolean tkPopupEnable = TRUE;
  79. // Fixed palette support.
  80. #define BLACK PALETTERGB(0,0,0)
  81. #define WHITE PALETTERGB(255,255,255)
  82. #define MAX_STATIC_COLORS (COLOR_INFOBK - COLOR_SCROLLBAR + 1)
  83. static int tkNumStaticColors = MAX_STATIC_COLORS;
  84. // TRUE if app wants to take over palette
  85. static BOOL tkUseStaticColors = FALSE;
  86. // TRUE if static system color settings have been replaced with B&W settings.
  87. BOOL tkSystemColorsInUse = FALSE;
  88. // TRUE if original static colors saved
  89. static BOOL tkStaticColorsSaved = FALSE;
  90. // saved system static colors (initialize with default colors)
  91. static COLORREF gacrSave[MAX_STATIC_COLORS];
  92. // new B&W system static colors
  93. static COLORREF gacrBlackAndWhite[] = {
  94. WHITE, // COLOR_SCROLLBAR
  95. BLACK, // COLOR_BACKGROUND
  96. BLACK, // COLOR_ACTIVECAPTION
  97. WHITE, // COLOR_INACTIVECAPTION
  98. WHITE, // COLOR_MENU
  99. WHITE, // COLOR_WINDOW
  100. BLACK, // COLOR_WINDOWFRAME
  101. BLACK, // COLOR_MENUTEXT
  102. BLACK, // COLOR_WINDOWTEXT
  103. WHITE, // COLOR_CAPTIONTEXT
  104. WHITE, // COLOR_ACTIVEBORDER
  105. WHITE, // COLOR_INACTIVEBORDER
  106. WHITE, // COLOR_APPWORKSPACE
  107. BLACK, // COLOR_HIGHLIGHT
  108. WHITE, // COLOR_HIGHLIGHTTEXT
  109. WHITE, // COLOR_BTNFACE
  110. BLACK, // COLOR_BTNSHADOW
  111. BLACK, // COLOR_GRAYTEXT
  112. BLACK, // COLOR_BTNTEXT
  113. BLACK, // COLOR_INACTIVECAPTIONTEXT
  114. BLACK, // COLOR_BTNHIGHLIGHT
  115. BLACK, // COLOR_3DDKSHADOW
  116. WHITE, // COLOR_3DLIGHT
  117. BLACK, // COLOR_INFOTEXT
  118. WHITE // COLOR_INFOBK
  119. };
  120. static INT gaiStaticIndex[] = {
  121. COLOR_SCROLLBAR ,
  122. COLOR_BACKGROUND ,
  123. COLOR_ACTIVECAPTION ,
  124. COLOR_INACTIVECAPTION ,
  125. COLOR_MENU ,
  126. COLOR_WINDOW ,
  127. COLOR_WINDOWFRAME ,
  128. COLOR_MENUTEXT ,
  129. COLOR_WINDOWTEXT ,
  130. COLOR_CAPTIONTEXT ,
  131. COLOR_ACTIVEBORDER ,
  132. COLOR_INACTIVEBORDER ,
  133. COLOR_APPWORKSPACE ,
  134. COLOR_HIGHLIGHT ,
  135. COLOR_HIGHLIGHTTEXT ,
  136. COLOR_BTNFACE ,
  137. COLOR_BTNSHADOW ,
  138. COLOR_GRAYTEXT ,
  139. COLOR_BTNTEXT ,
  140. COLOR_INACTIVECAPTIONTEXT,
  141. COLOR_BTNHIGHLIGHT ,
  142. COLOR_3DDKSHADOW ,
  143. COLOR_3DLIGHT ,
  144. COLOR_INFOTEXT ,
  145. COLOR_INFOBK
  146. };
  147. static BOOL GrabStaticEntries(HDC);
  148. static BOOL ReleaseStaticEntries(HDC);
  149. #define RESTORE_FROM_REGISTRY 1
  150. #if RESTORE_FROM_REGISTRY
  151. // Registry names for the system colors.
  152. CHAR *gaszSysClrNames[] = {
  153. "Scrollbar", // COLOR_SCROLLBAR 0
  154. "Background", // COLOR_BACKGROUND 1 (also COLOR_DESKTOP)
  155. "ActiveTitle", // COLOR_ACTIVECAPTION 2
  156. "InactiveTitle", // COLOR_INACTIVECAPTION 3
  157. "Menu", // COLOR_MENU 4
  158. "Window", // COLOR_WINDOW 5
  159. "WindowFrame", // COLOR_WINDOWFRAME 6
  160. "MenuText", // COLOR_MENUTEXT 7
  161. "WindowText", // COLOR_WINDOWTEXT 8
  162. "TitleText", // COLOR_CAPTIONTEXT 9
  163. "ActiveBorder", // COLOR_ACTIVEBORDER 10
  164. "InactiveBorder", // COLOR_INACTIVEBORDER 11
  165. "AppWorkspace", // COLOR_APPWORKSPACE 12
  166. "Hilight", // COLOR_HIGHLIGHT 13
  167. "HilightText", // COLOR_HIGHLIGHTTEXT 14
  168. "ButtonFace", // COLOR_BTNFACE 15 (also COLOR_3DFACE)
  169. "ButtonShadow", // COLOR_BTNSHADOW 16 (also COLOR_3DSHADOW)
  170. "GrayText", // COLOR_GRAYTEXT 17
  171. "ButtonText", // COLOR_BTNTEXT 18
  172. "InactiveTitleText", // COLOR_INACTIVECAPTIONTEXT 19
  173. "ButtonHilight", // COLOR_BTNHIGHLIGHT 20 (also COLOR_3DHILIGHT)
  174. "ButtonDkShadow", // COLOR_3DDKSHADOW 21
  175. "ButtonLight", // COLOR_3DLIGHT 22
  176. "InfoText", // COLOR_INFOTEXT 23
  177. "InfoWindow" // COLOR_INFOBK 24
  178. };
  179. static BOOL GetRegistrySysColors(COLORREF *, int);
  180. #endif
  181. static void (*ExposeFunc)(int, int) = NULL;
  182. static void (*ReshapeFunc)(int, int) = NULL;
  183. static void (*DisplayFunc)(void) = NULL;
  184. static GLenum (*KeyDownFunc)(int, GLenum) = NULL;
  185. static GLenum (*MouseDownFunc)(int, int, GLenum) = NULL;
  186. static GLenum (*MouseUpFunc)(int, int, GLenum) = NULL;
  187. static GLenum (*MouseMoveFunc)(int, int, GLenum) = NULL;
  188. static void (*IdleFunc)(void) = NULL;
  189. static char *lpszClassName = "tkLibWClass";
  190. static WCHAR *lpszClassNameW = L"tkLibWClass";
  191. static LRESULT tkWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
  192. static unsigned char ComponentFromIndex(int i, int nbits, int shift );
  193. static void PrintMessage( const char *Format, ... );
  194. static PALETTEENTRY *FillRgbPaletteEntries( PIXELFORMATDESCRIPTOR *Pfd, PALETTEENTRY *Entries, UINT Count );
  195. static HPALETTE CreateCIPalette( HDC Dc );
  196. static HPALETTE CreateRGBPalette( HDC hdc );
  197. static void DestroyThisWindow( HWND Window );
  198. static void CleanUp( void );
  199. static void DelayPaletteRealization( void );
  200. static long RealizePaletteNow( HDC Dc, HPALETTE Palette, BOOL bForceBackground );
  201. static void ForceRedraw( HWND Window );
  202. static BOOL FindPixelFormat(HDC hdc, GLenum type);
  203. static int FindBestPixelFormat(HDC hdc, GLenum type, PIXELFORMATDESCRIPTOR *ppfd);
  204. static int FindExactPixelFormat(HDC hdc, GLenum type, PIXELFORMATDESCRIPTOR *ppfd);
  205. static BOOL IsPixelFormatValid(HDC hdc, int ipfd, PIXELFORMATDESCRIPTOR *ppfd);
  206. static int PixelFormatDescriptorFromDc( HDC Dc, PIXELFORMATDESCRIPTOR *Pfd );
  207. static void *AllocateMemory( size_t Size );
  208. static void *AllocateZeroedMemory( size_t Size );
  209. static void FreeMemory( void *Chunk );
  210. /*
  211. * Prototypes for the debugging functions go here
  212. */
  213. #define DBGFUNC 0
  214. #if DBGFUNC
  215. static void DbgPrintf( const char *Format, ... );
  216. static void pwi( void );
  217. static void pwr(RECT *pr);
  218. static void ShowPixelFormat(HDC hdc);
  219. #endif
  220. static float colorMaps[] = {
  221. 0.000000F, 1.000000F, 0.000000F, 1.000000F, 0.000000F, 1.000000F,
  222. 0.000000F, 1.000000F, 0.333333F, 0.776471F, 0.443137F, 0.556863F,
  223. 0.443137F, 0.556863F, 0.219608F, 0.666667F, 0.666667F, 0.333333F,
  224. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  225. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  226. 0.666667F, 0.333333F, 0.039216F, 0.078431F, 0.117647F, 0.156863F,
  227. 0.200000F, 0.239216F, 0.278431F, 0.317647F, 0.356863F, 0.400000F,
  228. 0.439216F, 0.478431F, 0.517647F, 0.556863F, 0.600000F, 0.639216F,
  229. 0.678431F, 0.717647F, 0.756863F, 0.800000F, 0.839216F, 0.878431F,
  230. 0.917647F, 0.956863F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  231. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.247059F, 0.247059F,
  232. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  233. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  234. 0.498039F, 0.498039F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  235. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 1.000000F, 1.000000F,
  236. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  237. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  238. 0.000000F, 0.000000F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  239. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.498039F, 0.498039F,
  240. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  241. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  242. 0.749020F, 0.749020F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  243. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 0.000000F, 0.000000F,
  244. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  245. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  246. 0.247059F, 0.247059F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  247. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.749020F, 0.749020F,
  248. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  249. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  250. 1.000000F, 1.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  251. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.247059F, 0.247059F,
  252. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  253. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  254. 0.498039F, 0.498039F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  255. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 1.000000F, 1.000000F,
  256. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  257. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  258. 0.000000F, 0.000000F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  259. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.498039F, 0.498039F,
  260. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  261. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  262. 0.749020F, 0.749020F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  263. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 0.000000F, 0.000000F,
  264. 1.000000F, 1.000000F, 0.000000F, 0.000000F, 1.000000F, 1.000000F,
  265. 0.333333F, 0.443137F, 0.776471F, 0.556863F, 0.443137F, 0.219608F,
  266. 0.556863F, 0.666667F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  267. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  268. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  269. 0.039216F, 0.078431F, 0.117647F, 0.156863F, 0.200000F, 0.239216F,
  270. 0.278431F, 0.317647F, 0.356863F, 0.400000F, 0.439216F, 0.478431F,
  271. 0.517647F, 0.556863F, 0.600000F, 0.639216F, 0.678431F, 0.717647F,
  272. 0.756863F, 0.800000F, 0.839216F, 0.878431F, 0.917647F, 0.956863F,
  273. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  274. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  275. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  276. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  277. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  278. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  279. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  280. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  281. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  282. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  283. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  284. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  285. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  286. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  287. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  288. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  289. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  290. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  291. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  292. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  293. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  294. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  295. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  296. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  297. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  298. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  299. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  300. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  301. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  302. 0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
  303. 0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
  304. 0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
  305. 0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
  306. 0.854902F, 1.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  307. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 0.333333F, 0.443137F,
  308. 0.443137F, 0.219608F, 0.776471F, 0.556863F, 0.556863F, 0.666667F,
  309. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  310. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
  311. 0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.039216F, 0.078431F,
  312. 0.117647F, 0.156863F, 0.200000F, 0.239216F, 0.278431F, 0.317647F,
  313. 0.356863F, 0.400000F, 0.439216F, 0.478431F, 0.517647F, 0.556863F,
  314. 0.600000F, 0.639216F, 0.678431F, 0.717647F, 0.756863F, 0.800000F,
  315. 0.839216F, 0.878431F, 0.917647F, 0.956863F, 0.000000F, 0.000000F,
  316. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  317. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  318. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  319. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  320. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  321. 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
  322. 0.000000F, 0.000000F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  323. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  324. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  325. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  326. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  327. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  328. 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
  329. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  330. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  331. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  332. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  333. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  334. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
  335. 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.749020F, 0.749020F,
  336. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  337. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  338. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  339. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  340. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  341. 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
  342. 0.749020F, 0.749020F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  343. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  344. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  345. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  346. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  347. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  348. 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
  349. };
  350. /* Default Palette */
  351. float auxRGBMap[20][3] = {
  352. { 0.0F, 0.0F, 0.0F }, /* 0: black */
  353. { 0x80/255.0F, 0.0F, 0.0F }, /* 1: Half red */
  354. { 0.0F, 0x80/255.0F, 0.0F }, /* 2: Half green */
  355. { 0x80/255.0F, 0x80/255.0F, 0.0F }, /* 3: Half yellow */
  356. { 0.0F, 0.0F, 0x80/255.0F }, /* 4: Half blue */
  357. { 0x80/255.0F, 0.0F, 0x80/255.0F }, /* 5: Half magenta */
  358. { 0.0F, 0x80/255.0F, 0x80/255.0F }, /* 6: Half cyan */
  359. { 0xC0/255.0F, 0xC0/255.0F, 0xC0/255.0F }, /* 7: Light gray */
  360. { 0xC0/255.0F, 0xDC/255.0F, 0xC0/255.0F }, /* 8: Green gray */
  361. { 0xA6/255.0F, 0xCA/255.0F, 0xF0/255.0F }, /* 9: Half gray */
  362. { 1.0F, 0xFB/255.0F, 0xF0/255.0F }, /* 10: Pale */
  363. { 0xA0/255.0F, 0xA0/255.0F, 0xA4/255.0F }, /* 11: Med gray */
  364. { 0x80/255.0F, 0x80/255.0F, 0x80/255.0F }, /* 12: Dark gray */
  365. { 1.0F, 0.0F, 0.0F }, /* 13: red */
  366. { 0.0F, 1.0F, 0.0F }, /* 14: green */
  367. { 1.0F, 1.0F, 0.0F }, /* 15: yellow */
  368. { 0.0F, 0.0F, 1.0F }, /* 16: blue */
  369. { 1.0F, 0.0F, 1.0F }, /* 17: magenta */
  370. { 0.0F, 1.0F, 1.0F }, /* 18: cyan */
  371. { 1.0F, 1.0F, 1.0F }, /* 19: white */
  372. };
  373. /***************************************************************
  374. * *
  375. * Exported Functions go here *
  376. * *
  377. ***************************************************************/
  378. void tkErrorPopups(GLboolean bEnable)
  379. {
  380. tkPopupEnable = bEnable;
  381. }
  382. void tkCloseWindow(void)
  383. {
  384. DestroyThisWindow(tkhwnd);
  385. }
  386. void tkExec(void)
  387. {
  388. MSG Message;
  389. /*
  390. * WM_SIZE gets delivered before we get here!
  391. */
  392. if (ReshapeFunc)
  393. {
  394. RECT ClientRect;
  395. GetClientRect(tkhwnd, &ClientRect);
  396. (*ReshapeFunc)(ClientRect.right, ClientRect.bottom);
  397. }
  398. while (GL_TRUE)
  399. {
  400. /*
  401. * Process all pending messages
  402. */
  403. if (IdleFunc) {
  404. while (PeekMessage(&Message, NULL, 0, 0, PM_NOREMOVE) == TRUE) {
  405. if (GetMessage(&Message, NULL, 0, 0) ) {
  406. TranslateMessage(&Message);
  407. DispatchMessage(&Message);
  408. } else {
  409. /*
  410. * Nothing else to do here, just return
  411. */
  412. return;
  413. }
  414. }
  415. /*
  416. * If an idle function was defined, call it
  417. */
  418. if (IdleFunc) {
  419. (*IdleFunc)();
  420. }
  421. } else {
  422. if (GetMessage(&Message, NULL, 0, 0)) {
  423. TranslateMessage(&Message);
  424. DispatchMessage(&Message);
  425. } else {
  426. return;
  427. }
  428. }
  429. }
  430. }
  431. void tkExposeFunc(void (*Func)(int, int))
  432. {
  433. ExposeFunc = Func;
  434. }
  435. void tkReshapeFunc(void (*Func)(int, int))
  436. {
  437. ReshapeFunc = Func;
  438. }
  439. void tkDisplayFunc(void (*Func)(void))
  440. {
  441. DisplayFunc = Func;
  442. }
  443. void tkKeyDownFunc(GLenum (*Func)(int, GLenum))
  444. {
  445. KeyDownFunc = Func;
  446. }
  447. void tkMouseDownFunc(GLenum (*Func)(int, int, GLenum))
  448. {
  449. MouseDownFunc = Func;
  450. }
  451. void tkMouseUpFunc(GLenum (*Func)(int, int, GLenum))
  452. {
  453. MouseUpFunc = Func;
  454. }
  455. void tkMouseMoveFunc(GLenum (*Func)(int, int, GLenum))
  456. {
  457. MouseMoveFunc = Func;
  458. }
  459. void tkIdleFunc(void (*Func)(void))
  460. {
  461. IdleFunc = Func;
  462. }
  463. void tkInitPosition(int x, int y, int width, int height)
  464. {
  465. if (x == CW_USEDEFAULT)
  466. {
  467. x = 0;
  468. y = 0;
  469. windInfo.bDefPos = TRUE;
  470. }
  471. else
  472. windInfo.bDefPos = FALSE;
  473. windInfo.x = x + GetSystemMetrics(SM_CXFRAME);
  474. windInfo.y = y + GetSystemMetrics(SM_CYCAPTION)
  475. - GetSystemMetrics(SM_CYBORDER)
  476. + GetSystemMetrics(SM_CYFRAME);
  477. windInfo.width = width;
  478. windInfo.height = height;
  479. }
  480. void tkInitDisplayMode(GLenum type)
  481. {
  482. windInfo.type = type;
  483. }
  484. void tkInitDisplayModePolicy(GLenum type)
  485. {
  486. windInfo.dmPolicy = type;
  487. }
  488. GLenum tkInitDisplayModeID(GLint ipfd)
  489. {
  490. windInfo.ipfd = ipfd;
  491. return GL_TRUE;
  492. }
  493. // Initialize a window, create a rendering context for that window
  494. GLenum tkInitWindow(char *title)
  495. {
  496. TKASSERT( NULL==tkhwnd );
  497. TKASSERT( NULL==tkhdc );
  498. TKASSERT( NULL==tkhrc );
  499. TKASSERT( NULL==tkhpalette );
  500. return tkInitWindowAW(title, FALSE);
  501. }
  502. GLenum tkInitWindowAW(char *title, BOOL bUnicode)
  503. {
  504. WNDCLASS wndclass;
  505. RECT WinRect;
  506. HANDLE hInstance;
  507. ATOM aRegister;
  508. GLenum Result = GL_FALSE;
  509. BOOL bGetVersionExRet;
  510. hInstance = GetModuleHandle(NULL);
  511. tkOSVerInfo.dwOSVersionInfoSize = sizeof(tkOSVerInfo);
  512. bGetVersionExRet = GetVersionEx(&tkOSVerInfo);
  513. TKASSERT(bGetVersionExRet);
  514. if ( tkOSVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
  515. tkOSVerInfo.dwMajorVersion == 3 &&
  516. (tkOSVerInfo.dwMinorVersion == 5 || tkOSVerInfo.dwMinorVersion == 51) )
  517. tkNumStaticColors = COLOR_BTNHIGHLIGHT - COLOR_SCROLLBAR + 1;
  518. else
  519. tkNumStaticColors = COLOR_INFOBK - COLOR_SCROLLBAR + 1;
  520. // Must not define CS_PARENTDC style.
  521. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  522. wndclass.lpfnWndProc = (WNDPROC)tkWndProc;
  523. wndclass.cbClsExtra = 0;
  524. wndclass.cbWndExtra = 0;
  525. wndclass.hInstance = hInstance;
  526. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  527. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  528. wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
  529. wndclass.lpszMenuName = NULL;
  530. if (bUnicode)
  531. wndclass.lpszClassName = (LPCSTR)lpszClassNameW;
  532. else
  533. wndclass.lpszClassName = (LPCSTR)lpszClassName;
  534. if (bUnicode)
  535. {
  536. aRegister = RegisterClassW((CONST WNDCLASSW *)&wndclass);
  537. }
  538. else
  539. {
  540. aRegister = RegisterClass(&wndclass);
  541. }
  542. /*
  543. * If the window failed to register, then there's no
  544. * need to continue further.
  545. */
  546. if(0 == aRegister)
  547. {
  548. PrintMessage("Failed to register window class\n");
  549. return(Result);
  550. }
  551. /*
  552. * Make window large enough to hold a client area as large as windInfo
  553. */
  554. WinRect.left = windInfo.x;
  555. WinRect.right = windInfo.x + windInfo.width;
  556. WinRect.top = windInfo.y;
  557. WinRect.bottom = windInfo.y + windInfo.height;
  558. AdjustWindowRect(&WinRect, WS_OVERLAPPEDWINDOW, FALSE);
  559. /*
  560. * Must use WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles.
  561. */
  562. if (bUnicode)
  563. {
  564. tkhwnd = CreateWindowW(
  565. (LPCWSTR)lpszClassNameW,
  566. (LPCWSTR)title,
  567. WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  568. (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.left,
  569. (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.top,
  570. WinRect.right - WinRect.left,
  571. WinRect.bottom - WinRect.top,
  572. NULL,
  573. NULL,
  574. hInstance,
  575. NULL);
  576. }
  577. else
  578. {
  579. tkhwnd = CreateWindow(
  580. lpszClassName,
  581. title,
  582. WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  583. (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.left,
  584. (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.top,
  585. WinRect.right - WinRect.left,
  586. WinRect.bottom - WinRect.top,
  587. NULL,
  588. NULL,
  589. hInstance,
  590. NULL);
  591. }
  592. if ( NULL != tkhwnd )
  593. {
  594. // If default window positioning used, find out window position and fix
  595. // up the windInfo position info.
  596. if (windInfo.bDefPos)
  597. {
  598. GetWindowRect(tkhwnd, &WinRect);
  599. windInfo.x = WinRect.left + GetSystemMetrics(SM_CXFRAME);
  600. windInfo.y = WinRect.top + GetSystemMetrics(SM_CYCAPTION)
  601. - GetSystemMetrics(SM_CYBORDER)
  602. + GetSystemMetrics(SM_CYFRAME);
  603. }
  604. tkhdc = GetDC(tkhwnd);
  605. if ( NULL != tkhdc )
  606. {
  607. ShowWindow(tkhwnd, SW_SHOWDEFAULT);
  608. if ( FindPixelFormat(tkhdc, windInfo.type) )
  609. {
  610. /*
  611. * Create a Rendering Context
  612. */
  613. tkhrc = wglCreateContext(tkhdc);
  614. if ( NULL != tkhrc )
  615. {
  616. /*
  617. * Make it Current
  618. */
  619. if ( wglMakeCurrent(tkhdc, tkhrc) )
  620. {
  621. Result = GL_TRUE;
  622. }
  623. else
  624. {
  625. PrintMessage("wglMakeCurrent Failed\n");
  626. }
  627. }
  628. else
  629. {
  630. PrintMessage("wglCreateContext Failed\n");
  631. }
  632. }
  633. }
  634. else
  635. {
  636. PrintMessage("Could not get an HDC for window 0x%08lX\n", tkhwnd );
  637. }
  638. }
  639. else
  640. {
  641. PrintMessage("create window failed\n");
  642. }
  643. if ( GL_FALSE == Result )
  644. {
  645. DestroyThisWindow(tkhwnd); // Something Failed, Destroy this window
  646. }
  647. return( Result );
  648. }
  649. /******************************************************************************/
  650. /*
  651. * You cannot just call DestroyWindow() here. The programs do not expect
  652. * tkQuit() to return; DestroyWindow() just sends a WM_DESTROY message
  653. */
  654. void tkQuit(void)
  655. {
  656. DestroyThisWindow(tkhwnd);
  657. ExitProcess(0);
  658. }
  659. /******************************************************************************/
  660. void tkSetOneColor(int index, float r, float g, float b)
  661. {
  662. PALETTEENTRY PalEntry;
  663. HPALETTE Palette;
  664. if ( NULL != (Palette = CreateCIPalette( tkhdc )) )
  665. {
  666. if ( tkUseStaticColors && ( index == 0 || index == 255 ) )
  667. return;
  668. PalEntry.peRed = (BYTE)(r*(float)255.0 + (float)0.5);
  669. PalEntry.peGreen = (BYTE)(g*(float)255.0 + (float)0.5);
  670. PalEntry.peBlue = (BYTE)(b*(float)255.0 + (float)0.5);
  671. PalEntry.peFlags = ( tkUseStaticColors ) ? PC_NOCOLLAPSE : 0;
  672. // This is a workaround for a GDI palette "feature". If any of
  673. // the static colors are repeated in the palette, those colors
  674. // will map to the first occurance. So, for our case where there
  675. // are only two static colors (black and white), if a white
  676. // color appears anywhere in the palette other than in the last
  677. // entry, the static white will remap to the first white. This
  678. // destroys the nice one-to-one mapping we are trying to achieve.
  679. //
  680. // There are two ways to workaround this. The first is to
  681. // simply not allow a pure white anywhere but in the last entry.
  682. // Such requests are replaced with an attenuated white of
  683. // (0xFE, 0xFE, 0xFE).
  684. //
  685. // The other way is to mark these extra whites with PC_RESERVED
  686. // which will cause GDI to skip these entries when mapping colors.
  687. // This way the app gets the actual colors requested, but can
  688. // have side effects on other apps.
  689. //
  690. // Both solutions are included below. The PC_RESERVED solution is
  691. // the one currently enabled. It may have side effects, but taking
  692. // over the static colors as we are is a really big side effect that
  693. // should swamp out the effects of using PC_RESERVED.
  694. if ( tkUseStaticColors )
  695. {
  696. if ( PalEntry.peRed == 0xFF &&
  697. PalEntry.peGreen == 0xFF &&
  698. PalEntry.peBlue == 0xFF )
  699. {
  700. #define USE_PC_RESERVED_WORKAROUND 1
  701. #if USE_PC_RESERVED_WORKAROUND
  702. PalEntry.peFlags |= PC_RESERVED;
  703. #else
  704. PalEntry.peRed =
  705. PalEntry.peGreen =
  706. PalEntry.peBlue = 0xFE;
  707. #endif
  708. }
  709. }
  710. SetPaletteEntries( Palette, index, 1, &PalEntry);
  711. DelayPaletteRealization();
  712. }
  713. }
  714. void tkSetFogRamp(int density, int startIndex)
  715. {
  716. HPALETTE CurrentPal;
  717. PALETTEENTRY *pPalEntry;
  718. UINT n, i, j, k, intensity, fogValues, colorValues;
  719. if ( NULL != (CurrentPal = CreateCIPalette(tkhdc)) )
  720. {
  721. n = GetPaletteEntries( CurrentPal, 0, 0, NULL );
  722. pPalEntry = AllocateMemory( n * sizeof(PALETTEENTRY) );
  723. if ( NULL != pPalEntry)
  724. {
  725. fogValues = 1 << density;
  726. colorValues = 1 << startIndex;
  727. for (i = 0; i < colorValues; i++) {
  728. for (j = 0; j < fogValues; j++) {
  729. k = i * fogValues + j;
  730. intensity = i * fogValues + j * colorValues;
  731. //mf: not sure what they're trying to do here
  732. //intensity = (intensity << 8) | intensity; ???
  733. // This is a workaround for a GDI palette "feature". If any of
  734. // the static colors are repeated in the palette, those colors
  735. // will map to the first occurance. So, for our case where there
  736. // are only two static colors (black and white), if a white
  737. // color appears anywhere in the palette other than in the last
  738. // entry, the static white will remap to the first white. This
  739. // destroys the nice one-to-one mapping we are trying to achieve.
  740. //
  741. // There are two ways to workaround this. The first is to
  742. // simply not allow a pure white anywhere but in the last entry.
  743. // Such requests are replaced with an attenuated white of
  744. // (0xFE, 0xFE, 0xFE).
  745. //
  746. // The other way is to mark these extra whites with PC_RESERVED
  747. // which will cause GDI to skip these entries when mapping colors.
  748. // This way the app gets the actual colors requested, but can
  749. // have side effects on other apps.
  750. //
  751. // Both solutions are included below. The PC_RESERVED solution is
  752. // the one currently enabled. It may have side effects, but taking
  753. // over the static colors as we are is a really big side effect that
  754. // should swamp out the effects of using PC_RESERVED.
  755. #if USE_PC_RESERVED_WORKAROUND
  756. if (intensity > 0xFF)
  757. intensity = 0xFF;
  758. #else
  759. if (intensity >= 0xFF)
  760. intensity = ( tkUseStaticColors && k != 255) ? 0xFE : 0xFF;
  761. #endif
  762. pPalEntry[k].peRed =
  763. pPalEntry[k].peGreen =
  764. pPalEntry[k].peBlue = (BYTE) intensity;
  765. pPalEntry[k].peFlags = ( tkUseStaticColors && k != 0 && k != 255 )
  766. ? PC_NOCOLLAPSE : 0;
  767. #if USE_PC_RESERVED_WORKAROUND
  768. if (tkUseStaticColors && intensity == 0xFF
  769. && k != 0 && k!= 255)
  770. pPalEntry[k].peFlags |= PC_RESERVED;
  771. #endif
  772. }
  773. }
  774. SetPaletteEntries(CurrentPal, 0, n, pPalEntry);
  775. FreeMemory( pPalEntry );
  776. DelayPaletteRealization();
  777. }
  778. }
  779. }
  780. void tkSetGreyRamp(void)
  781. {
  782. HPALETTE CurrentPal;
  783. PALETTEENTRY *Entries;
  784. UINT Count, i;
  785. float intensity;
  786. if ( NULL != (CurrentPal = CreateCIPalette( tkhdc )) )
  787. {
  788. Count = GetPaletteEntries( CurrentPal, 0, 0, NULL );
  789. Entries = AllocateMemory( Count * sizeof(PALETTEENTRY) );
  790. if ( NULL != Entries )
  791. {
  792. for (i = 0; i < Count; i++)
  793. {
  794. intensity = (float)(((double)i / (double)(Count-1)) * (double)255.0 + (double)0.5);
  795. Entries[i].peRed =
  796. Entries[i].peGreen =
  797. Entries[i].peBlue = (BYTE) intensity;
  798. Entries[i].peFlags = ( tkUseStaticColors && i != 0 && i != 255 )
  799. ? PC_NOCOLLAPSE : 0;
  800. }
  801. SetPaletteEntries( CurrentPal, 0, Count, Entries );
  802. FreeMemory( Entries );
  803. DelayPaletteRealization();
  804. }
  805. }
  806. }
  807. void tkSetRGBMap( int Size, float *Values )
  808. {
  809. HPALETTE CurrentPal;
  810. PIXELFORMATDESCRIPTOR Pfd, *pPfd;
  811. PALETTEENTRY *Entries;
  812. UINT Count;
  813. if ( NULL != (CurrentPal = CreateCIPalette( tkhdc )) )
  814. {
  815. pPfd = &Pfd;
  816. if ( PixelFormatDescriptorFromDc( tkhdc, pPfd ) )
  817. {
  818. Count = 1 << pPfd->cColorBits;
  819. Entries = AllocateMemory( Count * sizeof(PALETTEENTRY) );
  820. if ( NULL != Entries )
  821. {
  822. FillRgbPaletteEntries( pPfd, Entries, Count );
  823. SetPaletteEntries( CurrentPal, 0, Count, Entries );
  824. FreeMemory(Entries);
  825. RealizePaletteNow( tkhdc, tkhpalette, FALSE );
  826. }
  827. }
  828. }
  829. }
  830. /******************************************************************************/
  831. void tkSwapBuffers(void)
  832. {
  833. SwapBuffers(tkhdc);
  834. }
  835. /******************************************************************************/
  836. GLint tkGetColorMapSize(void)
  837. {
  838. CreateCIPalette( tkhdc );
  839. if ( NULL == tkhpalette )
  840. return( 0 );
  841. return( GetPaletteEntries( tkhpalette, 0, 0, NULL ) );
  842. }
  843. void tkGetMouseLoc(int *x, int *y)
  844. {
  845. POINT Point;
  846. *x = 0;
  847. *y = 0;
  848. GetCursorPos(&Point);
  849. /*
  850. * GetCursorPos returns screen coordinates,
  851. * we want window coordinates
  852. */
  853. *x = Point.x - windInfo.x;
  854. *y = Point.y - windInfo.y;
  855. }
  856. HWND tkGetHWND(void)
  857. {
  858. return tkhwnd;
  859. }
  860. HDC tkGetHDC(void)
  861. {
  862. return tkhdc;
  863. }
  864. HGLRC tkGetHRC(void)
  865. {
  866. return tkhrc;
  867. }
  868. GLenum tkGetDisplayModePolicy(void)
  869. {
  870. return windInfo.dmPolicy;
  871. }
  872. GLint tkGetDisplayModeID(void)
  873. {
  874. return windInfo.ipfd;
  875. }
  876. GLenum tkGetDisplayMode(void)
  877. {
  878. return windInfo.type;
  879. }
  880. /***********************************************************************
  881. * *
  882. * The Following functions are for our own use only. (ie static) *
  883. * *
  884. ***********************************************************************/
  885. static LRESULT
  886. tkWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  887. {
  888. int key;
  889. PAINTSTRUCT paint;
  890. HDC hdc;
  891. PIXELFORMATDESCRIPTOR pfd;
  892. switch (message) {
  893. case WM_USER:
  894. if ( RealizePaletteNow( tkhdc, tkhpalette, FALSE ) > 0 )
  895. {
  896. ForceRedraw( hWnd );
  897. }
  898. return(0);
  899. case WM_SIZE:
  900. windInfo.width = LOWORD(lParam);
  901. windInfo.height = HIWORD(lParam);
  902. if (ReshapeFunc)
  903. {
  904. (*ReshapeFunc)(windInfo.width, windInfo.height);
  905. ForceRedraw( hWnd );
  906. }
  907. return (0);
  908. case WM_MOVE:
  909. windInfo.x = LOWORD(lParam);
  910. windInfo.y = HIWORD(lParam);
  911. return (0);
  912. case WM_PAINT:
  913. /*
  914. * Validate the region even if there are no DisplayFunc.
  915. * Otherwise, USER will not stop sending WM_PAINT messages.
  916. */
  917. hdc = BeginPaint(tkhwnd, &paint);
  918. if (DisplayFunc)
  919. {
  920. (*DisplayFunc)();
  921. }
  922. EndPaint(tkhwnd, &paint);
  923. return (0);
  924. case WM_QUERYNEWPALETTE:
  925. // We don't actually realize the palette here (we do it at WM_ACTIVATE
  926. // time), but we need the system to think that we have so that a
  927. // WM_PALETTECHANGED message is generated.
  928. return (1);
  929. case WM_PALETTECHANGED:
  930. // Respond to this message only if the window that changed the palette
  931. // is not this app's window.
  932. // We are not the foreground window, so realize palette in the
  933. // background. We cannot call RealizePaletteNow to do this because
  934. // we should not do any of the tkUseStaticColors processing while
  935. // in background.
  936. if ( hWnd != (HWND) wParam )
  937. {
  938. if ( !tkSystemColorsInUse &&
  939. NULL != tkhpalette &&
  940. NULL != SelectPalette( tkhdc, tkhpalette, TRUE ) )
  941. RealizePalette( tkhdc );
  942. }
  943. return (0);
  944. case WM_SYSCOLORCHANGE:
  945. // If the system colors have changed and we have a palette
  946. // for an RGB surface then we need to recompute the static
  947. // color mapping because they might have been changed in
  948. // the process of changing the system colors.
  949. if (tkhdc != NULL && tkhpalette != NULL &&
  950. PixelFormatDescriptorFromDc(tkhdc, &pfd) &&
  951. (pfd.dwFlags & PFD_NEED_PALETTE) &&
  952. pfd.iPixelType == PFD_TYPE_RGBA)
  953. {
  954. HPALETTE hpalTmp;
  955. hpalTmp = tkhpalette;
  956. tkhpalette = NULL;
  957. if (CreateRGBPalette(tkhdc) != NULL)
  958. {
  959. DeleteObject(hpalTmp);
  960. ForceRedraw(hWnd);
  961. }
  962. else
  963. {
  964. tkhpalette = hpalTmp;
  965. }
  966. }
  967. break;
  968. case WM_ACTIVATE:
  969. // If the window is going inactive, the palette must be realized to
  970. // the background. Cannot depend on WM_PALETTECHANGED to be sent since
  971. // the window that comes to the foreground may or may not be palette
  972. // managed.
  973. if ( LOWORD(wParam) == WA_INACTIVE )
  974. {
  975. if ( NULL != tkhpalette )
  976. {
  977. // Realize as a background palette. Need to call
  978. // RealizePaletteNow rather than RealizePalette directly to
  979. // because it may be necessary to release usage of the static
  980. // system colors.
  981. if ( RealizePaletteNow( tkhdc, tkhpalette, TRUE ) > 0 )
  982. ForceRedraw( hWnd );
  983. }
  984. }
  985. // Window is going active. If we are not iconized, realize palette
  986. // to the foreground. If management of the system static colors is
  987. // needed, RealizePaletteNow will take care of it.
  988. else if ( HIWORD(wParam) == 0 )
  989. {
  990. if ( NULL != tkhpalette )
  991. {
  992. if ( RealizePaletteNow( tkhdc, tkhpalette, FALSE ) > 0 )
  993. ForceRedraw( hWnd );
  994. return (1);
  995. }
  996. }
  997. // Allow DefWindowProc() to finish the default processing (which includes
  998. // changing the keyboard focus).
  999. break;
  1000. case WM_MOUSEMOVE:
  1001. if (MouseMoveFunc)
  1002. {
  1003. GLenum mask;
  1004. mask = 0;
  1005. if (wParam & MK_LBUTTON) {
  1006. mask |= TK_LEFTBUTTON;
  1007. }
  1008. if (wParam & MK_MBUTTON) {
  1009. mask |= TK_MIDDLEBUTTON;
  1010. }
  1011. if (wParam & MK_RBUTTON) {
  1012. mask |= TK_RIGHTBUTTON;
  1013. }
  1014. if ((*MouseMoveFunc)( LOWORD(lParam), HIWORD(lParam), mask ))
  1015. {
  1016. ForceRedraw( hWnd );
  1017. }
  1018. }
  1019. return (0);
  1020. case WM_LBUTTONDOWN:
  1021. SetCapture(hWnd);
  1022. if (MouseDownFunc)
  1023. {
  1024. if ( (*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  1025. TK_LEFTBUTTON) )
  1026. {
  1027. ForceRedraw( hWnd );
  1028. }
  1029. }
  1030. return (0);
  1031. case WM_LBUTTONUP:
  1032. ReleaseCapture();
  1033. if (MouseUpFunc)
  1034. {
  1035. if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam), TK_LEFTBUTTON))
  1036. {
  1037. ForceRedraw( hWnd );
  1038. }
  1039. }
  1040. return (0);
  1041. case WM_MBUTTONDOWN:
  1042. SetCapture(hWnd);
  1043. if (MouseDownFunc)
  1044. {
  1045. if ((*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  1046. TK_MIDDLEBUTTON))
  1047. {
  1048. ForceRedraw( hWnd );
  1049. }
  1050. }
  1051. return (0);
  1052. case WM_MBUTTONUP:
  1053. ReleaseCapture();
  1054. if (MouseUpFunc)
  1055. {
  1056. if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
  1057. TK_MIDDLEBUTTON))
  1058. {
  1059. ForceRedraw( hWnd );
  1060. }
  1061. }
  1062. return (0);
  1063. case WM_RBUTTONDOWN:
  1064. SetCapture(hWnd);
  1065. if (MouseDownFunc)
  1066. {
  1067. if ((*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  1068. TK_RIGHTBUTTON))
  1069. {
  1070. ForceRedraw( hWnd );
  1071. }
  1072. }
  1073. return (0);
  1074. case WM_RBUTTONUP:
  1075. ReleaseCapture();
  1076. if (MouseUpFunc)
  1077. {
  1078. if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
  1079. TK_RIGHTBUTTON))
  1080. {
  1081. ForceRedraw( hWnd );
  1082. }
  1083. }
  1084. return (0);
  1085. case WM_KEYDOWN:
  1086. switch (wParam) {
  1087. case VK_SPACE: key = TK_SPACE; break;
  1088. case VK_RETURN: key = TK_RETURN; break;
  1089. case VK_ESCAPE: key = TK_ESCAPE; break;
  1090. case VK_LEFT: key = TK_LEFT; break;
  1091. case VK_UP: key = TK_UP; break;
  1092. case VK_RIGHT: key = TK_RIGHT; break;
  1093. case VK_DOWN: key = TK_DOWN; break;
  1094. default: key = GL_FALSE; break;
  1095. }
  1096. if (key && KeyDownFunc)
  1097. {
  1098. GLenum mask;
  1099. mask = 0;
  1100. if (GetKeyState(VK_CONTROL)) {
  1101. mask |= TK_CONTROL;
  1102. }
  1103. if (GetKeyState(VK_SHIFT)) {
  1104. mask |= TK_SHIFT;
  1105. }
  1106. if ( (*KeyDownFunc)(key, mask) )
  1107. {
  1108. ForceRedraw( hWnd );
  1109. }
  1110. }
  1111. return (0);
  1112. case WM_CHAR:
  1113. if (('0' <= wParam && wParam <= '9') ||
  1114. ('a' <= wParam && wParam <= 'z') ||
  1115. ('A' <= wParam && wParam <= 'Z')) {
  1116. key = (int)wParam;
  1117. } else {
  1118. key = GL_FALSE;
  1119. }
  1120. if (key && KeyDownFunc) {
  1121. GLenum mask;
  1122. mask = 0;
  1123. if (GetKeyState(VK_CONTROL)) {
  1124. mask |= TK_CONTROL;
  1125. }
  1126. if (GetKeyState(VK_SHIFT)) {
  1127. mask |= TK_SHIFT;
  1128. }
  1129. if ( (*KeyDownFunc)(key, mask) )
  1130. {
  1131. ForceRedraw( hWnd );
  1132. }
  1133. }
  1134. return (0);
  1135. case WM_CLOSE:
  1136. DestroyWindow(tkhwnd);
  1137. return(0);
  1138. case WM_DESTROY:
  1139. CleanUp();
  1140. PostQuitMessage(TRUE);
  1141. return 0;
  1142. }
  1143. return(DefWindowProc( hWnd, message, wParam, lParam));
  1144. }
  1145. #if RESTORE_FROM_REGISTRY
  1146. /******************************Public*Routine******************************\
  1147. * GetRegistrySysColors
  1148. *
  1149. * Reads the Control Panel's color settings from the registry and stores
  1150. * those values in pcr. If we fail to get any value, then the corresponding
  1151. * entry in pcr is not modified.
  1152. *
  1153. * History:
  1154. * 12-Apr-1995 -by- Gilman Wong [gilmanw]
  1155. * Wrote it.
  1156. \**************************************************************************/
  1157. static BOOL GetRegistrySysColors(COLORREF *pcr, int nColors)
  1158. {
  1159. BOOL bRet = FALSE;
  1160. long lRet;
  1161. HKEY hkSysColors = (HKEY) NULL;
  1162. int i;
  1163. DWORD dwDataType;
  1164. char achColor[64];
  1165. DWORD cjColor;
  1166. TKASSERT(nColors <= tkNumStaticColors);
  1167. // Open the key for the system color settings.
  1168. lRet = RegOpenKeyExA(HKEY_CURRENT_USER,
  1169. "Control Panel\\Colors",
  1170. 0,
  1171. KEY_QUERY_VALUE,
  1172. &hkSysColors);
  1173. if ( lRet != ERROR_SUCCESS )
  1174. {
  1175. goto GetRegistrySysColors_exit;
  1176. }
  1177. // Read each system color value. The names are stored in the global
  1178. // array of char *, gaszSysClrNames.
  1179. for (i = 0; i < nColors; i++)
  1180. {
  1181. cjColor = sizeof(achColor);
  1182. lRet = RegQueryValueExA(hkSysColors,
  1183. (LPSTR) gaszSysClrNames[i],
  1184. (LPDWORD) NULL,
  1185. &dwDataType,
  1186. (LPBYTE) achColor,
  1187. &cjColor);
  1188. TKASSERT(lRet != ERROR_MORE_DATA);
  1189. if ( lRet == ERROR_SUCCESS && dwDataType == REG_SZ )
  1190. {
  1191. DWORD r, g, b;
  1192. sscanf(achColor, "%ld %ld %ld", &r, &g, &b);
  1193. pcr[i] = RGB(r, g, b);
  1194. }
  1195. }
  1196. bRet = TRUE;
  1197. GetRegistrySysColors_exit:
  1198. if (hkSysColors)
  1199. RegCloseKey(hkSysColors);
  1200. return bRet;
  1201. }
  1202. #endif
  1203. /******************************Public*Routine******************************\
  1204. * GrabStaticEntries
  1205. *
  1206. * Support routine for RealizePaletteNow to manage the static system color
  1207. * usage.
  1208. *
  1209. * This function will save the current static system color usage state.
  1210. * It will fail if:
  1211. *
  1212. * 1. TK is not in "sys color in use state but system palette is in
  1213. * SYSPAL_NOSTATIC mode. This means that another app still possesses
  1214. * the static system colors. This this happens, GrabStaticEntries
  1215. * will post a message to cause TK to try again (by calling
  1216. * DelayPaletteRealization).
  1217. *
  1218. * Side effect:
  1219. * If system colors are changed, then WM_SYSCOLORCHANGE message is
  1220. * broadcast to all top level windows.
  1221. *
  1222. * DelayPaletteRealization may be called in case 2 above, resulting in
  1223. * a WM_USER message being posted to our message queue.
  1224. *
  1225. * Returns:
  1226. * TRUE if successful, FALSE otherwise (see above).
  1227. *
  1228. * History:
  1229. * 26-Apr-1994 -by- Gilman Wong [gilmanw]
  1230. * Wrote it.
  1231. \**************************************************************************/
  1232. static BOOL GrabStaticEntries(HDC hdc)
  1233. {
  1234. int i;
  1235. BOOL bRet = FALSE;
  1236. // Do nothing if sys colors already in use.
  1237. if ( !tkSystemColorsInUse )
  1238. {
  1239. // Take possession only if no other app has the static colors.
  1240. // How can we tell? If the return from SetSystemPaletteUse is
  1241. // SYSPAL_STATIC, then no other app has the statics. If it is
  1242. // SYSPAL_NOSTATIC, someone else has them and we must fail.
  1243. //
  1244. // SetSystemPaletteUse is properly synchronized internally
  1245. // so that it is atomic.
  1246. //
  1247. // Because we are relying on SetSystemPaletteUse to synchronize TK,
  1248. // it is important to observe the following order for grabbing and
  1249. // releasing:
  1250. //
  1251. // Grab call SetSystemPaletteUse and check for SYSPAL_STATIC
  1252. // save sys color settings
  1253. // set new sys color settings
  1254. //
  1255. // Release restore sys color settings
  1256. // call SetSystemPaletteUse
  1257. if ( SetSystemPaletteUse( hdc, SYSPAL_NOSTATIC ) == SYSPAL_STATIC )
  1258. {
  1259. // Save current sys color settings.
  1260. for (i = COLOR_SCROLLBAR; i <= COLOR_BTNHIGHLIGHT; i++)
  1261. gacrSave[i - COLOR_SCROLLBAR] = GetSysColor(i);
  1262. // Set b&w sys color settings. Put TK in "sys colors in use" state.
  1263. SetSysColors(tkNumStaticColors, gaiStaticIndex, gacrBlackAndWhite);
  1264. tkSystemColorsInUse = TRUE;
  1265. // Inform all other top-level windows of the system color change.
  1266. PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
  1267. bRet = TRUE;
  1268. }
  1269. // Sleep a little and then post message to try palette realization again
  1270. // later.
  1271. else
  1272. {
  1273. Sleep(0L);
  1274. DelayPaletteRealization();
  1275. }
  1276. }
  1277. else
  1278. bRet = TRUE;
  1279. return bRet;
  1280. }
  1281. /******************************Public*Routine******************************\
  1282. * ReleaseStaticEntries
  1283. *
  1284. * Support routine for RealizePaletteNow to manage the static system color
  1285. * usage.
  1286. *
  1287. * This function will reset the current static system color usage state.
  1288. * It will fail if:
  1289. *
  1290. * 1. TK is not in a "sys colors in use" state. If we are in this case,
  1291. * then the static system colors do not need to be released.
  1292. *
  1293. * Side effect:
  1294. * If system colors are changed, then WM_SYSCOLORCHANGE message is
  1295. * broadcast to all top level windows.
  1296. *
  1297. * Returns:
  1298. * TRUE if successful, FALSE otherwise (see above).
  1299. *
  1300. * History:
  1301. * 21-Jul-1994 -by- Gilman Wong [gilmanw]
  1302. * Wrote it.
  1303. \**************************************************************************/
  1304. static BOOL ReleaseStaticEntries(HDC hdc)
  1305. {
  1306. BOOL bRet = FALSE;
  1307. // Do nothing if sys colors not in use.
  1308. if ( tkSystemColorsInUse )
  1309. {
  1310. #if RESTORE_FROM_REGISTRY
  1311. // Replace saved system colors with registry values. We do it now
  1312. // rather than earlier because someone may have changed registry while
  1313. // TK app was running in the foreground (very unlikely, but it could
  1314. // happen).
  1315. //
  1316. // Also, we still try to save current setting in GrabStaticEntries so
  1317. // that if for some reason we fail to grab one or more of the colors
  1318. // from the registry, we can still fall back on what we grabbed via
  1319. // GetSysColors (even though there is a chance its the wrong color).
  1320. GetRegistrySysColors(gacrSave, tkNumStaticColors);
  1321. #endif
  1322. // Restore the saved system color settings.
  1323. SetSysColors(tkNumStaticColors, gaiStaticIndex, gacrSave);
  1324. // Return the system palette to SYSPAL_STATIC.
  1325. SetSystemPaletteUse( hdc, SYSPAL_STATIC );
  1326. // Inform all other top-level windows of the system color change.
  1327. PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
  1328. // Reset the "sys colors in use" state and return success.
  1329. tkSystemColorsInUse = FALSE;
  1330. bRet = TRUE;
  1331. }
  1332. return bRet;
  1333. }
  1334. // Default palette entry flags
  1335. #define PALETTE_FLAGS PC_NOCOLLAPSE
  1336. // Gamma correction factor * 10
  1337. #define GAMMA_CORRECTION 14
  1338. // Maximum color distance with 8-bit components
  1339. #define MAX_COL_DIST (3*256*256L)
  1340. // Number of static colors
  1341. #define STATIC_COLORS 20
  1342. // Flags used when matching colors
  1343. #define EXACT_MATCH 1
  1344. #define COLOR_USED 1
  1345. // Conversion tables for n bits to eight bits
  1346. #if GAMMA_CORRECTION == 10
  1347. // These tables are corrected for a gamma of 1.0
  1348. static unsigned char abThreeToEight[8] =
  1349. {
  1350. 0, 0111 >> 1, 0222 >> 1, 0333 >> 1, 0444 >> 1, 0555 >> 1, 0666 >> 1, 0377
  1351. };
  1352. static unsigned char abTwoToEight[4] =
  1353. {
  1354. 0, 0x55, 0xaa, 0xff
  1355. };
  1356. static unsigned char abOneToEight[2] =
  1357. {
  1358. 0, 255
  1359. };
  1360. #else
  1361. // These tables are corrected for a gamma of 1.4
  1362. static unsigned char abThreeToEight[8] =
  1363. {
  1364. 0, 63, 104, 139, 171, 200, 229, 255
  1365. };
  1366. static unsigned char abTwoToEight[4] =
  1367. {
  1368. 0, 116, 191, 255
  1369. };
  1370. static unsigned char abOneToEight[2] =
  1371. {
  1372. 0, 255
  1373. };
  1374. #endif
  1375. // Table which indicates which colors in a 3-3-2 palette should be
  1376. // replaced with the system default colors
  1377. #if GAMMA_CORRECTION == 10
  1378. static int aiDefaultOverride[STATIC_COLORS] =
  1379. {
  1380. 0, 4, 32, 36, 128, 132, 160, 173, 181, 245,
  1381. 247, 164, 156, 7, 56, 63, 192, 199, 248, 255
  1382. };
  1383. #else
  1384. static int aiDefaultOverride[STATIC_COLORS] =
  1385. {
  1386. 0, 3, 24, 27, 64, 67, 88, 173, 181, 236,
  1387. 247, 164, 91, 7, 56, 63, 192, 199, 248, 255
  1388. };
  1389. #endif
  1390. static unsigned char
  1391. ComponentFromIndex(int i, int nbits, int shift)
  1392. {
  1393. unsigned char val;
  1394. TKASSERT(nbits >= 1 && nbits <= 3);
  1395. val = i >> shift;
  1396. switch (nbits)
  1397. {
  1398. case 1:
  1399. return abOneToEight[val & 1];
  1400. case 2:
  1401. return abTwoToEight[val & 3];
  1402. case 3:
  1403. return abThreeToEight[val & 7];
  1404. }
  1405. return 0;
  1406. }
  1407. // System default colors
  1408. static PALETTEENTRY apeDefaultPalEntry[STATIC_COLORS] =
  1409. {
  1410. { 0, 0, 0, 0 },
  1411. { 0x80,0, 0, 0 },
  1412. { 0, 0x80,0, 0 },
  1413. { 0x80,0x80,0, 0 },
  1414. { 0, 0, 0x80, 0 },
  1415. { 0x80,0, 0x80, 0 },
  1416. { 0, 0x80,0x80, 0 },
  1417. { 0xC0,0xC0,0xC0, 0 },
  1418. { 192, 220, 192, 0 },
  1419. { 166, 202, 240, 0 },
  1420. { 255, 251, 240, 0 },
  1421. { 160, 160, 164, 0 },
  1422. { 0x80,0x80,0x80, 0 },
  1423. { 0xFF,0, 0, 0 },
  1424. { 0, 0xFF,0, 0 },
  1425. { 0xFF,0xFF,0, 0 },
  1426. { 0, 0, 0xFF, 0 },
  1427. { 0xFF,0, 0xFF, 0 },
  1428. { 0, 0xFF,0xFF, 0 },
  1429. { 0xFF,0xFF,0xFF, 0 }
  1430. };
  1431. /******************************Public*Routine******************************\
  1432. *
  1433. * UpdateStaticMapping
  1434. *
  1435. * Computes the best match between the current system static colors
  1436. * and a 3-3-2 palette
  1437. *
  1438. * History:
  1439. * Tue Aug 01 18:18:12 1995 -by- Drew Bliss [drewb]
  1440. * Created
  1441. *
  1442. \**************************************************************************/
  1443. static void
  1444. UpdateStaticMapping(PALETTEENTRY *pe332Palette)
  1445. {
  1446. HPALETTE hpalStock;
  1447. int iStatic, i332;
  1448. int iMinDist, iDist;
  1449. int iDelta;
  1450. int iMinEntry;
  1451. PALETTEENTRY *peStatic, *pe332;
  1452. hpalStock = GetStockObject(DEFAULT_PALETTE);
  1453. // The system should always have one of these
  1454. TKASSERT(hpalStock != NULL);
  1455. // Make sure there's the correct number of entries
  1456. TKASSERT(GetPaletteEntries(hpalStock, 0, 0, NULL) == STATIC_COLORS);
  1457. // Get the current static colors
  1458. GetPaletteEntries(hpalStock, 0, STATIC_COLORS, apeDefaultPalEntry);
  1459. // Zero the flags in the static colors because they are used later
  1460. peStatic = apeDefaultPalEntry;
  1461. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  1462. {
  1463. peStatic->peFlags = 0;
  1464. peStatic++;
  1465. }
  1466. // Zero the flags in the incoming palette because they are used later
  1467. pe332 = pe332Palette;
  1468. for (i332 = 0; i332 < 256; i332++)
  1469. {
  1470. pe332->peFlags = 0;
  1471. pe332++;
  1472. }
  1473. // Try to match each static color exactly
  1474. // This saves time by avoiding the least-squares match for each
  1475. // exact match
  1476. peStatic = apeDefaultPalEntry;
  1477. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  1478. {
  1479. pe332 = pe332Palette;
  1480. for (i332 = 0; i332 < 256; i332++)
  1481. {
  1482. if (peStatic->peRed == pe332->peRed &&
  1483. peStatic->peGreen == pe332->peGreen &&
  1484. peStatic->peBlue == pe332->peBlue)
  1485. {
  1486. TKASSERT(pe332->peFlags != COLOR_USED);
  1487. peStatic->peFlags = EXACT_MATCH;
  1488. pe332->peFlags = COLOR_USED;
  1489. aiDefaultOverride[iStatic] = i332;
  1490. break;
  1491. }
  1492. pe332++;
  1493. }
  1494. peStatic++;
  1495. }
  1496. // Match each static color as closely as possible to an entry
  1497. // in the 332 palette by minimized the square of the distance
  1498. peStatic = apeDefaultPalEntry;
  1499. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  1500. {
  1501. // Skip colors already matched exactly
  1502. if (peStatic->peFlags == EXACT_MATCH)
  1503. {
  1504. peStatic++;
  1505. continue;
  1506. }
  1507. iMinDist = MAX_COL_DIST+1;
  1508. #if DBG
  1509. iMinEntry = -1;
  1510. #endif
  1511. pe332 = pe332Palette;
  1512. for (i332 = 0; i332 < 256; i332++)
  1513. {
  1514. // Skip colors already used
  1515. if (pe332->peFlags == COLOR_USED)
  1516. {
  1517. pe332++;
  1518. continue;
  1519. }
  1520. // Compute Euclidean distance squared
  1521. iDelta = pe332->peRed-peStatic->peRed;
  1522. iDist = iDelta*iDelta;
  1523. iDelta = pe332->peGreen-peStatic->peGreen;
  1524. iDist += iDelta*iDelta;
  1525. iDelta = pe332->peBlue-peStatic->peBlue;
  1526. iDist += iDelta*iDelta;
  1527. if (iDist < iMinDist)
  1528. {
  1529. iMinDist = iDist;
  1530. iMinEntry = i332;
  1531. }
  1532. pe332++;
  1533. }
  1534. TKASSERT(iMinEntry != -1);
  1535. // Remember the best match
  1536. aiDefaultOverride[iStatic] = iMinEntry;
  1537. pe332Palette[iMinEntry].peFlags = COLOR_USED;
  1538. peStatic++;
  1539. }
  1540. // Zero the flags in the static colors because they may have been
  1541. // set. We want them to be zero so the colors can be remapped
  1542. peStatic = apeDefaultPalEntry;
  1543. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  1544. {
  1545. peStatic->peFlags = 0;
  1546. peStatic++;
  1547. }
  1548. // Reset the 332 flags because we may have set them
  1549. pe332 = pe332Palette;
  1550. for (i332 = 0; i332 < 256; i332++)
  1551. {
  1552. pe332->peFlags = PALETTE_FLAGS;
  1553. pe332++;
  1554. }
  1555. #if 0
  1556. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  1557. {
  1558. PrintMessage("Static color %2d maps to %d\n",
  1559. iStatic, aiDefaultOverride[iStatic]);
  1560. }
  1561. #endif
  1562. }
  1563. /******************************Public*Routine******************************\
  1564. * FillRgbPaletteEntries
  1565. *
  1566. * Fills a PALETTEENTRY array with values required for a logical rgb palette.
  1567. * If tkSetStaticColorUsage has been called with TRUE, the static system
  1568. * colors will be overridden. Otherwise, the PALETTEENTRY array will be
  1569. * fixed up to contain the default static system colors.
  1570. *
  1571. * History:
  1572. * 26-Apr-1994 -by- Gilman Wong [gilmanw]
  1573. * Wrote it.
  1574. \**************************************************************************/
  1575. static PALETTEENTRY *
  1576. FillRgbPaletteEntries( PIXELFORMATDESCRIPTOR *Pfd,
  1577. PALETTEENTRY *Entries,
  1578. UINT Count
  1579. )
  1580. {
  1581. PALETTEENTRY *Entry;
  1582. UINT i;
  1583. if ( NULL != Entries )
  1584. {
  1585. for ( i = 0, Entry = Entries ; i < Count ; i++, Entry++ )
  1586. {
  1587. Entry->peRed = ComponentFromIndex(i, Pfd->cRedBits,
  1588. Pfd->cRedShift);
  1589. Entry->peGreen = ComponentFromIndex(i, Pfd->cGreenBits,
  1590. Pfd->cGreenShift);
  1591. Entry->peBlue = ComponentFromIndex(i, Pfd->cBlueBits,
  1592. Pfd->cBlueShift);
  1593. Entry->peFlags = PALETTE_FLAGS;
  1594. }
  1595. if ( 256 == Count)
  1596. {
  1597. // If app set static system color usage for fixed palette support,
  1598. // setup to take over the static colors. Otherwise, fixup the
  1599. // static system colors.
  1600. if ( tkUseStaticColors )
  1601. {
  1602. // Black and white already exist as the only remaining static
  1603. // colors. Let those remap. All others should be put into
  1604. // the palette (i.e., set PC_NOCOLLAPSE).
  1605. Entries[0].peFlags = 0;
  1606. Entries[255].peFlags = 0;
  1607. }
  1608. else
  1609. {
  1610. // The defaultOverride array is computed assuming a 332
  1611. // palette where red has zero shift, etc.
  1612. if ( (3 == Pfd->cRedBits) && (0 == Pfd->cRedShift) &&
  1613. (3 == Pfd->cGreenBits) && (3 == Pfd->cGreenShift) &&
  1614. (2 == Pfd->cBlueBits) && (6 == Pfd->cBlueShift) )
  1615. {
  1616. UpdateStaticMapping(Entries);
  1617. for ( i = 0 ; i < STATIC_COLORS ; i++)
  1618. {
  1619. Entries[aiDefaultOverride[i]] = apeDefaultPalEntry[i];
  1620. }
  1621. }
  1622. }
  1623. }
  1624. }
  1625. return( Entries );
  1626. }
  1627. /******************************Public*Routine******************************\
  1628. * FlushPalette
  1629. *
  1630. * Because of Win 3.1 compatibility, GDI palette mapping always starts
  1631. * at zero and stops at the first exact match. So if there are duplicates,
  1632. * the higher colors aren't mapped to--which is often a problem if we
  1633. * are trying to make to any of the upper 10 static colors. To work around
  1634. * this, we flush the palette to all black.
  1635. *
  1636. * This only needs to be done for the 8BPP (256 color) case.
  1637. *
  1638. \**************************************************************************/
  1639. static void
  1640. FlushPalette(HDC hdc, int nColors)
  1641. {
  1642. LOGPALETTE *pPal;
  1643. HPALETTE hpal, hpalOld;
  1644. int i;
  1645. if (nColors == 256)
  1646. {
  1647. pPal = (LOGPALETTE *) LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT,
  1648. sizeof(LOGPALETTE) + nColors * sizeof(PALETTEENTRY));
  1649. if (pPal)
  1650. {
  1651. pPal->palVersion = 0x300;
  1652. pPal->palNumEntries = (WORD)nColors;
  1653. // Mark everything PC_NOCOLLAPSE and PC_RESERVED to force every thing
  1654. // into the palette. Colors are already black because we zero initialized
  1655. // during memory allocation.
  1656. for (i = 0; i < nColors; i++)
  1657. {
  1658. pPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE | PC_RESERVED;
  1659. }
  1660. hpal = CreatePalette(pPal);
  1661. LocalFree(pPal);
  1662. hpalOld = SelectPalette(hdc, hpal, FALSE);
  1663. RealizePalette(hdc);
  1664. SelectPalette(hdc, hpalOld, FALSE);
  1665. DeleteObject(hpal);
  1666. }
  1667. }
  1668. }
  1669. static HPALETTE
  1670. CreateRGBPalette( HDC Dc )
  1671. {
  1672. PIXELFORMATDESCRIPTOR Pfd, *pPfd;
  1673. LOGPALETTE *LogPalette;
  1674. UINT Count;
  1675. if ( NULL == tkhpalette )
  1676. {
  1677. pPfd = &Pfd;
  1678. if ( PixelFormatDescriptorFromDc( Dc, pPfd ) )
  1679. {
  1680. /*
  1681. * Make sure we need a palette
  1682. */
  1683. if ( (pPfd->iPixelType == PFD_TYPE_RGBA) &&
  1684. (pPfd->dwFlags & PFD_NEED_PALETTE) )
  1685. {
  1686. /*
  1687. * Note how palette is to be realized. Take over the
  1688. * system colors if either the pixel format requires it
  1689. * or the app wants it.
  1690. */
  1691. tkUseStaticColors = ( pPfd->dwFlags & PFD_NEED_SYSTEM_PALETTE )
  1692. || TK_USE_FIXED_332_PAL(windInfo.type);
  1693. Count = 1 << pPfd->cColorBits;
  1694. LogPalette = AllocateMemory( sizeof(LOGPALETTE) +
  1695. Count * sizeof(PALETTEENTRY));
  1696. if ( NULL != LogPalette )
  1697. {
  1698. LogPalette->palVersion = 0x300;
  1699. LogPalette->palNumEntries = (WORD)Count;
  1700. FillRgbPaletteEntries( pPfd,
  1701. &LogPalette->palPalEntry[0],
  1702. Count );
  1703. tkhpalette = CreatePalette(LogPalette);
  1704. FreeMemory(LogPalette);
  1705. FlushPalette(Dc, Count);
  1706. RealizePaletteNow( Dc, tkhpalette, FALSE );
  1707. }
  1708. }
  1709. }
  1710. }
  1711. return( tkhpalette );
  1712. }
  1713. static HPALETTE
  1714. CreateCIPalette( HDC Dc )
  1715. {
  1716. PIXELFORMATDESCRIPTOR Pfd;
  1717. LOGPALETTE *LogicalPalette;
  1718. HPALETTE StockPalette;
  1719. UINT PaletteSize, StockPaletteSize, EntriesToCopy;
  1720. if ( (Dc != NULL) && (NULL == tkhpalette) )
  1721. {
  1722. if ( PixelFormatDescriptorFromDc( Dc, &Pfd ) )
  1723. {
  1724. if ( Pfd.iPixelType == PFD_TYPE_COLORINDEX )
  1725. {
  1726. /*
  1727. * Note how palette is to be realized (Is this the correct place to do this?)
  1728. */
  1729. tkUseStaticColors = ( Pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE )
  1730. || TK_USE_FIXED_332_PAL(windInfo.type);
  1731. /*
  1732. * Limit the size of the palette to 256 colors.
  1733. * Why? Because this is what was decided.
  1734. */
  1735. PaletteSize = (Pfd.cColorBits >= 8) ? 256 : (1 << Pfd.cColorBits);
  1736. LogicalPalette = AllocateZeroedMemory( sizeof(LOGPALETTE) +
  1737. (PaletteSize * sizeof(PALETTEENTRY)) );
  1738. if ( NULL != LogicalPalette )
  1739. {
  1740. LogicalPalette->palVersion = 0x300;
  1741. LogicalPalette->palNumEntries = (WORD)PaletteSize;
  1742. StockPalette = GetStockObject(DEFAULT_PALETTE);
  1743. StockPaletteSize = GetPaletteEntries( StockPalette, 0, 0, NULL );
  1744. /*
  1745. * start by copying default palette into new one
  1746. */
  1747. EntriesToCopy = StockPaletteSize < PaletteSize ?
  1748. StockPaletteSize : PaletteSize;
  1749. GetPaletteEntries( StockPalette, 0, EntriesToCopy,
  1750. LogicalPalette->palPalEntry );
  1751. /*
  1752. * If we are taking possession of the system colors,
  1753. * must guarantee that 0 and 255 are black and white
  1754. * (respectively).
  1755. */
  1756. if ( tkUseStaticColors && PaletteSize == 256 )
  1757. {
  1758. int i;
  1759. LogicalPalette->palPalEntry[0].peRed =
  1760. LogicalPalette->palPalEntry[0].peGreen =
  1761. LogicalPalette->palPalEntry[0].peBlue = 0x00;
  1762. LogicalPalette->palPalEntry[255].peRed =
  1763. LogicalPalette->palPalEntry[255].peGreen =
  1764. LogicalPalette->palPalEntry[255].peBlue = 0xFF;
  1765. LogicalPalette->palPalEntry[0].peFlags =
  1766. LogicalPalette->palPalEntry[255].peFlags = 0;
  1767. /*
  1768. * All other entries should be remappable,
  1769. * so mark them as PC_NOCOLLAPSE.
  1770. */
  1771. for ( i = 1; i < 255; i++ )
  1772. LogicalPalette->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
  1773. }
  1774. tkhpalette = CreatePalette(LogicalPalette);
  1775. FreeMemory(LogicalPalette);
  1776. RealizePaletteNow( Dc, tkhpalette, FALSE );
  1777. }
  1778. }
  1779. }
  1780. }
  1781. return( tkhpalette );
  1782. }
  1783. static BOOL
  1784. FindPixelFormat(HDC hdc, GLenum type)
  1785. {
  1786. PIXELFORMATDESCRIPTOR pfd;
  1787. int PfdIndex;
  1788. BOOL Result = FALSE;
  1789. if ( TK_MINIMUM_CRITERIA == windInfo.dmPolicy )
  1790. PfdIndex = FindBestPixelFormat(hdc, type, &pfd);
  1791. else if ( TK_EXACT_MATCH == windInfo.dmPolicy )
  1792. PfdIndex = FindExactPixelFormat(hdc, type, &pfd);
  1793. else if ( IsPixelFormatValid(hdc, windInfo.ipfd, &pfd) )
  1794. PfdIndex = windInfo.ipfd;
  1795. else
  1796. PfdIndex = 0;
  1797. if ( PfdIndex )
  1798. {
  1799. if ( SetPixelFormat(hdc, PfdIndex, &pfd) )
  1800. {
  1801. /*
  1802. * If this pixel format requires a palette do it now.
  1803. * In colorindex mode, create a logical palette only
  1804. * if the application needs to modify it.
  1805. */
  1806. CreateRGBPalette( hdc );
  1807. Result = TRUE;
  1808. }
  1809. else
  1810. {
  1811. PrintMessage("SetPixelFormat failed\n");
  1812. }
  1813. }
  1814. else
  1815. {
  1816. PrintMessage("Selecting a pixel format failed\n");
  1817. }
  1818. return(Result);
  1819. }
  1820. static int
  1821. FindBestPixelFormat(HDC hdc, GLenum type, PIXELFORMATDESCRIPTOR *ppfd)
  1822. {
  1823. PIXELFORMATDESCRIPTOR pfd;
  1824. pfd.nSize = sizeof(pfd);
  1825. pfd.nVersion = 1;
  1826. pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
  1827. if (TK_IS_DOUBLE(type))
  1828. pfd.dwFlags |= PFD_DOUBLEBUFFER;
  1829. if (TK_IS_INDEX(type)) {
  1830. pfd.iPixelType = PFD_TYPE_COLORINDEX;
  1831. pfd.cColorBits = 8;
  1832. } else {
  1833. pfd.iPixelType = PFD_TYPE_RGBA;
  1834. pfd.cColorBits = 24;
  1835. }
  1836. if (TK_HAS_ALPHA(type))
  1837. pfd.cAlphaBits = 8;
  1838. else
  1839. pfd.cAlphaBits = 0;
  1840. if (TK_HAS_ACCUM(type))
  1841. pfd.cAccumBits = pfd.cColorBits + pfd.cAlphaBits;
  1842. else
  1843. pfd.cAccumBits = 0;
  1844. if (TK_HAS_DEPTH(type)) {
  1845. if (TK_IS_DEPTH16(type))
  1846. pfd.cDepthBits = 16;
  1847. else
  1848. pfd.cDepthBits = 24;
  1849. } else {
  1850. pfd.cDepthBits = 0;
  1851. }
  1852. if (TK_HAS_STENCIL(type))
  1853. pfd.cStencilBits = 4;
  1854. else
  1855. pfd.cStencilBits = 0;
  1856. pfd.cAuxBuffers = 0;
  1857. pfd.iLayerType = PFD_MAIN_PLANE;
  1858. *ppfd = pfd;
  1859. return ( ChoosePixelFormat(hdc, &pfd) );
  1860. }
  1861. static int
  1862. FindExactPixelFormat(HDC hdc, GLenum type, PIXELFORMATDESCRIPTOR *ppfd)
  1863. {
  1864. int i, MaxPFDs, Score, BestScore, BestPFD;
  1865. PIXELFORMATDESCRIPTOR pfd;
  1866. i = 1;
  1867. BestPFD = BestScore = 0;
  1868. do
  1869. {
  1870. MaxPFDs = DescribePixelFormat(hdc, i, sizeof(pfd), &pfd);
  1871. if ( MaxPFDs <= 0 )
  1872. return ( 0 );
  1873. Score = 0;
  1874. if ( !( ( pfd.dwFlags & PFD_DRAW_TO_WINDOW ) &&
  1875. ( pfd.dwFlags & PFD_SUPPORT_OPENGL ) ) )
  1876. continue;
  1877. if ( pfd.iLayerType != PFD_MAIN_PLANE )
  1878. continue;
  1879. if ( ( pfd.iPixelType == PFD_TYPE_RGBA ) && ( TK_IS_INDEX(type) ) )
  1880. continue;
  1881. if ( ( pfd.iPixelType == PFD_TYPE_COLORINDEX ) && ( TK_IS_RGB(type) ) )
  1882. continue;
  1883. if ( ( pfd.dwFlags & PFD_DOUBLEBUFFER ) && ( TK_IS_SINGLE(type) ) )
  1884. continue;
  1885. if ( !( pfd.dwFlags & PFD_DOUBLEBUFFER ) && ( TK_IS_DOUBLE(type) ) )
  1886. continue;
  1887. /* If accum requested then accum rgb size must be > 0 */
  1888. /* If alpha requested then alpha size must be > 0 */
  1889. /* if accum & alpha requested then accum alpha size must be > 0 */
  1890. if ( TK_IS_RGB(type) )
  1891. {
  1892. if ( TK_HAS_ACCUM(type) )
  1893. {
  1894. if ( pfd.cAccumBits <= 0 )
  1895. continue;
  1896. }
  1897. else
  1898. {
  1899. if ( pfd.cAccumBits > 0 )
  1900. continue;
  1901. }
  1902. if ( TK_HAS_ALPHA(type) )
  1903. {
  1904. if ( pfd.cAlphaBits <= 0 )
  1905. continue;
  1906. if ( TK_HAS_ACCUM(type) && pfd.cAccumAlphaBits <= 0 )
  1907. continue;
  1908. }
  1909. else
  1910. {
  1911. if ( pfd.cAlphaBits > 0 )
  1912. continue;
  1913. }
  1914. }
  1915. if ( TK_HAS_DEPTH(type) )
  1916. {
  1917. if ( pfd.cDepthBits <= 0 )
  1918. continue;
  1919. }
  1920. else
  1921. {
  1922. if ( pfd.cDepthBits > 0 )
  1923. continue;
  1924. }
  1925. if ( TK_HAS_STENCIL(type) )
  1926. {
  1927. if ( pfd.cStencilBits <= 0 )
  1928. continue;
  1929. }
  1930. else
  1931. {
  1932. if ( pfd.cStencilBits > 0 )
  1933. continue;
  1934. }
  1935. Score = pfd.cColorBits;
  1936. if (Score > BestScore)
  1937. {
  1938. BestScore = Score;
  1939. BestPFD = i;
  1940. *ppfd = pfd;
  1941. }
  1942. } while (++i <= MaxPFDs);
  1943. return ( BestPFD );
  1944. }
  1945. static BOOL IsPixelFormatValid(HDC hdc, int ipfd, PIXELFORMATDESCRIPTOR *ppfd)
  1946. {
  1947. if ( ipfd > 0 )
  1948. {
  1949. if ( ipfd <= DescribePixelFormat(hdc, ipfd, sizeof(*ppfd), ppfd) )
  1950. {
  1951. if ( ( ppfd->dwFlags & PFD_DRAW_TO_WINDOW ) &&
  1952. ( ppfd->dwFlags & PFD_SUPPORT_OPENGL ) )
  1953. {
  1954. return ( TRUE );
  1955. }
  1956. }
  1957. }
  1958. return ( FALSE );
  1959. }
  1960. static void
  1961. PrintMessage( const char *Format, ... )
  1962. {
  1963. va_list ArgList;
  1964. char Buffer[256];
  1965. va_start(ArgList, Format);
  1966. vsprintf(Buffer, Format, ArgList);
  1967. va_end(ArgList);
  1968. MESSAGEBOX(GetFocus(), Buffer, "Error", MB_OK);
  1969. }
  1970. static void
  1971. DelayPaletteRealization( void )
  1972. {
  1973. MSG Message;
  1974. TKASSERT(NULL!=tkhwnd);
  1975. /*
  1976. * Add a WM_USER message to the queue, if there isn't one there already.
  1977. */
  1978. if (!PeekMessage(&Message, tkhwnd, WM_USER, WM_USER, PM_NOREMOVE) )
  1979. {
  1980. PostMessage( tkhwnd, WM_USER, 0, 0);
  1981. }
  1982. }
  1983. /******************************Public*Routine******************************\
  1984. * RealizePaletteNow
  1985. *
  1986. * Select the given palette in background or foreground mode (as specified
  1987. * by the bForceBackground flag), and realize the palette.
  1988. *
  1989. * If static system color usage is set, the system colors are replaced.
  1990. *
  1991. * History:
  1992. * 26-Apr-1994 -by- Gilman Wong [gilmanw]
  1993. * Wrote it.
  1994. \**************************************************************************/
  1995. long
  1996. RealizePaletteNow( HDC Dc, HPALETTE Palette, BOOL bForceBackground )
  1997. {
  1998. long Result = -1;
  1999. BOOL bHaveSysPal = TRUE;
  2000. TKASSERT( NULL!=Dc );
  2001. TKASSERT( NULL!=Palette );
  2002. // If static system color usage is set, prepare to take over the
  2003. // system palette.
  2004. if ( tkUseStaticColors )
  2005. {
  2006. // If foreground, take over the static colors. If background, release
  2007. // the static colors.
  2008. if ( !bForceBackground )
  2009. {
  2010. // If GrabStaticEntries succeeds, then it is OK to take over the
  2011. // static colors. If not, then GrabStaticEntries will have
  2012. // posted a WM_USER message for us to try again later.
  2013. bHaveSysPal = GrabStaticEntries( Dc );
  2014. }
  2015. else
  2016. {
  2017. // If we are currently using the system colors (tkSystemColorsInUse)
  2018. // and RealizePaletteNow was called with bForceBackground set, we
  2019. // are being deactivated and must release the static system colors.
  2020. ReleaseStaticEntries( Dc );
  2021. }
  2022. // Rerealize the palette.
  2023. //
  2024. // If set to TRUE, bForceBackground will force the palette to be realized
  2025. // as a background palette, regardless of focus. This will happen anyway
  2026. // if the TK window does not have the keyboard focus.
  2027. if ( (bForceBackground || bHaveSysPal) &&
  2028. UnrealizeObject( Palette ) &&
  2029. NULL != SelectPalette( Dc, Palette, bForceBackground ) )
  2030. {
  2031. Result = RealizePalette( Dc );
  2032. }
  2033. }
  2034. else
  2035. {
  2036. if ( NULL != SelectPalette( Dc, Palette, FALSE ) )
  2037. {
  2038. Result = RealizePalette( Dc );
  2039. }
  2040. }
  2041. return( Result );
  2042. }
  2043. static void
  2044. ForceRedraw( HWND Window )
  2045. {
  2046. MSG Message;
  2047. if (!PeekMessage(&Message, Window, WM_PAINT, WM_PAINT, PM_NOREMOVE) )
  2048. {
  2049. InvalidateRect( Window, NULL, FALSE );
  2050. }
  2051. }
  2052. static int
  2053. PixelFormatDescriptorFromDc( HDC Dc, PIXELFORMATDESCRIPTOR *Pfd )
  2054. {
  2055. int PfdIndex;
  2056. if ( 0 < (PfdIndex = GetPixelFormat( Dc )) )
  2057. {
  2058. if ( 0 < DescribePixelFormat( Dc, PfdIndex, sizeof(*Pfd), Pfd ) )
  2059. {
  2060. return(PfdIndex);
  2061. }
  2062. else
  2063. {
  2064. PrintMessage("Could not get a description of pixel format %d\n",
  2065. PfdIndex );
  2066. }
  2067. }
  2068. else
  2069. {
  2070. PrintMessage("Could not get pixel format for Dc 0x%08lX\n", Dc );
  2071. }
  2072. return( 0 );
  2073. }
  2074. static void
  2075. DestroyThisWindow( HWND Window )
  2076. {
  2077. if ( NULL != Window )
  2078. {
  2079. DestroyWindow( Window );
  2080. }
  2081. }
  2082. /*
  2083. * This Should be called in response to a WM_DESTROY message
  2084. */
  2085. static void
  2086. CleanUp( void )
  2087. {
  2088. HPALETTE hStock;
  2089. // Cleanup the palette.
  2090. if ( NULL != tkhpalette )
  2091. {
  2092. // If static system color usage is set, restore the system colors.
  2093. if ( tkUseStaticColors )
  2094. {
  2095. RealizePaletteNow( tkhdc, GetStockObject(DEFAULT_PALETTE), TRUE );
  2096. }
  2097. else
  2098. {
  2099. if ( hStock = GetStockObject( DEFAULT_PALETTE ) )
  2100. SelectPalette( tkhdc, hStock, FALSE );
  2101. }
  2102. DeleteObject( tkhpalette );
  2103. }
  2104. // Cleanup the RC.
  2105. if ( NULL != tkhrc )
  2106. {
  2107. wglMakeCurrent( tkhdc, NULL ); // Release first...
  2108. wglDeleteContext( tkhrc ); // then delete.
  2109. }
  2110. // Cleanup the DC.
  2111. if ( NULL != tkhdc )
  2112. {
  2113. ReleaseDC( tkhwnd, tkhdc );
  2114. }
  2115. // Be really nice and reset global values.
  2116. tkhwnd = NULL;
  2117. tkhdc = NULL;
  2118. tkhrc = NULL;
  2119. tkhpalette = NULL;
  2120. ExposeFunc = NULL;
  2121. ReshapeFunc = NULL;
  2122. IdleFunc = NULL;
  2123. DisplayFunc = NULL;
  2124. KeyDownFunc = NULL;
  2125. MouseDownFunc = NULL;
  2126. MouseUpFunc = NULL;
  2127. MouseMoveFunc = NULL;
  2128. }
  2129. static void *
  2130. AllocateMemory( size_t Size )
  2131. {
  2132. return( LocalAlloc( LMEM_FIXED, Size ) );
  2133. }
  2134. static void *
  2135. AllocateZeroedMemory( size_t Size )
  2136. {
  2137. return( LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, Size ) );
  2138. }
  2139. static void
  2140. FreeMemory( void *Chunk )
  2141. {
  2142. TKASSERT( NULL!=Chunk );
  2143. LocalFree( Chunk );
  2144. }
  2145. /*******************************************************************
  2146. * *
  2147. * Debugging functions go here *
  2148. * *
  2149. *******************************************************************/
  2150. #if DBGFUNC
  2151. static void
  2152. DbgPrintf( const char *Format, ... )
  2153. {
  2154. va_list ArgList;
  2155. char Buffer[256];
  2156. va_start(ArgList, Format);
  2157. vsprintf(Buffer, Format, ArgList);
  2158. va_end(ArgList);
  2159. printf("%s", Buffer );
  2160. fflush(stdout);
  2161. }
  2162. static void
  2163. pwi( void )
  2164. {
  2165. DbgPrintf("windInfo: x %d, y %d, w %d, h %d\n", windInfo.x, windInfo.y, windInfo.width, windInfo.height);
  2166. }
  2167. static void
  2168. pwr(RECT *pr)
  2169. {
  2170. DbgPrintf("Rect: left %d, top %d, right %d, bottom %d\n", pr->left, pr->top, pr->right, pr->bottom);
  2171. }
  2172. static void
  2173. ShowPixelFormat(HDC hdc)
  2174. {
  2175. PIXELFORMATDESCRIPTOR pfd, *ppfd;
  2176. int format;
  2177. ppfd = &pfd;
  2178. format = PixelFormatDescriptorFromDc( hdc, ppfd );
  2179. DbgPrintf("Pixel format %d\n", format);
  2180. DbgPrintf(" dwFlags - 0x%x", ppfd->dwFlags);
  2181. if (ppfd->dwFlags & PFD_DOUBLEBUFFER) DbgPrintf("PFD_DOUBLEBUFFER ");
  2182. if (ppfd->dwFlags & PFD_STEREO) DbgPrintf("PFD_STEREO ");
  2183. if (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) DbgPrintf("PFD_DRAW_TO_WINDOW ");
  2184. if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) DbgPrintf("PFD_DRAW_TO_BITMAP ");
  2185. if (ppfd->dwFlags & PFD_SUPPORT_GDI) DbgPrintf("PFD_SUPPORT_GDI ");
  2186. if (ppfd->dwFlags & PFD_SUPPORT_OPENGL) DbgPrintf("PFD_SUPPORT_OPENGL ");
  2187. if (ppfd->dwFlags & PFD_GENERIC_FORMAT) DbgPrintf("PFD_GENERIC_FORMAT ");
  2188. if (ppfd->dwFlags & PFD_NEED_PALETTE) DbgPrintf("PFD_NEED_PALETTE ");
  2189. if (ppfd->dwFlags & PFD_NEED_SYSTEM_PALETTE) DbgPrintf("PFD_NEED_SYSTEM_PALETTE ");
  2190. DbgPrintf("\n");
  2191. DbgPrintf(" iPixelType - %d", ppfd->iPixelType);
  2192. if (ppfd->iPixelType == PFD_TYPE_RGBA) DbgPrintf("PGD_TYPE_RGBA\n");
  2193. if (ppfd->iPixelType == PFD_TYPE_COLORINDEX) DbgPrintf("PGD_TYPE_COLORINDEX\n");
  2194. DbgPrintf(" cColorBits - %d\n", ppfd->cColorBits);
  2195. DbgPrintf(" cRedBits - %d\n", ppfd->cRedBits);
  2196. DbgPrintf(" cRedShift - %d\n", ppfd->cRedShift);
  2197. DbgPrintf(" cGreenBits - %d\n", ppfd->cGreenBits);
  2198. DbgPrintf(" cGreenShift - %d\n", ppfd->cGreenShift);
  2199. DbgPrintf(" cBlueBits - %d\n", ppfd->cBlueBits);
  2200. DbgPrintf(" cBlueShift - %d\n", ppfd->cBlueShift);
  2201. DbgPrintf(" cAlphaBits - %d\n", ppfd->cAlphaBits);
  2202. DbgPrintf(" cAlphaShift - 0x%x\n", ppfd->cAlphaShift);
  2203. DbgPrintf(" cAccumBits - %d\n", ppfd->cAccumBits);
  2204. DbgPrintf(" cAccumRedBits - %d\n", ppfd->cAccumRedBits);
  2205. DbgPrintf(" cAccumGreenBits - %d\n", ppfd->cAccumGreenBits);
  2206. DbgPrintf(" cAccumBlueBits - %d\n", ppfd->cAccumBlueBits);
  2207. DbgPrintf(" cAccumAlphaBits - %d\n", ppfd->cAccumAlphaBits);
  2208. DbgPrintf(" cDepthBits - %d\n", ppfd->cDepthBits);
  2209. DbgPrintf(" cStencilBits - %d\n", ppfd->cStencilBits);
  2210. DbgPrintf(" cAuxBuffers - %d\n", ppfd->cAuxBuffers);
  2211. DbgPrintf(" iLayerType - %d\n", ppfd->iLayerType);
  2212. DbgPrintf(" bReserved - %d\n", ppfd->bReserved);
  2213. DbgPrintf(" dwLayerMask - 0x%x\n", ppfd->dwLayerMask);
  2214. DbgPrintf(" dwVisibleMask - 0x%x\n", ppfd->dwVisibleMask);
  2215. DbgPrintf(" dwDamageMask - 0x%x\n", ppfd->dwDamageMask);
  2216. }
  2217. #endif /* DBG */