gdi32: Allocate palette entries separately from the main GDI object.

This allows resizing the palette without changing the object pointer.
oldstable
Alexandre Julliard 2009-01-28 19:02:17 +01:00
parent de831f334c
commit a83c81b544
1 changed files with 53 additions and 53 deletions

View File

@ -42,7 +42,9 @@ typedef struct tagPALETTEOBJ
{ {
GDIOBJHDR header; GDIOBJHDR header;
const DC_FUNCTIONS *funcs; /* DC function table */ const DC_FUNCTIONS *funcs; /* DC function table */
LOGPALETTE logpalette; /* _MUST_ be the last field */ WORD version; /* palette version */
WORD count; /* count of palette entries */
PALETTEENTRY *entries;
} PALETTEOBJ; } PALETTEOBJ;
static INT PALETTE_GetObject( HGDIOBJ handle, INT count, LPVOID buffer ); static INT PALETTE_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
@ -149,15 +151,22 @@ HPALETTE WINAPI CreatePalette(
size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY); size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
if (!(palettePtr = HeapAlloc( GetProcessHeap(), 0, if (!(palettePtr = HeapAlloc( GetProcessHeap(), 0, sizeof(*palettePtr) ))) return 0;
FIELD_OFFSET( PALETTEOBJ, logpalette.palPalEntry[palette->palNumEntries] )))) palettePtr->funcs = NULL;
return 0; palettePtr->version = palette->palVersion;
palettePtr->count = palette->palNumEntries;
memcpy( &palettePtr->logpalette, palette, size ); size = palettePtr->count * sizeof(*palettePtr->entries);
palettePtr->funcs = NULL; if (!(palettePtr->entries = HeapAlloc( GetProcessHeap(), 0, size )))
if (!(hpalette = alloc_gdi_handle( &palettePtr->header, OBJ_PAL, &palette_funcs ))) {
HeapFree( GetProcessHeap(), 0, palettePtr ); HeapFree( GetProcessHeap(), 0, palettePtr );
return 0;
}
memcpy( palettePtr->entries, palette->palPalEntry, size );
if (!(hpalette = alloc_gdi_handle( &palettePtr->header, OBJ_PAL, &palette_funcs )))
{
HeapFree( GetProcessHeap(), 0, palettePtr->entries );
HeapFree( GetProcessHeap(), 0, palettePtr );
}
TRACE(" returning %p\n", hpalette); TRACE(" returning %p\n", hpalette);
return hpalette; return hpalette;
} }
@ -286,22 +295,17 @@ UINT WINAPI GetPaletteEntries(
/* NOTE: not documented but test show this to be the case */ /* NOTE: not documented but test show this to be the case */
if (count == 0) if (count == 0)
{ {
int rc = palPtr->logpalette.palNumEntries; count = palPtr->count;
GDI_ReleaseObj( hpalette );
return rc;
} }
else
numEntries = palPtr->logpalette.palNumEntries;
if (start+count > numEntries) count = numEntries - start;
if (entries)
{ {
if (start >= numEntries) numEntries = palPtr->count;
{ if (start+count > numEntries) count = numEntries - start;
GDI_ReleaseObj( hpalette ); if (entries)
return 0; {
} if (start >= numEntries) count = 0;
memcpy( entries, &palPtr->logpalette.palPalEntry[start], else memcpy( entries, &palPtr->entries[start], count * sizeof(PALETTEENTRY) );
count * sizeof(PALETTEENTRY) ); }
} }
GDI_ReleaseObj( hpalette ); GDI_ReleaseObj( hpalette );
@ -333,17 +337,16 @@ UINT WINAPI SetPaletteEntries(
palPtr = GDI_GetObjPtr( hpalette, OBJ_PAL ); palPtr = GDI_GetObjPtr( hpalette, OBJ_PAL );
if (!palPtr) return 0; if (!palPtr) return 0;
numEntries = palPtr->logpalette.palNumEntries; numEntries = palPtr->count;
if (start >= numEntries) if (start >= numEntries)
{ {
GDI_ReleaseObj( hpalette ); GDI_ReleaseObj( hpalette );
return 0; return 0;
} }
if (start+count > numEntries) count = numEntries - start; if (start+count > numEntries) count = numEntries - start;
memcpy( &palPtr->logpalette.palPalEntry[start], entries, memcpy( &palPtr->entries[start], entries, count * sizeof(PALETTEENTRY) );
count * sizeof(PALETTEENTRY) );
UnrealizeObject( hpalette );
GDI_ReleaseObj( hpalette ); GDI_ReleaseObj( hpalette );
UnrealizeObject( hpalette );
return count; return count;
} }
@ -362,23 +365,20 @@ BOOL WINAPI ResizePalette(
UINT cEntries) /* [in] Number of entries in logical palette */ UINT cEntries) /* [in] Number of entries in logical palette */
{ {
PALETTEOBJ * palPtr = GDI_GetObjPtr( hPal, OBJ_PAL ); PALETTEOBJ * palPtr = GDI_GetObjPtr( hPal, OBJ_PAL );
UINT cPrevEnt, prevVer; PALETTEENTRY *entries;
int prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
TRACE("hpal = %p, prev = %i, new = %i\n",
hPal, palPtr ? palPtr->logpalette.palNumEntries : -1, cEntries );
if( !palPtr ) return FALSE; if( !palPtr ) return FALSE;
cPrevEnt = palPtr->logpalette.palNumEntries; TRACE("hpal = %p, prev = %i, new = %i\n", hPal, palPtr->count, cEntries );
prevVer = palPtr->logpalette.palVersion;
prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) +
sizeof(int*) + sizeof(GDIOBJHDR);
size += sizeof(int*) + sizeof(GDIOBJHDR);
if (!(palPtr = GDI_ReallocObject( size, hPal, palPtr ))) return FALSE; if (!(entries = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
palPtr->entries, cEntries * sizeof(*palPtr->entries) )))
{
GDI_ReleaseObj( hPal );
return FALSE;
}
palPtr->entries = entries;
palPtr->count = cEntries;
if( cEntries > cPrevEnt ) memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
palPtr->logpalette.palNumEntries = cEntries;
palPtr->logpalette.palVersion = prevVer;
GDI_ReleaseObj( hPal ); GDI_ReleaseObj( hPal );
PALETTE_UnrealizeObject( hPal ); PALETTE_UnrealizeObject( hPal );
return TRUE; return TRUE;
@ -410,11 +410,12 @@ BOOL WINAPI AnimatePalette(
PALETTEOBJ * palPtr; PALETTEOBJ * palPtr;
UINT pal_entries; UINT pal_entries;
const PALETTEENTRY *pptr = PaletteColors; const PALETTEENTRY *pptr = PaletteColors;
const DC_FUNCTIONS *funcs;
palPtr = GDI_GetObjPtr( hPal, OBJ_PAL ); palPtr = GDI_GetObjPtr( hPal, OBJ_PAL );
if (!palPtr) return 0; if (!palPtr) return 0;
pal_entries = palPtr->logpalette.palNumEntries; pal_entries = palPtr->count;
if (StartIndex >= pal_entries) if (StartIndex >= pal_entries)
{ {
GDI_ReleaseObj( hPal ); GDI_ReleaseObj( hPal );
@ -424,22 +425,20 @@ BOOL WINAPI AnimatePalette(
for (NumEntries += StartIndex; StartIndex < NumEntries; StartIndex++, pptr++) { for (NumEntries += StartIndex; StartIndex < NumEntries; StartIndex++, pptr++) {
/* According to MSDN, only animate PC_RESERVED colours */ /* According to MSDN, only animate PC_RESERVED colours */
if (palPtr->logpalette.palPalEntry[StartIndex].peFlags & PC_RESERVED) { if (palPtr->entries[StartIndex].peFlags & PC_RESERVED) {
TRACE("Animating colour (%d,%d,%d) to (%d,%d,%d)\n", TRACE("Animating colour (%d,%d,%d) to (%d,%d,%d)\n",
palPtr->logpalette.palPalEntry[StartIndex].peRed, palPtr->entries[StartIndex].peRed,
palPtr->logpalette.palPalEntry[StartIndex].peGreen, palPtr->entries[StartIndex].peGreen,
palPtr->logpalette.palPalEntry[StartIndex].peBlue, palPtr->entries[StartIndex].peBlue,
pptr->peRed, pptr->peGreen, pptr->peBlue); pptr->peRed, pptr->peGreen, pptr->peBlue);
memcpy( &palPtr->logpalette.palPalEntry[StartIndex], pptr, palPtr->entries[StartIndex] = *pptr;
sizeof(PALETTEENTRY) );
} else { } else {
TRACE("Not animating entry %d -- not PC_RESERVED\n", StartIndex); TRACE("Not animating entry %d -- not PC_RESERVED\n", StartIndex);
} }
} }
if (palPtr->funcs && palPtr->funcs->pRealizePalette) funcs = palPtr->funcs;
palPtr->funcs->pRealizePalette( NULL, hPal, hPal == hPrimaryPalette );
GDI_ReleaseObj( hPal ); GDI_ReleaseObj( hPal );
if (funcs && funcs->pRealizePalette) funcs->pRealizePalette( NULL, hPal, hPal == hPrimaryPalette );
} }
return TRUE; return TRUE;
} }
@ -545,9 +544,9 @@ UINT WINAPI GetNearestPaletteIndex(
{ {
int i, diff = 0x7fffffff; int i, diff = 0x7fffffff;
int r,g,b; int r,g,b;
PALETTEENTRY* entry = palObj->logpalette.palPalEntry; PALETTEENTRY* entry = palObj->entries;
for( i = 0; i < palObj->logpalette.palNumEntries && diff ; i++, entry++) for( i = 0; i < palObj->count && diff ; i++, entry++)
{ {
r = entry->peRed - GetRValue(color); r = entry->peRed - GetRValue(color);
g = entry->peGreen - GetGValue(color); g = entry->peGreen - GetGValue(color);
@ -641,7 +640,7 @@ static INT PALETTE_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
if (buffer) if (buffer)
{ {
if (count > sizeof(WORD)) count = sizeof(WORD); if (count > sizeof(WORD)) count = sizeof(WORD);
memcpy( buffer, &palette->logpalette.palNumEntries, count ); memcpy( buffer, &palette->count, count );
} }
else count = sizeof(WORD); else count = sizeof(WORD);
GDI_ReleaseObj( handle ); GDI_ReleaseObj( handle );
@ -680,6 +679,7 @@ static BOOL PALETTE_DeleteObject( HGDIOBJ handle )
PALETTE_UnrealizeObject( handle ); PALETTE_UnrealizeObject( handle );
if (!(obj = free_gdi_handle( handle ))) return FALSE; if (!(obj = free_gdi_handle( handle ))) return FALSE;
HeapFree( GetProcessHeap(), 0, obj->entries );
return HeapFree( GetProcessHeap(), 0, obj ); return HeapFree( GetProcessHeap(), 0, obj );
} }