Leaked source code of windows server 2003
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.

259 lines
8.5 KiB

  1. /**************************** Module Header ********************************\
  2. * Module Name: palette.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * Palette Handling Routines
  7. *
  8. * History:
  9. * 24-May-1993 MikeKe From win3.1
  10. \***************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. /***************************************************************************\
  14. * IsTopmostRealApp
  15. *
  16. * Returns true if current process is the shell process and this window
  17. * is the first non-shell/user one we find in zorder. If so, we consider
  18. * him to be the "palette foreground".
  19. *
  20. * History:
  21. \***************************************************************************/
  22. BOOL IsTopmostRealApp(
  23. PWND pwnd)
  24. {
  25. PTHREADINFO ptiCurrent = PtiCurrent();
  26. PDESKTOPINFO pdeskinfo = pwnd->head.rpdesk->pDeskInfo;
  27. if ((pdeskinfo->spwndShell == NULL) ||
  28. (GETPTI(pdeskinfo->spwndShell)->pq != gpqForeground)) {
  29. return FALSE;
  30. }
  31. return (pwnd == NextTopWindow(ptiCurrent,
  32. NULL,
  33. NULL,
  34. NTW_IGNORETOOLWINDOW));
  35. }
  36. /***************************************************************************\
  37. * _SelectPalette
  38. *
  39. * Selects palette into DC. This is a wrapper to gdi where we can perform
  40. * checks to see if it's a foreground dc.
  41. *
  42. * History:
  43. \***************************************************************************/
  44. HPALETTE _SelectPalette(
  45. HDC hdc,
  46. HPALETTE hpal,
  47. BOOL fForceBackground)
  48. {
  49. PWND pwndTop;
  50. BOOL fBackgroundPalette = TRUE;
  51. PWND pwnd = NULL;
  52. /*
  53. * If we are not forcing palette into background, find out where it does
  54. * actually belong. Don't ever select the default palette in as a
  55. * foreground palette because this confuses gdi. Many apps do a
  56. * (oldPal = SelectPalette) (myPal); Draw; SelectObject(oldPal).
  57. * and we don't want to allow this to go through.
  58. */
  59. if (!fForceBackground &&
  60. TEST_PUSIF(PUSIF_PALETTEDISPLAY) &&
  61. (hpal != GreGetStockObject(DEFAULT_PALETTE))) {
  62. if (pwnd = WindowFromCacheDC(hdc)) {
  63. PWND pwndActive;
  64. /*
  65. * don't "select" palette unless on a palette device
  66. */
  67. pwndTop = GetTopLevelWindow(pwnd);
  68. if (!TestWF(pwndTop, WFHASPALETTE)) {
  69. if (pwndTop != _GetDesktopWindow())
  70. GETPTI(pwndTop)->TIF_flags |= TIF_PALETTEAWARE;
  71. SetWF(pwndTop, WFHASPALETTE);
  72. }
  73. /*
  74. * Hack-o-rama:
  75. * Windows get foreground use of the palette if
  76. * * They are the foreground's active window
  77. * * The current process is the shell and they are the
  78. * topmost valid non-toolwindow in the zorder.
  79. *
  80. * This makes our tray friendly on palettized displays.
  81. * Currently, if you run a palette app and click on the tray,
  82. * the palette app goes all weird. Broderbund apps go
  83. * completely black. This is because they get forced to be
  84. * background always, even though the shell isn't really
  85. * palettized.
  86. *
  87. * Note: this palette architecture isn't very good. Apps get forced to
  88. * be background palette users even if the foreground thread
  89. * couldn't care less about the palette. Should go by zorder
  90. * if so, but in a more clean way than this.
  91. *
  92. * We really only care about the tray && the background.
  93. * Cabinet dudes don't matter so much.
  94. */
  95. pwndActive = (gpqForeground ? gpqForeground->spwndActive : NULL);
  96. #if 0
  97. if (pwndActive &&
  98. (pwndTop != pwnd->head.rpdesk->pDeskInfo->spwndShell) &&
  99. ((pwndActive == pwnd) || _IsChild(pwndActive, pwnd) || IsTopmostRealApp(pwnd)) &&
  100. !TestWF(pwnd, WEFTOOLWINDOW)) {
  101. fBackgroundPalette = FALSE;
  102. }
  103. #else
  104. if ((pwndTop != pwndTop->head.rpdesk->pDeskInfo->spwnd) &&
  105. (pwndTop != pwndTop->head.rpdesk->pDeskInfo->spwndShell) &&
  106. (pwndActive != NULL) &&
  107. ((pwndActive == pwnd) ||
  108. _IsChild(pwndActive, pwnd) ||
  109. IsTopmostRealApp(pwnd)) &&
  110. !TestWF(pwnd, WEFTOOLWINDOW)) {
  111. fBackgroundPalette = FALSE;
  112. }
  113. #endif
  114. }
  115. }
  116. return GreSelectPalette(hdc, hpal, fBackgroundPalette);
  117. }
  118. /***************************************************************************\
  119. * xxxRealizePalette
  120. *
  121. * Realizes palette to the DC. This is a wrapper to gdi so that we can
  122. * check for changes prior to sending notifications.
  123. *
  124. * History:
  125. \***************************************************************************/
  126. int xxxRealizePalette(
  127. HDC hdc)
  128. {
  129. PWND pwnd;
  130. DWORD dwNumChanged;
  131. PWINDOWSTATION pwinsta;
  132. PDESKTOP pdesk;
  133. TL tlpwnd;
  134. dwNumChanged = GreRealizePalette(hdc);
  135. if (HIWORD(dwNumChanged) && IsDCCurrentPalette(hdc)) {
  136. pwnd = WindowFromCacheDC(hdc);
  137. /*
  138. * if there is no associated window, don't send the palette change
  139. * messages since this is a memory hdc.
  140. */
  141. if (pwnd != NULL) {
  142. /*
  143. * Ok, send WM_PALETTECHANGED message to everyone. The wParam
  144. * contains a handle to the currently active window. Send
  145. * message to the desktop also, so things on the desktop bitmap
  146. * will paint ok.
  147. */
  148. ThreadLock(pwnd, &tlpwnd);
  149. xxxBroadcastPaletteChanged(pwnd, FALSE);
  150. ThreadUnlock(&tlpwnd);
  151. /*
  152. * Mark all other desktops as needing to send out
  153. * WM_PALETTECHANGED messages.
  154. */
  155. pwinsta = grpWinStaList;
  156. while (pwinsta != NULL) {
  157. pdesk = pwinsta->rpdeskList;
  158. while (pdesk != NULL) {
  159. if (pdesk != pwnd->head.rpdesk) {
  160. pdesk->dwDTFlags |= DTF_NEEDSPALETTECHANGED;
  161. }
  162. pdesk = pdesk->rpdeskNext;
  163. }
  164. pwinsta = pwinsta->rpwinstaNext;
  165. }
  166. GreRealizePalette(hdc);
  167. }
  168. }
  169. /*
  170. * Walk through the SPB list (the saved bitmaps under windows with the
  171. * CS_SAVEBITS style) discarding all bitmaps
  172. */
  173. if (HIWORD(dwNumChanged)) {
  174. FreeAllSpbs();
  175. }
  176. return LOWORD(dwNumChanged);
  177. }
  178. /***************************************************************************\
  179. * xxxFlushPalette
  180. *
  181. * This resets the palette and lets the next foreground app grab the
  182. * foreground palette. This is called in such instances when we
  183. * minimize a window.
  184. *
  185. * History:
  186. * 31-Aug-1995 ChrisWil Created.
  187. \***************************************************************************/
  188. VOID xxxFlushPalette(
  189. PWND pwnd)
  190. {
  191. CheckLock(pwnd);
  192. /*
  193. * Broadcast the palette changed messages.
  194. */
  195. GreRealizeDefaultPalette(gpDispInfo->hdcScreen, TRUE);
  196. xxxBroadcastPaletteChanged(pwnd, TRUE);
  197. }
  198. /***************************************************************************\
  199. * xxxBroadcastPaletteChanged
  200. *
  201. * RealizePalette passes FALSE for fForceDesktopso so that it does not
  202. * cause a loop in case RealizePalette was called by the desktop window.
  203. * In such a case we don't want to call RealizeDesktop. In all other cases
  204. * we do want to go to RealizeDesktop to give the desktop a chance to
  205. * reailze its palette or possibly just repaint.
  206. *
  207. * 04/22/97 vadimg created
  208. \***************************************************************************/
  209. VOID xxxBroadcastPaletteChanged(PWND pwnd, BOOL fForceDesktop)
  210. {
  211. PWND pwndDesk;
  212. HWND hwnd = HWq(pwnd);
  213. CheckLock(pwnd);
  214. pwndDesk = PWNDDESKTOP(pwnd);
  215. if (fForceDesktop || pwnd != pwndDesk) {
  216. TL tlpwndDesk;
  217. ThreadLockAlways(pwndDesk, &tlpwndDesk);
  218. xxxRealizeDesktop(pwndDesk);
  219. ThreadUnlock(&tlpwndDesk);
  220. }
  221. xxxSendNotifyMessage(PWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hwnd, 0L);
  222. }