wine/objects/palette.c
Alexandre Julliard d30dfd24d6 Release 980927
Sun Sep 27 14:25:38 1998  Petter Reinholdtsen <pere@td.org.uit.no>

	* [files/drive.c]
	Make sure GetDriveType32A() handles param NULL.  Added some
	doc on function.

Sun Sep 27 14:07:26 1998  Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>

	* [controls/edit.c] [windows/win.c]
	Don't call SetWindowLong() in EDIT_WM_NCREATE.
	Fix SetWindowLong(GWL_[EX]STYLE) to work for 16bit windows. Remove
	UpdateWindow() call. 

Sun Sep 27 13:41:22 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [scheduler/*.c] [server/event.c] [server/mutex.c]
	  [server/semaphore.c]
	Implemented server-side synchronisation objects.

Sun Sep 27 01:13:35 1998  Alex Priem <alexp@sci.kun.nl>

	* [dlls/comctl32/treeview.c] [include/treeview.h] [include/comctl.h]
	Treeview implementation.

	* [dlls/comctl32/trackbar.c] [include/trackbar.h] 
	Trackbar implementation.

Sat Sep 26 20:49:13 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>

	* [if1632/thunk.c] [tools/build.c] [win32/kernel32.c]
	Bugfix: several problems with flat thunks fixed.

	* [memory/selector.c]
	Bugfix: IsBad...Ptr16 didn't work for limit_in_pages segments.

	* [scheduler/thread.c]
	Bugfix: CreateThread: Allow id parameter == NULL.

	* [objects/gdiobj.c]
	Bugfix: IsGDIObject: Return correct object type for stock objects.

	* [msdos/dpmi.c]
	Bugfix: fixed typo in INT_DoRealModeInt.

	* [msdos/int21.c]
	Bugfix: int21 READ *must* use WIN16_hread, not _hread16.

	* [if1632/kernel.spec] [if1632/dummy.c] [if1632/thunk.c]
	  [loader/ne/module.c] [scheduler/event.c] [scheduler/synchro.c]
	  [scheduler/thread.c] [win32/kernel32.c] [win32/ordinals.c]
	Added names/stubs for all undocumented KERNEL routines (Win95).
	Added the following undoc. 16-bit equivalents to Win32 routines:
	KERNEL.441-443,449-453,456-462,471-476,479-486,488.
	Added stubs for some other KERNEL routines.

	* [memory/heap.c] [memory/global.c] [include/global.h]
	Implemented Local32... 32-bit local heap routines (KERNEL.208-215, 229).

	* [miscemu/instr.c] [loader/module.c] [include/module.h]
	Implemented __GP fault handling and HasGPHandler (KERNEL.338).

	* [misc/error.c]
	Implemented LogParamErrorRegs (KERNEL.327).

	* [loader/task.c] [include/windows.h]
	Implemented GetCodeInfo (KERNEL.104).

	* [loader/task.c] [scheduler/thread.c] [include/thread.h]
	Implemented [GS]etThreadQueue and [GS]etFastQueue (KERNEL.463/4, 624/5).

	* [if1632/gdi.spec] [objects/dc.c] [objects/dib.c]
	  [objects/bitmap.c] [include/windows.h]
	Bugfix: fixed wrong parameter for CreateDIBSection16.
	Added [GS]etDIBColorTable16, stub for GetBoundsRect16.
	Partially implemented BITMAP_GetObject16 for DIBs.

	* [if1632/gdi.spec] [relay32/gdi32.spec] [objects/palette.c]
	Added some GDI stubs.

	* [if1632/Makefile.in] [if1632/display.spec] [if1632/mouse.spec]
	  [if1632/keyboard.spec] [if1632/builtin.c] [windows/keyboard.c]
	Added some stubs for Win16 drivers: KEYBOARD, MOUSE, DISPLAY.

	* [if1632/wprocs.spec] [msdos/vxd.c]
	Added some stubs for VxDs: VMM, ConfigMG, TimerAPI.

	* [msdos/int2f.c]
	Added some stubs for real-mode network drivers.

Sat Sep 26 18:18:18 1998  Marcus Meissner <marcus@jet.franken.de>

	* [configure.in]
	Merged in some more of the FreeBSD ports/emulators/wine patches. 
	(Maintainer(s) of this port: You can just submit these
	patches to Alexandre directly.)

	 * [loader/pe_image.c]
	Check filesize of image against size derived from header
	to spot truncated executeables without crashing.

	* [files/directory.c]
	Set envvar "COMSPEC". One win32(!!) program crashes without it.

	* [multimedia/mmio.c]
	Added mmioSetInfo32.

	* [include/file.h]
	Return STD_ERROR_HANDLE for AUX and PRT dos handles.

	* [loader/module.c]
	Handle executeables with spaces in their names a bit better in
	CreateProcess.

	* [relay32/msvfw32.spec][if1632/msvideo.spec][multimedia/msvideo.c][include/vfw.h]
	Started on MS Video support (can load Win32 ICMs).

	* [tools/testrun]
	A bit smarter use of ps.

	* [memory/virtual.c]
	Report PAGE_GUARDed pages as PAGE_PROTECTED (AutoCAD LT R17 fails
	without that check (since Win95 doesn't know about PAGE_GUARD)).

Sat Sep 26 15:04:05 1998  Ove Kaaven <ovek@arcticnet.no>

	* [include/miscemu.h] [if1632/builtin.c] [loader/task.c]
	  [miscemu/instr.c] [msdos/dpmi.c] [msdos/int21.c]
	  [msdos/interrupts.c] [windows/user.c]
	INT_[S|G]etHandler was renamed to INT_[S|G]etPMHandler.
	Added handlers to deal with real-mode interrupts; DOS
	programs are now able to hook real-mode interrupts.

	* [loader/dos/module.c] [msdos/dosmem.c] [msdos/int21.c]
	Moved real-mode interrupt table initialization to
	msdos/dosmem.c, and made new V86 tasks get a full copy
	of the existing "system memory" instead of almost empty
	space. Misc fixes.

	* [include/dosexe.h] [loader/dos/module.c] [msdos/dpmi.c]
	  [msdos/int2f.c]
	First shot at letting DOS programs start up DPMI (but DPMI
	is still disabled for DOS programs, for pkunzip's sake).

	* [include/debugger.h] [debugger/break.c] [debugger/dbg.y]
	  [debugger/registers.c] [debugger/memory.c] [debugger/info.c]
	  [loader/dos/dosvm.c]
	First shot at making Wine's debugger work for DOS programs.
	The -debug flag works, as do "nexti" and "stepi".

Sat Sep 26 13:13:13 1998  Juergen Schmied <juergen.schmied@metronet.de>

	* [dlls/shell32/dataobject.c]
	New classes IEnumFORMATETC implemented, IDataObject stubs.
	
	* [dlls/shell32/*.*][relay32/shell32.spec]
	Bugfixes.
	New: ICM_InsertItem(), ILCreateFromPath().
	Implemented: ILCloneFirst().
	Stubs: ILIsEqual(), ILFindChild(), SHLogILFromFSIL(),
	  PathMatchSpec(), PathIsExe().
	Changed: ILGetSize(), _ILIsDesktop(), PathCombine().

	* [include/shlobj.h]
	New SHLGUID's
	New structures: DVTARGETDEVICE32, STGMEDIUM32, FORMATETC32,
	CLIPFORMAT32.
	New interfaces: IEnumFORMATETC, IDataObject, ICommDlgBrowser
	IDockingWindowFrame, IServiceProvider.

	* [dlls/shell32/folders.c]
	Stubs for IShellLink.

	* [loader/resource.c]
	Small fixes.

	* [misc/crtdll.c][relay32/crtdll.spec]
	New __dllonexit().

	* [windows/message.c]
	SendNotifyMessageA, SendMessageCallBack32A half implemented.

	* [controls/edit.c]
	EDIT_WM_SetText set EF_UPDATE flag not for ES_MULTILINE.

	* [files/file.c]
	Handling of fileposition fixed.

Fri Sep 25 18:13:30 1998  Patrik Stridvall <ps@leissner.se>

	* [include/windows.h] [include/wintypes.h]
	  [ole/ole2nls.h] [relay32/kernel32.spec]
	Implemented EnumDateFormats and EnumTimeFormats.
	Only adds US English support.

	* [Makefile.in] [configure.in] 
	  [dlls/Makefile.in] [dlls/psapi/Makefile.in] 
	  [dlls/psapi/psapi_main.c] 
	New files to implement stubs for PSAPI.DLL (NT only).

	* [relay32/Makefile.in] [relay32/builtin32.c] 
	  [relay32/psapi.spec]
	New spec file for PSAPI.DLL (NT only).

	* [scheduler/handle.c]
	HANDLE_GetObjPtr should only interpret the pseudo handles as the
	current thread or the current process if a thread or a process is
	requested.

	* [include/winversion.h] [misc/version.c]
	Adds the global function VERSION_GetVersion() so functions can
	have different behavior depending on the -winver flag.

	* [include/oledlg.h] [ole/oledlg.c]
	Minor fixes. 

	* [windows/winproc.c]
	Minor changes.

	* [include/imm.h] [misc/imm.c]
	Now returns correct values under both Windows 95 and NT 4.0.

Thu Sep 24 22:11:44 1998  Kristian Nielsen  <kristian.nielsen@risoe.dk>

	* [configure.in] [include/acconfig.h] [include/thread.h]
	  [scheduler/sysdeps.c]
	Autoconfig test for non-reentrant libc.

Wed Sep 23 19:52:12 1998  Matthew Becker <mbecker@glasscity.net>

	* [*/*.c]
	Miscellaneous documentation updates and debugging output 
	standardizations.

	* [objects/clipping.c]
	Added ExtSelectClipRgn.

Wed Sep 23 00:03:28 EDT 1998  Pete Ratzlaff <pratzlaff@cfa.harvard.edu>

	* [include/windows.h] [if1632/user.spec] [relay32/user32.spec]
	  [windows/keyboard.c]
	Added, marginally implemented, GetKeyboardLayoutName().
	Only returns US English keyboard name.

Tue Sep 22 16:32:41 1998  Marcel Baur <mbaur@iiic.ethz.ch>

	* [programs/control/*]
	New Winelib application.

Mon Sep 21 00:29:18 1998  Peter Hunnisett <hunnise@nortel.ca>

	* [include/dplay.h][multimedia/dplay.c][ole/compobj.c]
	Added all DirectPlayLobby interfaces and enhanced DirectPlay
	and DirectPlayLobby support. Still not all that much. Useful
	enough if you just need to start a program, don't try any
	real dplay/lobby stuff.

	* [documentation/status/directplay]
	Added a very little bit.

	* [graphics/ddraw.c]
	- Call to SetWindowLong32A wasn't working because there was no
	  memory set aside when the window class was registered.
	- Fixed some xlib reference counting and change the behaviour
	  of DirectDrawSurface3_SetPalette to mimic observed behaviour
	  (palette is associated will all backbuffers)
	- Also stored all palette colour fields and spit back our saved
	  colour fields rather than query X for them.
	- Added plenty of AddRef and Release traces.
	- Added Xlib support for using -desktop option.
	- Fixed Xlib message handling. Messages weren't being passed to
	  the application. Fixes mouse movements in some xlib DDraw games.
	- Added a few stubs.

	* [windows/win.c][include/winerror.h]
	Fixed up some error handling in WIN_SetWindowLong. SetLastError
	wasn't being used. Could cause problems with 0 return codes.
	Added new error in winerror (1400).

	* [AUTHORS] [include/authors.h]
	Added myself as a Wine author.

Sun Sep 20 21:22:44 1998  Alexander Larsson  <alla@lysator.liu.se>

	* [loader/module.c]
	Changed GetModuleFileName32A so that is returns the
	long version of the filename. Note that just the name
	is long, not the directories.

Sat Sep 19 20:05:30 1998 Per Ångström <pang@mind.nu> 

	* [controls/menu.c]
	Made a couple of fixes to make life easier for applications that alter
	their menus at runtime.

	* [windows/defdlg.c]
	Removed the cast of the return value from dialog procedures to a 16-bit
	bool. The return value needs to retain all its 32 bits, since it is not 
	always a bool, such as when responding to the WM_NCHITTEST message.

Fri Sep 18 11:30:38 1998  Sergey Turchanov <turchanov@usa.net>

	* [loader/resource.c]
	Fixed very funny bug (though gravely affecting further excecution)
	with FindResource[Ex]32 functions.

	* [include/multimon.h] [windows/multimon.c] [relay32/user32.spec]
	  [include/windows.h] [windows/sysmetrics.c]
	Default implementation for Multimonitor API.

	* [include/windows.h] [windows/winpos.c]
	Fixed incorrect declaration (and behaviour) of GetWindowRect32.

Wed Sep 16 10:21:15 1998  Gerard Patel <G.Patel@Wanadoo.fr>

	* [controls/edit.c]
	Fixed EDIT_EM_GetLine to use correctly length of lines.

Tue Sep 15 20:40:16 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>

	* [misc/tweak.c][include/tweak.h][controls/menu.c]
	Replaced the tweak graphic routines by calls to DrawEdge32().

	* [misc/tweak.c][include/tweak.h][documentation/win95look]
	  [wine.ini][*/*]
	Changed "look and feel" selection. Allows Win3.1, Win95 and
	Win98 (no GUI code implemented) look and feel.

	* [dlls/comctl32/header.c][include/header.h][include/commctrl.h]
	Started callback item support and did some minor improvements.

	* [dlls/comctl32/imagelist.c]
	Fixed bug in transparent image display.
	ImageList_GetIcon is still buggy :-(

	* [dlls/comctl32/toolbar.c]
	Fixed button drawing (partial hack).

	* [dlls/comctl32/commctrl.c]
	Fixed MenuHelp().

	* [controls/button.c]
	Added 3d effect for groupbox.

	* [windows/msgbox.c]
	Added font support for message boxes.

	* [windows/nonclient.c]
	Fixed window moving bug.

	* [dlls/comctl32/*.c]
	Various improvements.

	* [dlls/comctl32/listview.c][dlls/comctl32/rebar.c]
	  [include/commctrl.h]
	More messages.

	* [windows/syscolor.c][include/windows.h]
	Introduced new Win98 system colors.

Tue Sep 15 18:29:45 1998 Wesley Filardo <eightknots@aol.com>

	* [files/profile.c]
	Added support in PROFILE_LoadWineIni for -config option

	* [misc/main.c] [include/options.h]
	Added -config option.

Tue Sep 15 18:22:26 1998  Petter Reinholdtsen <pere@td.org.uit.no>

	* [documentation/Makefile.in]
	Make sure directory exists before installing into it.

Tue Sep 15 01:47:33 1998  Pablo Saratxaga <pablo.sarachaga@ping.be>

	* [ole/nls/*] [ole/ole2nls.c] [include/winnls.h]
	Fixed a few errors and completed some NLS files.

Mon Sep 14 01:23:45 1998  Joseph Pranevich <knight@baltimore.wwaves.com>

	* [include/miscemu.h] [msdos/interrupts.c]
	Removed a compilation warning, added INT 25 to the list of interrupts
	callable from DOS applications, added a debug message when unsupported
	interrupts are used.

Sun Sep 13 19:55:22 1998  Lawson Whitney <lawson_whitney@juno.com>

	* [if1632/relay.c]
	CallProcEx32W should not reverse arguments.

Sun Aug 17 21:18:12 1998  Eric Pouech  <eric.pouech@lemel.fr>

	* [multimedia/midi.c] [multimedia/init.c] [multimedia/mmsys.c] 
	  [include/multimedia.h] [include/mmsystem.h] 
	  [multimedia/Makefile.in] [multimedia/midipatch.c]
	  [if1632/multimedia.spec]
	Made MIDI input and output functional on OSS capable systems.

	* [multimedia/timer.c]
	Changes to trigger callbacks at the accurate pace even when
	fake timers are used.
1998-09-27 18:28:36 +00:00

794 lines
23 KiB
C

/*
* GDI palette objects
*
* Copyright 1993,1994 Alexandre Julliard
* Copyright 1996 Alex Korobka
*
* PALETTEOBJ is documented in the Dr. Dobbs Journal May 1993.
* Information in the "Undocumented Windows" is incorrect.
*/
#include <stdlib.h>
#include <string.h>
#include "ts_xlib.h"
#include "gdi.h"
#include "color.h"
#include "palette.h"
#include "xmalloc.h"
#include "debug.h"
FARPROC32 pfnSelectPalette = NULL;
FARPROC32 pfnRealizePalette = NULL;
static UINT32 SystemPaletteUse = SYSPAL_STATIC; /* currently not considered */
static HPALETTE16 hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
static HPALETTE16 hLastRealizedPalette = 0; /* UnrealizeObject() needs it */
/***********************************************************************
* PALETTE_Init
*
* Create the system palette.
*/
HPALETTE16 PALETTE_Init(void)
{
int i;
HPALETTE16 hpalette;
LOGPALETTE * palPtr;
PALETTEOBJ* palObj;
const PALETTEENTRY* __sysPalTemplate = COLOR_GetSystemPaletteTemplate();
/* create default palette (20 system colors) */
palPtr = HeapAlloc( GetProcessHeap(), 0,
sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY));
if (!palPtr) return FALSE;
palPtr->palVersion = 0x300;
palPtr->palNumEntries = NB_RESERVED_COLORS;
for( i = 0; i < NB_RESERVED_COLORS; i ++ )
{
palPtr->palPalEntry[i].peRed = __sysPalTemplate[i].peRed;
palPtr->palPalEntry[i].peGreen = __sysPalTemplate[i].peGreen;
palPtr->palPalEntry[i].peBlue = __sysPalTemplate[i].peBlue;
palPtr->palPalEntry[i].peFlags = 0;
}
hpalette = CreatePalette16( palPtr );
palObj = (PALETTEOBJ*) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
palObj->mapping = xmalloc( sizeof(int) * 20 );
GDI_HEAP_UNLOCK( hpalette );
HeapFree( GetProcessHeap(), 0, palPtr );
return hpalette;
}
/***********************************************************************
* PALETTE_ValidateFlags
*/
void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size)
{
int i = 0;
for( ; i<size ; i++ )
lpPalE[i].peFlags = PC_SYS_USED | (lpPalE[i].peFlags & 0x07);
}
/***********************************************************************
* CreatePalette16 (GDI.360)
*/
HPALETTE16 WINAPI CreatePalette16( const LOGPALETTE* palette )
{
return CreatePalette32( palette );
}
/***********************************************************************
* CreatePalette32 [GDI32.53] Creates a logical color palette
*
* RETURNS
* Success: Handle to logical palette
* Failure: NULL
*/
HPALETTE32 WINAPI CreatePalette32(
const LOGPALETTE* palette) /* [in] Pointer to logical color palette */
{
PALETTEOBJ * palettePtr;
HPALETTE32 hpalette;
int size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
TRACE(palette,"entries=%i\n", palette->palNumEntries);
hpalette = GDI_AllocObject( size + sizeof(int*) +sizeof(GDIOBJHDR) , PALETTE_MAGIC );
if (!hpalette) return 0;
palettePtr = (PALETTEOBJ *) GDI_HEAP_LOCK( hpalette );
memcpy( &palettePtr->logpalette, palette, size );
PALETTE_ValidateFlags(palettePtr->logpalette.palPalEntry,
palettePtr->logpalette.palNumEntries);
palettePtr->mapping = NULL;
GDI_HEAP_UNLOCK( hpalette );
TRACE(palette," returning %04x\n", hpalette);
return hpalette;
}
/***********************************************************************
* CreateHalftonePalette [GDI32.47] Creates a halftone palette
*
* RETURNS
* Success: Handle to logical halftone palette
* Failure: 0
*/
HPALETTE32 WINAPI CreateHalftonePalette(
HDC32 hdc) /* [in] Handle to device context */
{
FIXME(palette,"(0x%x): stub\n", hdc);
return (HPALETTE32)NULL;
}
/***********************************************************************
* GetPaletteEntries16 (GDI.363)
*/
UINT16 WINAPI GetPaletteEntries16( HPALETTE16 hpalette, UINT16 start,
UINT16 count, LPPALETTEENTRY entries )
{
return GetPaletteEntries32( hpalette, start, count, entries );
}
/***********************************************************************
* GetPaletteEntries32 [GDI32.209] Retrieves palette entries
*
* RETURNS
* Success: Number of entries from logical palette
* Failure: 0
*/
UINT32 WINAPI GetPaletteEntries32(
HPALETTE32 hpalette, /* [in] Handle of logical palette */
UINT32 start, /* [in] First entry to receive */
UINT32 count, /* [in] Number of entries to receive */
LPPALETTEENTRY entries) /* [out] Address of array receiving entries */
{
PALETTEOBJ * palPtr;
INT32 numEntries;
TRACE(palette,"hpal = %04x, count=%i\n", hpalette, count );
palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
if (!palPtr) return 0;
numEntries = palPtr->logpalette.palNumEntries;
if (start+count > numEntries) count = numEntries - start;
if (entries)
{
if (start >= numEntries)
{
GDI_HEAP_UNLOCK( hpalette );
return 0;
}
memcpy( entries, &palPtr->logpalette.palPalEntry[start],
count * sizeof(PALETTEENTRY) );
for( numEntries = 0; numEntries < count ; numEntries++ )
if (entries[numEntries].peFlags & 0xF0)
entries[numEntries].peFlags = 0;
GDI_HEAP_UNLOCK( hpalette );
}
return count;
}
/***********************************************************************
* SetPaletteEntries16 (GDI.364)
*/
UINT16 WINAPI SetPaletteEntries16( HPALETTE16 hpalette, UINT16 start,
UINT16 count, LPPALETTEENTRY entries )
{
return SetPaletteEntries32( hpalette, start, count, entries );
}
/***********************************************************************
* SetPaletteEntries32 [GDI32.326] Sets color values for range in palette
*
* RETURNS
* Success: Number of entries that were set
* Failure: 0
*/
UINT32 WINAPI SetPaletteEntries32(
HPALETTE32 hpalette, /* [in] Handle of logical palette */
UINT32 start, /* [in] Index of first entry to set */
UINT32 count, /* [in] Number of entries to set */
LPPALETTEENTRY entries) /* [in] Address of array of structures */
{
PALETTEOBJ * palPtr;
INT32 numEntries;
TRACE(palette,"hpal=%04x,start=%i,count=%i\n",hpalette,start,count );
palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
if (!palPtr) return 0;
numEntries = palPtr->logpalette.palNumEntries;
if (start >= numEntries)
{
GDI_HEAP_UNLOCK( hpalette );
return 0;
}
if (start+count > numEntries) count = numEntries - start;
memcpy( &palPtr->logpalette.palPalEntry[start], entries,
count * sizeof(PALETTEENTRY) );
PALETTE_ValidateFlags(palPtr->logpalette.palPalEntry,
palPtr->logpalette.palNumEntries);
free(palPtr->mapping);
palPtr->mapping = NULL;
GDI_HEAP_UNLOCK( hpalette );
return count;
}
/***********************************************************************
* ResizePalette16 (GDI.368)
*/
BOOL16 WINAPI ResizePalette16( HPALETTE16 hPal, UINT16 cEntries )
{
return ResizePalette32( hPal, cEntries );
}
/***********************************************************************
* ResizePalette32 [GDI32.289] Resizes logical palette
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI ResizePalette32(
HPALETTE32 hPal, /* [in] Handle of logical palette */
UINT32 cEntries) /* [in] Number of entries in logical palette */
{
PALETTEOBJ * palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
UINT32 cPrevEnt, prevVer;
int prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
int* mapping = NULL;
TRACE(palette,"hpal = %04x, prev = %i, new = %i\n",
hPal, palPtr ? palPtr->logpalette.palNumEntries : -1,
cEntries );
if( !palPtr ) return FALSE;
cPrevEnt = palPtr->logpalette.palNumEntries;
prevVer = palPtr->logpalette.palVersion;
prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) +
sizeof(int*) + sizeof(GDIOBJHDR);
size += sizeof(int*) + sizeof(GDIOBJHDR);
mapping = palPtr->mapping;
GDI_HEAP_UNLOCK( hPal );
hPal = GDI_HEAP_REALLOC( hPal, size );
palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
if( !palPtr ) return FALSE;
if( mapping )
palPtr->mapping = (int*) xrealloc( mapping, cEntries * sizeof(int) );
if( cEntries > cPrevEnt )
{
if( mapping )
memset(palPtr->mapping + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize),
cEntries - cPrevEnt );
}
palPtr->logpalette.palNumEntries = cEntries;
palPtr->logpalette.palVersion = prevVer;
GDI_HEAP_UNLOCK( hPal );
return TRUE;
}
/***********************************************************************
* AnimatePalette16 (GDI.367)
*/
void WINAPI AnimatePalette16( HPALETTE16 hPal, UINT16 StartIndex,
UINT16 NumEntries, LPPALETTEENTRY PaletteColors)
{
AnimatePalette32( hPal, StartIndex, NumEntries, PaletteColors );
}
/***********************************************************************
* AnimatePalette32 [GDI32.6] Replaces entries in logical palette
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* FIXME
* Should use existing mapping when animating a primary palette
*/
BOOL32 WINAPI AnimatePalette32(
HPALETTE32 hPal, /* [in] Handle to logical palette */
UINT32 StartIndex, /* [in] First entry in palette */
UINT32 NumEntries, /* [in] Count of entries in palette */
LPPALETTEENTRY PaletteColors) /* [in] Pointer to first replacement */
{
TRACE(palette, "%04x (%i - %i)\n", hPal, StartIndex,StartIndex+NumEntries);
if( hPal != STOCK_DEFAULT_PALETTE )
{
PALETTEOBJ* palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPal, PALETTE_MAGIC);
if( (StartIndex + NumEntries) <= palPtr->logpalette.palNumEntries )
{
UINT32 u;
for( u = 0; u < NumEntries; u++ )
palPtr->logpalette.palPalEntry[u + StartIndex] = PaletteColors[u];
COLOR_SetMapping(palPtr, StartIndex, NumEntries,
hPal != hPrimaryPalette );
GDI_HEAP_UNLOCK( hPal );
return TRUE;
}
}
return FALSE;
}
/***********************************************************************
* SetSystemPaletteUse16 (GDI.373)
*/
UINT16 WINAPI SetSystemPaletteUse16( HDC16 hdc, UINT16 use )
{
return SetSystemPaletteUse32( hdc, use );
}
/***********************************************************************
* SetSystemPaletteUse32 [GDI32.335]
*
* RETURNS
* Success: Previous system palette
* Failure: SYSPAL_ERROR
*/
UINT32 WINAPI SetSystemPaletteUse32(
HDC32 hdc, /* [in] Handle of device context */
UINT32 use) /* [in] Palette-usage flag */
{
UINT32 old = SystemPaletteUse;
FIXME(palette,"(%04x,%04x): stub\n", hdc, use );
SystemPaletteUse = use;
return old;
}
/***********************************************************************
* GetSystemPaletteUse16 (GDI.374)
*/
UINT16 WINAPI GetSystemPaletteUse16( HDC16 hdc )
{
return SystemPaletteUse;
}
/***********************************************************************
* GetSystemPaletteUse32 [GDI32.223] Gets state of system palette
*
* RETURNS
* Current state of system palette
*/
UINT32 WINAPI GetSystemPaletteUse32(
HDC32 hdc) /* [in] Handle of device context */
{
return SystemPaletteUse;
}
/***********************************************************************
* GetSystemPaletteEntries16 (GDI.375)
*/
UINT16 WINAPI GetSystemPaletteEntries16( HDC16 hdc, UINT16 start, UINT16 count,
LPPALETTEENTRY entries )
{
return GetSystemPaletteEntries32( hdc, start, count, entries );
}
/***********************************************************************
* GetSystemPaletteEntries32 [GDI32.222] Gets range of palette entries
*
* RETURNS
* Success: Number of entries retrieved from palette
* Failure: 0
*/
UINT32 WINAPI GetSystemPaletteEntries32(
HDC32 hdc, /* [in] Handle of device context */
UINT32 start, /* [in] Index of first entry to be retrieved */
UINT32 count, /* [in] Number of entries to be retrieved */
LPPALETTEENTRY entries) /* [out] Array receiving system-palette entries */
{
UINT32 i;
DC *dc;
TRACE(palette, "hdc=%04x,start=%i,count=%i\n", hdc,start,count);
if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
if (start >= dc->w.devCaps->sizePalette)
{
GDI_HEAP_UNLOCK( hdc );
return 0;
}
if (start+count >= dc->w.devCaps->sizePalette)
count = dc->w.devCaps->sizePalette - start;
for (i = 0; i < count; i++)
{
*(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry( start + i );
TRACE(palette,"\tidx(%02x) -> RGB(%08lx)\n",
start + i, *(COLORREF*)(entries + i) );
}
GDI_HEAP_UNLOCK( hdc );
return count;
}
/***********************************************************************
* GetNearestPaletteIndex16 (GDI.370)
*/
UINT16 WINAPI GetNearestPaletteIndex16( HPALETTE16 hpalette, COLORREF color )
{
return GetNearestPaletteIndex32( hpalette, color );
}
/***********************************************************************
* GetNearestPaletteIndex32 [GDI32.203] Gets palette index for color
*
* NOTES
* Should index be initialized to CLR_INVALID instead of 0?
*
* RETURNS
* Success: Index of entry in logical palette
* Failure: CLR_INVALID
*/
UINT32 WINAPI GetNearestPaletteIndex32(
HPALETTE32 hpalette, /* [in] Handle of logical color palette */
COLORREF color) /* [in] Color to be matched */
{
PALETTEOBJ* palObj = (PALETTEOBJ*)GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
UINT32 index = 0;
if( palObj )
index = COLOR_PaletteLookupPixel( palObj->logpalette.palPalEntry,
palObj->logpalette.palNumEntries,
NULL, color, FALSE );
TRACE(palette,"(%04x,%06lx): returning %d\n", hpalette, color, index );
GDI_HEAP_UNLOCK( hpalette );
return index;
}
/***********************************************************************
* GetNearestColor16 (GDI.154)
*/
COLORREF WINAPI GetNearestColor16( HDC16 hdc, COLORREF color )
{
return GetNearestColor32( hdc, color );
}
/***********************************************************************
* GetNearestColor32 [GDI32.202] Gets a system color to match
*
* NOTES
* Should this return CLR_INVALID instead of FadeCafe?
*
* RETURNS
* Success: Color from system palette that corresponds to given color
* Failure: CLR_INVALID
*/
COLORREF WINAPI GetNearestColor32(
HDC32 hdc, /* [in] Handle of device context */
COLORREF color) /* [in] Color to be matched */
{
COLORREF nearest = 0xFADECAFE;
DC *dc;
PALETTEOBJ *palObj;
if ( (dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC )) )
{
palObj = (PALETTEOBJ*)
GDI_GetObjPtr( (dc->w.hPalette)? dc->w.hPalette
: STOCK_DEFAULT_PALETTE, PALETTE_MAGIC );
nearest = COLOR_LookupNearestColor( palObj->logpalette.palPalEntry,
palObj->logpalette.palNumEntries, color );
GDI_HEAP_UNLOCK( dc->w.hPalette );
}
TRACE(palette,"(%06lx): returning %06lx\n", color, nearest );
GDI_HEAP_UNLOCK( hdc );
return nearest;
}
/***********************************************************************
* PALETTE_GetObject
*/
int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer )
{
if (count > sizeof(WORD)) count = sizeof(WORD);
memcpy( buffer, &palette->logpalette.palNumEntries, count );
return count;
}
/***********************************************************************
* PALETTE_UnrealizeObject
*/
BOOL32 PALETTE_UnrealizeObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
{
if (palette->mapping)
{
free( palette->mapping );
palette->mapping = NULL;
}
if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0;
return TRUE;
}
/***********************************************************************
* PALETTE_DeleteObject
*/
BOOL32 PALETTE_DeleteObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
{
free( palette->mapping );
if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0;
return GDI_FreeObject( hpalette );
}
/***********************************************************************
* GDISelectPalette (GDI.361)
*/
HPALETTE16 WINAPI GDISelectPalette( HDC16 hdc, HPALETTE16 hpal, WORD wBkg)
{
HPALETTE16 prev;
DC *dc;
TRACE(palette, "%04x %04x\n", hdc, hpal );
dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc)
{
dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
if (!dc) return 0;
}
prev = dc->w.hPalette;
dc->w.hPalette = hpal;
GDI_HEAP_UNLOCK( hdc );
if (!wBkg) hPrimaryPalette = hpal;
return prev;
}
/***********************************************************************
* GDIRealizePalette (GDI.362)
*/
UINT16 WINAPI GDIRealizePalette( HDC16 hdc )
{
PALETTEOBJ* palPtr;
int realized = 0;
DC* dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc)
{
dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
if (!dc) return 0;
}
TRACE(palette, "%04x...\n", hdc );
if( dc && dc->w.hPalette != hLastRealizedPalette )
{
if( dc->w.hPalette == STOCK_DEFAULT_PALETTE )
return RealizeDefaultPalette( hdc );
palPtr = (PALETTEOBJ *) GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC );
if (!palPtr) {
FIXME(palette,"invalid selected palette %04x\n",dc->w.hPalette);
return 0;
}
realized = COLOR_SetMapping(palPtr,0,palPtr->logpalette.palNumEntries,
(dc->w.hPalette != hPrimaryPalette) ||
(dc->w.hPalette == STOCK_DEFAULT_PALETTE));
GDI_HEAP_UNLOCK( dc->w.hPalette );
hLastRealizedPalette = dc->w.hPalette;
}
else TRACE(palette, " skipping (hLastRealizedPalette = %04x)\n",
hLastRealizedPalette);
GDI_HEAP_UNLOCK( hdc );
TRACE(palette, " realized %i colors.\n", realized );
return (UINT16)realized;
}
/***********************************************************************
* RealizeDefaultPalette (GDI.365)
*/
UINT16 WINAPI RealizeDefaultPalette( HDC16 hdc )
{
DC *dc;
PALETTEOBJ* palPtr;
int i, index, realized = 0;
TRACE(palette,"%04x\n", hdc );
dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc)
{
dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
if (!dc) return 0;
}
if ( dc->w.flags & DC_MEMORY )
{
GDI_HEAP_UNLOCK( hdc );
return 0;
}
hPrimaryPalette = STOCK_DEFAULT_PALETTE;
hLastRealizedPalette = STOCK_DEFAULT_PALETTE;
palPtr = (PALETTEOBJ*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE, PALETTE_MAGIC );
/* lookup is needed to account for SetSystemPaletteUse() stuff */
for( i = 0; i < 20; i++ )
{
index = COLOR_LookupSystemPixel(*(COLORREF*)(palPtr->logpalette.palPalEntry + i));
/* mapping is allocated in COLOR_InitPalette() */
if( index != palPtr->mapping[i] ) { palPtr->mapping[i]=index; realized++; }
}
return realized;
}
/***********************************************************************
* IsDCCurrentPalette (GDI.412)
*/
BOOL16 WINAPI IsDCCurrentPalette(HDC16 hDC)
{
DC* dc = (DC *)GDI_GetObjPtr( hDC, DC_MAGIC );
if (dc)
{
GDI_HEAP_UNLOCK( hDC );
return dc->w.hPalette == hPrimaryPalette;
}
return FALSE;
}
/***********************************************************************
* SelectPalette16 (USER.282)
*/
HPALETTE16 WINAPI SelectPalette16( HDC16 hDC, HPALETTE16 hPal,
BOOL16 bForceBackground )
{
return SelectPalette32( hDC, hPal, bForceBackground );
}
/***********************************************************************
* SelectPalette32 [GDI32.300] Selects logical palette into DC
*
* RETURNS
* Success: Previous logical palette
* Failure: NULL
*/
HPALETTE32 WINAPI SelectPalette32(
HDC32 hDC, /* [in] Handle of device context */
HPALETTE32 hPal, /* [in] Handle of logical color palette */
BOOL32 bForceBackground) /* [in] Foreground/background mode */
{
WORD wBkgPalette = 1;
PALETTEOBJ* lpt = (PALETTEOBJ*) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
TRACE(palette,"dc=%04x,pal=%04x,force=%i\n", hDC, hPal, bForceBackground);
if( !lpt ) return 0;
TRACE(palette," entries = %d\n", lpt->logpalette.palNumEntries);
GDI_HEAP_UNLOCK( hPal );
if( hPal != STOCK_DEFAULT_PALETTE )
{
HWND32 hWnd = WindowFromDC32( hDC );
HWND32 hActive = GetActiveWindow32();
/* set primary palette if it's related to current active */
if((!hWnd || (hActive == hWnd || IsChild16(hActive,hWnd))) &&
!bForceBackground )
wBkgPalette = 0;
}
return GDISelectPalette( hDC, hPal, wBkgPalette);
}
/***********************************************************************
* RealizePalette16 (USER.283)
*/
UINT16 WINAPI RealizePalette16( HDC16 hDC )
{
return RealizePalette32( hDC );
}
/***********************************************************************
* RealizePalette32 [GDI32.280] Maps palette entries to system palette
*
* RETURNS
* Success: Number of entries in logical palette
* Failure: GDI_ERROR
*/
UINT32 WINAPI RealizePalette32(
HDC32 hDC) /* [in] Handle of device context */
{
UINT32 realized = GDIRealizePalette( hDC );
/* do not send anything if no colors were changed */
if( IsDCCurrentPalette( hDC ) && realized &&
!(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
{
/* Send palette change notification */
HWND32 hWnd;
if( (hWnd = WindowFromDC32( hDC )) )
SendMessage16( HWND_BROADCAST, WM_PALETTECHANGED, hWnd, 0L);
}
return realized;
}
/**********************************************************************
* UpdateColors16 (GDI.366)
*/
INT16 WINAPI UpdateColors16( HDC16 hDC )
{
HWND32 hWnd = WindowFromDC32( hDC );
/* Docs say that we have to remap current drawable pixel by pixel
* but it would take forever given the speed of XGet/PutPixel.
*/
if (hWnd && !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
InvalidateRect32( hWnd, NULL, FALSE );
return 0x666;
}
/**********************************************************************
* UpdateColors32 [GDI32.359] Remaps current colors to logical palette
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI UpdateColors32(
HDC32 hDC) /* [in] Handle of device context */
{
UpdateColors16( hDC );
return TRUE;
}