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.

954 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 "mtk.h"
  16. #include "palette.hxx"
  17. #if(WINVER < 0x0400)
  18. // Ordinarily not defined for versions before 4.00.
  19. #define COLOR_3DDKSHADOW 21
  20. #define COLOR_3DLIGHT 22
  21. #define COLOR_INFOTEXT 23
  22. #define COLOR_INFOBK 24
  23. #endif
  24. #define TKASSERT(x) SS_ASSERT( x, "palette processing failure\n" )
  25. /******************************************************************************/
  26. // Fixed palette support.
  27. #define BLACK PALETTERGB(0,0,0)
  28. #define WHITE PALETTERGB(255,255,255)
  29. #define MAX_STATIC_COLORS (COLOR_INFOBK - COLOR_SCROLLBAR + 1)
  30. static int gNumStaticColors = MAX_STATIC_COLORS;
  31. // TRUE if static system color settings have been replaced with B&W settings.
  32. // TRUE if original static colors saved
  33. //static BOOL tkStaticColorsSaved = FALSE;
  34. // saved system static colors (initialize with default colors)
  35. static COLORREF gacrSave[MAX_STATIC_COLORS];
  36. // new B&W system static colors
  37. static COLORREF gacrBlackAndWhite[] = {
  38. WHITE, // COLOR_SCROLLBAR
  39. BLACK, // COLOR_BACKGROUND
  40. BLACK, // COLOR_ACTIVECAPTION
  41. WHITE, // COLOR_INACTIVECAPTION
  42. WHITE, // COLOR_MENU
  43. WHITE, // COLOR_WINDOW
  44. BLACK, // COLOR_WINDOWFRAME
  45. BLACK, // COLOR_MENUTEXT
  46. BLACK, // COLOR_WINDOWTEXT
  47. WHITE, // COLOR_CAPTIONTEXT
  48. WHITE, // COLOR_ACTIVEBORDER
  49. WHITE, // COLOR_INACTIVEBORDER
  50. WHITE, // COLOR_APPWORKSPACE
  51. BLACK, // COLOR_HIGHLIGHT
  52. WHITE, // COLOR_HIGHLIGHTTEXT
  53. WHITE, // COLOR_BTNFACE
  54. BLACK, // COLOR_BTNSHADOW
  55. BLACK, // COLOR_GRAYTEXT
  56. BLACK, // COLOR_BTNTEXT
  57. BLACK, // COLOR_INACTIVECAPTIONTEXT
  58. BLACK, // COLOR_BTNHIGHLIGHT
  59. BLACK, // COLOR_3DDKSHADOW
  60. WHITE, // COLOR_3DLIGHT
  61. BLACK, // COLOR_INFOTEXT
  62. WHITE // COLOR_INFOBK
  63. };
  64. static INT gaiStaticIndex[] = {
  65. COLOR_SCROLLBAR ,
  66. COLOR_BACKGROUND ,
  67. COLOR_ACTIVECAPTION ,
  68. COLOR_INACTIVECAPTION ,
  69. COLOR_MENU ,
  70. COLOR_WINDOW ,
  71. COLOR_WINDOWFRAME ,
  72. COLOR_MENUTEXT ,
  73. COLOR_WINDOWTEXT ,
  74. COLOR_CAPTIONTEXT ,
  75. COLOR_ACTIVEBORDER ,
  76. COLOR_INACTIVEBORDER ,
  77. COLOR_APPWORKSPACE ,
  78. COLOR_HIGHLIGHT ,
  79. COLOR_HIGHLIGHTTEXT ,
  80. COLOR_BTNFACE ,
  81. COLOR_BTNSHADOW ,
  82. COLOR_GRAYTEXT ,
  83. COLOR_BTNTEXT ,
  84. COLOR_INACTIVECAPTIONTEXT,
  85. COLOR_BTNHIGHLIGHT ,
  86. COLOR_3DDKSHADOW ,
  87. COLOR_3DLIGHT ,
  88. COLOR_INFOTEXT ,
  89. COLOR_INFOBK
  90. };
  91. #define RESTORE_FROM_REGISTRY 1
  92. #if RESTORE_FROM_REGISTRY
  93. // Registry names for the system colors.
  94. static CHAR *gaszSysClrNames[] = {
  95. "Scrollbar", // COLOR_SCROLLBAR 0
  96. "Background", // COLOR_BACKGROUND 1 (also COLOR_DESKTOP)
  97. "ActiveTitle", // COLOR_ACTIVECAPTION 2
  98. "InactiveTitle", // COLOR_INACTIVECAPTION 3
  99. "Menu", // COLOR_MENU 4
  100. "Window", // COLOR_WINDOW 5
  101. "WindowFrame", // COLOR_WINDOWFRAME 6
  102. "MenuText", // COLOR_MENUTEXT 7
  103. "WindowText", // COLOR_WINDOWTEXT 8
  104. "TitleText", // COLOR_CAPTIONTEXT 9
  105. "ActiveBorder", // COLOR_ACTIVEBORDER 10
  106. "InactiveBorder", // COLOR_INACTIVEBORDER 11
  107. "AppWorkspace", // COLOR_APPWORKSPACE 12
  108. "Hilight", // COLOR_HIGHLIGHT 13
  109. "HilightText", // COLOR_HIGHLIGHTTEXT 14
  110. "ButtonFace", // COLOR_BTNFACE 15 (also COLOR_3DFACE)
  111. "ButtonShadow", // COLOR_BTNSHADOW 16 (also COLOR_3DSHADOW)
  112. "GrayText", // COLOR_GRAYTEXT 17
  113. "ButtonText", // COLOR_BTNTEXT 18
  114. "InactiveTitleText", // COLOR_INACTIVECAPTIONTEXT 19
  115. "ButtonHilight", // COLOR_BTNHIGHLIGHT 20 (also COLOR_3DHILIGHT)
  116. "ButtonDkShadow", // COLOR_3DDKSHADOW 21
  117. "ButtonLight", // COLOR_3DLIGHT 22
  118. "InfoText", // COLOR_INFOTEXT 23
  119. "InfoWindow" // COLOR_INFOBK 24
  120. };
  121. static BOOL GetRegistrySysColors(COLORREF *, int);
  122. #endif
  123. unsigned char ss_ComponentFromIndex(int i, int nbits, int shift );
  124. static int ss_PixelFormatDescriptorFromDc( HDC hdc, PIXELFORMATDESCRIPTOR *Pfd );
  125. LONG
  126. NullPaletteManageProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  127. /******************************************************************************/
  128. #if RESTORE_FROM_REGISTRY
  129. /******************************Public*Routine******************************\
  130. * GetRegistrySysColors
  131. *
  132. * Reads the Control Panel's color settings from the registry and stores
  133. * those values in pcr. If we fail to get any value, then the corresponding
  134. * entry in pcr is not modified.
  135. *
  136. * History:
  137. * 12-Apr-1995 -by- Gilman Wong [gilmanw]
  138. * Wrote it.
  139. \**************************************************************************/
  140. static BOOL GetRegistrySysColors(COLORREF *pcr, int nColors)
  141. {
  142. BOOL bRet = FALSE;
  143. long lRet;
  144. HKEY hkSysColors = (HKEY) NULL;
  145. int i;
  146. DWORD dwDataType;
  147. char achColor[64];
  148. DWORD cjColor;
  149. TKASSERT(nColors <= gNumStaticColors);
  150. // Open the key for the system color settings.
  151. lRet = RegOpenKeyExA(HKEY_CURRENT_USER,
  152. "Control Panel\\Colors",
  153. 0,
  154. KEY_QUERY_VALUE,
  155. &hkSysColors);
  156. if ( lRet != ERROR_SUCCESS )
  157. {
  158. goto GetRegistrySysColors_exit;
  159. }
  160. // Read each system color value. The names are stored in the global
  161. // array of char *, gaszSysClrNames.
  162. for (i = 0; i < nColors; i++)
  163. {
  164. cjColor = sizeof(achColor);
  165. lRet = RegQueryValueExA(hkSysColors,
  166. (LPSTR) gaszSysClrNames[i],
  167. (LPDWORD) NULL,
  168. &dwDataType,
  169. (LPBYTE) achColor,
  170. &cjColor);
  171. TKASSERT(lRet != ERROR_MORE_DATA);
  172. if ( lRet == ERROR_SUCCESS && dwDataType == REG_SZ )
  173. {
  174. DWORD r, g, b;
  175. sscanf(achColor, "%ld %ld %ld", &r, &g, &b);
  176. pcr[i] = RGB(r, g, b);
  177. }
  178. }
  179. bRet = TRUE;
  180. GetRegistrySysColors_exit:
  181. if (hkSysColors)
  182. RegCloseKey(hkSysColors);
  183. return bRet;
  184. }
  185. #endif
  186. /******************************Public*Routine******************************\
  187. * GrabStaticEntries
  188. *
  189. * Support routine for Realize to manage the static system color
  190. * usage.
  191. *
  192. * This function will save the current static system color usage state.
  193. * It will fail if:
  194. *
  195. * 1. TK is not in "sys color in use state but system palette is in
  196. * SYSPAL_NOSTATIC mode. This means that another app still possesses
  197. * the static system colors. If this happens <TBD>
  198. *
  199. * Side effect:
  200. * If system colors are changed, then WM_SYSCOLORCHANGE message is
  201. * broadcast to all top level windows.
  202. *
  203. * Returns:
  204. * TRUE if successful, FALSE otherwise (see above).
  205. *
  206. * History:
  207. * 26-Apr-1994 -by- Gilman Wong [gilmanw]
  208. * Wrote it.
  209. \**************************************************************************/
  210. BOOL
  211. SS_PAL::GrabStaticEntries()
  212. {
  213. int i;
  214. BOOL bRet = FALSE;
  215. // Do nothing if sys colors already in use.
  216. if ( !bSystemColorsInUse )
  217. {
  218. // Take possession only if no other app has the static colors.
  219. // How can we tell? If the return from SetSystemPaletteUse is
  220. // SYSPAL_STATIC, then no other app has the statics. If it is
  221. // SYSPAL_NOSTATIC, someone else has them and we must fail.
  222. //
  223. // SetSystemPaletteUse is properly synchronized internally
  224. // so that it is atomic.
  225. //
  226. // Because we are relying on SetSystemPaletteUse to synchronize TK,
  227. // it is important to observe the following order for grabbing and
  228. // releasing:
  229. //
  230. // Grab call SetSystemPaletteUse and check for SYSPAL_STATIC
  231. // save sys color settings
  232. // set new sys color settings
  233. //
  234. // Release restore sys color settings
  235. // call SetSystemPaletteUse
  236. //mf: ! potential pitfall here, if a 'bad' app has not released the static
  237. // colors on deactivation.
  238. if ( SetSystemPaletteUse( hdc, SYSPAL_NOSTATIC ) == SYSPAL_STATIC )
  239. {
  240. // Save current sys color settings.
  241. for (i = COLOR_SCROLLBAR; i <= COLOR_BTNHIGHLIGHT; i++)
  242. gacrSave[i - COLOR_SCROLLBAR] = GetSysColor(i);
  243. bSystemColorsInUse = TRUE;
  244. // Set b&w sys color settings.
  245. SetSysColors(gNumStaticColors, gaiStaticIndex, gacrBlackAndWhite);
  246. // Inform all other top-level windows of the system color change.
  247. PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
  248. bRet = TRUE;
  249. } else {
  250. // handle case where can't get sys colors
  251. }
  252. }
  253. else
  254. bRet = TRUE;
  255. return bRet;
  256. }
  257. /******************************Public*Routine******************************\
  258. * ReleaseStaticEntries
  259. *
  260. * Support routine for Realize to manage the static system color
  261. * usage.
  262. *
  263. * This function will reset the current static system color usage state.
  264. * It will fail if:
  265. *
  266. * 1. TK is not in a "sys colors in use" state. If we are in this case,
  267. * then the static system colors do not need to be released.
  268. *
  269. * Side effect:
  270. * If system colors are changed, then WM_SYSCOLORCHANGE message is
  271. * broadcast to all top level windows.
  272. *
  273. * Returns:
  274. * TRUE if successful, FALSE otherwise (see above).
  275. *
  276. * History:
  277. * 21-Jul-1994 -by- Gilman Wong [gilmanw]
  278. * Wrote it.
  279. \**************************************************************************/
  280. BOOL
  281. SS_PAL::ReleaseStaticEntries()
  282. {
  283. BOOL bRet = FALSE;
  284. // Do nothing if sys colors not in use.
  285. if ( bSystemColorsInUse )
  286. {
  287. #if RESTORE_FROM_REGISTRY
  288. // Replace saved system colors with registry values. We do it now
  289. // rather than earlier because someone may have changed registry while
  290. // TK app was running in the foreground (very unlikely, but it could
  291. // happen).
  292. //
  293. // Also, we still try to save current setting in GrabStaticEntries so
  294. // that if for some reason we fail to grab one or more of the colors
  295. // from the registry, we can still fall back on what we grabbed via
  296. // GetSysColors (even though there is a chance its the wrong color).
  297. GetRegistrySysColors(gacrSave, gNumStaticColors);
  298. #endif
  299. // Do this now, since SetSysColors() generates WM_SYSCOLORCHANGE,
  300. // which can cause this routine to be re-entered
  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 = 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. : hdc( hdcArg ), pfd( *ppfd ), bTakeOver( bTakeOverPalette )
  672. {
  673. hwnd = 0;
  674. hPal = 0;
  675. bUseStatic = FALSE;
  676. bSystemColorsInUse = FALSE;
  677. // bTakeOver : mf: for now, when this is set, it means
  678. // the screen saver is running in full screen mode - implying that
  679. // interaction with other apps not necessary
  680. if( bTakeOver ) {
  681. //mf: !!! bFlush should be per-window, not per SS_PAL !!
  682. //mf: hmmm, not so sure about that...
  683. bFlush = FALSE;
  684. bUseStatic = TRUE;
  685. } else {
  686. bFlush = TRUE;
  687. bUseStatic = ppfd->dwFlags & PFD_NEED_SYSTEM_PALETTE;
  688. }
  689. if( bUseStatic )
  690. // save current static palette usage so we can restore it
  691. uiOldStaticUse = GetSystemPaletteUse( hdc );
  692. paletteManageProc = NullPaletteManageProc;
  693. // Now create the palette and return
  694. hPal = MakeRGBPalette();
  695. SS_ASSERT( hPal, "SS_PAL constructor failure\n" );
  696. }
  697. /******************************Public*Routine******************************\
  698. * SS_PAL destructor
  699. \**************************************************************************/
  700. SS_PAL::~SS_PAL()
  701. {
  702. if( bUseStatic )
  703. {
  704. if( uiOldStaticUse )
  705. //mf: ! make sure hdc is valid !!!
  706. SetSystemPaletteUse(hdc, uiOldStaticUse);
  707. SS_DBGINFO( "SS_PAL destructor: broadcasting WM_SYSCOLORCHANGE\n" );
  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 = 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. }
  801. LONG
  802. NullPaletteManageProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  803. {
  804. return 0;
  805. }