Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

palette.c

Go to the documentation of this file.
00001 /**************************** Module Header ********************************\ 00002 * Module Name: palette.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * Palette Handling Routines 00007 * 00008 * History: 00009 * 24-May-1993 MikeKe From win3.1 00010 \***************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 /***************************************************************************\ 00016 * IsTopmostRealApp 00017 * 00018 * Returns true if current process is the shell process and this window 00019 * is the first non-shell/user one we find in zorder. If so, we consider 00020 * him to be the "palette foreground". 00021 * 00022 * History: 00023 \***************************************************************************/ 00024 00025 BOOL IsTopmostRealApp( 00026 PWND pwnd) 00027 { 00028 PTHREADINFO ptiCurrent = PtiCurrent(); 00029 PDESKTOPINFO pdeskinfo = pwnd->head.rpdesk->pDeskInfo; 00030 if ((pdeskinfo->spwndShell == NULL) || 00031 (GETPTI(pdeskinfo->spwndShell)->pq != gpqForeground)) { 00032 00033 return FALSE; 00034 } 00035 00036 return (pwnd == NextTopWindow(ptiCurrent, 00037 NULL, 00038 NULL, 00039 NTW_IGNORETOOLWINDOW)); 00040 } 00041 00042 /***************************************************************************\ 00043 * _SelectPalette 00044 * 00045 * Selects palette into DC. This is a wrapper to gdi where we can perform 00046 * checks to see if it's a foreground dc. 00047 * 00048 * History: 00049 \***************************************************************************/ 00050 00051 HPALETTE _SelectPalette( 00052 HDC hdc, 00053 HPALETTE hpal, 00054 BOOL fForceBackground) 00055 { 00056 PWND pwndTop; 00057 BOOL fBackgroundPalette = TRUE; 00058 PWND pwnd = NULL; 00059 /* 00060 * If we are not forcing palette into background, find out where it does 00061 * actually belong. Don't ever select the default palette in as a 00062 * foreground palette because this confuses gdi. Many apps do a 00063 * (oldPal = SelectPalette) (myPal); Draw; SelectObject(oldPal). 00064 * and we don't want to allow this to go through. 00065 */ 00066 if (!fForceBackground && 00067 TEST_PUSIF(PUSIF_PALETTEDISPLAY) && 00068 (hpal != GreGetStockObject(DEFAULT_PALETTE))) { 00069 00070 if (pwnd = WindowFromCacheDC(hdc)) { 00071 00072 PWND pwndActive; 00073 00074 /* 00075 * don't "select" palette unless on a palette device 00076 */ 00077 pwndTop = GetTopLevelWindow(pwnd); 00078 00079 if (!TestWF(pwndTop, WFHASPALETTE)) { 00080 00081 if (pwndTop != _GetDesktopWindow()) 00082 GETPTI(pwndTop)->TIF_flags |= TIF_PALETTEAWARE; 00083 00084 SetWF(pwndTop, WFHASPALETTE); 00085 } 00086 00087 /* 00088 * Hack-o-rama: 00089 * Windows get foreground use of the palette if 00090 * * They are the foreground's active window 00091 * * The current process is the shell and they are the 00092 * topmost valid non-toolwindow in the zorder. 00093 * 00094 * This makes our tray friendly on palettized displays. 00095 * Currently, if you run a palette app and click on the tray, 00096 * the palette app goes all weird. Broderbund apps go 00097 * completely black. This is because they get forced to be 00098 * background always, even though the shell isn't really 00099 * palettized. 00100 * 00101 * Note: this palette architecture sucks. Apps get forced to 00102 * be background palette users even if the foreground thread 00103 * couldn't care less about the palette. Should go by zorder 00104 * if so, but in a more clean way than this. 00105 * 00106 * We really only care about the tray && the background. 00107 * Cabinet dudes don't matter so much. 00108 */ 00109 pwndActive = (gpqForeground ? gpqForeground->spwndActive : NULL); 00110 00111 #if 0 00112 if (pwndActive && 00113 (pwndTop != pwnd->head.rpdesk->pDeskInfo->spwndShell) && 00114 ((pwndActive == pwnd) || _IsChild(pwndActive, pwnd) || IsTopmostRealApp(pwnd)) && 00115 !TestWF(pwnd, WEFTOOLWINDOW)) { 00116 00117 fBackgroundPalette = FALSE; 00118 } 00119 #else 00120 if ((pwndTop != pwndTop->head.rpdesk->pDeskInfo->spwnd) && 00121 (pwndTop != pwndTop->head.rpdesk->pDeskInfo->spwndShell) && 00122 (pwndActive != NULL) && 00123 ((pwndActive == pwnd) || 00124 _IsChild(pwndActive, pwnd) || 00125 IsTopmostRealApp(pwnd)) && 00126 !TestWF(pwnd, WEFTOOLWINDOW)) { 00127 00128 fBackgroundPalette = FALSE; 00129 } 00130 #endif 00131 } 00132 } 00133 00134 return GreSelectPalette(hdc, hpal, fBackgroundPalette); 00135 } 00136 00137 /***************************************************************************\ 00138 * xxxRealizePalette 00139 * 00140 * Realizes palette to the DC. This is a wrapper to gdi so that we can 00141 * check for changes prior to sending notifications. 00142 * 00143 * History: 00144 \***************************************************************************/ 00145 00146 int xxxRealizePalette( 00147 HDC hdc) 00148 { 00149 PWND pwnd; 00150 DWORD dwNumChanged; 00151 PWINDOWSTATION pwinsta; 00152 PDESKTOP pdesk; 00153 TL tlpwnd; 00154 00155 dwNumChanged = GreRealizePalette(hdc); 00156 00157 if (HIWORD(dwNumChanged) && IsDCCurrentPalette(hdc)) { 00158 00159 pwnd = WindowFromCacheDC(hdc); 00160 00161 /* 00162 * if there is no associated window, don't send the palette change 00163 * messages since this is a memory hdc. 00164 */ 00165 if (pwnd != NULL) { 00166 /* 00167 * Ok, send WM_PALETTECHANGED message to everyone. The wParam 00168 * contains a handle to the currently active window. Send 00169 * message to the desktop also, so things on the desktop bitmap 00170 * will paint ok. 00171 */ 00172 ThreadLock(pwnd, &tlpwnd); 00173 xxxBroadcastPaletteChanged(pwnd, FALSE); 00174 ThreadUnlock(&tlpwnd); 00175 00176 /* 00177 * Mark all other desktops as needing to send out 00178 * WM_PALETTECHANGED messages. 00179 */ 00180 00181 pwinsta = grpWinStaList; 00182 00183 while (pwinsta != NULL) { 00184 pdesk = pwinsta->rpdeskList; 00185 while (pdesk != NULL) { 00186 if (pdesk != pwnd->head.rpdesk) { 00187 pdesk->dwDTFlags |= DTF_NEEDSPALETTECHANGED; 00188 } 00189 pdesk = pdesk->rpdeskNext; 00190 } 00191 pwinsta = pwinsta->rpwinstaNext; 00192 } 00193 00194 GreRealizePalette(hdc); 00195 } 00196 } 00197 00198 /* 00199 * Walk through the SPB list (the saved bitmaps under windows with the 00200 * CS_SAVEBITS style) discarding all bitmaps 00201 */ 00202 if (HIWORD(dwNumChanged)) { 00203 FreeAllSpbs(); 00204 } 00205 00206 return LOWORD(dwNumChanged); 00207 } 00208 00209 /***************************************************************************\ 00210 * xxxFlushPalette 00211 * 00212 * This resets the palette and lets the next foreground app grab the 00213 * foreground palette. This is called in such instances when we 00214 * minimize a window. 00215 * 00216 * History: 00217 * 31-Aug-1995 ChrisWil Created. 00218 \***************************************************************************/ 00219 00220 VOID xxxFlushPalette( 00221 PWND pwnd) 00222 { 00223 CheckLock(pwnd); 00224 /* 00225 * Broadcast the palette changed messages. 00226 */ 00227 GreRealizeDefaultPalette(gpDispInfo->hdcScreen, TRUE); 00228 xxxBroadcastPaletteChanged(pwnd, TRUE); 00229 } 00230 00231 /***************************************************************************\ 00232 * xxxBroadcastPaletteChanged 00233 * 00234 * RealizePalette passes FALSE for fForceDesktopso so that it does not 00235 * cause a loop in case RealizePalette was called by the desktop window. 00236 * In such a case we don't want to call RealizeDesktop. In all other cases 00237 * we do want to go to RealizeDesktop to give the desktop a chance to 00238 * reailze its palette or possibly just repaint. 00239 * 00240 * 04/22/97 vadimg created 00241 \***************************************************************************/ 00242 00243 VOID xxxBroadcastPaletteChanged(PWND pwnd, BOOL fForceDesktop) 00244 { 00245 PWND pwndDesk; 00246 HWND hwnd = HWq(pwnd); 00247 00248 CheckLock(pwnd); 00249 00250 pwndDesk = PWNDDESKTOP(pwnd); 00251 if (fForceDesktop || pwnd != pwndDesk) { 00252 TL tlpwndDesk; 00253 ThreadLockAlways(pwndDesk, &tlpwndDesk); 00254 xxxRealizeDesktop(pwndDesk); 00255 ThreadUnlock(&tlpwndDesk); 00256 } 00257 00258 xxxSendNotifyMessage(PWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hwnd, 0L); 00259 }

Generated on Sat May 15 19:41:08 2004 for test by doxygen 1.3.7