2640 lines
76 KiB
C++
2640 lines
76 KiB
C++
/******************************Module*Header*******************************\
|
||
* Module Name: palgdi.cxx
|
||
*
|
||
* This module provides the API level interface functions for dealing with
|
||
* palettes.
|
||
*
|
||
* Created: 07-Nov-1990 22:21:11
|
||
* Author: Patrick Haluptzok patrickh
|
||
*
|
||
* Copyright (c) 1990-1999 Microsoft Corporation
|
||
\**************************************************************************/
|
||
|
||
#include "precomp.hxx"
|
||
|
||
// hForePalette is a global variable that tells which palette is currently
|
||
// realized in the foreground.
|
||
|
||
HPALETTE hForePalette = 0;
|
||
PW32PROCESS hForePID = 0;
|
||
|
||
|
||
#if DBG
|
||
|
||
ULONG DbgPal = 0;
|
||
#define PAL_DEBUG(l,x) {if (l <= DbgPal) {DbgPrint("%p ", hpalDC); DbgPrint(x);}}
|
||
|
||
#else
|
||
|
||
#define PAL_DEBUG(l,x)
|
||
|
||
#endif
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreGetDIBColorTable
|
||
*
|
||
* Get the color table of the DIB section currently selected into the dc
|
||
* identified by the given hdc. If the surface is not a DIB section,
|
||
* this function will fail.
|
||
*
|
||
* History:
|
||
* 07-Sep-1993 -by- Wendy Wu [wendywu]
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
#if ((BMF_1BPP != 1) || (BMF_4BPP != 2) || (BMF_8BPP != 3))
|
||
#error GetDIBColorTable BAD FORMAT
|
||
#endif
|
||
|
||
UINT
|
||
APIENTRY
|
||
GreGetDIBColorTable(
|
||
HDC hdc,
|
||
UINT iStart,
|
||
UINT cEntries,
|
||
RGBQUAD *pRGB
|
||
)
|
||
{
|
||
|
||
UINT iRet = 0;
|
||
DCOBJ dco(hdc);
|
||
|
||
if (pRGB != (RGBQUAD *)NULL)
|
||
{
|
||
if (dco.bValid())
|
||
{
|
||
//
|
||
// Protect against dynamic mode changes while we go grunging
|
||
// around in the surface.
|
||
//
|
||
|
||
DEVLOCKOBJ dlo;
|
||
dlo.vLockNoDrawing(dco);
|
||
|
||
//
|
||
// Fail if the selected in surface is not a DIB or the depth is more than
|
||
// 8BPP.
|
||
//
|
||
|
||
SURFACE *pSurf = dco.pSurfaceEff();
|
||
ULONG iFormat = pSurf->iFormat();
|
||
if ((pSurf->bDIBSection() || (pSurf->pPal != NULL)) &&
|
||
(iFormat <= BMF_8BPP) && (iFormat >= BMF_1BPP))
|
||
{
|
||
//
|
||
// Lock the surface palette and figure out the max index allowed on the
|
||
// palette. Win95 does not return un-used entries.
|
||
//
|
||
|
||
XEPALOBJ pal(pSurf->ppal());
|
||
ASSERTGDI(pal.bValid(), "GetDIBColorTable: invalid pal\n");
|
||
|
||
UINT iMax = (UINT) pal.cEntries();
|
||
|
||
if (iStart >= iMax)
|
||
{
|
||
return(0);
|
||
}
|
||
|
||
UINT iLast = iStart + cEntries;
|
||
|
||
if (iLast > iMax)
|
||
{
|
||
iLast = iMax;
|
||
}
|
||
|
||
pal.vFill_rgbquads(pRGB, iStart, iRet = iLast - iStart);
|
||
}
|
||
else
|
||
{
|
||
SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SAVE_ERROR_CODE(ERROR_INVALID_PARAMETER);
|
||
}
|
||
|
||
return(iRet);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreSetDIBColorTable
|
||
*
|
||
* Set the color table of the DIB section currently selected into the dc
|
||
* identified by the given hdc. If the surface is not a DIB section,
|
||
* this function will fail.
|
||
*
|
||
* History:
|
||
* 07-Sep-1993 -by- Wendy Wu [wendywu]
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
UINT
|
||
APIENTRY
|
||
GreSetDIBColorTable(
|
||
HDC hdc,
|
||
UINT iStart,
|
||
UINT cEntries,
|
||
RGBQUAD *pRGB
|
||
)
|
||
{
|
||
|
||
UINT iRet = 0;
|
||
DCOBJ dco(hdc);
|
||
|
||
if (dco.bValid())
|
||
{
|
||
//
|
||
// Protect against dynamic mode changes while we go grunging
|
||
// around in the surface.
|
||
//
|
||
|
||
DEVLOCKOBJ dlo;
|
||
dlo.vLockNoDrawing(dco);
|
||
|
||
//
|
||
// Fail if the selected in surface is not a DIB or the depth is more than
|
||
// 8BPP.
|
||
//
|
||
|
||
SURFACE *pSurf = dco.pSurfaceEff();
|
||
ULONG iFormat = pSurf->iFormat();
|
||
if (pSurf->bDIBSection() &&
|
||
(iFormat <= BMF_8BPP) && (iFormat >= BMF_1BPP))
|
||
{
|
||
//
|
||
// Mark the brushes dirty.
|
||
//
|
||
|
||
dco.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
|
||
|
||
//
|
||
// Lock the surface palette and figure out the max
|
||
// index allowed on the palette.
|
||
//
|
||
|
||
XEPALOBJ pal(pSurf->ppal());
|
||
ASSERTGDI(pal.bValid(), "GetDIBColorTable: invalid pal\n");
|
||
|
||
UINT iMax = (UINT) pal.cEntries();
|
||
if (iStart < iMax)
|
||
{
|
||
UINT iLast = iStart + cEntries;
|
||
if (iLast > iMax)
|
||
iLast = iMax;
|
||
|
||
pal.vCopy_rgbquad(pRGB, iStart, iRet = iLast - iStart);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
|
||
}
|
||
|
||
return(iRet);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreCreatePalette - creates a palette from the logpal information given
|
||
*
|
||
* API function.
|
||
*
|
||
* returns HPALETTE for succes, (HPALETTE) 0 for failure
|
||
*
|
||
* History:
|
||
* 07-Nov-1990 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
HPALETTE
|
||
APIENTRY
|
||
GreCreatePalette(
|
||
LPLOGPALETTE pLogPal
|
||
)
|
||
{
|
||
|
||
return(GreCreatePaletteInternal(pLogPal,pLogPal->palNumEntries));
|
||
}
|
||
|
||
HPALETTE
|
||
APIENTRY
|
||
GreCreatePaletteInternal(
|
||
LPLOGPALETTE pLogPal,
|
||
UINT cEntries
|
||
)
|
||
{
|
||
if ((pLogPal->palVersion != 0x300) || (cEntries == 0))
|
||
{
|
||
WARNING("GreCreatePalette failed, 0 entries or wrong version\n");
|
||
return((HPALETTE) 0);
|
||
}
|
||
|
||
//
|
||
// The constructor checks for invalid flags and fails if they are found.
|
||
//
|
||
|
||
PALMEMOBJ pal;
|
||
|
||
if (!pal.bCreatePalette(PAL_INDEXED,
|
||
cEntries,
|
||
(PULONG) pLogPal->palPalEntry,
|
||
0, 0, 0,
|
||
(PAL_DC | PAL_FREE)))
|
||
{
|
||
return((HPALETTE) 0);
|
||
}
|
||
|
||
ASSERTGDI(pal.cEntries() != 0, "ERROR can't be 0, bGetEntriesFrom depends on that");
|
||
|
||
pal.vKeepIt();
|
||
GreSetPaletteOwner((HPALETTE)pal.hpal(), OBJECT_OWNER_CURRENT);
|
||
return((HPALETTE) pal.hpal());
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* NtGdiCreatePaletteInternal()
|
||
*
|
||
* History:
|
||
* 01-Nov-1994 -by- Eric Kutter [erick]
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
HPALETTE
|
||
APIENTRY
|
||
NtGdiCreatePaletteInternal(
|
||
LPLOGPALETTE pLogPal,
|
||
UINT cEntries
|
||
)
|
||
{
|
||
HPALETTE hpalRet = (HPALETTE)1;
|
||
|
||
//
|
||
// verify cEntries
|
||
//
|
||
|
||
if (cEntries <= 65536)
|
||
{
|
||
int cj = cEntries * sizeof(PALETTEENTRY) + offsetof(LOGPALETTE,palPalEntry);
|
||
WORD Version;
|
||
PULONG pPaletteEntry;
|
||
|
||
__try
|
||
{
|
||
// it is safe to do a byte here. If we can access dword's on byte boundries
|
||
// this will work. If not we will hit an exception under a try except. Winhelp
|
||
// passes in an unaligned palette but only on x86.
|
||
|
||
ProbeForRead(pLogPal,cj, sizeof(BYTE));
|
||
Version = pLogPal->palVersion;
|
||
pPaletteEntry = (PULONG) pLogPal->palPalEntry;
|
||
}
|
||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||
{
|
||
// SetLastError(GetExceptionCode());
|
||
|
||
hpalRet = (HPALETTE)0;
|
||
}
|
||
|
||
if (hpalRet)
|
||
{
|
||
if ((Version != 0x300) || (cEntries == 0))
|
||
{
|
||
WARNING("GreCreatePalette failed, 0 entries or wrong version\n");
|
||
hpalRet = (HPALETTE)0;
|
||
}
|
||
|
||
if (hpalRet)
|
||
{
|
||
|
||
//
|
||
// The constructor checks for invalid flags and fails if they are found.
|
||
//
|
||
|
||
PALMEMOBJ pal;
|
||
BOOL bStatus;
|
||
|
||
//
|
||
// bCreatePalette must use a try-except when accessing pPaletteEntry
|
||
//
|
||
|
||
bStatus = pal.bCreatePalette(PAL_INDEXED,
|
||
cEntries,
|
||
pPaletteEntry,
|
||
0,
|
||
0,
|
||
0,
|
||
(PAL_DC | PAL_FREE));
|
||
|
||
if (bStatus)
|
||
{
|
||
ASSERTGDI(pal.cEntries() != 0, "ERROR can't be 0, bGetEntriesFrom depends on that");
|
||
|
||
bStatus = GreSetPaletteOwner((HPALETTE)pal.hpal(), OBJECT_OWNER_CURRENT);
|
||
|
||
if (bStatus)
|
||
{
|
||
pal.vKeepIt();
|
||
hpalRet = pal.hpal();
|
||
}
|
||
else
|
||
{
|
||
hpalRet = (HPALETTE)0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
hpalRet = (HPALETTE)0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
hpalRet = 0;
|
||
WARNING("GreCreatePalette failed,cEntries too large\n");
|
||
}
|
||
|
||
|
||
return(hpalRet);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreCreateCompatibleHalftonePalette
|
||
*
|
||
* Creates the win95 compatible halftone palette
|
||
*
|
||
* Arguments:
|
||
*
|
||
*
|
||
*
|
||
* Return Value:
|
||
*
|
||
*
|
||
*
|
||
* History:
|
||
*
|
||
* 11/27/1996 Mark Enstrom [marke]
|
||
*
|
||
\**************************************************************************/
|
||
|
||
HPALETTE
|
||
APIENTRY
|
||
GreCreateCompatibleHalftonePalette(
|
||
HDC hdc
|
||
)
|
||
{
|
||
HPALETTE hpalRet;
|
||
PALMEMOBJ pal;
|
||
BOOL bStatus;
|
||
|
||
//
|
||
// bCreatePalette must use a try-except when accessing pPaletteEntry
|
||
//
|
||
|
||
bStatus = pal.bCreatePalette(PAL_INDEXED,
|
||
256,
|
||
(PULONG)&aPalHalftone[0].ul,
|
||
0,
|
||
0,
|
||
0,
|
||
(PAL_DC | PAL_FREE | PAL_HT));
|
||
|
||
if (bStatus)
|
||
{
|
||
ASSERTGDI(pal.cEntries() != 0, "ERROR can't be 0, bGetEntriesFrom depends on that");
|
||
|
||
pal.flPal(PAL_HT);
|
||
|
||
bStatus = GreSetPaletteOwner((HPALETTE)pal.hpal(), OBJECT_OWNER_CURRENT);
|
||
|
||
if (bStatus)
|
||
{
|
||
pal.vKeepIt();
|
||
hpalRet = pal.hpal();
|
||
}
|
||
else
|
||
{
|
||
hpalRet = (HPALETTE)0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
hpalRet = (HPALETTE)0;
|
||
}
|
||
return(hpalRet);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreCreateHalftonePalette(hdc)
|
||
*
|
||
* Create a halftone palette for the given DC.
|
||
*
|
||
* History:
|
||
* 31-Aug-1992 -by- Wendy Wu [wendywu]
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
HPALETTE
|
||
APIENTRY
|
||
GreCreateHalftonePalette(
|
||
HDC hdc
|
||
)
|
||
{
|
||
//
|
||
// Validate and lock down the DC. NOTE: Even though the surface is accessed
|
||
// in this function, it is only for information purposes. No reading or
|
||
// writing of the surface occurs.
|
||
//
|
||
|
||
DCOBJ dco(hdc);
|
||
|
||
if (!dco.bValid())
|
||
{
|
||
SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
|
||
return((HPALETTE) 0);
|
||
}
|
||
|
||
//
|
||
// Get the PDEV from the DC.
|
||
//
|
||
|
||
PDEVOBJ po(dco.hdev());
|
||
|
||
//
|
||
// Acquire the devlock to protect against dynamic mode changes while
|
||
// we enable halftoning for the PDEV and we construct the halftone
|
||
// palette from this information.
|
||
//
|
||
|
||
DEVLOCKOBJ dlo(po);
|
||
|
||
//
|
||
// Create the halftone block if it has not existed yet.
|
||
//
|
||
|
||
if ((po.pDevHTInfo() == NULL) &&
|
||
!po.bEnableHalftone((PCOLORADJUSTMENT)NULL))
|
||
return((HPALETTE) 0);
|
||
|
||
DEVICEHALFTONEINFO *pDevHTInfo = (DEVICEHALFTONEINFO *)po.pDevHTInfo();
|
||
|
||
//
|
||
// Use the entries in the halftone palette in the halftone block to create
|
||
// the palette.
|
||
//
|
||
|
||
EPALOBJ palHT((HPALETTE)pDevHTInfo->DeviceOwnData);
|
||
ASSERTGDI(palHT.bValid(), "GreCreateHalftonePalette: invalid HT pal\n");
|
||
|
||
PALMEMOBJ pal;
|
||
if (palHT.cEntries())
|
||
{
|
||
if (!pal.bCreatePalette(PAL_INDEXED, palHT.cEntries(),
|
||
(PULONG)palHT.apalColorGet(), 0, 0, 0,
|
||
(PAL_DC | PAL_FREE | PAL_HT)))
|
||
{
|
||
return((HPALETTE) 0);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// 16BPP halftone uses 555 for RGB. We can't create a zero
|
||
// entry palette at the API level, so lets create a default palette.
|
||
//
|
||
|
||
if (!pal.bCreatePalette(PAL_INDEXED, (ULONG)logDefaultPal.palNumEntries,
|
||
(PULONG)logDefaultPal.palPalEntry, 0, 0, 0,
|
||
PAL_DC | PAL_FREE | PAL_HT))
|
||
{
|
||
return(FALSE);
|
||
}
|
||
}
|
||
|
||
pal.vKeepIt();
|
||
GreSetPaletteOwner((HPALETTE)pal.hpal(), OBJECT_OWNER_CURRENT);
|
||
return((HPALETTE) pal.hpal());
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreGetNearestPaletteIndex - returns the nearest palette index to crColor
|
||
* in the hpalette. Can only fail if hpal passed in is busy or bad.
|
||
*
|
||
* API function.
|
||
*
|
||
* returns value >= 0 for success, -1 for failure.
|
||
*
|
||
* History:
|
||
* 09-Nov-1990 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
UINT
|
||
APIENTRY
|
||
NtGdiGetNearestPaletteIndex(
|
||
HPALETTE hpal,
|
||
COLORREF crColor
|
||
)
|
||
{
|
||
EPALOBJ pal((HPALETTE) hpal);
|
||
|
||
if (pal.bValid())
|
||
{
|
||
//
|
||
// If the palette has 0 entries return the color passed in.
|
||
//
|
||
|
||
if (pal.cEntries())
|
||
{
|
||
if (crColor & 0x01000000)
|
||
{
|
||
crColor &= 0x0000FFFF;
|
||
|
||
if (crColor >= pal.cEntries())
|
||
crColor = 0;
|
||
}
|
||
else
|
||
{
|
||
crColor &= 0x00FFFFFF;
|
||
crColor = pal.ulGetNearestFromPalentry(*((PPALETTEENTRY) &crColor));
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
|
||
crColor = CLR_INVALID;
|
||
}
|
||
|
||
return((UINT) crColor);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreAnimatePalette
|
||
*
|
||
* API function
|
||
*
|
||
* Returns: The number of logical palette entries animated, 0 for error.
|
||
*
|
||
* History:
|
||
* 17-Nov-1990 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
BOOL APIENTRY GreAnimatePalette(HPALETTE hpal, UINT ulStartIndex,
|
||
UINT ulNumEntries, CONST PALETTEENTRY *lpPaletteColors)
|
||
{
|
||
BOOL bReturn = FALSE;
|
||
|
||
EPALOBJ pal((HPALETTE) hpal);
|
||
|
||
if (pal.bValid())
|
||
{
|
||
bReturn = (BOOL) pal.ulAnimatePalette(ulStartIndex, ulNumEntries, lpPaletteColors);
|
||
}
|
||
|
||
return(bReturn);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreGetPaletteEntries
|
||
*
|
||
* API function
|
||
*
|
||
* returns: 0 for failure, else number of entries retrieved.
|
||
*
|
||
* History:
|
||
* 18-Nov-1990 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
UINT APIENTRY GreGetPaletteEntries(HPALETTE hpal, UINT ulStartIndex,
|
||
UINT ulNumEntries, LPPALETTEENTRY pRGB)
|
||
{
|
||
//
|
||
// Note on this call we can just let the default palette go through
|
||
// since it isn't getting modified, and the constructor is smart
|
||
// enough not to really lock it down.
|
||
//
|
||
|
||
EPALOBJ pal((HPALETTE) hpal);
|
||
|
||
if (!pal.bValid())
|
||
{
|
||
SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
|
||
return(0);
|
||
}
|
||
|
||
return(pal.ulGetEntries(ulStartIndex, ulNumEntries, pRGB, FALSE));
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreSetPaletteEntries
|
||
*
|
||
* API function
|
||
*
|
||
* returns: 0 for failure, else number of entries retrieved.
|
||
*
|
||
* History:
|
||
* 18-Nov-1990 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
UINT
|
||
GreSetPaletteEntries(
|
||
HPALETTE hpal,
|
||
UINT ulStartIndex,
|
||
UINT ulNumEntries,
|
||
CONST PALETTEENTRY *pRGB
|
||
)
|
||
{
|
||
//
|
||
// Note on this call we don't worry about STOCKOBJ_PAL because ulSetEntries
|
||
// won't let the default palette get modified.
|
||
//
|
||
|
||
UINT uiReturn = 0;
|
||
|
||
EPALOBJ pal((HPALETTE) hpal);
|
||
|
||
if (pal.bValid())
|
||
{
|
||
//
|
||
// You must grab the palette semaphore to touch the linked list of DC's.
|
||
//
|
||
|
||
SEMOBJ semo(ghsemPalette);
|
||
|
||
uiReturn = (UINT) pal.ulSetEntries(ulStartIndex, ulNumEntries, pRGB);
|
||
|
||
//
|
||
// Run down all the DC's for this palette.
|
||
// Set the flags to dirty the brushes, since we changed the palette!
|
||
//
|
||
|
||
{
|
||
MLOCKFAST mlo;
|
||
|
||
HDC hdcNext = pal.hdcHead();
|
||
while ( hdcNext != (HDC)0 )
|
||
{
|
||
MDCOBJA dco(hdcNext);
|
||
|
||
//
|
||
// WINBUG #55203 2-1-2000 bhouse Remove temporary fix to avoid AV when setting DIRTY_BRUSHES
|
||
// This is just a temp fix (since '95 hehehe) to keep
|
||
// this from doing an AV. Lingyun, making the
|
||
// brush flags all be in kernel memory will
|
||
// fix this.
|
||
//
|
||
// this should just be
|
||
// dco.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
|
||
//
|
||
|
||
if (GreGetObjectOwner((HOBJ)hdcNext,DC_TYPE) == W32GetCurrentPID())
|
||
{
|
||
dco.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
|
||
}
|
||
else
|
||
{
|
||
dco.pdc->flbrushAdd(DIRTY_FILL);
|
||
}
|
||
|
||
hdcNext = dco.pdc->hdcNext();
|
||
}
|
||
}
|
||
}
|
||
|
||
return(uiReturn);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreGetNearestColor
|
||
*
|
||
* This function returns the color that will be displayed on the device
|
||
* if a solid brush was created with the given colorref.
|
||
*
|
||
* History:
|
||
* Mon 29-Nov-1993 -by- Patrick Haluptzok [patrickh]
|
||
* Don't round the color on non-indexed devices
|
||
*
|
||
* 15-Jan-1991 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
COLORREF APIENTRY GreGetNearestColor(HDC hdc, COLORREF crColor)
|
||
{
|
||
ULONG ulRet;
|
||
|
||
DCOBJ dco(hdc);
|
||
|
||
if (dco.bValid())
|
||
{
|
||
|
||
//
|
||
// Protect against dynamic mode changes while we go grunging
|
||
// around in the surface.
|
||
//
|
||
|
||
DEVLOCKOBJ dlo;
|
||
dlo.vLockNoDrawing(dco);
|
||
|
||
XEPALOBJ palDC(dco.ppal());
|
||
|
||
XEPALOBJ palSurf;
|
||
|
||
SURFACE *pSurf = dco.pSurfaceEff();
|
||
|
||
if ((dco.dctp() == DCTYPE_INFO) || (dco.dctp() == DCTYPE_DIRECT))
|
||
{
|
||
PDEVOBJ po(dco.hdev());
|
||
ASSERTGDI(po.bValid(), "ERROR GreGetNearestColor invalid PDEV\n");
|
||
|
||
palSurf.ppalSet(po.ppalSurf());
|
||
ASSERTGDI(palSurf.bValid(), "ERROR GreGetNearestColor invalid palDefault");
|
||
}
|
||
else
|
||
{
|
||
ASSERTGDI(dco.dctp() == DCTYPE_MEMORY, "Not a memory DC type");
|
||
palSurf.ppalSet(pSurf->ppal());
|
||
}
|
||
|
||
//
|
||
// if ICM translate the color to CMYK, just return the passed CMYK color.
|
||
//
|
||
if (dco.pdc->bIsCMYKColor())
|
||
{
|
||
ulRet = crColor;
|
||
}
|
||
else
|
||
{
|
||
if (((crColor & 0x01000000) == 0) &&
|
||
(palSurf.bValid() && !(palSurf.bIsIndexed())))
|
||
{
|
||
//
|
||
// Well if it isn't index it's RGB,BGR, or Bitfields.
|
||
// In any case to support Win3.1 we need to return exactly
|
||
// what was passed in otherwise they think we are a monochrome
|
||
// device. Bitfields could result is some messy rounding so
|
||
// it's more exact to just return the RGB passed in.
|
||
//
|
||
|
||
ulRet = crColor & 0x00FFFFFF; // mask off the highest byte
|
||
}
|
||
else
|
||
{
|
||
ulRet = ulIndexToRGB(palSurf, palDC, ulGetNearestIndexFromColorref(palSurf, palDC, crColor));
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ulRet = CLR_INVALID;
|
||
}
|
||
|
||
return(ulRet);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreGetSystemPaletteEntries
|
||
*
|
||
* API Function - copies out the range of palette entries from the DC's
|
||
* surface's palette.
|
||
*
|
||
* returns: number of entries retrieved from the surface palette, 0 for FAIL
|
||
*
|
||
* History:
|
||
* 15-Jan-1991 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
UINT APIENTRY GreGetSystemPaletteEntries(HDC hdc, UINT ulStartIndex,
|
||
UINT ulNumEntries, PPALETTEENTRY pRGB)
|
||
{
|
||
UINT uiReturn = 0;
|
||
|
||
DCOBJ dco(hdc);
|
||
|
||
if (dco.bValid())
|
||
{
|
||
PDEVOBJ po(dco.hdev());
|
||
|
||
//
|
||
// Acquire the devlock while grunging in the surface palette to
|
||
// protect against dynamic mode changes.
|
||
//
|
||
|
||
DEVLOCKOBJ dlo(po);
|
||
|
||
if (po.bIsPalManaged())
|
||
{
|
||
XEPALOBJ palSurf(po.ppalSurf());
|
||
uiReturn = (UINT) palSurf.ulGetEntries(ulStartIndex, ulNumEntries,
|
||
pRGB, TRUE);
|
||
}
|
||
}
|
||
|
||
return(uiReturn);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreGetSystemPaletteUse
|
||
*
|
||
* API function
|
||
*
|
||
* returns: SYSPAL_STATIC or SYSPAL_NOSTATIC, 0 for an error
|
||
*
|
||
* History:
|
||
* 15-Jan-1991 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
UINT APIENTRY GreGetSystemPaletteUse(HDC hdc)
|
||
{
|
||
ULONG ulReturn = SYSPAL_ERROR;
|
||
|
||
DCOBJ dco(hdc);
|
||
|
||
if (dco.bValid())
|
||
{
|
||
PDEVOBJ po(dco.hdev());
|
||
|
||
//
|
||
// Acquire the devlock while grunging in the surface palette to
|
||
// protect against dynamic mode changes.
|
||
//
|
||
|
||
DEVLOCKOBJ dlo(po);
|
||
|
||
if (po.bIsPalManaged())
|
||
{
|
||
XEPALOBJ palSurf(po.ppalSurf());
|
||
|
||
if (palSurf.bIsNoStatic())
|
||
{
|
||
ulReturn = SYSPAL_NOSTATIC;
|
||
}
|
||
else if (palSurf.bIsNoStatic256())
|
||
{
|
||
ulReturn = SYSPAL_NOSTATIC256;
|
||
}
|
||
else
|
||
{
|
||
ulReturn = SYSPAL_STATIC;
|
||
}
|
||
}
|
||
}
|
||
|
||
return(ulReturn);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreSetSystemPaletteUse
|
||
*
|
||
* API function - Sets the number of reserved entries if palette managed
|
||
*
|
||
* returns - the old flag for the palette, 0 for error
|
||
*
|
||
* History:
|
||
* 15-Jan-1991 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
UINT APIENTRY GreSetSystemPaletteUse(HDC hdc, UINT ulUsage)
|
||
{
|
||
//
|
||
// Validate the parameters, Win3.1 sets the flag to static if it's invalid.
|
||
//
|
||
|
||
if ((ulUsage != SYSPAL_STATIC) && (ulUsage != SYSPAL_NOSTATIC) &&
|
||
(ulUsage != SYSPAL_NOSTATIC256))
|
||
ulUsage = SYSPAL_STATIC;
|
||
|
||
//
|
||
// Initialize return value.
|
||
//
|
||
|
||
ULONG ulReturn = SYSPAL_ERROR;
|
||
BOOL bPalChanged = FALSE;
|
||
ULONG i;
|
||
|
||
DCOBJ dco(hdc);
|
||
|
||
if (dco.bValid())
|
||
{
|
||
//
|
||
// Lock the screen semaphore so that we don't get flipped into
|
||
// full screen after checking the bit. This also protects us
|
||
// from dynamic mode changes that change the 'bIsPalManaged'
|
||
// status.
|
||
//
|
||
|
||
PDEVOBJ po(dco.hdev());
|
||
|
||
DEVLOCKOBJ dlo(po);
|
||
|
||
XEPALOBJ palSurf(po.ppalSurf());
|
||
XEPALOBJ palDC(dco.ppal());
|
||
|
||
if (po.bIsPalManaged())
|
||
{
|
||
//
|
||
// The palette managed case.
|
||
//
|
||
|
||
{
|
||
//
|
||
// Protect access to the goodies in the system palette
|
||
// with the SEMOBJ. We don't want a realize happening
|
||
// while we fiddle flags.
|
||
//
|
||
|
||
SEMOBJ semo(ghsemPalette);
|
||
|
||
if (palSurf.bIsNoStatic())
|
||
{
|
||
ulReturn = SYSPAL_NOSTATIC;
|
||
}
|
||
else if (palSurf.bIsNoStatic256())
|
||
{
|
||
ulReturn = SYSPAL_NOSTATIC256;
|
||
}
|
||
else
|
||
{
|
||
ulReturn = SYSPAL_STATIC;
|
||
}
|
||
|
||
|
||
if (ulUsage == SYSPAL_STATIC)
|
||
{
|
||
//
|
||
// reset the colors from their original copy in the devinfo palette.
|
||
// The copy already has the flags properly set.
|
||
//
|
||
|
||
if (palSurf.bIsNoStatic() || palSurf.bIsNoStatic256())
|
||
{
|
||
//
|
||
// Change the palette that GDI manages, copy over up to
|
||
// 20 static colors from ppalDefault
|
||
//
|
||
|
||
XEPALOBJ palOriginal(ppalDefault);
|
||
ASSERTGDI(palOriginal.bValid(), "ERROR ulMakeStatic0");
|
||
|
||
ULONG ulNumReserved = palSurf.ulNumReserved() >> 1;
|
||
|
||
if (ulNumReserved > 10)
|
||
{
|
||
ulNumReserved = 10;
|
||
}
|
||
|
||
//
|
||
// set the beginning entries
|
||
//
|
||
|
||
for (i = 0; i < ulNumReserved; i++)
|
||
{
|
||
PALETTEENTRY palEntry = palOriginal.palentryGet(i);
|
||
|
||
palEntry.peFlags = PC_USED | PC_FOREGROUND;
|
||
palSurf.palentrySet(i,palEntry);
|
||
}
|
||
|
||
//
|
||
// set the ending entries
|
||
//
|
||
|
||
ULONG ulCurrentPal = palSurf.cEntries();
|
||
ULONG ulCurrentDef = 20;
|
||
|
||
for (i = 0; i < ulNumReserved; i++)
|
||
{
|
||
PALETTEENTRY palEntry;
|
||
|
||
ulCurrentPal--;
|
||
ulCurrentDef--;
|
||
|
||
palEntry = palOriginal.palentryGet(ulCurrentDef);
|
||
palEntry.peFlags = PC_USED | PC_FOREGROUND;
|
||
palSurf.palentrySet(ulCurrentPal,palEntry);
|
||
}
|
||
|
||
//
|
||
// Mark the brushes dirty for this DC.
|
||
//
|
||
|
||
dco.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
|
||
|
||
|
||
palSurf.flPalSet(palSurf.flPal() & ~PAL_NOSTATIC & ~PAL_NOSTATIC256);
|
||
palSurf.vUpdateTime();
|
||
bPalChanged = TRUE;
|
||
}
|
||
}
|
||
else if (ulUsage == SYSPAL_NOSTATIC)
|
||
{
|
||
//
|
||
// unmark all the static colors, with the exception of black and
|
||
// white that stay with us.
|
||
//
|
||
|
||
for (i = 1; i < (palSurf.cEntries()-1); i++)
|
||
{
|
||
palSurf.apalColorGet()[i].pal.peFlags = 0;
|
||
}
|
||
|
||
palSurf.vSetNoStatic();
|
||
}
|
||
else //SYSPAL_NOSTATIC256
|
||
{
|
||
//
|
||
// unmark all the static colors
|
||
//
|
||
for (i = 0; i < (palSurf.cEntries()); i++)
|
||
{
|
||
palSurf.apalColorGet()[i].pal.peFlags = 0;
|
||
}
|
||
|
||
palSurf.vSetNoStatic256();
|
||
|
||
}
|
||
|
||
}
|
||
|
||
if (bPalChanged)
|
||
{
|
||
SEMOBJ so(po.hsemPointer());
|
||
|
||
if (!po.bDisabled())
|
||
{
|
||
po.pfnSetPalette()(
|
||
po.dhpdevParent(),
|
||
(PALOBJ *) &palSurf,
|
||
0,
|
||
0,
|
||
palSurf.cEntries());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return(ulReturn);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* NtGdiResizePalette()
|
||
*
|
||
* API function
|
||
*
|
||
* returns: TRUE for success, FALSE for failure
|
||
*
|
||
* History:
|
||
* Tue 10-Sep-1991 -by- Patrick Haluptzok [patrickh]
|
||
* rewrite to be multi-threaded safe
|
||
*
|
||
* 19-Jan-1991 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
#define PAL_MAX_SIZE 1024
|
||
|
||
BOOL
|
||
APIENTRY
|
||
NtGdiResizePalette(
|
||
HPALETTE hpal,
|
||
UINT cEntry
|
||
)
|
||
{
|
||
//
|
||
// Check for quick out before constructors
|
||
//
|
||
|
||
if ((cEntry > PAL_MAX_SIZE) || (cEntry == 0))
|
||
{
|
||
WARNING("GreResizePalette failed - invalid size\n");
|
||
return(FALSE);
|
||
}
|
||
|
||
BOOL bReturn = FALSE;
|
||
|
||
//
|
||
// Validate the parameter.
|
||
//
|
||
|
||
EPALOBJ palOld(hpal);
|
||
|
||
if ((palOld.bValid()) && (!palOld.bIsPalDefault()) && (palOld.bIsPalDC()))
|
||
{
|
||
//
|
||
// Create a new palette. Don't mark it to keep because after
|
||
// bSwap it will be palOld and we want it to be deleted.
|
||
//
|
||
|
||
PALMEMOBJ pal;
|
||
|
||
if (pal.bCreatePalette(PAL_INDEXED,
|
||
cEntry,
|
||
(PULONG) NULL,
|
||
0, 0, 0,
|
||
PAL_DC | PAL_FREE))
|
||
{
|
||
|
||
//
|
||
// Grab the palette semaphore which stops any palettes from being selected
|
||
// in or out. It protects the linked DC list, can't copy DC head until
|
||
// we hold it.
|
||
//
|
||
|
||
SEMOBJ semo(ghsemPalette);
|
||
|
||
//
|
||
// Copy the data from old palette.
|
||
//
|
||
|
||
pal.vCopyEntriesFrom(palOld);
|
||
pal.flPalSet(palOld.flPal());
|
||
pal.hdcHead(palOld.hdcHead());
|
||
pal.hdev(palOld.hdev());
|
||
pal.cRefhpal(palOld.cRefhpal());
|
||
pal.vComputeCallTables();
|
||
|
||
HDC hdcNext, hdcTemp;
|
||
|
||
MLOCKFAST mlo;
|
||
|
||
//
|
||
// Run down the list and exclusive lock all the handles.
|
||
//
|
||
|
||
{
|
||
hdcNext = pal.hdcHead();
|
||
|
||
while (hdcNext != (HDC) 0)
|
||
{
|
||
MDCOBJ dcoLock(hdcNext);
|
||
|
||
if (!dcoLock.bLocked())
|
||
{
|
||
WARNING1("ResizePalette failed because a DC the hpal is in is busy\n");
|
||
break;
|
||
}
|
||
|
||
hdcNext = dcoLock.pdc->hdcNext();
|
||
dcoLock.vDontUnlockDC();
|
||
}
|
||
}
|
||
|
||
if (hdcNext == (HDC) 0)
|
||
{
|
||
//
|
||
// We have the palette semaphore and all the DC's exclusively locked. Noone else
|
||
// can be accessing the translates because you must hold one of those things to
|
||
// access them. So we can delete the translates.
|
||
//
|
||
|
||
palOld.vMakeNoXlate();
|
||
palOld.vUpdateTime();
|
||
|
||
//
|
||
// Note that bSwap calls locked SpapHandle vesrion so the Hmgr Resource
|
||
// is required (luckily it was grabbed earlier).
|
||
//
|
||
|
||
//
|
||
// try to swap palettes, bSwap can only succedd if
|
||
// this routine owns the only locks on the objecs
|
||
//
|
||
|
||
bReturn = pal.bSwap((PPALETTE *) &palOld,1,1);
|
||
|
||
if (bReturn)
|
||
{
|
||
ASSERTGDI(bReturn, "ERROR no way");
|
||
|
||
//
|
||
// Run down all the DC's for this palette and update the pointer.
|
||
// Set the flags to dirty the brushes since we changed the palette.
|
||
//
|
||
|
||
{
|
||
hdcNext = pal.hdcHead();
|
||
|
||
while (hdcNext != (HDC)0)
|
||
{
|
||
MDCOBJA dcoAltLock(hdcNext);
|
||
dcoAltLock.pdc->ppal(palOld.ppalGet());
|
||
dcoAltLock.ulDirty(dcoAltLock.ulDirty() | DIRTY_BRUSHES);
|
||
hdcNext = dcoAltLock.pdc->hdcNext();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
WARNING1("ResizePalette failed - ref count != 1\n");
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
WARNING1("ResizePalette failed lock of DC in chain\n");
|
||
}
|
||
|
||
//
|
||
// Unlock all the DC we have locked and return FALSE
|
||
//
|
||
|
||
{
|
||
hdcTemp = pal.hdcHead();
|
||
|
||
while (hdcTemp != hdcNext)
|
||
{
|
||
MDCOBJ dcoUnlock(hdcTemp);
|
||
ASSERTGDI(dcoUnlock.bLocked(), "ERROR couldn't re-lock to unlock");
|
||
DEC_EXCLUSIVE_REF_CNT(dcoUnlock.pdc);
|
||
hdcTemp = dcoUnlock.pdc->hdcNext();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
WARNING("GreResizePalette failed palette creation\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
WARNING("GreResizePalette failed invalid hpal\n");
|
||
}
|
||
|
||
return(bReturn);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreUpdateColors
|
||
*
|
||
* API function - Updates the colors in the Visible Region for a Window on
|
||
* a palette mangaged device.
|
||
*
|
||
* This is an example of how UpdateColors is used:
|
||
*
|
||
* case WM_PALETTECHANGED:
|
||
*
|
||
* // if NTPAL was not responsible for palette change and if
|
||
* // palette realization causes a palette change, do a redraw.
|
||
*
|
||
* if ((HWND)wParam != hWnd)
|
||
* {
|
||
* if (bLegitDraw)
|
||
* {
|
||
* hDC = GetDC(hWnd);
|
||
* hOldPal = SelectPalette(hDC, hpalCurrent, 0);
|
||
*
|
||
* i = RealizePalette(hDC);
|
||
*
|
||
* if (i)
|
||
* {
|
||
* if (bUpdateColors)
|
||
* {
|
||
* UpdateColors(hDC);
|
||
* UpdateCount++;
|
||
* }
|
||
* else
|
||
* InvalidateRect(hWnd, (LPRECT) (NULL), 1);
|
||
* }
|
||
*
|
||
* SelectPalette(hDC, hOldPal, 0);
|
||
* ReleaseDC(hWnd, hDC);
|
||
* }
|
||
* }
|
||
* break;
|
||
*
|
||
* The hpal can only be selected into 1 type of device DC at a time.
|
||
* Xlates from the DC palette to the surface palette are only done on DC's
|
||
* that are for the PDEV surface. Since an hpal can only be selected into
|
||
* one of these and creation and deletion of the pxlate needs to be semaphored
|
||
* we use the PDEV semaphore to protect it's access.
|
||
*
|
||
* An xlate vector mapping the DC palette to the surface palette is created
|
||
* during a RealizePalette if the surface is a palette managed device. This
|
||
* is put in pxlate in the hpal. The old pxlate is moved into pxlateOld
|
||
* and the xlate in pxlateOld is deleted. UpdateColors works by looking at
|
||
* the difference between the current xlate mapping and the old xlate mapping
|
||
* and updating the pixels in the VisRgn to get a closest mapping.
|
||
*
|
||
* This API can only be called once for a palette. The old xlate is deleted
|
||
* during UpdateColors so that the next time it is called it will fail. This
|
||
* is because it only makes sense to update the pixels once. Doing it more
|
||
* than once would give ugly unpredictable results.
|
||
*
|
||
* History:
|
||
* 12-Dec-1991 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
BOOL APIENTRY NtGdiUpdateColors(HDC hdc)
|
||
{
|
||
BOOL bReturn = FALSE;
|
||
|
||
DCOBJ dco(hdc);
|
||
|
||
if (!dco.bValidSurf())
|
||
{
|
||
return(FALSE);
|
||
}
|
||
|
||
PDEVOBJ pdo(dco.hdev());
|
||
|
||
//
|
||
// Grab DEVLOCK for output and to lock the surface
|
||
//
|
||
|
||
DEVLOCKOBJ dlo(dco);
|
||
|
||
if (pdo.bIsPalManaged())
|
||
{
|
||
SURFACE *pSurf = dco.pSurface();
|
||
|
||
//
|
||
// This only works on palette managed surfaces.
|
||
//
|
||
|
||
if (pSurf == pdo.pSurface())
|
||
{
|
||
XEPALOBJ palSurf(pSurf->ppal());
|
||
XEPALOBJ palDC(dco.ppal());
|
||
|
||
//
|
||
// Accumulate bounds. We can do this before knowing if the operation is
|
||
// successful because bounds can be loose.
|
||
//
|
||
|
||
if (dco.fjAccum())
|
||
dco.vAccumulate(dco.erclWindow());
|
||
|
||
if (dlo.bValid())
|
||
{
|
||
if ((palDC.ptransCurrent() != NULL) &&
|
||
(palDC.ptransOld() != NULL))
|
||
{
|
||
XLATEMEMOBJ xlo(palSurf, palDC);
|
||
|
||
if (xlo.bValid())
|
||
{
|
||
ECLIPOBJ co(dco.prgnEffRao(), dco.erclWindow());
|
||
|
||
//
|
||
// Check the destination which is reduced by clipping.
|
||
//
|
||
|
||
if (!co.erclExclude().bEmpty())
|
||
{
|
||
//
|
||
// Exclude the pointer.
|
||
//
|
||
|
||
DEVEXCLUDEOBJ dxo(dco,&co.erclExclude(),&co);
|
||
|
||
//
|
||
// Inc the target surface uniqueness
|
||
//
|
||
|
||
INC_SURF_UNIQ(pSurf);
|
||
|
||
if (!pdo.bMetaDriver())
|
||
{
|
||
//
|
||
// Dispatch the call. Give it no mask.
|
||
//
|
||
|
||
bReturn = (*PPFNGET(pdo, CopyBits, pSurf->flags())) (
|
||
pSurf->pSurfobj(),
|
||
pSurf->pSurfobj(),
|
||
&co,
|
||
xlo.pxlo(),
|
||
(RECTL *) &co.erclExclude(),
|
||
(POINTL *) &co.erclExclude());
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Dispatch to DDML.
|
||
//
|
||
|
||
bReturn = MulUpdateColors(
|
||
pSurf->pSurfobj(),
|
||
&co,
|
||
xlo.pxlo());
|
||
}
|
||
}
|
||
else
|
||
bReturn = TRUE;
|
||
}
|
||
}
|
||
else
|
||
bReturn = TRUE; // Nothing to update
|
||
}
|
||
else
|
||
{
|
||
bReturn = dco.bFullScreen();
|
||
}
|
||
}
|
||
}
|
||
|
||
return(bReturn);
|
||
}
|
||
|
||
|
||
/******************************Public*Routine******************************\
|
||
* RealizeDefaultPalette
|
||
*
|
||
* Take away colors that have been realized by other Windows. Reset it to
|
||
* state where no colors have been taken. Return number of colors
|
||
*
|
||
* History:
|
||
* 07-Jan-1993 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
extern "C"
|
||
ULONG GreRealizeDefaultPalette(
|
||
HDC hdcScreen,
|
||
BOOL bClearDefaultPalette)
|
||
{
|
||
|
||
DCOBJ dco(hdcScreen);
|
||
|
||
if (dco.bValid())
|
||
{
|
||
PDEVOBJ po(dco.hdev());
|
||
|
||
//
|
||
// Block out the GreRealizePalette code. Also protect us from
|
||
// dynamic mode changes while we grunge in the surface palette.
|
||
//
|
||
DEVLOCKOBJ dlo(po);
|
||
|
||
SEMOBJ semo(ghsemPalette);
|
||
|
||
if (po.bIsPalManaged())
|
||
{
|
||
XEPALOBJ palSurf(po.ppalSurf());
|
||
ASSERTGDI(palSurf.bIsPalManaged(), "GreRealizeDefaultPalette");
|
||
|
||
//
|
||
// Now map back to static colors if necesary. Win3.1 does not do this but we do
|
||
// just in case naughty app died and left the palette hosed.
|
||
//
|
||
//
|
||
if (palSurf.bIsNoStatic() || palSurf.bIsNoStatic256())
|
||
{
|
||
GreSetSystemPaletteUse(hdcScreen, SYSPAL_STATIC);
|
||
}
|
||
|
||
//
|
||
// Get rid of the PC_FOREGROUND flag from the non-reserved entries.
|
||
//
|
||
|
||
ULONG ulTemp = palSurf.ulNumReserved() >> 1;
|
||
ULONG ulMax = palSurf.cEntries() - ulTemp;
|
||
|
||
for (; ulTemp < ulMax; ulTemp++)
|
||
{
|
||
palSurf.apalColorGet()[ulTemp].pal.peFlags &= (~PC_FOREGROUND);
|
||
}
|
||
|
||
if (bClearDefaultPalette)
|
||
{
|
||
hForePalette = NULL;
|
||
}
|
||
|
||
palSurf.vUpdateTime();
|
||
|
||
//
|
||
// Mark the brushes dirty.
|
||
//
|
||
|
||
dco.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
WARNING("ERROR User called RealizeDefaultPalette with bad hdc\n");
|
||
}
|
||
|
||
//
|
||
// What should this return value be ?
|
||
//
|
||
|
||
return(0);
|
||
}
|
||
|
||
|
||
/******************************Public*Routine******************************\
|
||
* UnrealizeObject
|
||
*
|
||
* Resets a logical palette.
|
||
*
|
||
* History:
|
||
* 16-May-1993 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
BOOL GreUnrealizeObject(HANDLE hpal)
|
||
{
|
||
BOOL bReturn = FALSE;
|
||
|
||
EPALOBJ pal((HPALETTE) hpal);
|
||
|
||
if (pal.bValid())
|
||
{
|
||
|
||
//
|
||
// You must grab the palette semaphore to access the translates.
|
||
//
|
||
|
||
SEMOBJ semo(ghsemPalette);
|
||
|
||
if (pal.ptransFore() != NULL)
|
||
{
|
||
pal.ptransFore()->iUniq = 0;
|
||
}
|
||
|
||
if (pal.ptransCurrent() != NULL)
|
||
{
|
||
pal.ptransCurrent()->iUniq = 0;
|
||
}
|
||
|
||
bReturn = TRUE;
|
||
}
|
||
|
||
return(bReturn);
|
||
}
|
||
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreRealizePalette
|
||
*
|
||
* Re-written to be Win3.1 compatible.
|
||
*
|
||
* History:
|
||
* 22-Nov-1992 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
extern "C" DWORD GreRealizePalette(HDC hdc)
|
||
{
|
||
ULONG nTransChanged = 0;
|
||
ULONG nPhysChanged = 0;
|
||
|
||
DCOBJ dco(hdc);
|
||
|
||
if (dco.bValid())
|
||
{
|
||
PDEVOBJ po(dco.hdev());
|
||
|
||
//
|
||
// Lock the screen semaphore so that we don't get flipped into
|
||
// full screen after checking the bit. This also protects us
|
||
// from dynamic mode changes that change the 'bIsPalManaged'
|
||
// status.
|
||
//
|
||
|
||
DEVLOCKOBJ dlo(po);
|
||
|
||
XEPALOBJ palSurf(po.ppalSurf());
|
||
XEPALOBJ palDC(dco.ppal());
|
||
|
||
HPALETTE hpalDC = palDC.hpal();
|
||
HDC hdcNext, hdcTemp;
|
||
|
||
if (po.bIsPalManaged())
|
||
{
|
||
ASSERTGDI(palSurf.bIsPalManaged(), "GreRealizePalette");
|
||
|
||
//
|
||
// Access to the ptrans and the fields of the hpal are protected by
|
||
// this semaphore.
|
||
//
|
||
|
||
SEMOBJ semo(ghsemPalette);
|
||
|
||
if ((SAMEHANDLE(hpalDC,hForePalette)) ||
|
||
((dco.pdc->iGraphicsMode() == GM_COMPATIBLE) &&
|
||
(SAMEINDEX(hpalDC, hForePalette)) &&
|
||
(hForePID == W32GetCurrentProcess())))
|
||
{
|
||
//
|
||
// Check for early out.
|
||
//
|
||
|
||
if (palDC.bIsPalDefault())
|
||
{
|
||
//
|
||
// Do nothing.
|
||
//
|
||
|
||
PAL_DEBUG(2,"DC has default palette quick out\n");
|
||
|
||
}
|
||
else
|
||
{
|
||
if ((palDC.ptransFore() != NULL) &&
|
||
(palDC.ptransFore() == palDC.ptransCurrent()) &&
|
||
(palDC.ptransFore()->iUniq == palSurf.ulTime()))
|
||
{
|
||
//
|
||
// Everything is valid.
|
||
//
|
||
|
||
PAL_DEBUG(2,"ptransCurrent == ptransFore quick out\n");
|
||
}
|
||
else
|
||
{
|
||
MLOCKFAST mlo;
|
||
|
||
//
|
||
// Run down the list and exclusive lock all the handles.
|
||
//
|
||
|
||
{
|
||
hdcNext = palDC.hdcHead();
|
||
|
||
while (hdcNext != (HDC) 0)
|
||
{
|
||
MDCOBJ dcoLock(hdcNext);
|
||
|
||
if (!dcoLock.bLocked())
|
||
{
|
||
WARNING1("GreRealizePalette failed because a DC the hpal is in is busy\n");
|
||
break;
|
||
}
|
||
|
||
dcoLock.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
|
||
hdcNext = dcoLock.pdc->hdcNext();
|
||
dcoLock.vDontUnlockDC();
|
||
}
|
||
}
|
||
|
||
if (hdcNext == (HDC) 0)
|
||
{
|
||
//
|
||
// Get rid of the old mapping, it is useless now.
|
||
//
|
||
|
||
if (palDC.ptransOld())
|
||
{
|
||
if (palDC.ptransOld() != palDC.ptransFore())
|
||
VFREEMEM(palDC.ptransOld());
|
||
|
||
palDC.ptransOld(NULL);
|
||
}
|
||
|
||
//
|
||
// Check if we have stale translates.
|
||
// UnrealizeObject and SetPaletteEntries can cause it.
|
||
//
|
||
|
||
if ((palDC.ptransFore()) && (palDC.ptransFore()->iUniq == 0))
|
||
{
|
||
if (palDC.ptransCurrent() != palDC.ptransFore())
|
||
VFREEMEM(palDC.ptransFore());
|
||
|
||
palDC.ptransFore(NULL);
|
||
}
|
||
|
||
//
|
||
// Check if we need a new foreground realization.
|
||
//
|
||
|
||
if (palDC.ptransFore() == NULL)
|
||
{
|
||
//
|
||
// Need to force ourselves in for the first time.
|
||
//
|
||
|
||
PAL_DEBUG(2,"Creating a foreground realization\n");
|
||
|
||
palDC.ptransFore(ptransMatchAPal(dco.pdc,palSurf, palDC, TRUE, &nPhysChanged, &nTransChanged));
|
||
|
||
if (palDC.ptransFore() == NULL)
|
||
{
|
||
WARNING("RealizePalette failed initial foreground realize\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Foreground Realize already done and isn't stale.
|
||
// Force the foreground mapping into the physical palette.
|
||
//
|
||
|
||
PAL_DEBUG(2,"Forcing a foreground realization in to palette\n");
|
||
|
||
|
||
vMatchAPal(dco.pdc,palSurf, palDC, &nPhysChanged, &nTransChanged);
|
||
}
|
||
|
||
palDC.ptransOld(palDC.ptransCurrent());
|
||
palDC.ptransCurrent(palDC.ptransFore());
|
||
}
|
||
else
|
||
{
|
||
WARNING("GreRealizePalette failed to lock down all DC's in linked list\n");
|
||
}
|
||
|
||
//
|
||
// Unlock all the DC we have locked.
|
||
//
|
||
|
||
{
|
||
hdcTemp = palDC.hdcHead();
|
||
|
||
while (hdcTemp != hdcNext)
|
||
{
|
||
MDCOBJ dcoUnlock(hdcTemp);
|
||
ASSERTGDI(dcoUnlock.bLocked(), "ERROR couldn't re-lock to unlock");
|
||
DEC_EXCLUSIVE_REF_CNT(dcoUnlock.pdc);
|
||
hdcTemp = dcoUnlock.pdc->hdcNext();
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// We are a background palette.
|
||
//
|
||
|
||
if (!palDC.bIsPalDefault())
|
||
{
|
||
|
||
//
|
||
// Check for the quick out.
|
||
//
|
||
|
||
if ((palDC.ptransCurrent() != NULL) &&
|
||
(palDC.ptransCurrent()->iUniq == palSurf.ulTime()))
|
||
{
|
||
//
|
||
// Well it's good enough. Nothing has changed that
|
||
// would give us any better mapping.
|
||
//
|
||
|
||
PAL_DEBUG(2,"ptransCurrent not foreground but good enough\n");
|
||
}
|
||
else
|
||
{
|
||
MLOCKFAST mlo;
|
||
|
||
//
|
||
// Run down the list and exclusive lock all the handles.
|
||
//
|
||
|
||
{
|
||
hdcNext = palDC.hdcHead();
|
||
|
||
while (hdcNext != (HDC) 0)
|
||
{
|
||
MDCOBJ dcoLock(hdcNext);
|
||
|
||
if (!dcoLock.bLocked())
|
||
{
|
||
WARNING1("GreRealizePalette failed because a DC the hpal is in is busy\n");
|
||
break;
|
||
}
|
||
|
||
dcoLock.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
|
||
hdcNext = dcoLock.pdc->hdcNext();
|
||
dcoLock.vDontUnlockDC();
|
||
}
|
||
}
|
||
|
||
if (hdcNext == (HDC) 0)
|
||
{
|
||
//
|
||
// We have work to do, get rid of the old translate.
|
||
//
|
||
|
||
if (palDC.ptransOld())
|
||
{
|
||
if (palDC.ptransOld() != palDC.ptransFore())
|
||
VFREEMEM(palDC.ptransOld());
|
||
|
||
palDC.ptransOld(NULL);
|
||
}
|
||
|
||
//
|
||
// Check if we have stale translates.
|
||
// UnrealizeObject and SetPaletteEntries can cause it.
|
||
//
|
||
|
||
if ((palDC.ptransFore()) && (palDC.ptransFore()->iUniq == 0))
|
||
{
|
||
if (palDC.ptransCurrent() != palDC.ptransFore())
|
||
{
|
||
VFREEMEM(palDC.ptransFore());
|
||
}
|
||
|
||
palDC.ptransFore(NULL);
|
||
}
|
||
|
||
//
|
||
// Check for initial foreground realization.
|
||
//
|
||
|
||
PAL_DEBUG(2,"Realizing in the background\n");
|
||
|
||
if (palDC.ptransFore() == NULL)
|
||
{
|
||
//
|
||
// Create a scratch pad to establish a foreground realize.
|
||
//
|
||
|
||
PAL_DEBUG(2,"Making ptransFore in the background\n");
|
||
|
||
PALMEMOBJ palTemp;
|
||
|
||
if (palTemp.bCreatePalette(PAL_INDEXED,
|
||
palSurf.cEntries(),
|
||
NULL,
|
||
0, 0, 0, PAL_MANAGED))
|
||
{
|
||
ULONG ulTemp = 0;
|
||
ASSERTGDI(palTemp.cEntries() == 256, "ERROR palTemp invalid");
|
||
|
||
palTemp.vCopyEntriesFrom(palSurf);
|
||
palTemp.ulNumReserved(palSurf.ulNumReserved());
|
||
palTemp.flPalSet(palSurf.flPal());
|
||
palTemp.vComputeCallTables();
|
||
|
||
PAL_DEBUG(2,"Need to make a foreground realize first\n");
|
||
|
||
//
|
||
// Need to map ourselves for the first time. This actually doesn't
|
||
// change the current surface palette but instead computes the
|
||
// translate vector that would result if it was to be mapped in now.
|
||
//
|
||
|
||
palDC.ptransFore(ptransMatchAPal(dco.pdc,palTemp, palDC, TRUE, &ulTemp, &ulTemp));
|
||
}
|
||
|
||
#if DBG
|
||
if (palDC.ptransFore() == NULL)
|
||
{
|
||
WARNING("RealizePalette failed initial foreground realize\n");
|
||
}
|
||
#endif
|
||
}
|
||
|
||
//
|
||
// Save the Current mapping into Old.
|
||
//
|
||
|
||
palDC.ptransOld(palDC.ptransCurrent());
|
||
|
||
if (palDC.ptransFore() == NULL)
|
||
{
|
||
//
|
||
// The Current can't be set if the Fore
|
||
// is NULL so we're done.
|
||
//
|
||
|
||
palDC.ptransCurrent(NULL);
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Get the new Current mapping.
|
||
//
|
||
|
||
PAL_DEBUG(2,"Making ptransCurrent\n");
|
||
|
||
palDC.ptransCurrent(ptransMatchAPal(dco.pdc,palSurf, palDC, FALSE, &nPhysChanged, &nTransChanged));
|
||
|
||
if (palDC.ptransCurrent() == NULL)
|
||
{
|
||
//
|
||
// Well we can't have the foreground set
|
||
// and the current being NULL so just
|
||
// make it foreground for this memory
|
||
// failure case.
|
||
//
|
||
|
||
palDC.ptransCurrent(palDC.ptransFore());
|
||
WARNING("ptransCurrent failed allocation in RealizePalette");
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// Unlock all the DC we have locked.
|
||
//
|
||
|
||
{
|
||
hdcTemp = palDC.hdcHead();
|
||
|
||
while (hdcTemp != hdcNext)
|
||
{
|
||
MDCOBJ dcoUnlock(hdcTemp);
|
||
ASSERTGDI(dcoUnlock.bLocked(), "ERROR couldn't re-lock to unlock");
|
||
DEC_EXCLUSIVE_REF_CNT(dcoUnlock.pdc);
|
||
hdcTemp = dcoUnlock.pdc->hdcNext();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// Check if the device needs to be notified.
|
||
//
|
||
|
||
if (nPhysChanged)
|
||
{
|
||
//
|
||
// Lock the screen semaphore so that we don't get flipped into
|
||
// full screen after checking the bit.
|
||
//
|
||
|
||
GreAcquireSemaphoreEx(po.hsemDevLock(), SEMORDER_DEVLOCK, NULL);
|
||
GreEnterMonitoredSection(po.ppdev, WD_DEVLOCK);
|
||
|
||
{
|
||
SEMOBJ so(po.hsemPointer());
|
||
|
||
if (!po.bDisabled())
|
||
{
|
||
po.pfnSetPalette()(
|
||
po.dhpdevParent(),
|
||
(PALOBJ *) &palSurf,
|
||
0,
|
||
0,
|
||
palSurf.cEntries());
|
||
}
|
||
}
|
||
|
||
GreExitMonitoredSection(po.ppdev, WD_DEVLOCK);
|
||
GreReleaseSemaphoreEx(po.hsemDevLock());
|
||
|
||
//
|
||
// mark palsurf if it is a halftone palette
|
||
//
|
||
|
||
if (palSurf.cEntries() == 256)
|
||
{
|
||
ULONG ulIndex;
|
||
for (ulIndex=0;ulIndex<256;ulIndex++)
|
||
{
|
||
if (
|
||
(palSurf.ulEntryGet(ulIndex) & 0xffffff) !=
|
||
(aPalHalftone[ulIndex].ul & 0xffffff)
|
||
)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (ulIndex == 256)
|
||
{
|
||
palSurf.flPal(PAL_HT);
|
||
}
|
||
else
|
||
{
|
||
FLONG fl = palSurf.flPal();
|
||
fl &= ~PAL_HT;
|
||
palSurf.flPalSet(fl);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return(nTransChanged | (nPhysChanged << 16));
|
||
}
|
||
|
||
|
||
/******************************Public*Routine******************************\
|
||
* IsDCCurrentPalette
|
||
*
|
||
* Returns TRUE if the palette is the foreground palette.
|
||
*
|
||
* History:
|
||
* 18-May-1993 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
extern "C" BOOL IsDCCurrentPalette(HDC hdc)
|
||
{
|
||
BOOL bReturn = FALSE;
|
||
|
||
DCOBJ dco(hdc);
|
||
|
||
if (dco.bValid())
|
||
{
|
||
if ((SAMEHANDLE(dco.hpal(), (HPAL)hForePalette)) ||
|
||
((dco.pdc->iGraphicsMode() == GM_COMPATIBLE) &&
|
||
(SAMEINDEX(dco.hpal(), hForePalette)) &&
|
||
(hForePID == W32GetCurrentProcess())))
|
||
{
|
||
bReturn = TRUE;
|
||
}
|
||
}
|
||
|
||
return(bReturn);
|
||
}
|
||
|
||
|
||
|
||
/******************************Public*Routine******************************\
|
||
* GreSelectPalette
|
||
*
|
||
* API function for selecting palette into the DC.
|
||
*
|
||
* Returns previous hpal if successful, (HPALETTE) 0 for failure.
|
||
*
|
||
* History:
|
||
* 17-Nov-1990 -by- Patrick Haluptzok patrickh
|
||
* Wrote it.
|
||
\**************************************************************************/
|
||
|
||
extern "C"
|
||
HPALETTE GreSelectPalette(
|
||
HDC hdc,
|
||
HPALETTE hpalNew,
|
||
BOOL bForceBackground)
|
||
{
|
||
|
||
//
|
||
// The palette semaphore serializes access to the reference count and
|
||
// the linked list of DC's a palette is selected into. We don't want
|
||
// 2 people trying to select at the same time. We must hold this between
|
||
// the setting of the hsem and the incrementing of the reference count.
|
||
//
|
||
|
||
SEMOBJ semo(ghsemPalette);
|
||
|
||
//
|
||
// Validate and lock down the DC and new palette.
|
||
//
|
||
|
||
DCOBJ dco(hdc);
|
||
EPALOBJ palNew(hpalNew);
|
||
|
||
#if DBG
|
||
if (DbgPal >= 2)
|
||
{
|
||
DbgPrint("GreSelectPalette %p\n",palNew.ppalGet());
|
||
}
|
||
#endif
|
||
|
||
if ((!dco.bLocked()) ||
|
||
(!palNew.bValid())|| (!palNew.bIsPalDC()))
|
||
{
|
||
//
|
||
// Error code logged by failed lock.
|
||
//
|
||
|
||
WARNING1("GreSelectPalette failed, invalid palette or DC\n");
|
||
return((HPALETTE)NULL);
|
||
}
|
||
|
||
if (!bForceBackground)
|
||
{
|
||
hForePID = W32GetCurrentProcess();
|
||
hForePalette = hpalNew;
|
||
}
|
||
|
||
HPAL hpalOld = (HPAL) dco.hpal();
|
||
|
||
if (SAMEHANDLE(hpalOld,(HPAL)hpalNew))
|
||
{
|
||
return((HPALETTE)hpalOld);
|
||
}
|
||
|
||
PDEVOBJ po(dco.hdev());
|
||
XEPALOBJ palOld(dco.ppal());
|
||
|
||
//
|
||
// Check that we aren't trying to select the palette into a
|
||
// device incompatible with a type we are already selected into.
|
||
// We need to be able to translate from the DC hpal to the surface hpal
|
||
// to do Animate, ect. So we can only be selected into one
|
||
// surface with a PAL_MANAGED hpal because we only maintain one
|
||
// translate table in the DC hpal.
|
||
//
|
||
|
||
if (!palNew.bIsPalDefault())
|
||
{
|
||
if (!palNew.bSet_hdev(dco.hdev()))
|
||
{
|
||
WARNING("GreSelectPalette failed hsemDisplay check\n");
|
||
return((HPALETTE)NULL);
|
||
}
|
||
}
|
||
|
||
//
|
||
// Grab the multi-lock semaphore to run the DC link list.
|
||
//
|
||
|
||
MLOCKFAST mlo;
|
||
|
||
//
|
||
// Take care of the old hpal. Remove from linked list. Decrement cRef.
|
||
// Remove the hdc from the linked list of DC's associated with palette.
|
||
//
|
||
|
||
palOld.vRemoveFromList(dco);
|
||
|
||
//
|
||
// Set the new palette in so the old hpal is truly gone.
|
||
//
|
||
|
||
dco.pdc->hpal((HPAL)hpalNew);
|
||
dco.pdc->ppal(palNew.ppalGet());
|
||
dco.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
|
||
|
||
//
|
||
// Associate the palette with the bitmap for use when converting DDBs
|
||
// to DIBs for dynamic mode changes. We don't associate the default
|
||
// palette because the normal usage pattern is:
|
||
//
|
||
// hpalOld = SelectPalette(hdc, hpal);
|
||
// RealizePalette(hdc);
|
||
// BitBlt(hdc);
|
||
// SelectPalette(hdc, hpalOld);
|
||
//
|
||
|
||
if ((dco.bHasSurface()) && (!palNew.bIsPalDefault()))
|
||
{
|
||
dco.pSurface()->hpalHint(hpalNew);
|
||
}
|
||
|
||
//
|
||
// Take care of the new hpal.
|
||
//
|
||
|
||
palNew.vAddToList(dco);
|
||
|
||
return((HPALETTE)hpalOld);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* ulMagicFind - look for given magic color in default palette
|
||
*
|
||
* Arguments:
|
||
*
|
||
* clrMagic - COLORREF of color to search for
|
||
*
|
||
* Return Value:
|
||
*
|
||
* Index if found, 0xffffffff if not found.
|
||
*
|
||
* History:
|
||
*
|
||
* 15-Nov-1995 -by- Mark Enstrom [marke]
|
||
*
|
||
\**************************************************************************/
|
||
|
||
ULONG
|
||
ulMagicFind(
|
||
PALETTEENTRY peMagic
|
||
)
|
||
{
|
||
XEPALOBJ xePalDefault(ppalDefault);
|
||
return(xePalDefault.ulGetMatchFromPalentry(peMagic));
|
||
}
|
||
|
||
|
||
/******************************Public*Routine******************************\
|
||
* bSetMagicColor - set the specified magic color in both the device
|
||
* palette and the default palette
|
||
*
|
||
* Arguments:
|
||
*
|
||
* hdev - hdev
|
||
* Index - magic color index (8,9,246,247)
|
||
* palSurf - surface palette
|
||
* palDC - logical palette
|
||
* palColor - magic color
|
||
*
|
||
* Return Value:
|
||
*
|
||
* Status
|
||
*
|
||
* History:
|
||
*
|
||
* 15-Nov-1995 -by- Mark Enstrom [marke]
|
||
*
|
||
\**************************************************************************/
|
||
|
||
extern PPALETTE gppalHalftone;
|
||
|
||
BOOL
|
||
bSetMagicColor(
|
||
XEPALOBJ palSurf,
|
||
ULONG ulIndex,
|
||
PAL_ULONG PalEntry
|
||
)
|
||
{
|
||
BOOL bRet = FALSE;
|
||
|
||
ASSERTGDI(((ulIndex == 8) || (ulIndex == 9) || (ulIndex == 246) || (ulIndex == 247)),
|
||
"bSetMagicColor Error, wrong palette index");
|
||
|
||
//
|
||
// make sure there are 20 reserved entries, and the static
|
||
// colors are in use
|
||
//
|
||
|
||
if (
|
||
(palSurf.ulNumReserved() == 20) &&
|
||
(!palSurf.bIsNoStatic()) &&
|
||
(!palSurf.bIsNoStatic256())
|
||
)
|
||
{
|
||
//
|
||
// set the entrie in the surface palette
|
||
//
|
||
|
||
PalEntry.pal.peFlags = PC_FOREGROUND | PC_USED;
|
||
palSurf.ulEntrySet(ulIndex,PalEntry.ul);
|
||
|
||
//
|
||
// update the palette time stamp
|
||
//
|
||
|
||
palSurf.vUpdateTime();
|
||
|
||
//
|
||
// set colors in the defaukt halftone palette for multimon system
|
||
//
|
||
|
||
if (gppalHalftone)
|
||
{
|
||
XEPALOBJ palHalftone(gppalHalftone);
|
||
palHalftone.ulEntrySet(ulIndex,PalEntry.ul);
|
||
}
|
||
|
||
//
|
||
// offset to upper half of default palette if needed
|
||
//
|
||
|
||
if (ulIndex > 10)
|
||
{
|
||
ulIndex = ulIndex - 236;
|
||
}
|
||
|
||
PalEntry.pal.peFlags = 0;
|
||
|
||
//
|
||
// set colors in the default Logical palette.
|
||
//
|
||
|
||
logDefaultPal.palPalEntry[ulIndex] = PalEntry.pal;
|
||
|
||
//
|
||
// set colors in the default palette and default log palette
|
||
//
|
||
|
||
XEPALOBJ palDefault(ppalDefault);
|
||
palDefault.ulEntrySet(ulIndex,PalEntry.ul);
|
||
|
||
bRet = TRUE;
|
||
}
|
||
|
||
return(bRet);
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
* vResetSurfacePalette - copy the magic colors from the default palette
|
||
* to the surface palette, and call the driver to set the palette
|
||
*
|
||
* NOTE: The devlock and pointer semaphore must already be held!
|
||
*
|
||
* Arguments:
|
||
*
|
||
* po - PDEV object
|
||
* palSurf - surface palette
|
||
*
|
||
* Return Value:
|
||
*
|
||
* Status
|
||
*
|
||
* History:
|
||
*
|
||
* 21-Mar-1996 -by- J. Andrew Goossen [andrewgo]
|
||
*
|
||
\**************************************************************************/
|
||
|
||
VOID
|
||
vResetSurfacePalette(
|
||
HDEV hdev
|
||
)
|
||
{
|
||
PDEVOBJ po(hdev);
|
||
|
||
if (po.bIsPalManaged())
|
||
{
|
||
XEPALOBJ palSurf(po.ppalSurf());
|
||
|
||
ASSERTGDI(palSurf.bValid(), "Invalid surface palette");
|
||
|
||
if (
|
||
(palSurf.ulNumReserved() == 20) &&
|
||
(!palSurf.bIsNoStatic()) &&
|
||
(!palSurf.bIsNoStatic256())
|
||
)
|
||
{
|
||
PAL_ULONG PalEntry;
|
||
|
||
XEPALOBJ palDefault(ppalDefault);
|
||
|
||
//
|
||
// set the entries in the surface palette
|
||
//
|
||
|
||
PalEntry.pal = palDefault.palentryGet(8);
|
||
PalEntry.pal.peFlags = PC_FOREGROUND | PC_USED;
|
||
palSurf.ulEntrySet(8,PalEntry.ul);
|
||
|
||
PalEntry.pal = palDefault.palentryGet(9);
|
||
PalEntry.pal.peFlags = PC_FOREGROUND | PC_USED;
|
||
palSurf.ulEntrySet(9,PalEntry.ul);
|
||
|
||
PalEntry.pal = palDefault.palentryGet(246 - 236);
|
||
PalEntry.pal.peFlags = PC_FOREGROUND | PC_USED;
|
||
palSurf.ulEntrySet(246,PalEntry.ul);
|
||
|
||
PalEntry.pal = palDefault.palentryGet(247 - 236);
|
||
PalEntry.pal.peFlags = PC_FOREGROUND | PC_USED;
|
||
palSurf.ulEntrySet(247,PalEntry.ul);
|
||
}
|
||
|
||
if (!po.bDisabled())
|
||
{
|
||
(*PPFNDRV(po,SetPalette))(
|
||
po.dhpdev(),
|
||
(PALOBJ *) &palSurf,
|
||
0,
|
||
0,
|
||
palSurf.cEntries());
|
||
}
|
||
}
|
||
}
|
||
|
||
/******************************Public*Routine******************************\
|
||
*
|
||
* GreSetMagicColor win95 compatible: set surface and default palette
|
||
* "magic" entries. This changes the default palette,
|
||
* and will affect bitmaps that think they have the
|
||
* correct 20 default colors already...
|
||
*
|
||
* Arguments:
|
||
*
|
||
* hdc - DC, specifies device surface
|
||
* Index - magic index, 1 of 8,9,246,247
|
||
* peMagic - new color
|
||
*
|
||
* Return Value:
|
||
*
|
||
* Status
|
||
*
|
||
* History:
|
||
*
|
||
* 10-Nov-1995 -by- Mark Enstrom [marke]
|
||
*
|
||
\**************************************************************************/
|
||
|
||
BOOL
|
||
NtGdiSetMagicColors(
|
||
HDC hdc,
|
||
PALETTEENTRY peMagic,
|
||
ULONG Index
|
||
)
|
||
{
|
||
return(GreSetMagicColors(hdc,peMagic,Index));
|
||
}
|
||
|
||
BOOL
|
||
GreSetMagicColors(
|
||
HDC hdc,
|
||
PALETTEENTRY peMagic,
|
||
ULONG Index
|
||
)
|
||
{
|
||
DCOBJ dco(hdc);
|
||
BOOL bRet = FALSE;
|
||
BOOL bPaletteChange = FALSE;
|
||
BOOL bChildDriver = FALSE;
|
||
|
||
if (dco.bValid())
|
||
{
|
||
if (
|
||
(Index == 8) ||
|
||
(Index == 9) ||
|
||
(Index == 246) ||
|
||
(Index == 247)
|
||
)
|
||
{
|
||
PAL_ULONG PalEntry;
|
||
|
||
PalEntry.pal = peMagic;
|
||
|
||
//
|
||
// must be RGB or PALETTERGB
|
||
//
|
||
|
||
if (
|
||
((PalEntry.ul & 0xff000000) == 0) ||
|
||
((PalEntry.ul & 0xff000000) == 0x02000000)
|
||
)
|
||
{
|
||
PDEVOBJ po(dco.hdev());
|
||
BOOL bSetColor = FALSE;
|
||
|
||
//
|
||
// Lock the screen semaphore so that we don't get flipped into
|
||
// full screen after checking the bit. Plus it also protects
|
||
// us from a dynamic mode change, which can change the
|
||
// bIsPalManaged status.
|
||
//
|
||
|
||
DEVLOCKOBJ dlo(po);
|
||
|
||
if (po.bIsPalManaged())
|
||
{
|
||
bSetColor = TRUE;
|
||
}
|
||
else if (po.bMetaDriver())
|
||
{
|
||
//
|
||
// If this is meta-driver, check if there is any palette device
|
||
//
|
||
PVDEV pvdev = (VDEV*) po.dhpdev();
|
||
PDISPSURF pds = pvdev->pds;
|
||
LONG csurf = pvdev->cSurfaces;
|
||
do
|
||
{
|
||
po.vInit(pds->hdev);
|
||
if (po.bIsPalManaged())
|
||
{
|
||
bSetColor = TRUE;
|
||
bChildDriver = TRUE;
|
||
break;
|
||
}
|
||
pds = pds->pdsNext;
|
||
} while (--csurf);
|
||
}
|
||
|
||
if (bSetColor)
|
||
{
|
||
XEPALOBJ palSurf(po.ppalSurf());
|
||
|
||
//
|
||
// palette sem scope
|
||
//
|
||
|
||
{
|
||
SEMOBJ semPalette(ghsemPalette);
|
||
|
||
//
|
||
// look for color
|
||
//
|
||
|
||
ULONG ulMagicIndex = ulMagicFind(PalEntry.pal);
|
||
|
||
if (ulMagicIndex != 0xffffffff)
|
||
{
|
||
//
|
||
// found exact match
|
||
//
|
||
|
||
if (ulMagicIndex >= 10)
|
||
{
|
||
//
|
||
// the returned index must be adjusted for surface palette
|
||
//
|
||
|
||
ulMagicIndex += 236;
|
||
}
|
||
|
||
if (ulMagicIndex == Index)
|
||
{
|
||
if (bChildDriver)
|
||
{
|
||
// If this is child of meta driver, we still need to call
|
||
// driver to update palette. (in the ppalDefault, doesn't
|
||
// mean in the child surface palette).
|
||
//
|
||
// set magic color
|
||
//
|
||
|
||
bPaletteChange = bSetMagicColor(palSurf,Index,PalEntry);
|
||
bRet = bPaletteChange;
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// already set
|
||
//
|
||
|
||
bRet = TRUE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// make sure RGB is not a non-magic VGA color,
|
||
// if there is a match, it can only be a magic
|
||
// color
|
||
//
|
||
|
||
if (
|
||
(ulMagicIndex == 8) ||
|
||
(ulMagicIndex == 9) ||
|
||
(ulMagicIndex == 246) ||
|
||
(ulMagicIndex == 247)
|
||
)
|
||
{
|
||
//
|
||
// set magic color
|
||
//
|
||
|
||
bPaletteChange = bSetMagicColor(palSurf,Index,PalEntry);
|
||
bRet = bPaletteChange;
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// bad rgb, restore Index with
|
||
// default color
|
||
//
|
||
|
||
if (Index == 8)
|
||
{
|
||
PalEntry.ul = 0x00C0DCC0;
|
||
}
|
||
else if (Index == 9)
|
||
{
|
||
PalEntry.ul = 0x00F0CAA6;
|
||
}
|
||
else if (Index == 246)
|
||
{
|
||
PalEntry.ul = 0x00F0FBFF;
|
||
}
|
||
else
|
||
{
|
||
PalEntry.ul = 0x00A4A0A0;
|
||
}
|
||
|
||
bPaletteChange = bSetMagicColor(palSurf,Index,PalEntry);
|
||
bRet = FALSE;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// set magic color
|
||
//
|
||
|
||
bPaletteChange = bSetMagicColor(palSurf,Index,PalEntry);
|
||
bRet = bPaletteChange;
|
||
}
|
||
}
|
||
|
||
if (bPaletteChange)
|
||
{
|
||
SEMOBJ so(po.hsemPointer());
|
||
|
||
if (!po.bDisabled())
|
||
{
|
||
po.pfnSetPalette()(
|
||
po.dhpdevParent(),
|
||
(PALOBJ *) &palSurf,
|
||
0,
|
||
0,
|
||
palSurf.cEntries());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return(bRet);
|
||
}
|