gdi32: Allocate palette entries separately from the main GDI object.
This allows resizing the palette without changing the object pointer.
This commit is contained in:
parent
de831f334c
commit
a83c81b544
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue