Windows NT 4.0 source code leak
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.

1695 lines
52 KiB

5 years ago
  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 <stdarg.h>
  41. #include <windows.h>
  42. #include "ctk.h"
  43. //#define static
  44. #if defined(__cplusplus) || defined(c_plusplus)
  45. #define class c_class
  46. #endif
  47. #if DBG
  48. #define TKASSERT(x) \
  49. if ( !(x) ) { \
  50. PrintMessage("%s(%d) Assertion failed %s\n", \
  51. __FILE__, __LINE__, #x); \
  52. }
  53. #else
  54. #define TKASSERT(x)
  55. #endif /* DBG */
  56. /********************************************************************/
  57. static long NoOpExecFunc( TK_EventRec *pEvent );
  58. static long (*ExecFunc)(TK_EventRec *pEvent ) = NoOpExecFunc;
  59. static TK_EventRec tkEvent = {
  60. TK_EVENT_EXPOSE,
  61. { 0, 0, 0, 0 }
  62. };
  63. static HWND tkhwnd = NULL;
  64. static HDC tkhdc = NULL;
  65. static HDC tkhmemdc = NULL;
  66. static HGLRC tkhrc = NULL;
  67. static HPALETTE tkhPalette = NULL;
  68. static char *lpszClassName = "ctkLibWClass";
  69. static long tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam);
  70. static VOID StorePixelFormatsIDs( TK_VisualIDsRec *VisualID );
  71. static void PrintMessage( const char *Format, ... );
  72. static HGLRC CreateAndMakeContextCurrent( HDC Dc );
  73. static void CleanUp( void );
  74. static void DestroyThisWindow( HWND Window );
  75. static short FindPixelFormat( HDC Dc, long FormatType );
  76. static short GetPixelFormatInformation( HDC Dc, TK_WindowRec *tkWr, PIXELFORMATDESCRIPTOR *Pfd );
  77. static TK_WindowRec *PIXELFORMATDESCRIPTOR_To_TK_WindowRec ( TK_WindowRec *WindowRec, PIXELFORMATDESCRIPTOR *Pfd );
  78. HDC CreatePixelMapDC(HDC,TK_WindowRec *,UINT, int, LPPIXELFORMATDESCRIPTOR);
  79. BOOL DeletePixelMapDC(HDC);
  80. // Fixed palette support.
  81. #define BLACK PALETTERGB(0,0,0)
  82. #define WHITE PALETTERGB(255,255,255)
  83. #define NUM_STATIC_COLORS (COLOR_BTNHIGHLIGHT - COLOR_SCROLLBAR + 1)
  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. static BOOL tkSystemColorsInUse = FALSE;
  88. // TRUE if static colors have been saved
  89. static BOOL tkStaticSaved = FALSE;
  90. // saved system static colors
  91. static COLORREF gacrSave[NUM_STATIC_COLORS];
  92. // new B&W system static colors
  93. static COLORREF gacrBlackAndWhite[NUM_STATIC_COLORS] = {
  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. };
  116. static INT gaiStaticIndex[NUM_STATIC_COLORS] = {
  117. COLOR_SCROLLBAR ,
  118. COLOR_BACKGROUND ,
  119. COLOR_ACTIVECAPTION ,
  120. COLOR_INACTIVECAPTION ,
  121. COLOR_MENU ,
  122. COLOR_WINDOW ,
  123. COLOR_WINDOWFRAME ,
  124. COLOR_MENUTEXT ,
  125. COLOR_WINDOWTEXT ,
  126. COLOR_CAPTIONTEXT ,
  127. COLOR_ACTIVEBORDER ,
  128. COLOR_INACTIVEBORDER ,
  129. COLOR_APPWORKSPACE ,
  130. COLOR_HIGHLIGHT ,
  131. COLOR_HIGHLIGHTTEXT ,
  132. COLOR_BTNFACE ,
  133. COLOR_BTNSHADOW ,
  134. COLOR_GRAYTEXT ,
  135. COLOR_BTNTEXT ,
  136. COLOR_INACTIVECAPTIONTEXT,
  137. COLOR_BTNHIGHLIGHT
  138. };
  139. static VOID SaveStaticEntries(HDC);
  140. static VOID UseStaticEntries(HDC);
  141. static VOID RestoreStaticEntries(HDC);
  142. /********************************************************************/
  143. void tkCloseWindow(void)
  144. {
  145. DestroyThisWindow(tkhwnd);
  146. }
  147. /********************************************************************/
  148. long tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam)
  149. {
  150. PAINTSTRUCT Paint;
  151. switch (message)
  152. {
  153. case WM_PAINT:
  154. BeginPaint( hWnd, &Paint );
  155. if (!(*ExecFunc)(&tkEvent))
  156. {
  157. tkCloseWindow();
  158. }
  159. EndPaint( hWnd, &Paint );
  160. break;
  161. case WM_GETMINMAXINFO:
  162. {
  163. LPMINMAXINFO lpmmi = (LPMINMAXINFO) lParam;
  164. lpmmi->ptMinTrackSize.x = 1;
  165. lpmmi->ptMinTrackSize.y = 1;
  166. }
  167. return 0;
  168. case WM_DESTROY:
  169. CleanUp();
  170. PostQuitMessage(TRUE);
  171. return(DefWindowProc( hWnd, message, wParam, lParam));
  172. }
  173. return(DefWindowProc( hWnd, message, wParam, lParam));
  174. }
  175. void tkExec( long (*Func)(TK_EventRec *pEvent) )
  176. {
  177. MSG Message;
  178. // WM_SIZE gets delivered before we get here!
  179. if ( NULL != Func )
  180. {
  181. ExecFunc = Func; /* save a pointer to the drawing function */
  182. }
  183. else
  184. {
  185. ExecFunc = NoOpExecFunc;
  186. }
  187. while (GL_TRUE)
  188. {
  189. if (GetMessage(&Message, NULL, 0, 0) )
  190. {
  191. TranslateMessage(&Message);
  192. DispatchMessage(&Message);
  193. }
  194. else
  195. {
  196. break;
  197. }
  198. }
  199. }
  200. static long
  201. NoOpExecFunc( TK_EventRec *pEvent )
  202. {
  203. return(1);
  204. }
  205. /********************************************************************/
  206. // Default palette entry flags
  207. #define PALETTE_FLAGS PC_NOCOLLAPSE
  208. // Gamma correction factor * 10
  209. #define GAMMA_CORRECTION 10
  210. // Maximum color distance with 8-bit components
  211. #define MAX_COL_DIST (3*256*256L)
  212. // Number of static colors
  213. #define STATIC_COLORS 20
  214. // Flags used when matching colors
  215. #define EXACT_MATCH 1
  216. #define COLOR_USED 1
  217. // Conversion tables for n bits to eight bits
  218. #if GAMMA_CORRECTION == 10
  219. // These tables are corrected for a gamma of 1.0
  220. static unsigned char abThreeToEight[8] =
  221. {
  222. 0, 0111 >> 1, 0222 >> 1, 0333 >> 1, 0444 >> 1, 0555 >> 1, 0666 >> 1, 0377
  223. };
  224. static unsigned char abTwoToEight[4] =
  225. {
  226. 0, 0x55, 0xaa, 0xff
  227. };
  228. static unsigned char abOneToEight[2] =
  229. {
  230. 0, 255
  231. };
  232. #else
  233. // These tables are corrected for a gamma of 1.4
  234. static unsigned char abThreeToEight[8] =
  235. {
  236. 0, 63, 104, 139, 171, 200, 229, 255
  237. };
  238. static unsigned char abTwoToEight[4] =
  239. {
  240. 0, 116, 191, 255
  241. };
  242. static unsigned char abOneToEight[2] =
  243. {
  244. 0, 255
  245. };
  246. #endif
  247. // Table which indicates which colors in a 3-3-2 palette should be
  248. // replaced with the system default colors
  249. #if GAMMA_CORRECTION == 10
  250. static int aiDefaultOverride[STATIC_COLORS] =
  251. {
  252. 0, 4, 32, 36, 128, 132, 160, 173, 181, 245,
  253. 247, 164, 156, 7, 56, 63, 192, 199, 248, 255
  254. };
  255. #else
  256. static int aiDefaultOverride[STATIC_COLORS] =
  257. {
  258. 0, 3, 24, 27, 64, 67, 88, 173, 181, 236,
  259. 247, 164, 91, 7, 56, 63, 192, 199, 248, 255
  260. };
  261. #endif
  262. static unsigned char
  263. ComponentFromIndex(int i, int nbits, int shift)
  264. {
  265. unsigned char val;
  266. TKASSERT(nbits >= 1 && nbits <= 3);
  267. val = i >> shift;
  268. switch (nbits)
  269. {
  270. case 1:
  271. return abOneToEight[val & 1];
  272. case 2:
  273. return abTwoToEight[val & 3];
  274. case 3:
  275. return abThreeToEight[val & 7];
  276. }
  277. }
  278. // System default colors
  279. static PALETTEENTRY apeDefaultPalEntry[STATIC_COLORS] =
  280. {
  281. { 0, 0, 0, 0 },
  282. { 0x80,0, 0, 0 },
  283. { 0, 0x80,0, 0 },
  284. { 0x80,0x80,0, 0 },
  285. { 0, 0, 0x80, 0 },
  286. { 0x80,0, 0x80, 0 },
  287. { 0, 0x80,0x80, 0 },
  288. { 0xC0,0xC0,0xC0, 0 },
  289. { 192, 220, 192, 0 },
  290. { 166, 202, 240, 0 },
  291. { 255, 251, 240, 0 },
  292. { 160, 160, 164, 0 },
  293. { 0x80,0x80,0x80, 0 },
  294. { 0xFF,0, 0, 0 },
  295. { 0, 0xFF,0, 0 },
  296. { 0xFF,0xFF,0, 0 },
  297. { 0, 0, 0xFF, 0 },
  298. { 0xFF,0, 0xFF, 0 },
  299. { 0, 0xFF,0xFF, 0 },
  300. { 0xFF,0xFF,0xFF, 0 }
  301. };
  302. /******************************Public*Routine******************************\
  303. *
  304. * UpdateStaticMapping
  305. *
  306. * Computes the best match between the current system static colors
  307. * and a 3-3-2 palette
  308. *
  309. * History:
  310. * Tue Aug 01 18:18:12 1995 -by- Drew Bliss [drewb]
  311. * Created
  312. *
  313. \**************************************************************************/
  314. static void
  315. UpdateStaticMapping(PALETTEENTRY *pe332Palette)
  316. {
  317. HPALETTE hpalStock;
  318. int iStatic, i332;
  319. int iMinDist, iDist;
  320. int iDelta;
  321. int iMinEntry;
  322. PALETTEENTRY *peStatic, *pe332;
  323. hpalStock = GetStockObject(DEFAULT_PALETTE);
  324. // The system should always have one of these
  325. TKASSERT(hpalStock != NULL);
  326. // Make sure there's the correct number of entries
  327. TKASSERT(GetPaletteEntries(hpalStock, 0, 0, NULL) == STATIC_COLORS);
  328. // Get the current static colors
  329. GetPaletteEntries(hpalStock, 0, STATIC_COLORS, apeDefaultPalEntry);
  330. // Zero the flags in the static colors because they are used later
  331. peStatic = apeDefaultPalEntry;
  332. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  333. {
  334. peStatic->peFlags = 0;
  335. peStatic++;
  336. }
  337. // Zero the flags in the incoming palette because they are used later
  338. pe332 = pe332Palette;
  339. for (i332 = 0; i332 < 256; i332++)
  340. {
  341. pe332->peFlags = 0;
  342. pe332++;
  343. }
  344. // Try to match each static color exactly
  345. // This saves time by avoiding the least-squares match for each
  346. // exact match
  347. peStatic = apeDefaultPalEntry;
  348. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  349. {
  350. pe332 = pe332Palette;
  351. for (i332 = 0; i332 < 256; i332++)
  352. {
  353. if (peStatic->peRed == pe332->peRed &&
  354. peStatic->peGreen == pe332->peGreen &&
  355. peStatic->peBlue == pe332->peBlue)
  356. {
  357. TKASSERT(pe332->peFlags != COLOR_USED);
  358. peStatic->peFlags = EXACT_MATCH;
  359. pe332->peFlags = COLOR_USED;
  360. aiDefaultOverride[iStatic] = i332;
  361. break;
  362. }
  363. pe332++;
  364. }
  365. peStatic++;
  366. }
  367. // Match each static color as closely as possible to an entry
  368. // in the 332 palette by minimized the square of the distance
  369. peStatic = apeDefaultPalEntry;
  370. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  371. {
  372. // Skip colors already matched exactly
  373. if (peStatic->peFlags == EXACT_MATCH)
  374. {
  375. peStatic++;
  376. continue;
  377. }
  378. iMinDist = MAX_COL_DIST+1;
  379. #if DBG
  380. iMinEntry = -1;
  381. #endif
  382. pe332 = pe332Palette;
  383. for (i332 = 0; i332 < 256; i332++)
  384. {
  385. // Skip colors already used
  386. if (pe332->peFlags == COLOR_USED)
  387. {
  388. pe332++;
  389. continue;
  390. }
  391. // Compute Euclidean distance squared
  392. iDelta = pe332->peRed-peStatic->peRed;
  393. iDist = iDelta*iDelta;
  394. iDelta = pe332->peGreen-peStatic->peGreen;
  395. iDist += iDelta*iDelta;
  396. iDelta = pe332->peBlue-peStatic->peBlue;
  397. iDist += iDelta*iDelta;
  398. if (iDist < iMinDist)
  399. {
  400. iMinDist = iDist;
  401. iMinEntry = i332;
  402. }
  403. pe332++;
  404. }
  405. TKASSERT(iMinEntry != -1);
  406. // Remember the best match
  407. aiDefaultOverride[iStatic] = iMinEntry;
  408. pe332Palette[iMinEntry].peFlags = COLOR_USED;
  409. peStatic++;
  410. }
  411. // Zero the flags in the static colors because they may have been
  412. // set. We want them to be zero so the colors can be remapped
  413. peStatic = apeDefaultPalEntry;
  414. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  415. {
  416. peStatic->peFlags = 0;
  417. peStatic++;
  418. }
  419. // Reset the 332 flags because we may have set them
  420. pe332 = pe332Palette;
  421. for (i332 = 0; i332 < 256; i332++)
  422. {
  423. pe332->peFlags = PALETTE_FLAGS;
  424. pe332++;
  425. }
  426. #if 0
  427. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  428. {
  429. PrintMessage("Static color %2d maps to %d\n",
  430. iStatic, aiDefaultOverride[iStatic]);
  431. }
  432. #endif
  433. }
  434. #define SwapPalE(i,j) { \
  435. PALETTEENTRY palE; \
  436. palE = pPal->palPalEntry[i]; \
  437. pPal->palPalEntry[i] = pPal->palPalEntry[j]; \
  438. pPal->palPalEntry[j] = palE; }
  439. /******************************Public*Routine******************************\
  440. * SaveStaticEntries
  441. *
  442. * Save the current static system color settings. This should be called
  443. * prior to UseStaticEntries() to initialize gacrSave. Once gacrSave is
  444. * called, RestoreStaticEntries() can be called to restore the static system
  445. * color settings.
  446. *
  447. * The colors can be saved only if the tk palette is the background palette.
  448. * This check is done so that we do not accidentally replace the saved
  449. * settings with the B&W settings used when static system color usage is set
  450. * and the fixed 332 rgb palette is realized in the foreground.
  451. *
  452. * History:
  453. * 26-Apr-1994 -by- Gilman Wong [gilmanw]
  454. * Wrote it.
  455. \**************************************************************************/
  456. static VOID SaveStaticEntries(HDC hdc)
  457. {
  458. int i;
  459. if ( !tkSystemColorsInUse )
  460. {
  461. for (i = COLOR_SCROLLBAR; i <= COLOR_BTNHIGHLIGHT; i++)
  462. gacrSave[i - COLOR_SCROLLBAR] = GetSysColor(i);
  463. tkStaticSaved = TRUE;
  464. }
  465. }
  466. /******************************Public*Routine******************************\
  467. * UseStaticEntries
  468. *
  469. * Replace the static system color settings with black and white color
  470. * settings. This is used when taking over the system static colors to
  471. * realize a 332 rgb fixed palette. Realizing such a palette in the
  472. * foreground screws up the system colors (menus, titles, scrollbars, etc.).
  473. * Setting the system colors to B&W, while not perfect (some elements of
  474. * the UI are DIBs and will not be effected by this--for example, the
  475. * system menu (or "coin slot") button), is somewhat better.
  476. *
  477. * Side effect:
  478. * WM_SYSCOLORCHANGE message is broadcast to all top-level windows to
  479. * inform them of the system palette change.
  480. *
  481. * History:
  482. * 26-Apr-1994 -by- Gilman Wong [gilmanw]
  483. * Wrote it.
  484. \**************************************************************************/
  485. static VOID UseStaticEntries(HDC hdc)
  486. {
  487. SetSysColors(NUM_STATIC_COLORS, gaiStaticIndex, gacrBlackAndWhite);
  488. tkSystemColorsInUse = TRUE;
  489. PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
  490. }
  491. /******************************Public*Routine******************************\
  492. * RestoreStaticEntries
  493. *
  494. * Restores the static system colors to the settings that existed at the
  495. * time SaveStaticEntries was called.
  496. *
  497. * Side effect:
  498. * WM_SYSCOLORCHANGE message is broadcast to all top-level windows to
  499. * inform them of the system palette change.
  500. *
  501. * History:
  502. * 26-Apr-1994 -by- Gilman Wong [gilmanw]
  503. * Wrote it.
  504. \**************************************************************************/
  505. static VOID RestoreStaticEntries(HDC hdc)
  506. {
  507. // Must check to see that SaveStaticEntries was called at least once.
  508. // Otherwise, a bad tk app might mess up the system colors.
  509. if ( tkStaticSaved )
  510. {
  511. SetSysColors(NUM_STATIC_COLORS, gaiStaticIndex, gacrSave);
  512. tkSystemColorsInUse = FALSE;
  513. PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
  514. }
  515. }
  516. /******************************Public*Routine******************************\
  517. * FlushPalette
  518. *
  519. * Because of Win 3.1 compatibility, GDI palette mapping always starts
  520. * at zero and stops at the first exact match. So if there are duplicates,
  521. * the higher colors aren't mapped to--which is often a problem if we
  522. * are trying to make to any of the upper 10 static colors. To work around
  523. * this, we flush the palette to all black.
  524. *
  525. * This only needs to be done for the 8BPP (256 color) case.
  526. *
  527. \**************************************************************************/
  528. static void
  529. FlushPalette(HDC hdc, int nColors)
  530. {
  531. LOGPALETTE *pPal;
  532. HPALETTE hpal, hpalOld;
  533. int i;
  534. if (nColors == 256)
  535. {
  536. pPal = (LOGPALETTE *) LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT,
  537. sizeof(LOGPALETTE) + nColors * sizeof(PALETTEENTRY));
  538. if (pPal)
  539. {
  540. pPal->palVersion = 0x300;
  541. pPal->palNumEntries = nColors;
  542. // Mark everything PC_NOCOLLAPSE and PC_RESERVED to force every thing
  543. // into the palette. Colors are already black because we zero initialized
  544. // during memory allocation.
  545. for (i = 0; i < nColors; i++)
  546. {
  547. pPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE | PC_RESERVED;
  548. }
  549. hpal = CreatePalette(pPal);
  550. LocalFree(pPal);
  551. hpalOld = SelectPalette(hdc, hpal, FALSE);
  552. RealizePalette(hdc);
  553. SelectPalette(hdc, hpalOld, FALSE);
  554. DeleteObject(hpal);
  555. }
  556. }
  557. }
  558. static void
  559. CreateRGBPalette(HDC hdc, PIXELFORMATDESCRIPTOR *ppfd )
  560. {
  561. LOGPALETTE *pPal;
  562. int n, i;
  563. tkUseStaticColors = ppfd->dwFlags & PFD_NEED_SYSTEM_PALETTE;
  564. // PFD_NEED_PALETTE should not be set if PFD_TYPE_COLORINDEX mode.
  565. TKASSERT( (ppfd->iPixelType == PFD_TYPE_COLORINDEX) ?
  566. ((ppfd->dwFlags & PFD_NEED_PALETTE) == 0) : TRUE );
  567. if (ppfd->dwFlags & PFD_NEED_PALETTE) {
  568. if (!tkhPalette) {
  569. n = 1 << ppfd->cColorBits;
  570. pPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
  571. n * sizeof(PALETTEENTRY));
  572. pPal->palVersion = 0x300;
  573. pPal->palNumEntries = n;
  574. for (i=0; i<n; i++) {
  575. pPal->palPalEntry[i].peRed =
  576. ComponentFromIndex(i, ppfd->cRedBits, ppfd->cRedShift);
  577. pPal->palPalEntry[i].peGreen =
  578. ComponentFromIndex(i, ppfd->cGreenBits, ppfd->cGreenShift);
  579. pPal->palPalEntry[i].peBlue =
  580. ComponentFromIndex(i, ppfd->cBlueBits, ppfd->cBlueShift);
  581. pPal->palPalEntry[i].peFlags = PALETTE_FLAGS;
  582. }
  583. if ( 256 == n )
  584. {
  585. if ( tkUseStaticColors )
  586. {
  587. // Black and white already exist as the only remaining static
  588. // colors. Let those remap. All others should be put into
  589. // the palette (i.e., peFlags == PC_NOCOLLAPSE).
  590. pPal->palPalEntry[0].peFlags = 0;
  591. pPal->palPalEntry[255].peFlags = 0;
  592. SaveStaticEntries(hdc);
  593. SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
  594. }
  595. else
  596. {
  597. if ( (3 == ppfd->cRedBits) && (0 == ppfd->cRedShift) &&
  598. (3 == ppfd->cGreenBits) && (3 == ppfd->cGreenShift) &&
  599. (2 == ppfd->cBlueBits) && (6 == ppfd->cBlueShift) )
  600. {
  601. UpdateStaticMapping(pPal->palPalEntry);
  602. for (i = 0; i < STATIC_COLORS; i++)
  603. {
  604. pPal->palPalEntry[aiDefaultOverride[i]] =
  605. apeDefaultPalEntry[i];
  606. }
  607. }
  608. }
  609. }
  610. tkhPalette = CreatePalette(pPal);
  611. LocalFree(pPal);
  612. }
  613. FlushPalette(hdc, n);
  614. SelectPalette(hdc, tkhPalette, FALSE);
  615. n = RealizePalette(hdc);
  616. if ( tkUseStaticColors )
  617. UseStaticEntries(hdc);
  618. }
  619. // set up logical indices for CI mode
  620. else if( ppfd->iPixelType == PFD_TYPE_COLORINDEX ) {
  621. if (!tkhPalette) {
  622. if (ppfd->cColorBits == 4) {
  623. // for 4-bit, create a logical palette with 16 entries
  624. n = 16;
  625. pPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
  626. n * sizeof(PALETTEENTRY));
  627. pPal->palVersion = 0x300;
  628. pPal->palNumEntries = n;
  629. for( i = 0; i < 8; i ++) {
  630. pPal->palPalEntry[i] = apeDefaultPalEntry[i];
  631. }
  632. for (i = 8; i < 16; i++) {
  633. pPal->palPalEntry[i] = apeDefaultPalEntry[i+4];
  634. }
  635. // conform expects indices 0..3 to be BLACK,RED,GREEN,BLUE, so
  636. // we rearrange the table for now.
  637. SwapPalE(1,9)
  638. SwapPalE(2,10)
  639. SwapPalE(3,12)
  640. } else if (ppfd->cColorBits == 8) {
  641. // for 8-bit, create a logical palette with 256 entries, making
  642. // sure that the 20 system colors exist in the palette
  643. n = 256;
  644. pPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
  645. n * sizeof(PALETTEENTRY));
  646. pPal->palVersion = 0x300;
  647. pPal->palNumEntries = n;
  648. tkhPalette = GetStockObject (DEFAULT_PALETTE);
  649. // start by copying default palette into new one
  650. GetPaletteEntries( tkhPalette, 0, 20, pPal->palPalEntry);
  651. // conform expects indices 0..3 to be BLACK,RED,GREEN,BLUE, so
  652. // we rearrange the table for now.
  653. SwapPalE(1,13)
  654. SwapPalE(2,14)
  655. SwapPalE(3,16)
  656. for( i = 20; i < n; i ++) {
  657. pPal->palPalEntry[i].peRed = (BYTE) (i - 1);
  658. pPal->palPalEntry[i].peGreen = (BYTE) (i - 2);
  659. pPal->palPalEntry[i].peBlue = (BYTE) (i - 3);
  660. pPal->palPalEntry[i].peFlags = (BYTE) 0;
  661. }
  662. // If we are taking possession of the system colors,
  663. // must guarantee that 0 and 255 are black and white
  664. // (respectively), so that they can remap to the
  665. // remaining two static colors. All other entries must
  666. // be marked as PC_NOCOLLAPSE.
  667. if ( tkUseStaticColors )
  668. {
  669. pPal->palPalEntry[0].peRed =
  670. pPal->palPalEntry[0].peGreen =
  671. pPal->palPalEntry[0].peBlue = 0x00;
  672. pPal->palPalEntry[255].peRed =
  673. pPal->palPalEntry[255].peGreen =
  674. pPal->palPalEntry[255].peBlue = 0xFF;
  675. pPal->palPalEntry[0].peFlags =
  676. pPal->palPalEntry[255].peFlags = 0;
  677. for ( i = 1 ; i < 255 ; i++ )
  678. {
  679. pPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
  680. // This is a workaround for a GDI palette "feature". If
  681. // any of the static colors are repeated in the palette,
  682. // those colors will map to the first occurance. So, for
  683. // our case where there are only two static colors (black
  684. // and white), if a white color appears anywhere in the
  685. // palette other than in the last entry, the static white
  686. // will remap to the first white. This destroys the nice
  687. // one-to-one mapping we are trying to achieve.
  688. //
  689. // There are two ways to workaround this. The first is to
  690. // simply not allow a pure white anywhere but in the last
  691. // entry. Such requests are replaced with an attenuated
  692. // white of (0xFE, 0xFE, 0xFE).
  693. //
  694. // The other way is to mark these extra whites with
  695. // PC_RESERVED which will cause GDI to skip these entries
  696. // when mapping colors. This way the app gets the actual
  697. // colors requested, but can have side effects on other
  698. // apps.
  699. if ( pPal->palPalEntry[i].peRed == 0xFF &&
  700. pPal->palPalEntry[i].peGreen == 0xFF &&
  701. pPal->palPalEntry[i].peBlue == 0xFF )
  702. {
  703. pPal->palPalEntry[i].peFlags |= PC_RESERVED;
  704. }
  705. }
  706. SaveStaticEntries(hdc);
  707. SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
  708. }
  709. } else {
  710. // for pixel formats > 8 bits deep, create a logical palette with
  711. // 4096 entries
  712. n = 4096;
  713. pPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
  714. n * sizeof(PALETTEENTRY));
  715. pPal->palVersion = 0x300;
  716. pPal->palNumEntries = n;
  717. for( i = 0; i < n; i ++) {
  718. pPal->palPalEntry[i].peRed = (BYTE) ((i & 0x000f) << 4);
  719. pPal->palPalEntry[i].peGreen = (BYTE) (i & 0x00f0);
  720. pPal->palPalEntry[i].peBlue = (BYTE) ((i & 0x0f00) >> 4);
  721. pPal->palPalEntry[i].peFlags = (BYTE) 0;
  722. }
  723. // conform expects indices 0..3 to be BLACK,RED,GREEN,BLUE, so
  724. // we rearrange the table for now.
  725. SwapPalE(1,0xf)
  726. SwapPalE(2,0xf0)
  727. SwapPalE(3,0xf00)
  728. }
  729. tkhPalette = CreatePalette(pPal);
  730. LocalFree(pPal);
  731. }
  732. FlushPalette(hdc, n);
  733. TKASSERT(tkhPalette != NULL);
  734. SelectPalette(hdc, tkhPalette, FALSE);
  735. n = RealizePalette(hdc);
  736. if ( tkUseStaticColors )
  737. UseStaticEntries(hdc);
  738. }
  739. }
  740. void
  741. ShowPixelFormat(HDC hdc)
  742. {
  743. PIXELFORMATDESCRIPTOR pfd, *ppfd;
  744. int format;
  745. ppfd = &pfd;
  746. format = GetPixelFormat(hdc);
  747. DescribePixelFormat(hdc, format, sizeof(PIXELFORMATDESCRIPTOR), ppfd);
  748. printf("Pixel format %d\n", format);
  749. printf(" dwFlags - 0x%x", ppfd->dwFlags);
  750. if (ppfd->dwFlags & PFD_DOUBLEBUFFER) printf("PFD_DOUBLEBUFFER ");
  751. if (ppfd->dwFlags & PFD_STEREO) printf("PFD_STEREO ");
  752. if (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) printf("PFD_DRAW_TO_WINDOW ");
  753. if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) printf("PFD_DRAW_TO_BITMAP ");
  754. if (ppfd->dwFlags & PFD_SUPPORT_GDI) printf("PFD_SUPPORT_GDI ");
  755. if (ppfd->dwFlags & PFD_SUPPORT_OPENGL) printf("PFD_SUPPORT_OPENGL ");
  756. if (ppfd->dwFlags & PFD_GENERIC_FORMAT) printf("PFD_GENERIC_FORMAT ");
  757. if (ppfd->dwFlags & PFD_NEED_PALETTE) printf("PFD_NEED_PALETTE ");
  758. if (ppfd->dwFlags & PFD_NEED_SYSTEM_PALETTE) printf("PFD_NEED_SYSTEM_PALETTE ");
  759. printf("\n");
  760. printf(" iPixelType - %d", ppfd->iPixelType);
  761. if (ppfd->iPixelType == PFD_TYPE_RGBA) printf("PGD_TYPE_RGBA\n");
  762. if (ppfd->iPixelType == PFD_TYPE_COLORINDEX) printf("PGD_TYPE_COLORINDEX\n");
  763. printf(" cColorBits - %d\n", ppfd->cColorBits);
  764. printf(" cRedBits - %d\n", ppfd->cRedBits);
  765. printf(" cRedShift - %d\n", ppfd->cRedShift);
  766. printf(" cGreenBits - %d\n", ppfd->cGreenBits);
  767. printf(" cGreenShift - %d\n", ppfd->cGreenShift);
  768. printf(" cBlueBits - %d\n", ppfd->cBlueBits);
  769. printf(" cBlueShift - %d\n", ppfd->cBlueShift);
  770. printf(" cAlphaBits - %d\n", ppfd->cAlphaBits);
  771. printf(" cAlphaShift - 0x%x\n", ppfd->cAlphaShift);
  772. printf(" cAccumBits - %d\n", ppfd->cAccumBits);
  773. printf(" cAccumRedBits - %d\n", ppfd->cAccumRedBits);
  774. printf(" cAccumGreenBits - %d\n", ppfd->cAccumGreenBits);
  775. printf(" cAccumBlueBits - %d\n", ppfd->cAccumBlueBits);
  776. printf(" cAccumAlphaBits - %d\n", ppfd->cAccumAlphaBits);
  777. printf(" cDepthBits - %d\n", ppfd->cDepthBits);
  778. printf(" cStencilBits - %d\n", ppfd->cStencilBits);
  779. printf(" cAuxBuffers - %d\n", ppfd->cAuxBuffers);
  780. printf(" iLayerType - %d\n", ppfd->iLayerType);
  781. printf(" bReserved - %d\n", ppfd->bReserved);
  782. printf(" dwLayerMask - 0x%x\n", ppfd->dwLayerMask);
  783. printf(" dwVisibleMask - 0x%x\n", ppfd->dwVisibleMask);
  784. printf(" dwDamageMask - 0x%x\n", ppfd->dwDamageMask);
  785. }
  786. /*
  787. * This function returns the pixel format index chosen
  788. * by choose pixel format.
  789. */
  790. static short
  791. FindPixelFormat( HDC Dc, long FormatType )
  792. {
  793. PIXELFORMATDESCRIPTOR Pfd;
  794. short PfdIndex;
  795. Pfd.nSize = sizeof(Pfd);
  796. Pfd.nVersion = 1;
  797. Pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
  798. Pfd.dwLayerMask = PFD_MAIN_PLANE;
  799. if (TK_WIND_IS_DB(FormatType)) {
  800. Pfd.dwFlags |= PFD_DOUBLEBUFFER;
  801. }
  802. if (TK_WIND_IS_CI(FormatType)) {
  803. Pfd.iPixelType = PFD_TYPE_COLORINDEX;
  804. Pfd.cColorBits = 8;
  805. }
  806. if (TK_WIND_IS_RGB(FormatType)) {
  807. Pfd.iPixelType = PFD_TYPE_RGBA;
  808. Pfd.cColorBits = 24;
  809. }
  810. if (TK_WIND_ACCUM & FormatType) {
  811. Pfd.cAccumBits = Pfd.cColorBits;
  812. } else {
  813. Pfd.cAccumBits = 0;
  814. }
  815. if (TK_WIND_Z & FormatType) {
  816. Pfd.cDepthBits = 32;
  817. } else if (TK_WIND_Z16 & FormatType) {
  818. Pfd.cDepthBits = 16;
  819. } else {
  820. Pfd.cDepthBits = 0;
  821. }
  822. if (TK_WIND_STENCIL & FormatType) {
  823. Pfd.cStencilBits = 8;
  824. } else {
  825. Pfd.cStencilBits = 0;
  826. }
  827. PfdIndex = ChoosePixelFormat( Dc, &Pfd );
  828. return( PfdIndex );
  829. }
  830. // Initialize a window, create a rendering context for that window
  831. // only allow CI on palette devices, RGB on true color devices
  832. // current server turns on Z, but no accum or stencil
  833. // When SetPixelFormat is implemented, remove all of these restrictions
  834. long
  835. tkNewWindow(TK_WindowRec *tkWr)
  836. {
  837. WNDCLASS wndclass;
  838. RECT WinRect;
  839. HANDLE hInstance;
  840. PIXELFORMATDESCRIPTOR Pfd;
  841. short PfdIndex;
  842. int nPixelFormats;
  843. BOOL Result = FALSE;
  844. HDC tmphdc = NULL;
  845. TKASSERT(NULL==tkhwnd );
  846. TKASSERT(NULL==tkhdc );
  847. TKASSERT(NULL==tkhrc );
  848. TKASSERT(NULL==tkhPalette );
  849. TKASSERT(ExecFunc==NoOpExecFunc );
  850. hInstance = GetModuleHandle(NULL);
  851. wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  852. wndclass.lpfnWndProc = (WNDPROC)tkWndProc;
  853. wndclass.cbClsExtra = 0;
  854. wndclass.cbWndExtra = 0;
  855. wndclass.hInstance = hInstance;
  856. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  857. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  858. wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
  859. wndclass.lpszMenuName = NULL;
  860. wndclass.lpszClassName = lpszClassName;
  861. RegisterClass(&wndclass);
  862. // Make window large enough to hold a client area as large as tkWr
  863. WinRect.left = (tkWr->x == CW_USEDEFAULT) ? 0 : tkWr->x;
  864. WinRect.top = (tkWr->y == CW_USEDEFAULT) ? 0 : tkWr->y;
  865. WinRect.right = WinRect.left + tkWr->width;
  866. WinRect.bottom = WinRect.top + tkWr->height;
  867. AdjustWindowRect(&WinRect, WS_OVERLAPPEDWINDOW, FALSE);
  868. tkhwnd = CreateWindowEx(
  869. WS_EX_TOPMOST,
  870. lpszClassName,
  871. tkWr->name,
  872. WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  873. (tkWr->x == CW_USEDEFAULT ? CW_USEDEFAULT : WinRect.left),
  874. (tkWr->y == CW_USEDEFAULT ? CW_USEDEFAULT : WinRect.top),
  875. WinRect.right - WinRect.left,
  876. WinRect.bottom - WinRect.top,
  877. NULL,
  878. NULL,
  879. hInstance,
  880. NULL);
  881. /*
  882. * Fixup window size in case minimum tracking size did something.
  883. */
  884. GetClientRect(tkhwnd, &WinRect);
  885. tkWr->width = WinRect.right;
  886. tkWr->height = WinRect.bottom;
  887. if ( NULL != tkhwnd )
  888. {
  889. tkhdc = GetDC(tkhwnd);
  890. if (tkWr->type == TK_WIND_VISUAL)
  891. {
  892. nPixelFormats = DescribePixelFormat(tkhdc,abs(tkWr->info),sizeof(PIXELFORMATDESCRIPTOR),&Pfd);
  893. // If tkWr->info is negative, this is a bitmap request
  894. // Otherwise, it is a display request
  895. if (tkWr->info < 0)
  896. {
  897. tkWr->info = -(tkWr->info);
  898. if (!(Pfd.dwFlags & PFD_DRAW_TO_BITMAP))
  899. goto tkNewWindow_exit;
  900. tkhmemdc = CreatePixelMapDC(tkhdc, tkWr, DIB_RGB_COLORS, Pfd.cColorBits, &Pfd);
  901. tmphdc = tkhmemdc;
  902. }
  903. else
  904. {
  905. if (!(Pfd.dwFlags & PFD_DRAW_TO_WINDOW))
  906. goto tkNewWindow_exit;
  907. tmphdc = tkhdc;
  908. }
  909. }
  910. else
  911. tmphdc = tkhdc;
  912. /*
  913. * XXXX
  914. * I would like to delay the show window a little longer
  915. * but this causes an exception, during clears. New code
  916. * will fix this.
  917. */
  918. ShowWindow(tkhwnd, SW_SHOWDEFAULT);
  919. PfdIndex = GetPixelFormatInformation( tmphdc, tkWr, &Pfd );
  920. if ( PfdIndex )
  921. {
  922. if ( SetPixelFormat( tmphdc, PfdIndex, &Pfd ) )
  923. {
  924. /*
  925. * Would be nice to delay until then, alas, we have a bug
  926. */
  927. ShowPixelFormat(tmphdc);
  928. /*
  929. * If the tmp DC is a memory DC, create and
  930. * realize the palette for the screen DC first.
  931. * Memory DC palettes are realized as background
  932. * palettes, so we must put the palette in the
  933. * foreground via the screen DC before we muck
  934. * around with the memory DC.
  935. */
  936. if (tmphdc != tkhdc)
  937. CreateRGBPalette( tkhdc, &Pfd );
  938. CreateRGBPalette( tmphdc, &Pfd );
  939. tkhrc = CreateAndMakeContextCurrent( tmphdc );
  940. if ( NULL != tkhrc )
  941. {
  942. ShowWindow(tkhwnd, SW_SHOWDEFAULT);
  943. /*
  944. * Convert information in the pixel format descriptor
  945. * to the TK_WindowRec format
  946. */
  947. PIXELFORMATDESCRIPTOR_To_TK_WindowRec ( tkWr, &Pfd );
  948. Result = TRUE;
  949. }
  950. }
  951. }
  952. }
  953. tkNewWindow_exit:
  954. if ( FALSE == Result )
  955. {
  956. /*
  957. * Something Failed, Destroy this window
  958. */
  959. DestroyThisWindow(tkhwnd);
  960. /*
  961. * Process all the messages
  962. */
  963. tkExec( (long (*)(TK_EventRec *pEvent))NULL );
  964. }
  965. return( Result );
  966. }
  967. /*
  968. * If a function fails, this function will clean itself up
  969. */
  970. static HGLRC
  971. CreateAndMakeContextCurrent( HDC Dc )
  972. {
  973. HGLRC Rc = NULL;
  974. /* Create a Rendering Context */
  975. Rc = wglCreateContext( Dc );
  976. if ( NULL != Rc )
  977. {
  978. /* Make it Current */
  979. if ( FALSE == wglMakeCurrent( Dc, Rc ) )
  980. {
  981. wglDeleteContext( Rc );
  982. Rc = NULL;
  983. }
  984. }
  985. return( Rc );
  986. }
  987. static void
  988. DestroyThisWindow( HWND Window )
  989. {
  990. if ( NULL != Window )
  991. {
  992. DestroyWindow( Window );
  993. }
  994. }
  995. /*
  996. * This Should be called in response to a WM_DESTROY message
  997. */
  998. static void
  999. CleanUp( void )
  1000. {
  1001. if ( NULL != tkhwnd )
  1002. {
  1003. if ( NULL != tkhdc )
  1004. {
  1005. if ( NULL != tkhPalette )
  1006. {
  1007. DeleteObject(
  1008. SelectObject( tkhdc, GetStockObject(DEFAULT_PALETTE) ));
  1009. if ( tkUseStaticColors )
  1010. {
  1011. SetSystemPaletteUse( tkhdc, SYSPAL_STATIC );
  1012. RealizePalette( tkhdc );
  1013. RestoreStaticEntries( tkhdc );
  1014. }
  1015. tkhPalette = NULL;
  1016. }
  1017. if ( NULL != tkhrc )
  1018. {
  1019. wglMakeCurrent( tkhdc, NULL ); // No current context
  1020. wglDeleteContext(tkhrc); // Delete this context
  1021. tkhrc = NULL;
  1022. }
  1023. ReleaseDC( tkhwnd, tkhdc );
  1024. tkhdc = NULL;
  1025. }
  1026. tkhwnd = NULL;
  1027. }
  1028. ExecFunc = NoOpExecFunc;
  1029. }
  1030. /*******************************************************************/
  1031. void tkQuit(void)
  1032. {
  1033. TKASSERT(NULL==tkhwnd );
  1034. TKASSERT(NULL==tkhdc );
  1035. TKASSERT(NULL==tkhrc );
  1036. TKASSERT(NULL==tkhPalette );
  1037. ExitProcess(0);
  1038. }
  1039. /*******************************************************************/
  1040. void tkSwapBuffers(void)
  1041. {
  1042. SwapBuffers(tkhdc);
  1043. }
  1044. /*******************************************************************/
  1045. void tkGet(long item, void *data)
  1046. {
  1047. if (item == TK_SCREENIMAGE)
  1048. {
  1049. // XXXX We will need this the covglx and conformw
  1050. OutputDebugString("tkGet(TK_SCREENIMAGE) is not implemented\n");
  1051. }
  1052. else if (item == TK_VISUALIDS)
  1053. {
  1054. StorePixelFormatsIDs( data );
  1055. }
  1056. }
  1057. static VOID
  1058. StorePixelFormatsIDs( TK_VisualIDsRec *VisualID )
  1059. {
  1060. HDC hDc;
  1061. int AvailableIds;
  1062. int Id;
  1063. PIXELFORMATDESCRIPTOR Pfd;
  1064. /*
  1065. * Get a DC for the display
  1066. */
  1067. hDc = GetDC(NULL);
  1068. /*
  1069. * Get the total number of pixel formats
  1070. */
  1071. AvailableIds = DescribePixelFormat( hDc, 0, 0, NULL );
  1072. /*
  1073. * Store the IDs in the structure.
  1074. * The first Id starts at one.
  1075. */
  1076. VisualID->count = 0;
  1077. for ( Id = 1 ; Id <= AvailableIds ; Id++ )
  1078. {
  1079. /*
  1080. * Make sure you don't overrun the structure's buffer
  1081. */
  1082. if (
  1083. Id <= ((sizeof(((TK_VisualIDsRec *)NULL)->IDs) /
  1084. sizeof(((TK_VisualIDsRec *)NULL)->IDs[0])))
  1085. )
  1086. {
  1087. if ( DescribePixelFormat( hDc, Id, sizeof(Pfd), &Pfd ) )
  1088. {
  1089. /*
  1090. * Make sure the pixel format index supports OpenGL
  1091. */
  1092. if ( PFD_SUPPORT_OPENGL & Pfd.dwFlags )
  1093. {
  1094. VisualID->IDs[VisualID->count++] = Id;
  1095. }
  1096. }
  1097. }
  1098. else
  1099. break;
  1100. }
  1101. /*
  1102. * Don't need the DC anymore
  1103. */
  1104. ReleaseDC( NULL, hDc );
  1105. }
  1106. static void
  1107. PrintMessage( const char *Format, ... )
  1108. {
  1109. va_list ArgList;
  1110. char Buffer[256];
  1111. va_start(ArgList, Format);
  1112. vsprintf(Buffer, Format, ArgList);
  1113. va_end(ArgList);
  1114. fprintf( stderr, "libctk: %s", Buffer );
  1115. fflush(stdout);
  1116. }
  1117. /********************************************************************/
  1118. /*
  1119. * This function returns the selected pixel format index and
  1120. * the pixel format descriptor.
  1121. */
  1122. static short
  1123. GetPixelFormatInformation( HDC Dc, TK_WindowRec *tkWr, PIXELFORMATDESCRIPTOR *Pfd )
  1124. {
  1125. short PfdIndex = 0; // Assume no pixel format matches
  1126. /*
  1127. * TK_WIND_REQUEST indicates that tkWr->info is a mask
  1128. * describing the type of pixel format requested.
  1129. */
  1130. if ( TK_WIND_REQUEST == tkWr->type )
  1131. {
  1132. PfdIndex = FindPixelFormat( Dc, tkWr->info );
  1133. }
  1134. else
  1135. {
  1136. /*
  1137. * Otherwise, tkWr->info contains the pixel format Id.
  1138. */
  1139. PfdIndex = (short)tkWr->info;
  1140. }
  1141. if ( DescribePixelFormat( Dc, PfdIndex, sizeof(*Pfd), Pfd) )
  1142. {
  1143. if ( !(PFD_SUPPORT_OPENGL & Pfd->dwFlags) )
  1144. {
  1145. PfdIndex = 0; // Does not support OpenGL, make it fail
  1146. }
  1147. }
  1148. return( PfdIndex );
  1149. }
  1150. /********************************************************************\
  1151. | CREATE PIXEL-MAP DC
  1152. |
  1153. | hWnd : WindowDC created via GetDC()
  1154. | nFormat: must be in the range 21 - 40
  1155. | uUsage : DIB_RGB_COLORS (do this one)
  1156. | DIB_PAL_COLORS
  1157. |
  1158. \********************************************************************/
  1159. HDC CreatePixelMapDC(HDC hDC, TK_WindowRec *tkWr, UINT uUsage, int nBpp, LPPIXELFORMATDESCRIPTOR lpPfd)
  1160. {
  1161. HDC hMemDC;
  1162. HBITMAP hBitmap,hSave;
  1163. int nWidth,nHeight,nColorTable,idx,nEntries;
  1164. DWORD dwSize,dwBits,dwCompression;
  1165. HANDLE hDib;
  1166. PVOID pvBits;
  1167. LPSTR lpDib,lpCT;
  1168. DWORD dwRMask,dwBMask,dwGMask;
  1169. static COLORREF cr16Color[] = {0x00000000,
  1170. 0x00000080,
  1171. 0x00008000,
  1172. 0x00008080,
  1173. 0x00800000,
  1174. 0x00800080,
  1175. 0x00808000,
  1176. 0x00808080,
  1177. 0x00C0C0C0,
  1178. 0x000000FF,
  1179. 0x0000FF00,
  1180. 0x0000FFFF,
  1181. 0x00FF0000,
  1182. 0x00FF00FF,
  1183. 0x00FFFF00,
  1184. 0x00FFFFFF};
  1185. if(hMemDC = CreateCompatibleDC(hDC))
  1186. {
  1187. // Get device information for the surface
  1188. //
  1189. nWidth = tkWr->width;
  1190. nHeight = tkWr->height;
  1191. #define USE_DFB 1
  1192. #if USE_DFB
  1193. // Use compatible bitmap (DFB if supported) if DC color
  1194. // depth matches requested color depth. Otherwise, use DIB.
  1195. if ( nBpp == (GetDeviceCaps(hDC, BITSPIXEL) *
  1196. GetDeviceCaps(hDC, PLANES)) )
  1197. {
  1198. if(hBitmap = CreateCompatibleBitmap(hDC,nWidth,nHeight))
  1199. {
  1200. if(hSave = SelectObject(hMemDC,hBitmap))
  1201. {
  1202. return(hMemDC);
  1203. }
  1204. DeleteObject(hBitmap);
  1205. }
  1206. }
  1207. else
  1208. {
  1209. #endif
  1210. if(nBpp)
  1211. {
  1212. // Get the colortable size.
  1213. //
  1214. switch(nBpp)
  1215. {
  1216. case 32:
  1217. case 16:
  1218. nColorTable = 3 * sizeof(DWORD);
  1219. dwCompression = BI_BITFIELDS;
  1220. break;
  1221. case 24:
  1222. nColorTable = 0;
  1223. dwCompression = BI_RGB;
  1224. break;
  1225. default:
  1226. nColorTable = ((UINT)1 << nBpp) * sizeof(RGBQUAD);
  1227. dwCompression = BI_RGB;
  1228. if(uUsage == DIB_PAL_COLORS)
  1229. nColorTable >>= 1;
  1230. break;
  1231. }
  1232. // Calculate necessary size for dib.
  1233. //
  1234. dwBits = (DWORD)(((nWidth * nBpp) + 31) / 32) * nHeight * sizeof(DWORD);
  1235. dwSize = (DWORD)dwBits + sizeof(BITMAPINFOHEADER) + nColorTable;
  1236. // Create the bitmap based upon the DIB specification.
  1237. //
  1238. if(hDib = GlobalAlloc(GHND,dwSize))
  1239. {
  1240. if(lpDib = GlobalLock(hDib))
  1241. {
  1242. // Initialize DIB specification.
  1243. //
  1244. ((LPBITMAPINFOHEADER)lpDib)->biSize = sizeof(BITMAPINFOHEADER);
  1245. ((LPBITMAPINFOHEADER)lpDib)->biWidth = nWidth;
  1246. ((LPBITMAPINFOHEADER)lpDib)->biHeight = nHeight;
  1247. ((LPBITMAPINFOHEADER)lpDib)->biPlanes = 1;
  1248. ((LPBITMAPINFOHEADER)lpDib)->biBitCount = (UINT)nBpp;
  1249. ((LPBITMAPINFOHEADER)lpDib)->biCompression = dwCompression;
  1250. ((LPBITMAPINFOHEADER)lpDib)->biSizeImage = 0;
  1251. ((LPBITMAPINFOHEADER)lpDib)->biXPelsPerMeter = 0;
  1252. ((LPBITMAPINFOHEADER)lpDib)->biYPelsPerMeter = 0;
  1253. ((LPBITMAPINFOHEADER)lpDib)->biClrUsed = 0;
  1254. ((LPBITMAPINFOHEADER)lpDib)->biClrImportant = 0;
  1255. // Fill in colortable for appropriate bitmap-format.
  1256. //
  1257. lpCT = (LPSTR)((LPBITMAPINFO)lpDib)->bmiColors;
  1258. switch(nBpp)
  1259. {
  1260. case 32:
  1261. case 16:
  1262. // This creates the rough mask of bits for the
  1263. // number of color-bits.
  1264. //
  1265. dwRMask = (((DWORD)1 << lpPfd->cRedBits ) - 1);
  1266. dwGMask = (((DWORD)1 << lpPfd->cGreenBits ) - 1);
  1267. dwBMask = (((DWORD)1 << lpPfd->cBlueBits ) - 1);
  1268. // Shift the masks for the color-table.
  1269. //
  1270. *((LPDWORD)lpCT) = dwRMask << lpPfd->cRedShift;
  1271. *(((LPDWORD)lpCT)+1) = dwGMask << lpPfd->cGreenShift;
  1272. *(((LPDWORD)lpCT)+2) = dwBMask << lpPfd->cBlueShift;
  1273. break;
  1274. case 24:
  1275. break;
  1276. case 8:
  1277. nEntries = ((UINT)1 << nBpp);
  1278. if(uUsage == DIB_PAL_COLORS)
  1279. {
  1280. for(idx=0; idx < nEntries; idx++)
  1281. *(((LPWORD)lpCT)+idx) = idx;
  1282. }
  1283. else
  1284. {
  1285. for(idx=0; idx < nEntries; idx++)
  1286. {
  1287. ((LPBITMAPINFO)lpDib)->bmiColors[idx].rgbRed = ComponentFromIndex(idx,lpPfd->cRedBits ,lpPfd->cRedShift );
  1288. ((LPBITMAPINFO)lpDib)->bmiColors[idx].rgbGreen = ComponentFromIndex(idx,lpPfd->cGreenBits,lpPfd->cGreenShift);
  1289. ((LPBITMAPINFO)lpDib)->bmiColors[idx].rgbBlue = ComponentFromIndex(idx,lpPfd->cBlueBits ,lpPfd->cBlueShift );
  1290. ((LPBITMAPINFO)lpDib)->bmiColors[idx].rgbReserved = 0;
  1291. }
  1292. }
  1293. break;
  1294. case 4:
  1295. nEntries = sizeof(cr16Color) / sizeof(cr16Color[0]);
  1296. if(uUsage == DIB_PAL_COLORS)
  1297. {
  1298. for(idx=0; idx < nEntries; idx++)
  1299. *(((LPWORD)lpCT)+idx) = idx;
  1300. }
  1301. else
  1302. {
  1303. for(idx=0; idx < nEntries; idx++)
  1304. *(((LPDWORD)lpCT)+idx) = cr16Color[idx];
  1305. }
  1306. break;
  1307. case 1:
  1308. if(uUsage == DIB_PAL_COLORS)
  1309. {
  1310. *((LPWORD)lpCT)++ = 0;
  1311. *((LPWORD)lpCT) = 255;
  1312. }
  1313. else
  1314. {
  1315. ((LPBITMAPINFO)lpDib)->bmiColors[0].rgbBlue = 0;
  1316. ((LPBITMAPINFO)lpDib)->bmiColors[0].rgbGreen = 0;
  1317. ((LPBITMAPINFO)lpDib)->bmiColors[0].rgbRed = 0;
  1318. ((LPBITMAPINFO)lpDib)->bmiColors[0].rgbReserved = 0;
  1319. ((LPBITMAPINFO)lpDib)->bmiColors[1].rgbBlue = 255;
  1320. ((LPBITMAPINFO)lpDib)->bmiColors[1].rgbGreen = 255;
  1321. ((LPBITMAPINFO)lpDib)->bmiColors[1].rgbRed = 255;
  1322. ((LPBITMAPINFO)lpDib)->bmiColors[1].rgbReserved = 0;
  1323. }
  1324. break;
  1325. }
  1326. if (hBitmap = CreateDIBSection(hMemDC, (LPBITMAPINFO)lpDib, uUsage, &pvBits, NULL, 0))
  1327. {
  1328. if(hSave = SelectObject(hMemDC,hBitmap))
  1329. {
  1330. GlobalUnlock(hDib);
  1331. GlobalFree(hDib);
  1332. return(hMemDC);
  1333. }
  1334. DeleteObject(hBitmap);
  1335. }
  1336. GlobalUnlock(hDib);
  1337. }
  1338. GlobalFree(hDib);
  1339. }
  1340. }
  1341. #if USE_DFB
  1342. }
  1343. #endif
  1344. }
  1345. return(NULL);
  1346. }
  1347. BOOL DeletePixelMapDC(HDC hDC)
  1348. {
  1349. HBITMAP hFormat,hBitmap;
  1350. BOOL bFree;
  1351. bFree = FALSE;
  1352. if(hFormat = CreateCompatibleBitmap(hDC,1,1))
  1353. {
  1354. if(hBitmap = SelectObject(hDC,hFormat))
  1355. {
  1356. DeleteObject(hBitmap);
  1357. bFree = DeleteDC(hDC);
  1358. }
  1359. DeleteObject(hFormat);
  1360. }
  1361. return(bFree);
  1362. }
  1363. /*
  1364. * This function updates a TK_WindowRec given a PIXELFORMATDESCRIPTOR
  1365. */
  1366. static TK_WindowRec *
  1367. PIXELFORMATDESCRIPTOR_To_TK_WindowRec ( TK_WindowRec *WindowRec, PIXELFORMATDESCRIPTOR *Pfd )
  1368. {
  1369. WindowRec->type = TK_WIND_REQUEST;
  1370. WindowRec->info = 0;
  1371. if ( PFD_DOUBLEBUFFER & Pfd->dwFlags )
  1372. {
  1373. WindowRec->info |= TK_WIND_DB;
  1374. }
  1375. else
  1376. {
  1377. WindowRec->info |= TK_WIND_SB;
  1378. }
  1379. if ( PFD_TYPE_COLORINDEX == Pfd->iPixelType )
  1380. {
  1381. WindowRec->info |= TK_WIND_CI;
  1382. }
  1383. else
  1384. {
  1385. WindowRec->info |= TK_WIND_RGB;
  1386. }
  1387. if ( Pfd->cAccumBits )
  1388. {
  1389. WindowRec->info |= TK_WIND_ACCUM;
  1390. }
  1391. if ( Pfd->cDepthBits > 16 )
  1392. {
  1393. WindowRec->info |= TK_WIND_Z;
  1394. }
  1395. else if ( Pfd->cDepthBits > 0 )
  1396. {
  1397. WindowRec->info |= TK_WIND_Z16;
  1398. }
  1399. if ( Pfd->cStencilBits )
  1400. {
  1401. WindowRec->info |= TK_WIND_STENCIL;
  1402. }
  1403. if ( Pfd->cAuxBuffers )
  1404. {
  1405. WindowRec->info |= TK_WIND_AUX;
  1406. }
  1407. return( WindowRec );
  1408. }