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.

945 lines
27 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: palette.cxx
  3. *
  4. * Palette processing functions
  5. *
  6. * Adapted from tk.c
  7. *
  8. * Copyright (c) 1996 Microsoft Corporation
  9. *
  10. \**************************************************************************/
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <windows.h>
  15. #include <GL/gl.h>
  16. #include "ssintrnl.hxx"
  17. #include "palette.hxx"
  18. #if(WINVER < 0x0400)
  19. // Ordinarily not defined for versions before 4.00.
  20. #define COLOR_3DDKSHADOW 21
  21. #define COLOR_3DLIGHT 22
  22. #define COLOR_INFOTEXT 23
  23. #define COLOR_INFOBK 24
  24. #endif
  25. #define TKASSERT(x) SS_ASSERT( x, "palette processing failure\n" )
  26. /******************************************************************************/
  27. // Fixed palette support.
  28. #define BLACK PALETTERGB(0,0,0)
  29. #define WHITE PALETTERGB(255,255,255)
  30. #define MAX_STATIC_COLORS (COLOR_INFOBK - COLOR_SCROLLBAR + 1)
  31. static int gNumStaticColors = MAX_STATIC_COLORS;
  32. // TRUE if static system color settings have been replaced with B&W settings.
  33. // TRUE if original static colors saved
  34. static BOOL tkStaticColorsSaved = FALSE;
  35. // saved system static colors (initialize with default colors)
  36. static COLORREF gacrSave[MAX_STATIC_COLORS];
  37. // new B&W system static colors
  38. static COLORREF gacrBlackAndWhite[] = {
  39. WHITE, // COLOR_SCROLLBAR
  40. BLACK, // COLOR_BACKGROUND
  41. BLACK, // COLOR_ACTIVECAPTION
  42. WHITE, // COLOR_INACTIVECAPTION
  43. WHITE, // COLOR_MENU
  44. WHITE, // COLOR_WINDOW
  45. BLACK, // COLOR_WINDOWFRAME
  46. BLACK, // COLOR_MENUTEXT
  47. BLACK, // COLOR_WINDOWTEXT
  48. WHITE, // COLOR_CAPTIONTEXT
  49. WHITE, // COLOR_ACTIVEBORDER
  50. WHITE, // COLOR_INACTIVEBORDER
  51. WHITE, // COLOR_APPWORKSPACE
  52. BLACK, // COLOR_HIGHLIGHT
  53. WHITE, // COLOR_HIGHLIGHTTEXT
  54. WHITE, // COLOR_BTNFACE
  55. BLACK, // COLOR_BTNSHADOW
  56. BLACK, // COLOR_GRAYTEXT
  57. BLACK, // COLOR_BTNTEXT
  58. BLACK, // COLOR_INACTIVECAPTIONTEXT
  59. BLACK, // COLOR_BTNHIGHLIGHT
  60. BLACK, // COLOR_3DDKSHADOW
  61. WHITE, // COLOR_3DLIGHT
  62. BLACK, // COLOR_INFOTEXT
  63. WHITE // COLOR_INFOBK
  64. };
  65. static INT gaiStaticIndex[] = {
  66. COLOR_SCROLLBAR ,
  67. COLOR_BACKGROUND ,
  68. COLOR_ACTIVECAPTION ,
  69. COLOR_INACTIVECAPTION ,
  70. COLOR_MENU ,
  71. COLOR_WINDOW ,
  72. COLOR_WINDOWFRAME ,
  73. COLOR_MENUTEXT ,
  74. COLOR_WINDOWTEXT ,
  75. COLOR_CAPTIONTEXT ,
  76. COLOR_ACTIVEBORDER ,
  77. COLOR_INACTIVEBORDER ,
  78. COLOR_APPWORKSPACE ,
  79. COLOR_HIGHLIGHT ,
  80. COLOR_HIGHLIGHTTEXT ,
  81. COLOR_BTNFACE ,
  82. COLOR_BTNSHADOW ,
  83. COLOR_GRAYTEXT ,
  84. COLOR_BTNTEXT ,
  85. COLOR_INACTIVECAPTIONTEXT,
  86. COLOR_BTNHIGHLIGHT ,
  87. COLOR_3DDKSHADOW ,
  88. COLOR_3DLIGHT ,
  89. COLOR_INFOTEXT ,
  90. COLOR_INFOBK
  91. };
  92. #define RESTORE_FROM_REGISTRY 1
  93. #if RESTORE_FROM_REGISTRY
  94. // Registry names for the system colors.
  95. static CHAR *gaszSysClrNames[] = {
  96. "Scrollbar", // COLOR_SCROLLBAR 0
  97. "Background", // COLOR_BACKGROUND 1 (also COLOR_DESKTOP)
  98. "ActiveTitle", // COLOR_ACTIVECAPTION 2
  99. "InactiveTitle", // COLOR_INACTIVECAPTION 3
  100. "Menu", // COLOR_MENU 4
  101. "Window", // COLOR_WINDOW 5
  102. "WindowFrame", // COLOR_WINDOWFRAME 6
  103. "MenuText", // COLOR_MENUTEXT 7
  104. "WindowText", // COLOR_WINDOWTEXT 8
  105. "TitleText", // COLOR_CAPTIONTEXT 9
  106. "ActiveBorder", // COLOR_ACTIVEBORDER 10
  107. "InactiveBorder", // COLOR_INACTIVEBORDER 11
  108. "AppWorkspace", // COLOR_APPWORKSPACE 12
  109. "Hilight", // COLOR_HIGHLIGHT 13
  110. "HilightText", // COLOR_HIGHLIGHTTEXT 14
  111. "ButtonFace", // COLOR_BTNFACE 15 (also COLOR_3DFACE)
  112. "ButtonShadow", // COLOR_BTNSHADOW 16 (also COLOR_3DSHADOW)
  113. "GrayText", // COLOR_GRAYTEXT 17
  114. "ButtonText", // COLOR_BTNTEXT 18
  115. "InactiveTitleText", // COLOR_INACTIVECAPTIONTEXT 19
  116. "ButtonHilight", // COLOR_BTNHIGHLIGHT 20 (also COLOR_3DHILIGHT)
  117. "ButtonDkShadow", // COLOR_3DDKSHADOW 21
  118. "ButtonLight", // COLOR_3DLIGHT 22
  119. "InfoText", // COLOR_INFOTEXT 23
  120. "InfoWindow" // COLOR_INFOBK 24
  121. };
  122. static BOOL GetRegistrySysColors(COLORREF *, int);
  123. #endif
  124. unsigned char ss_ComponentFromIndex(int i, int nbits, int shift );
  125. static int ss_PixelFormatDescriptorFromDc( HDC hdc, PIXELFORMATDESCRIPTOR *Pfd );
  126. /******************************************************************************/
  127. #if RESTORE_FROM_REGISTRY
  128. /******************************Public*Routine******************************\
  129. * GetRegistrySysColors
  130. *
  131. * Reads the Control Panel's color settings from the registry and stores
  132. * those values in pcr. If we fail to get any value, then the corresponding
  133. * entry in pcr is not modified.
  134. *
  135. * History:
  136. * 12-Apr-1995 -by- Gilman Wong [gilmanw]
  137. * Wrote it.
  138. \**************************************************************************/
  139. static BOOL GetRegistrySysColors(COLORREF *pcr, int nColors)
  140. {
  141. BOOL bRet = FALSE;
  142. long lRet;
  143. HKEY hkSysColors = (HKEY) NULL;
  144. int i;
  145. DWORD dwDataType;
  146. char achColor[64];
  147. DWORD cjColor;
  148. TKASSERT(nColors <= gNumStaticColors);
  149. // Open the key for the system color settings.
  150. lRet = RegOpenKeyExA(HKEY_CURRENT_USER,
  151. "Control Panel\\Colors",
  152. 0,
  153. KEY_QUERY_VALUE,
  154. &hkSysColors);
  155. if ( lRet != ERROR_SUCCESS )
  156. {
  157. goto GetRegistrySysColors_exit;
  158. }
  159. // Read each system color value. The names are stored in the global
  160. // array of char *, gaszSysClrNames.
  161. for (i = 0; i < nColors; i++)
  162. {
  163. cjColor = sizeof(achColor);
  164. lRet = RegQueryValueExA(hkSysColors,
  165. (LPSTR) gaszSysClrNames[i],
  166. (LPDWORD) NULL,
  167. &dwDataType,
  168. (LPBYTE) achColor,
  169. &cjColor);
  170. TKASSERT(lRet != ERROR_MORE_DATA);
  171. if ( lRet == ERROR_SUCCESS && dwDataType == REG_SZ )
  172. {
  173. DWORD r, g, b;
  174. sscanf(achColor, "%ld %ld %ld", &r, &g, &b);
  175. pcr[i] = RGB(r, g, b);
  176. }
  177. }
  178. bRet = TRUE;
  179. GetRegistrySysColors_exit:
  180. if (hkSysColors)
  181. RegCloseKey(hkSysColors);
  182. return bRet;
  183. }
  184. #endif
  185. /******************************Public*Routine******************************\
  186. * GrabStaticEntries
  187. *
  188. * Support routine for Realize to manage the static system color
  189. * usage.
  190. *
  191. * This function will save the current static system color usage state.
  192. * It will fail if:
  193. *
  194. * 1. TK is not in "sys color in use state but system palette is in
  195. * SYSPAL_NOSTATIC mode. This means that another app still possesses
  196. * the static system colors. If this happens <TBD>
  197. *
  198. * Side effect:
  199. * If system colors are changed, then WM_SYSCOLORCHANGE message is
  200. * broadcast to all top level windows.
  201. *
  202. * Returns:
  203. * TRUE if successful, FALSE otherwise (see above).
  204. *
  205. * History:
  206. * 26-Apr-1994 -by- Gilman Wong [gilmanw]
  207. * Wrote it.
  208. \**************************************************************************/
  209. BOOL
  210. SS_PAL::GrabStaticEntries()
  211. {
  212. int i;
  213. BOOL bRet = FALSE;
  214. // Do nothing if sys colors already in use.
  215. if ( !bSystemColorsInUse )
  216. {
  217. // Take possession only if no other app has the static colors.
  218. // How can we tell? If the return from SetSystemPaletteUse is
  219. // SYSPAL_STATIC, then no other app has the statics. If it is
  220. // SYSPAL_NOSTATIC, someone else has them and we must fail.
  221. //
  222. // SetSystemPaletteUse is properly synchronized internally
  223. // so that it is atomic.
  224. //
  225. // Because we are relying on SetSystemPaletteUse to synchronize TK,
  226. // it is important to observe the following order for grabbing and
  227. // releasing:
  228. //
  229. // Grab call SetSystemPaletteUse and check for SYSPAL_STATIC
  230. // save sys color settings
  231. // set new sys color settings
  232. //
  233. // Release restore sys color settings
  234. // call SetSystemPaletteUse
  235. //mf: ! potential pitfall here, if a 'bad' app has not released the static
  236. // colors on deactivation.
  237. if ( SetSystemPaletteUse( hdc, SYSPAL_NOSTATIC ) == SYSPAL_STATIC )
  238. {
  239. // Save current sys color settings.
  240. for (i = COLOR_SCROLLBAR; i <= COLOR_BTNHIGHLIGHT; i++)
  241. gacrSave[i - COLOR_SCROLLBAR] = GetSysColor(i);
  242. bSystemColorsInUse = TRUE;
  243. // Set b&w sys color settings.
  244. SetSysColors(gNumStaticColors, gaiStaticIndex, gacrBlackAndWhite);
  245. // Inform all other top-level windows of the system color change.
  246. PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
  247. bRet = TRUE;
  248. } else {
  249. // handle case where can't get sys colors
  250. }
  251. }
  252. else
  253. bRet = TRUE;
  254. return bRet;
  255. }
  256. /******************************Public*Routine******************************\
  257. * ReleaseStaticEntries
  258. *
  259. * Support routine for Realize to manage the static system color
  260. * usage.
  261. *
  262. * This function will reset the current static system color usage state.
  263. * It will fail if:
  264. *
  265. * 1. TK is not in a "sys colors in use" state. If we are in this case,
  266. * then the static system colors do not need to be released.
  267. *
  268. * Side effect:
  269. * If system colors are changed, then WM_SYSCOLORCHANGE message is
  270. * broadcast to all top level windows.
  271. *
  272. * Returns:
  273. * TRUE if successful, FALSE otherwise (see above).
  274. *
  275. * History:
  276. * 21-Jul-1994 -by- Gilman Wong [gilmanw]
  277. * Wrote it.
  278. \**************************************************************************/
  279. BOOL
  280. SS_PAL::ReleaseStaticEntries()
  281. {
  282. BOOL bRet = FALSE;
  283. // Do nothing if sys colors not in use.
  284. if ( bSystemColorsInUse )
  285. {
  286. #if RESTORE_FROM_REGISTRY
  287. // Replace saved system colors with registry values. We do it now
  288. // rather than earlier because someone may have changed registry while
  289. // TK app was running in the foreground (very unlikely, but it could
  290. // happen).
  291. //
  292. // Also, we still try to save current setting in GrabStaticEntries so
  293. // that if for some reason we fail to grab one or more of the colors
  294. // from the registry, we can still fall back on what we grabbed via
  295. // GetSysColors (even though there is a chance its the wrong color).
  296. GetRegistrySysColors(gacrSave, gNumStaticColors);
  297. #endif
  298. // Do this now, since SetSysColors() generates WM_SYSCOLORCHANGE,
  299. // which can cause this routine to be re-entered
  300. // back to here.
  301. bSystemColorsInUse = FALSE;
  302. // Return the system palette to SYSPAL_STATIC.
  303. SetSystemPaletteUse( hdc, SYSPAL_STATIC );
  304. // Restore the saved system color settings.
  305. SetSysColors(gNumStaticColors, gaiStaticIndex, gacrSave);
  306. // Inform all other top-level windows of the system color change.
  307. PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
  308. // Reset the "sys colors in use" state and return success.
  309. bSystemColorsInUse = FALSE;
  310. bRet = TRUE;
  311. }
  312. return bRet;
  313. }
  314. // Gamma correction factor * 10
  315. #define GAMMA_CORRECTION 14
  316. // Maximum color distance with 8-bit components
  317. #define MAX_COL_DIST (3*256*256L)
  318. // Number of static colors
  319. #define STATIC_COLORS 20
  320. // Flags used when matching colors
  321. #define EXACT_MATCH 1
  322. #define COLOR_USED 1
  323. // Conversion tables for n bits to eight bits
  324. #if GAMMA_CORRECTION == 10
  325. // These tables are corrected for a gamma of 1.0
  326. static unsigned char abThreeToEight[8] =
  327. {
  328. 0, 0111 >> 1, 0222 >> 1, 0333 >> 1, 0444 >> 1, 0555 >> 1, 0666 >> 1, 0377
  329. };
  330. static unsigned char abTwoToEight[4] =
  331. {
  332. 0, 0x55, 0xaa, 0xff
  333. };
  334. static unsigned char abOneToEight[2] =
  335. {
  336. 0, 255
  337. };
  338. #else
  339. // These tables are corrected for a gamma of 1.4
  340. static unsigned char abThreeToEight[8] =
  341. {
  342. 0, 63, 104, 139, 171, 200, 229, 255
  343. };
  344. static unsigned char abTwoToEight[4] =
  345. {
  346. 0, 116, 191, 255
  347. };
  348. static unsigned char abOneToEight[2] =
  349. {
  350. 0, 255
  351. };
  352. #endif
  353. // Table which indicates which colors in a 3-3-2 palette should be
  354. // replaced with the system default colors
  355. #if GAMMA_CORRECTION == 10
  356. static int aiDefaultOverride[STATIC_COLORS] =
  357. {
  358. 0, 4, 32, 36, 128, 132, 160, 173, 181, 245,
  359. 247, 164, 156, 7, 56, 63, 192, 199, 248, 255
  360. };
  361. #else
  362. static int aiDefaultOverride[STATIC_COLORS] =
  363. {
  364. 0, 3, 24, 27, 64, 67, 88, 173, 181, 236,
  365. 247, 164, 91, 7, 56, 63, 192, 199, 248, 255
  366. };
  367. #endif
  368. unsigned char
  369. ss_ComponentFromIndex(int i, int nbits, int shift)
  370. {
  371. unsigned char val;
  372. TKASSERT(nbits >= 1 && nbits <= 3);
  373. val = i >> shift;
  374. switch (nbits)
  375. {
  376. case 1:
  377. return abOneToEight[val & 1];
  378. case 2:
  379. return abTwoToEight[val & 3];
  380. case 3:
  381. return abThreeToEight[val & 7];
  382. }
  383. return 0;
  384. }
  385. // System default colors
  386. static PALETTEENTRY apeDefaultPalEntry[STATIC_COLORS] =
  387. {
  388. { 0, 0, 0, 0 },
  389. { 0x80,0, 0, 0 },
  390. { 0, 0x80,0, 0 },
  391. { 0x80,0x80,0, 0 },
  392. { 0, 0, 0x80, 0 },
  393. { 0x80,0, 0x80, 0 },
  394. { 0, 0x80,0x80, 0 },
  395. { 0xC0,0xC0,0xC0, 0 },
  396. { 192, 220, 192, 0 },
  397. { 166, 202, 240, 0 },
  398. { 255, 251, 240, 0 },
  399. { 160, 160, 164, 0 },
  400. { 0x80,0x80,0x80, 0 },
  401. { 0xFF,0, 0, 0 },
  402. { 0, 0xFF,0, 0 },
  403. { 0xFF,0xFF,0, 0 },
  404. { 0, 0, 0xFF, 0 },
  405. { 0xFF,0, 0xFF, 0 },
  406. { 0, 0xFF,0xFF, 0 },
  407. { 0xFF,0xFF,0xFF, 0 }
  408. };
  409. /******************************Public*Routine******************************\
  410. *
  411. * UpdateStaticMapping
  412. *
  413. * Computes the best match between the current system static colors
  414. * and a 3-3-2 palette
  415. *
  416. * History:
  417. * Tue Aug 01 18:18:12 1995 -by- Drew Bliss [drewb]
  418. * Created
  419. *
  420. \**************************************************************************/
  421. static void
  422. UpdateStaticMapping(PALETTEENTRY *pe332Palette)
  423. {
  424. HPALETTE hpalStock;
  425. int iStatic, i332;
  426. int iMinDist, iDist;
  427. int iDelta;
  428. int iMinEntry;
  429. PALETTEENTRY *peStatic, *pe332;
  430. hpalStock = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
  431. // The system should always have one of these
  432. TKASSERT(hpalStock != NULL);
  433. // Make sure there's the correct number of entries
  434. TKASSERT(GetPaletteEntries(hpalStock, 0, 0, NULL) == STATIC_COLORS);
  435. // Get the current static colors
  436. GetPaletteEntries(hpalStock, 0, STATIC_COLORS, apeDefaultPalEntry);
  437. // Zero the flags in the static colors because they are used later
  438. peStatic = apeDefaultPalEntry;
  439. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  440. {
  441. peStatic->peFlags = 0;
  442. peStatic++;
  443. }
  444. // Zero the flags in the incoming palette because they are used later
  445. pe332 = pe332Palette;
  446. for (i332 = 0; i332 < 256; i332++)
  447. {
  448. pe332->peFlags = 0;
  449. pe332++;
  450. }
  451. // Try to match each static color exactly
  452. // This saves time by avoiding the least-squares match for each
  453. // exact match
  454. peStatic = apeDefaultPalEntry;
  455. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  456. {
  457. pe332 = pe332Palette;
  458. for (i332 = 0; i332 < 256; i332++)
  459. {
  460. if (peStatic->peRed == pe332->peRed &&
  461. peStatic->peGreen == pe332->peGreen &&
  462. peStatic->peBlue == pe332->peBlue)
  463. {
  464. TKASSERT(pe332->peFlags != COLOR_USED);
  465. peStatic->peFlags = EXACT_MATCH;
  466. pe332->peFlags = COLOR_USED;
  467. aiDefaultOverride[iStatic] = i332;
  468. break;
  469. }
  470. pe332++;
  471. }
  472. peStatic++;
  473. }
  474. // Match each static color as closely as possible to an entry
  475. // in the 332 palette by minimized the square of the distance
  476. peStatic = apeDefaultPalEntry;
  477. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  478. {
  479. // Skip colors already matched exactly
  480. if (peStatic->peFlags == EXACT_MATCH)
  481. {
  482. peStatic++;
  483. continue;
  484. }
  485. iMinDist = MAX_COL_DIST+1;
  486. #if DBG
  487. iMinEntry = -1;
  488. #endif
  489. pe332 = pe332Palette;
  490. for (i332 = 0; i332 < 256; i332++)
  491. {
  492. // Skip colors already used
  493. if (pe332->peFlags == COLOR_USED)
  494. {
  495. pe332++;
  496. continue;
  497. }
  498. // Compute Euclidean distance squared
  499. iDelta = pe332->peRed-peStatic->peRed;
  500. iDist = iDelta*iDelta;
  501. iDelta = pe332->peGreen-peStatic->peGreen;
  502. iDist += iDelta*iDelta;
  503. iDelta = pe332->peBlue-peStatic->peBlue;
  504. iDist += iDelta*iDelta;
  505. if (iDist < iMinDist)
  506. {
  507. iMinDist = iDist;
  508. iMinEntry = i332;
  509. }
  510. pe332++;
  511. }
  512. TKASSERT(iMinEntry != -1);
  513. // Remember the best match
  514. aiDefaultOverride[iStatic] = iMinEntry;
  515. pe332Palette[iMinEntry].peFlags = COLOR_USED;
  516. peStatic++;
  517. }
  518. // Zero the flags in the static colors because they may have been
  519. // set. We want them to be zero so the colors can be remapped
  520. peStatic = apeDefaultPalEntry;
  521. for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++)
  522. {
  523. peStatic->peFlags = 0;
  524. peStatic++;
  525. }
  526. // Reset the 332 flags because we may have set them
  527. pe332 = pe332Palette;
  528. for (i332 = 0; i332 < 256; i332++)
  529. {
  530. pe332->peFlags = PC_NOCOLLAPSE;
  531. pe332++;
  532. }
  533. }
  534. /******************************Public*Routine******************************\
  535. * FlushPalette
  536. *
  537. * Because of Win 3.1 compatibility, GDI palette mapping always starts
  538. * at zero and stops at the first exact match. So if there are duplicates,
  539. * the higher colors aren't mapped to--which is often a problem if we
  540. * are trying to make to any of the upper 10 static colors. To work around
  541. * this, we flush the palette to all black.
  542. *
  543. \**************************************************************************/
  544. void
  545. SS_PAL::Flush()
  546. {
  547. LOGPALETTE *pPal;
  548. HPALETTE hpalBlack, hpalOld;
  549. int i;
  550. if( nEntries == 256 )
  551. {
  552. pPal = (LOGPALETTE *) LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT,
  553. sizeof(LOGPALETTE) + nEntries * sizeof(PALETTEENTRY));
  554. if (pPal)
  555. {
  556. pPal->palVersion = 0x300;
  557. pPal->palNumEntries = (WORD)nEntries;
  558. // Mark everything PC_NOCOLLAPSE and PC_RESERVED to force every
  559. // thing into the palette. Colors are already black because
  560. // we zero initialized during memory allocation.
  561. for (i = 0; i < nEntries; i++)
  562. {
  563. pPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE | PC_RESERVED;
  564. }
  565. hpalBlack = CreatePalette(pPal);
  566. LocalFree(pPal);
  567. hpalOld = SelectPalette(hdc, hpalBlack, FALSE);
  568. RealizePalette(hdc);
  569. SelectPalette(hdc, hpalOld, FALSE);
  570. DeleteObject(hpalBlack);
  571. }
  572. }
  573. }
  574. /******************************Public*Routine******************************\
  575. * Realize
  576. *
  577. * Select the given palette in background or foreground mode (as specified
  578. * by the bForceBackground flag), and realize the palette.
  579. *
  580. * If static system color usage is set, the system colors are replaced.
  581. *
  582. * History:
  583. * 26-Apr-1994 -by- Gilman Wong [gilmanw]
  584. * Wrote it.
  585. \**************************************************************************/
  586. //mf: ! this grabbing of colors n stuff should only be done by the top
  587. // level window - ? but what if it's not a GL window ?
  588. long
  589. SS_PAL::Realize( HWND hwndArg, HDC hdcArg, BOOL bForceBackground )
  590. {
  591. // cache:
  592. hwnd = hwndArg;
  593. hdc = hdcArg;
  594. if( bTakeOver ) {
  595. // Easy case
  596. SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
  597. SelectPalette(hdc, hPal, bForceBackground );
  598. RealizePalette(hdc);
  599. return 1;
  600. }
  601. // Else general purpose 'tk' method
  602. if( bFlush ) {
  603. Flush();
  604. bFlush = FALSE;
  605. }
  606. return Realize( bForceBackground );
  607. }
  608. long
  609. SS_PAL::Realize( BOOL bForceBackground )
  610. {
  611. long Result = -1;
  612. BOOL bHaveSysPal = TRUE;
  613. SS_DBGLEVEL2( SS_LEVEL_INFO, "SS_PAL::Realize: %d for %d\n", bForceBackground, hwnd );
  614. // If static system color usage is set, prepare to take over the
  615. // system palette.
  616. if( bUseStatic )
  617. {
  618. // If foreground, take over the static colors. If background, release
  619. // the static colors.
  620. if ( !bForceBackground )
  621. {
  622. // If GrabStaticEntries succeeds, then it is OK to take over the
  623. // static colors. If not <mf:TBD>
  624. bHaveSysPal = GrabStaticEntries();
  625. }
  626. else
  627. {
  628. // If we are currently using the system colors (bSystemColorsInUse)
  629. // and Realize was called with bForceBackground set, we
  630. // are being deactivated and must release the static system colors.
  631. ReleaseStaticEntries();
  632. }
  633. // Rerealize the palette.
  634. //
  635. // If set to TRUE, bForceBackground will force the palette to be
  636. // realized as a background palette, regardless of focus. This
  637. // will happen anyway if the TK window does not have the keyboard focus.
  638. if ( (bForceBackground || bHaveSysPal) &&
  639. UnrealizeObject( hPal ) &&
  640. NULL != SelectPalette( hdc, hPal, bForceBackground ) )
  641. {
  642. Result = RealizePalette( hdc );
  643. }
  644. //mf: ?? klugey fix for rude apps
  645. // If some rude app still has the system colors and we're in the
  646. // foreground, make the best of it.
  647. if( !bForceBackground && !bHaveSysPal ) {
  648. if( UnrealizeObject( hPal ) &&
  649. NULL != SelectPalette( hdc, hPal, TRUE ) )
  650. {
  651. Result = RealizePalette( hdc );
  652. }
  653. }
  654. }
  655. else
  656. {
  657. if ( NULL != SelectPalette( hdc, hPal, FALSE ) )
  658. {
  659. Result = RealizePalette( hdc );
  660. }
  661. }
  662. return( Result );
  663. }
  664. /******************************Public*Routine******************************\
  665. * SS_PAL constructor
  666. *
  667. * This creates the palette, but does not select or realize it
  668. *
  669. \**************************************************************************/
  670. SS_PAL::SS_PAL( HDC hdcArg, PIXELFORMATDESCRIPTOR *ppfd, BOOL bTakeOverPalette )
  671. {
  672. hwnd = 0;
  673. hPal = 0;
  674. bUseStatic = FALSE;
  675. bSystemColorsInUse = FALSE;
  676. pfd = *ppfd; // this is for palette purposes only (other fields may not apply)
  677. hdc = hdcArg;
  678. bTakeOver = bTakeOverPalette; // mf: for now, when this is set, it means
  679. // the screen saver is running in full screen mode - implying that
  680. // interaction with other apps not necessary
  681. if( bTakeOver ) {
  682. //mf: !!! bFlush should be per-window, not per SS_PAL !!
  683. //mf: hmmm, not so sure about that...
  684. bFlush = FALSE;
  685. bUseStatic = TRUE;
  686. } else {
  687. bFlush = TRUE;
  688. bUseStatic = ppfd->dwFlags & PFD_NEED_SYSTEM_PALETTE;
  689. }
  690. if( bUseStatic )
  691. // save current static palette usage so we can restore it
  692. uiOldStaticUse = GetSystemPaletteUse( hdc );
  693. paletteManageProc = NullPaletteManageProc;
  694. // Now create the palette and return
  695. hPal = MakeRGBPalette();
  696. SS_ASSERT( hPal, "SS_PAL constructor failure\n" );
  697. }
  698. /******************************Public*Routine******************************\
  699. * SS_PAL destructor
  700. \**************************************************************************/
  701. SS_PAL::~SS_PAL()
  702. {
  703. if( bUseStatic )
  704. {
  705. if( uiOldStaticUse )
  706. //mf: ! make sure hdc is valid !!!
  707. SetSystemPaletteUse(hdc, uiOldStaticUse);
  708. PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
  709. }
  710. if( hPal ) {
  711. SelectPalette( hdc, (HPALETTE) GetStockObject(DEFAULT_PALETTE), TRUE );
  712. DeleteObject( hPal );
  713. }
  714. }
  715. /******************************Public*Routine******************************\
  716. * ReCreateRGBPalette
  717. *
  718. *
  719. \**************************************************************************/
  720. void
  721. SS_PAL::ReCreateRGBPalette()
  722. {
  723. if( bTakeOver )
  724. return;
  725. HPALETTE hPalTmp = hPal;
  726. hPal = MakeRGBPalette();
  727. if( hPal ) {
  728. DeleteObject( hPalTmp );
  729. bFlush = TRUE;
  730. }
  731. }
  732. /******************************Public*Routine******************************\
  733. * MakeRGBPalette
  734. *
  735. * Creates an HPALETTE with values required for a logical rgb palette.
  736. * If bUseStatic is TRUE, the static system
  737. * colors will be overridden. Otherwise, the PALETTEENTRY array will be
  738. * fixed up to contain the default static system colors.
  739. *
  740. \**************************************************************************/
  741. HPALETTE
  742. SS_PAL::MakeRGBPalette()
  743. {
  744. LOGPALETTE *pPal;
  745. HPALETTE hpal;
  746. int count, i;
  747. PIXELFORMATDESCRIPTOR *ppfd = &pfd;
  748. count = 1 << ppfd->cColorBits;
  749. nEntries = count;
  750. pPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
  751. count * sizeof(PALETTEENTRY));
  752. if( !pPal )
  753. return (HPALETTE) 0;
  754. pPal->palVersion = 0x300;
  755. pPal->palNumEntries = (WORD)count;
  756. PALETTEENTRY *pEntry = pPal->palPalEntry;
  757. for ( i = 0; i < count ; i++, pEntry++ )
  758. {
  759. pEntry->peRed = ss_ComponentFromIndex(i, ppfd->cRedBits,
  760. ppfd->cRedShift);
  761. pEntry->peGreen = ss_ComponentFromIndex(i, ppfd->cGreenBits,
  762. ppfd->cGreenShift);
  763. pEntry->peBlue = ss_ComponentFromIndex(i, ppfd->cBlueBits,
  764. ppfd->cBlueShift);
  765. pEntry->peFlags = PC_NOCOLLAPSE;
  766. }
  767. if( count == 256 )
  768. {
  769. // If app set static system color usage for fixed palette support,
  770. // setup to take over the static colors. Otherwise, fixup the
  771. // static system colors.
  772. if ( bUseStatic )
  773. {
  774. // Black and white already exist as the only remaining static
  775. // colors. Let those remap. All others should be put into
  776. // the palette (i.e., set PC_NOCOLLAPSE).
  777. pPal->palPalEntry[0].peFlags = 0;
  778. pPal->palPalEntry[255].peFlags = 0;
  779. }
  780. else
  781. {
  782. // The defaultOverride array is computed assuming a 332
  783. // palette where red has zero shift, etc.
  784. if ( (3 == ppfd->cRedBits) && (0 == ppfd->cRedShift) &&
  785. (3 == ppfd->cGreenBits) && (3 == ppfd->cGreenShift) &&
  786. (2 == ppfd->cBlueBits) && (6 == ppfd->cBlueShift) )
  787. {
  788. pEntry = pPal->palPalEntry;
  789. UpdateStaticMapping( pEntry );
  790. for ( i = 0 ; i < STATIC_COLORS ; i++)
  791. {
  792. pEntry[aiDefaultOverride[i]] = apeDefaultPalEntry[i];
  793. }
  794. }
  795. }
  796. }
  797. hpal = CreatePalette(pPal);
  798. LocalFree(pPal);
  799. return hpal;
  800. }