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

/**************************** Module Header ********************************\
* Module Name: palette.c
*
* Copyright (c) 1985 - 1999, Microsoft Corporation
*
* Palette Handling Routines
*
* History:
* 24-May-1993 MikeKe From win3.1
\***************************************************************************/
#include "precomp.h"
#pragma hdrstop
/***************************************************************************\
* IsTopmostRealApp
*
* Returns true if current process is the shell process and this window
* is the first non-shell/user one we find in zorder. If so, we consider
* him to be the "palette foreground".
*
* History:
\***************************************************************************/
BOOL IsTopmostRealApp(
PWND pwnd)
{
PTHREADINFO ptiCurrent = PtiCurrent();
PDESKTOPINFO pdeskinfo = pwnd->head.rpdesk->pDeskInfo;
if ((pdeskinfo->spwndShell == NULL) ||
(GETPTI(pdeskinfo->spwndShell)->pq != gpqForeground)) {
return FALSE;
}
return (pwnd == NextTopWindow(ptiCurrent,
NULL,
NULL,
NTW_IGNORETOOLWINDOW));
}
/***************************************************************************\
* _SelectPalette
*
* Selects palette into DC. This is a wrapper to gdi where we can perform
* checks to see if it's a foreground dc.
*
* History:
\***************************************************************************/
HPALETTE _SelectPalette(
HDC hdc,
HPALETTE hpal,
BOOL fForceBackground)
{
PWND pwndTop;
BOOL fBackgroundPalette = TRUE;
PWND pwnd = NULL;
/*
* If we are not forcing palette into background, find out where it does
* actually belong. Don't ever select the default palette in as a
* foreground palette because this confuses gdi. Many apps do a
* (oldPal = SelectPalette) (myPal); Draw; SelectObject(oldPal).
* and we don't want to allow this to go through.
*/
if (!fForceBackground &&
TEST_PUSIF(PUSIF_PALETTEDISPLAY) &&
(hpal != GreGetStockObject(DEFAULT_PALETTE))) {
if (pwnd = WindowFromCacheDC(hdc)) {
PWND pwndActive;
/*
* don't "select" palette unless on a palette device
*/
pwndTop = GetTopLevelWindow(pwnd);
if (!TestWF(pwndTop, WFHASPALETTE)) {
if (pwndTop != _GetDesktopWindow())
GETPTI(pwndTop)->TIF_flags |= TIF_PALETTEAWARE;
SetWF(pwndTop, WFHASPALETTE);
}
/*
* Hack-o-rama:
* Windows get foreground use of the palette if
* * They are the foreground's active window
* * The current process is the shell and they are the
* topmost valid non-toolwindow in the zorder.
*
* This makes our tray friendly on palettized displays.
* Currently, if you run a palette app and click on the tray,
* the palette app goes all weird. Broderbund apps go
* completely black. This is because they get forced to be
* background always, even though the shell isn't really
* palettized.
*
* Note: this palette architecture isn't very good. Apps get forced to
* be background palette users even if the foreground thread
* couldn't care less about the palette. Should go by zorder
* if so, but in a more clean way than this.
*
* We really only care about the tray && the background.
* Cabinet dudes don't matter so much.
*/
pwndActive = (gpqForeground ? gpqForeground->spwndActive : NULL);
#if 0
if (pwndActive &&
(pwndTop != pwnd->head.rpdesk->pDeskInfo->spwndShell) &&
((pwndActive == pwnd) || _IsChild(pwndActive, pwnd) || IsTopmostRealApp(pwnd)) &&
!TestWF(pwnd, WEFTOOLWINDOW)) {
fBackgroundPalette = FALSE;
}
#else
if ((pwndTop != pwndTop->head.rpdesk->pDeskInfo->spwnd) &&
(pwndTop != pwndTop->head.rpdesk->pDeskInfo->spwndShell) &&
(pwndActive != NULL) &&
((pwndActive == pwnd) ||
_IsChild(pwndActive, pwnd) ||
IsTopmostRealApp(pwnd)) &&
!TestWF(pwnd, WEFTOOLWINDOW)) {
fBackgroundPalette = FALSE;
}
#endif
}
}
return GreSelectPalette(hdc, hpal, fBackgroundPalette);
}
/***************************************************************************\
* xxxRealizePalette
*
* Realizes palette to the DC. This is a wrapper to gdi so that we can
* check for changes prior to sending notifications.
*
* History:
\***************************************************************************/
int xxxRealizePalette(
HDC hdc)
{
PWND pwnd;
DWORD dwNumChanged;
PWINDOWSTATION pwinsta;
PDESKTOP pdesk;
TL tlpwnd;
dwNumChanged = GreRealizePalette(hdc);
if (HIWORD(dwNumChanged) && IsDCCurrentPalette(hdc)) {
pwnd = WindowFromCacheDC(hdc);
/*
* if there is no associated window, don't send the palette change
* messages since this is a memory hdc.
*/
if (pwnd != NULL) {
/*
* Ok, send WM_PALETTECHANGED message to everyone. The wParam
* contains a handle to the currently active window. Send
* message to the desktop also, so things on the desktop bitmap
* will paint ok.
*/
ThreadLock(pwnd, &tlpwnd);
xxxBroadcastPaletteChanged(pwnd, FALSE);
ThreadUnlock(&tlpwnd);
/*
* Mark all other desktops as needing to send out
* WM_PALETTECHANGED messages.
*/
pwinsta = grpWinStaList;
while (pwinsta != NULL) {
pdesk = pwinsta->rpdeskList;
while (pdesk != NULL) {
if (pdesk != pwnd->head.rpdesk) {
pdesk->dwDTFlags |= DTF_NEEDSPALETTECHANGED;
}
pdesk = pdesk->rpdeskNext;
}
pwinsta = pwinsta->rpwinstaNext;
}
GreRealizePalette(hdc);
}
}
/*
* Walk through the SPB list (the saved bitmaps under windows with the
* CS_SAVEBITS style) discarding all bitmaps
*/
if (HIWORD(dwNumChanged)) {
FreeAllSpbs();
}
return LOWORD(dwNumChanged);
}
/***************************************************************************\
* xxxFlushPalette
*
* This resets the palette and lets the next foreground app grab the
* foreground palette. This is called in such instances when we
* minimize a window.
*
* History:
* 31-Aug-1995 ChrisWil Created.
\***************************************************************************/
VOID xxxFlushPalette(
PWND pwnd)
{
CheckLock(pwnd);
/*
* Broadcast the palette changed messages.
*/
GreRealizeDefaultPalette(gpDispInfo->hdcScreen, TRUE);
xxxBroadcastPaletteChanged(pwnd, TRUE);
}
/***************************************************************************\
* xxxBroadcastPaletteChanged
*
* RealizePalette passes FALSE for fForceDesktopso so that it does not
* cause a loop in case RealizePalette was called by the desktop window.
* In such a case we don't want to call RealizeDesktop. In all other cases
* we do want to go to RealizeDesktop to give the desktop a chance to
* reailze its palette or possibly just repaint.
*
* 04/22/97 vadimg created
\***************************************************************************/
VOID xxxBroadcastPaletteChanged(PWND pwnd, BOOL fForceDesktop)
{
PWND pwndDesk;
HWND hwnd = HWq(pwnd);
CheckLock(pwnd);
pwndDesk = PWNDDESKTOP(pwnd);
if (fForceDesktop || pwnd != pwndDesk) {
TL tlpwndDesk;
ThreadLockAlways(pwndDesk, &tlpwndDesk);
xxxRealizeDesktop(pwndDesk);
ThreadUnlock(&tlpwndDesk);
}
xxxSendNotifyMessage(PWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hwnd, 0L);
}