death to warnings

svn path=/trunk/; revision=5368
This commit is contained in:
Royce Mitchell III 2003-08-01 16:08:14 +00:00
parent 81ef6d78bf
commit 63f62de42d
3 changed files with 115 additions and 99 deletions

View file

@ -13,15 +13,6 @@ typedef struct {
int max; int max;
} ColorShifts; } ColorShifts;
static ColorShifts PALETTE_PRed = {0,0,0};
static ColorShifts PALETTE_LRed = {0,0,0};
static ColorShifts PALETTE_PGreen = {0,0,0};
static ColorShifts PALETTE_LGreen = {0,0,0};
static ColorShifts PALETTE_PBlue = {0,0,0};
static ColorShifts PALETTE_LBlue = {0,0,0};
static int PALETTE_Graymax = 0;
static int palette_size;
HPALETTE FASTCALL PALETTE_Init (VOID); HPALETTE FASTCALL PALETTE_Init (VOID);
VOID FASTCALL PALETTE_ValidateFlags (PALETTEENTRY* lpPalE, INT size); VOID FASTCALL PALETTE_ValidateFlags (PALETTEENTRY* lpPalE, INT size);
INT STDCALL PALETTE_SetMapping(PPALOBJ palPtr, UINT uStart, UINT uNum, BOOL mapOnly); INT STDCALL PALETTE_SetMapping(PPALOBJ palPtr, UINT uStart, UINT uNum, BOOL mapOnly);

View file

@ -19,7 +19,7 @@
/* /*
* GDIOBJ.C - GDI object manipulation routines * GDIOBJ.C - GDI object manipulation routines
* *
* $Id: gdiobj.c,v 1.29 2003/06/20 16:26:53 ekohl Exp $ * $Id: gdiobj.c,v 1.30 2003/08/01 16:08:14 royce Exp $
* *
*/ */
@ -41,6 +41,9 @@
#define NDEBUG #define NDEBUG
#include <win32k/debug1.h> #include <win32k/debug1.h>
#define GDI_HANDLE2INDEX(h) (((WORD)(size_t)(h)) & 0xffff)
#define GDI_INDEX2HANDLE(i) ((HANDLE) (((size_t)(i))&0xffff) )
// GDI stock objects // GDI stock objects
static LOGBRUSH WhiteBrush = static LOGBRUSH WhiteBrush =
@ -81,44 +84,44 @@ static LOGFONTW OEMFixedFont =
/* Filler to make the location counter dword aligned again. This is necessary /* Filler to make the location counter dword aligned again. This is necessary
since (a) LOGFONT is packed, (b) gcc places initialised variables in the code since (a) LOGFONT is packed, (b) gcc places initialised variables in the code
segment, and (c) Solaris assembler is stupid. */ segment, and (c) Solaris assembler is stupid. */
static UINT align_OEMFixedFont = 1; //static UINT align_OEMFixedFont = 1;
static LOGFONTW AnsiFixedFont = static LOGFONTW AnsiFixedFont =
{ 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, { 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"" }; 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"" };
static UINT align_AnsiFixedFont = 1; //static UINT align_AnsiFixedFont = 1;
static LOGFONTW AnsiVarFont = static LOGFONTW AnsiVarFont =
{ 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, { 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif" }; 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif" };
static UINT align_AnsiVarFont = 1; //static UINT align_AnsiVarFont = 1;
static LOGFONTW SystemFont = static LOGFONTW SystemFont =
{ 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, { 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"System" }; 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"System" };
static UINT align_SystemFont = 1; //static UINT align_SystemFont = 1;
static LOGFONTW DeviceDefaultFont = static LOGFONTW DeviceDefaultFont =
{ 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, { 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"" }; 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"" };
static UINT align_DeviceDefaultFont = 1; //static UINT align_DeviceDefaultFont = 1;
static LOGFONTW SystemFixedFont = static LOGFONTW SystemFixedFont =
{ 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, { 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"" }; 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"" };
static UINT align_SystemFixedFont = 1; //static UINT align_SystemFixedFont = 1;
/* FIXME: Is this correct? */ /* FIXME: Is this correct? */
static LOGFONTW DefaultGuiFont = static LOGFONTW DefaultGuiFont =
{ 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, { 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif" }; 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif" };
static UINT align_DefaultGuiFont = 1; //static UINT align_DefaultGuiFont = 1;
static HGDIOBJ *StockObjects[NB_STOCK_OBJECTS]; // we dont assign these statically as WINE does because we might redesign static HGDIOBJ *StockObjects[NB_STOCK_OBJECTS]; // we dont assign these statically as WINE does because we might redesign
// the way handles work, so it's more dynamic now // the way handles work, so it's more dynamic now
@ -226,7 +229,7 @@ HGDIOBJ FASTCALL GDIOBJ_AllocObj(WORD Size, WORD Magic)
handleEntry->hProcessId = PsGetCurrentProcessId (); handleEntry->hProcessId = PsGetCurrentProcessId ();
handleEntry->pObject = newObject; handleEntry->pObject = newObject;
DPRINT("GDIOBJ_AllocObj: object handle %d\n", newObject->wTableIndex ); DPRINT("GDIOBJ_AllocObj: object handle %d\n", newObject->wTableIndex );
return (HGDIOBJ) newObject->wTableIndex; return GDI_INDEX2HANDLE(newObject->wTableIndex);
} }
/*! /*!
@ -250,7 +253,7 @@ BOOL STDCALL GDIOBJ_FreeObj(HGDIOBJ hObj, WORD Magic, DWORD Flag)
PGDIOBJ Obj; PGDIOBJ Obj;
BOOL bRet = TRUE; BOOL bRet = TRUE;
handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD)hObj & 0xffff); handleEntry = GDIOBJ_iGetHandleEntryForIndex ( GDI_HANDLE2INDEX(hObj) );
DPRINT("GDIOBJ_FreeObj: hObj: %d, magic: %x, handleEntry: %x\n", (WORD)hObj & 0xffff, Magic, handleEntry ); DPRINT("GDIOBJ_FreeObj: hObj: %d, magic: %x, handleEntry: %x\n", (WORD)hObj & 0xffff, Magic, handleEntry );
if (handleEntry == 0 || (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE ) if (handleEntry == 0 || (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE )
@ -328,20 +331,26 @@ BOOL STDCALL GDIOBJ_FreeObj(HGDIOBJ hObj, WORD Magic, DWORD Flag)
*/ */
PGDIOBJ FASTCALL GDIOBJ_LockObj( HGDIOBJ hObj, WORD Magic ) PGDIOBJ FASTCALL GDIOBJ_LockObj( HGDIOBJ hObj, WORD Magic )
{ {
PGDI_HANDLE_ENTRY handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD) hObj & 0xffff); PGDI_HANDLE_ENTRY handleEntry
= GDIOBJ_iGetHandleEntryForIndex ( GDI_HANDLE2INDEX(hObj) );
PGDIOBJHDR objectHeader; PGDIOBJHDR objectHeader;
DPRINT("GDIOBJ_LockObj: hObj: %d, magic: %x, \n handleEntry: %x, mag %x\n", hObj, Magic, handleEntry, handleEntry->wMagic); DPRINT("GDIOBJ_LockObj: hObj: %d, magic: %x, \n handleEntry: %x, mag %x\n", hObj, Magic, handleEntry, handleEntry->wMagic);
if (handleEntry == 0 || (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE ) if ( handleEntry == 0
|| (handleEntry->hProcessId != (HANDLE)0xFFFFFFFF && || (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE )
handleEntry->hProcessId != PsGetCurrentProcessId ())){ || (handleEntry->hProcessId != (HANDLE)0xFFFFFFFF
&& handleEntry->hProcessId != PsGetCurrentProcessId ()
)
)
{
DPRINT("GDIBOJ_LockObj failed for %d, magic: %d, reqMagic\n",(WORD) hObj & 0xffff, handleEntry->wMagic, Magic); DPRINT("GDIBOJ_LockObj failed for %d, magic: %d, reqMagic\n",(WORD) hObj & 0xffff, handleEntry->wMagic, Magic);
return NULL; return NULL;
} }
objectHeader = (PGDIOBJHDR) handleEntry->pObject; objectHeader = (PGDIOBJHDR) handleEntry->pObject;
ASSERT(objectHeader); ASSERT(objectHeader);
if( objectHeader->dwCount > 0 ){ if( objectHeader->dwCount > 0 )
{
DbgPrint("Caution! GDIOBJ_LockObj trying to lock object second time\n" ); DbgPrint("Caution! GDIOBJ_LockObj trying to lock object second time\n" );
DbgPrint("\t called from: %x\n", __builtin_return_address(0)); DbgPrint("\t called from: %x\n", __builtin_return_address(0));
} }
@ -399,13 +408,18 @@ BOOL FASTCALL GDIOBJ_LockMultipleObj( PGDIMULTILOCK pList, INT nObj )
*/ */
BOOL FASTCALL GDIOBJ_UnlockObj( HGDIOBJ hObj, WORD Magic ) BOOL FASTCALL GDIOBJ_UnlockObj( HGDIOBJ hObj, WORD Magic )
{ {
PGDI_HANDLE_ENTRY handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD) hObj & 0xffff); PGDI_HANDLE_ENTRY handleEntry
= GDIOBJ_iGetHandleEntryForIndex ( GDI_HANDLE2INDEX(hObj) );
PGDIOBJHDR objectHeader; PGDIOBJHDR objectHeader;
DPRINT("GDIOBJ_UnlockObj: hObj: %d, magic: %x, \n handleEntry: %x\n", hObj, Magic, handleEntry); DPRINT("GDIOBJ_UnlockObj: hObj: %d, magic: %x, \n handleEntry: %x\n", hObj, Magic, handleEntry);
if (handleEntry == 0 || (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE ) if ( handleEntry == 0
|| (handleEntry->hProcessId != (HANDLE)0xFFFFFFFF && || (handleEntry->wMagic != Magic && Magic != GO_MAGIC_DONTCARE )
handleEntry->hProcessId != PsGetCurrentProcessId ())){ || (handleEntry->hProcessId != (HANDLE)0xFFFFFFFF
&& handleEntry->hProcessId != PsGetCurrentProcessId ()
)
)
{
DPRINT( "GDIOBJ_UnLockObj: failed\n"); DPRINT( "GDIOBJ_UnLockObj: failed\n");
return FALSE; return FALSE;
} }
@ -414,7 +428,8 @@ BOOL FASTCALL GDIOBJ_UnlockObj( HGDIOBJ hObj, WORD Magic )
ASSERT(objectHeader); ASSERT(objectHeader);
ExAcquireFastMutex(&RefCountHandling); ExAcquireFastMutex(&RefCountHandling);
if( ( objectHeader->dwCount & ~0x80000000 ) == 0 ){ if( ( objectHeader->dwCount & ~0x80000000 ) == 0 )
{
ExReleaseFastMutex(&RefCountHandling); ExReleaseFastMutex(&RefCountHandling);
DPRINT( "GDIOBJ_UnLockObj: unlock object that is not locked\n" ); DPRINT( "GDIOBJ_UnLockObj: unlock object that is not locked\n" );
return FALSE; return FALSE;
@ -424,7 +439,8 @@ BOOL FASTCALL GDIOBJ_UnlockObj( HGDIOBJ hObj, WORD Magic )
ASSERT(objectHeader); ASSERT(objectHeader);
objectHeader->dwCount--; objectHeader->dwCount--;
if( objectHeader->dwCount == 0x80000000 ){ if( objectHeader->dwCount == 0x80000000 )
{
//delayed object release //delayed object release
objectHeader->dwCount = 0; objectHeader->dwCount = 0;
ExReleaseFastMutex(&RefCountHandling); ExReleaseFastMutex(&RefCountHandling);
@ -479,7 +495,7 @@ VOID FASTCALL GDIOBJ_MarkObjectGlobal(HGDIOBJ ObjectHandle)
if (ObjectHandle == NULL) if (ObjectHandle == NULL)
return; return;
handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD)ObjectHandle & 0xffff); handleEntry = GDIOBJ_iGetHandleEntryForIndex ( GDI_HANDLE2INDEX(ObjectHandle) );
if (handleEntry == 0) if (handleEntry == 0)
return; return;
@ -498,7 +514,7 @@ WORD FASTCALL GDIOBJ_GetHandleMagic (HGDIOBJ ObjectHandle)
if (ObjectHandle == NULL) if (ObjectHandle == NULL)
return 0; return 0;
handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD)ObjectHandle & 0xffff); handleEntry = GDIOBJ_iGetHandleEntryForIndex ( GDI_HANDLE2INDEX(ObjectHandle) );
if (handleEntry == 0 || if (handleEntry == 0 ||
(handleEntry->hProcessId != (HANDLE)0xFFFFFFFF && (handleEntry->hProcessId != (HANDLE)0xFFFFFFFF &&
handleEntry->hProcessId != PsGetCurrentProcessId ())) handleEntry->hProcessId != PsGetCurrentProcessId ()))
@ -550,17 +566,17 @@ VOID FASTCALL CreateStockObjects(void)
StockObjects[NULL_PEN] = W32kCreatePenIndirect(&NullPen); StockObjects[NULL_PEN] = W32kCreatePenIndirect(&NullPen);
GDIOBJ_MarkObjectGlobal(StockObjects[NULL_PEN]); GDIOBJ_MarkObjectGlobal(StockObjects[NULL_PEN]);
(void) TextIntCreateFontIndirect(&OEMFixedFont, &StockObjects[OEM_FIXED_FONT]); (void) TextIntCreateFontIndirect(&OEMFixedFont, (HFONT*)&StockObjects[OEM_FIXED_FONT]);
GDIOBJ_MarkObjectGlobal(StockObjects[OEM_FIXED_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[OEM_FIXED_FONT]);
(void) TextIntCreateFontIndirect(&AnsiFixedFont, &StockObjects[ANSI_FIXED_FONT]); (void) TextIntCreateFontIndirect(&AnsiFixedFont, (HFONT*)&StockObjects[ANSI_FIXED_FONT]);
GDIOBJ_MarkObjectGlobal(StockObjects[ANSI_FIXED_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[ANSI_FIXED_FONT]);
(void) TextIntCreateFontIndirect(&SystemFont, &StockObjects[SYSTEM_FONT]); (void) TextIntCreateFontIndirect(&SystemFont, (HFONT*)&StockObjects[SYSTEM_FONT]);
GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FONT]);
(void) TextIntCreateFontIndirect(&DeviceDefaultFont, &StockObjects[DEVICE_DEFAULT_FONT]); (void) TextIntCreateFontIndirect(&DeviceDefaultFont, (HFONT*)&StockObjects[DEVICE_DEFAULT_FONT]);
GDIOBJ_MarkObjectGlobal(StockObjects[DEVICE_DEFAULT_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[DEVICE_DEFAULT_FONT]);
(void) TextIntCreateFontIndirect(&SystemFixedFont, &StockObjects[SYSTEM_FIXED_FONT]); (void) TextIntCreateFontIndirect(&SystemFixedFont, (HFONT*)&StockObjects[SYSTEM_FIXED_FONT]);
GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FIXED_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FIXED_FONT]);
(void) TextIntCreateFontIndirect(&DefaultGuiFont, &StockObjects[DEFAULT_GUI_FONT]); (void) TextIntCreateFontIndirect(&DefaultGuiFont, (HFONT*)&StockObjects[DEFAULT_GUI_FONT]);
GDIOBJ_MarkObjectGlobal(StockObjects[DEFAULT_GUI_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[DEFAULT_GUI_FONT]);
StockObjects[DEFAULT_PALETTE] = (HGDIOBJ*)PALETTE_Init(); StockObjects[DEFAULT_PALETTE] = (HGDIOBJ*)PALETTE_Init();
@ -598,7 +614,7 @@ BOOL FASTCALL CleanupForProcess (struct _EPROCESS *Process, INT Pid)
DWORD i; DWORD i;
PGDI_HANDLE_ENTRY handleEntry; PGDI_HANDLE_ENTRY handleEntry;
PGDIOBJHDR objectHeader; PGDIOBJHDR objectHeader;
NTSTATUS Status; //NTSTATUS Status;
KeAttachProcess(Process); KeAttachProcess(Process);
@ -606,11 +622,11 @@ BOOL FASTCALL CleanupForProcess (struct _EPROCESS *Process, INT Pid)
{ {
handleEntry = GDIOBJ_iGetHandleEntryForIndex((WORD) i & 0xffff); handleEntry = GDIOBJ_iGetHandleEntryForIndex((WORD) i & 0xffff);
if (NULL != handleEntry && 0 != handleEntry->wMagic && if (NULL != handleEntry && 0 != handleEntry->wMagic &&
handleEntry->hProcessId == Pid) (INT)handleEntry->hProcessId == Pid)
{ {
objectHeader = (PGDIOBJHDR) handleEntry->pObject; objectHeader = (PGDIOBJHDR) handleEntry->pObject;
DPRINT("\nW32kCleanup: %d, magic: %x \n process: %d, locks: %d", i, handleEntry->wMagic, handleEntry->hProcessId, objectHeader->dwCount); DPRINT("\nW32kCleanup: %d, magic: %x \n process: %d, locks: %d", i, handleEntry->wMagic, handleEntry->hProcessId, objectHeader->dwCount);
GDIOBJ_FreeObj( (WORD) i & 0xffff, GO_MAGIC_DONTCARE, GDIOBJFLAG_IGNOREPID|GDIOBJFLAG_IGNORELOCK ); GDIOBJ_FreeObj( GDI_INDEX2HANDLE(i), GO_MAGIC_DONTCARE, GDIOBJFLAG_IGNOREPID|GDIOBJFLAG_IGNORELOCK );
} }
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: palette.c,v 1.8 2003/05/18 17:16:18 ea Exp $ */ /* $Id: palette.c,v 1.9 2003/08/01 16:08:14 royce Exp $ */
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
@ -31,6 +31,15 @@
static int PALETTE_firstFree = 0; static int PALETTE_firstFree = 0;
static unsigned char PALETTE_freeList[256]; static unsigned char PALETTE_freeList[256];
static ColorShifts PALETTE_PRed = {0,0,0};
//static ColorShifts PALETTE_LRed = {0,0,0};
static ColorShifts PALETTE_PGreen = {0,0,0};
//static ColorShifts PALETTE_LGreen = {0,0,0};
static ColorShifts PALETTE_PBlue = {0,0,0};
//static ColorShifts PALETTE_LBlue = {0,0,0};
static int PALETTE_Graymax = 0;
static int palette_size;
int PALETTE_PaletteFlags = 0; int PALETTE_PaletteFlags = 0;
PALETTEENTRY *COLOR_sysPal = NULL; PALETTEENTRY *COLOR_sysPal = NULL;
int COLOR_gapStart; int COLOR_gapStart;
@ -69,7 +78,7 @@ HPALETTE FASTCALL PALETTE_Init(VOID)
hpalette = W32kCreatePalette(palPtr); hpalette = W32kCreatePalette(palPtr);
ExFreePool(palPtr); ExFreePool(palPtr);
palObj = (PPALOBJ)AccessUserObject(hpalette); palObj = (PPALOBJ)AccessUserObject((ULONG)hpalette);
if (palObj) if (palObj)
{ {
if (!(palObj->mapping = ExAllocatePool(NonPagedPool, sizeof(int) * 20))) if (!(palObj->mapping = ExAllocatePool(NonPagedPool, sizeof(int) * 20)))
@ -133,7 +142,7 @@ UINT WINAPI GetNearestPaletteIndex(
HPALETTE hpalette, /* [in] Handle of logical color palette */ HPALETTE hpalette, /* [in] Handle of logical color palette */
COLORREF color) /* [in] Color to be matched */ COLORREF color) /* [in] Color to be matched */
{ {
PPALOBJ palObj = (PPALOBJ)AccessUserObject(hpalette); PPALOBJ palObj = (PPALOBJ)AccessUserObject((ULONG)hpalette);
UINT index = 0; UINT index = 0;
if( palObj ) if( palObj )
@ -278,7 +287,7 @@ INT FASTCALL PALETTE_ToPhysical (PDC dc, COLORREF color)
WORD index = 0; WORD index = 0;
HPALETTE hPal = (dc)? dc->w.hPalette: W32kGetStockObject(DEFAULT_PALETTE); HPALETTE hPal = (dc)? dc->w.hPalette: W32kGetStockObject(DEFAULT_PALETTE);
unsigned char spec_type = color >> 24; unsigned char spec_type = color >> 24;
PPALOBJ palPtr = (PPALOBJ)AccessUserObject(hPal); PPALOBJ palPtr = (PPALOBJ)AccessUserObject((ULONG)hPal);
/* palPtr can be NULL when DC is being destroyed */ /* palPtr can be NULL when DC is being destroyed */
if( !palPtr ) return 0; if( !palPtr ) return 0;