* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: color.c,v 1.31 2003/12/20 10:31:32 navaraf Exp $ */
+/* $Id$ */
+#include <w32k.h>
// FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping
-#undef WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <ddk/ntddk.h>
-#include <ddk/winddi.h>
-#include <win32k/brush.h>
-#include <win32k/dc.h>
-#include <win32k/color.h>
-#include <win32k/pen.h>
-#include <win32k/ntuser.h>
-#include "../eng/handle.h"
-#include <include/inteng.h>
-#include <include/color.h>
-#include <include/palette.h>
-#include <include/error.h>
-#include <include/dce.h>
-
-#define NDEBUG
-#include <win32k/debug1.h>
-
int COLOR_gapStart = 256;
int COLOR_gapEnd = -1;
int COLOR_gapFilled = 0;
int COLOR_max = 256;
+#ifndef NO_MAPPING
static HPALETTE hPrimaryPalette = 0; // used for WM_PALETTECHANGED
+#endif
//static HPALETTE hLastRealizedPalette = 0; // UnrealizeObject() needs it
+
+static UINT SystemPaletteUse = SYSPAL_NOSTATIC; /* the program need save the palate and restore it */
+
const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] =
{
// first 10 entries in the system palette
{ 0x00, 0x80, 0x80, PC_SYS_USED },
{ 0xc0, 0xc0, 0xc0, PC_SYS_USED },
{ 0xc0, 0xdc, 0xc0, PC_SYS_USED },
- { 0xa6, 0xca, 0xf0, PC_SYS_USED },
+ { 0xd4, 0xd0, 0xc7, PC_SYS_USED },
// ... c_min/2 dynamic colorcells
// ... gap (for sparse palettes)
// ... c_min/2 dynamic colorcells
{ 0xff, 0xfb, 0xf0, PC_SYS_USED },
- { 0xa0, 0xa0, 0xa4, PC_SYS_USED },
+ { 0x3a, 0x6e, 0xa5, PC_SYS_USED },
{ 0x80, 0x80, 0x80, PC_SYS_USED },
{ 0xff, 0x00, 0x00, PC_SYS_USED },
{ 0x00, 0xff, 0x00, PC_SYS_USED },
{ 0xff, 0xff, 0xff, PC_SYS_USED } // last 10
};
-const COLORREF SysColours[] =
+const PALETTEENTRY* FASTCALL COLOR_GetSystemPaletteTemplate(void)
{
- RGB(224, 224, 224) /* COLOR_SCROLLBAR */,
- RGB(58, 110, 165) /* COLOR_BACKGROUND */,
- RGB(0, 0, 128) /* COLOR_ACTIVECAPTION */,
- RGB(128, 128, 128) /* COLOR_INACTIVECAPTION */,
- RGB(192, 192, 192) /* COLOR_MENU */,
- RGB(255, 255, 255) /* COLOR_WINDOW */,
- RGB(0, 0, 0) /* COLOR_WINDOWFRAME */,
- RGB(0, 0, 0) /* COLOR_MENUTEXT */,
- RGB(0, 0, 0) /* COLOR_WINDOWTEXT */,
- RGB(255, 255, 255) /* COLOR_CAPTIONTEXT */,
- RGB(128, 128, 128) /* COLOR_ACTIVEBORDER */,
- RGB(255, 255, 255) /* COLOR_INACTIVEBORDER */,
- RGB(255, 255, 232) /* COLOR_APPWORKSPACE */,
- RGB(224, 224, 224) /* COLOR_HILIGHT */,
- RGB(0, 0, 128) /* COLOR_HILIGHTTEXT */,
- RGB(192, 192, 192) /* COLOR_BTNFACE */,
- RGB(128, 128, 128) /* COLOR_BTNSHADOW */,
- RGB(192, 192, 192) /* COLOR_GRAYTEXT */,
- RGB(0, 0, 0) /* COLOR_BTNTEXT */,
- RGB(192, 192, 192) /* COLOR_INACTIVECAPTIONTEXT */,
- RGB(255, 255, 255) /* COLOR_BTNHILIGHT */,
- RGB(32, 32, 32) /* COLOR_3DDKSHADOW */,
- RGB(192, 192, 192) /* COLOR_3DLIGHT */,
- RGB(0, 0, 0) /* COLOR_INFOTEXT */,
- RGB(255, 255, 192) /* COLOR_INFOBK */,
- RGB(184, 180, 184) /* COLOR_ALTERNATEBTNFACE */,
- RGB(0, 0, 255) /* COLOR_HOTLIGHT */,
- RGB(16, 132, 208) /* COLOR_GRADIENTACTIVECAPTION */,
- RGB(181, 181, 181) /* COLOR_GRADIENTINACTIVECAPTION */,
-};
+ return (const PALETTEENTRY*)&COLOR_sysPalTemplate;
+}
-HBRUSH STDCALL NtGdiGetSysColorBrush(int nIndex)
+BOOL STDCALL NtGdiAnimatePalette(HPALETTE hPal, UINT StartIndex,
+ UINT NumEntries, CONST PPALETTEENTRY PaletteColors)
{
- static HBRUSH SysBrushes[sizeof(SysColours) / sizeof(SysColours[0])];
-
- if (nIndex < 0 || sizeof(SysColours) / sizeof(SysColours[0]) < nIndex)
+ if( hPal != NtGdiGetStockObject(DEFAULT_PALETTE) )
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- /* FIXME Should be changed when a new user logs in? */
- if (NULL == SysBrushes[nIndex])
- {
- SysBrushes[nIndex] = (HBRUSH) ((DWORD)NtGdiCreateSolidBrush(SysColours[nIndex]));
- if (NULL != SysBrushes[nIndex])
+ PPALGDI palPtr;
+ UINT pal_entries;
+ HDC hDC;
+ PDC dc;
+ HWND hHwd;
+ const PALETTEENTRY *pptr = PaletteColors;
+
+ palPtr = (PPALGDI)PALETTE_LockPalette(hPal);
+ if (!palPtr) return FALSE;
+
+ pal_entries = palPtr->NumColors;
+ if (StartIndex >= pal_entries)
{
- GDIOBJ_SetOwnership(SysBrushes[nIndex], NULL);
+ PALETTE_UnlockPalette(hPal);
+ return FALSE;
}
+ if (StartIndex+NumEntries > pal_entries) NumEntries = pal_entries - StartIndex;
+
+ for (NumEntries += StartIndex; StartIndex < NumEntries; StartIndex++, pptr++) {
+ /* According to MSDN, only animate PC_RESERVED colours */
+ if (palPtr->IndexedColors[StartIndex].peFlags & PC_RESERVED) {
+ memcpy( &palPtr->IndexedColors[StartIndex], pptr,
+ sizeof(PALETTEENTRY) );
+ PALETTE_ValidateFlags(&palPtr->IndexedColors[StartIndex], 1);
+ }
+ }
+
+ PALETTE_UnlockPalette(hPal);
+
+ /* Immediately apply the new palette if current window uses it */
+ hHwd = NtUserGetDesktopWindow();
+ hDC = (HDC)NtUserGetWindowDC(hHwd);
+ dc = DC_LockDc(hDC);
+ if (NULL != dc)
+ {
+ if (dc->w.hPalette == hPal)
+ {
+ DC_UnlockDc(hDC);
+ NtGdiRealizePalette(hDC);
+ }
+ else
+ DC_UnlockDc(hDC);
+ }
+ NtUserReleaseDC(hHwd,hDC);
}
-
- return SysBrushes[nIndex];
-}
-
-const PALETTEENTRY* FASTCALL COLOR_GetSystemPaletteTemplate(void)
-{
- return (const PALETTEENTRY*)&COLOR_sysPalTemplate;
-}
-
-BOOL STDCALL NtGdiAnimatePalette(HPALETTE hPalette, UINT uStartIndex,
- UINT uEntries, CONST PPALETTEENTRY ppe)
-{
- UNIMPLEMENTED;
- SetLastWin32Error(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ return TRUE;
}
HPALETTE STDCALL NtGdiCreateHalftonePalette(HDC hDC)
for (i = 216; i < 246; i++)
{
- int v = (i - 216) * 8;
+ int v = (i - 216) << 3;
Palette.aEntries[i].peRed = v;
Palette.aEntries[i].peGreen = v;
Palette.aEntries[i].peBlue = v;
0, 0, 0);
PalGDI = (PPALGDI) PALETTE_LockPalette(NewPalette);
+ /* FIXME - Handle PalGDI == NULL!!!! */
PALETTE_ValidateFlags(PalGDI->IndexedColors, PalGDI->NumColors);
- PalGDI->PalObj.logicalToSystem = NULL;
+ PalGDI->logicalToSystem = NULL;
PALETTE_UnlockPalette(NewPalette);
BOOL STDCALL NtGdiGetColorAdjustment(HDC hDC,
LPCOLORADJUSTMENT ca)
{
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
+ return FALSE;
}
-COLORREF STDCALL NtGdiGetNearestColor(HDC hDC,
- COLORREF Color)
+unsigned short GetNumberOfBits(unsigned int dwMask)
{
- COLORREF nearest = CLR_INVALID;
- PDC dc;
- PPALGDI palGDI;
+ unsigned short wBits;
+ for (wBits = 0; dwMask; dwMask = dwMask & (dwMask - 1))
+ wBits++;
+ return wBits;
+}
- dc = DC_LockDc(hDC);
- if (NULL != dc)
- {
- HPALETTE hpal = (dc->w.hPalette) ? dc->w.hPalette : NtGdiGetStockObject(DEFAULT_PALETTE);
+COLORREF STDCALL NtGdiGetNearestColor(HDC hDC, COLORREF Color)
+{
+ COLORREF nearest = CLR_INVALID;
+ PDC dc;
+ PPALGDI palGDI;
+ LONG RBits, GBits, BBits;
+
+ dc = DC_LockDc(hDC);
+ if (NULL != dc)
+ {
+ HPALETTE hpal = dc->w.hPalette;
palGDI = (PPALGDI) PALETTE_LockPalette(hpal);
if (!palGDI)
- {
- DC_UnlockDc(hDC);
- return nearest;
- }
-
- nearest = COLOR_LookupNearestColor(palGDI->IndexedColors,
- palGDI->NumColors, Color);
+ {
+ DC_UnlockDc(hDC);
+ return nearest;
+ }
+
+ switch (palGDI->Mode)
+ {
+ case PAL_INDEXED:
+ nearest = COLOR_LookupNearestColor(palGDI->IndexedColors,
+ palGDI->NumColors, Color);
+ break;
+ case PAL_BGR:
+ case PAL_RGB:
+ nearest = Color;
+ break;
+ case PAL_BITFIELDS:
+ RBits = 8 - GetNumberOfBits(palGDI->RedMask);
+ GBits = 8 - GetNumberOfBits(palGDI->GreenMask);
+ BBits = 8 - GetNumberOfBits(palGDI->BlueMask);
+ nearest = RGB(
+ (GetRValue(Color) >> RBits) << RBits,
+ (GetGValue(Color) >> GBits) << GBits,
+ (GetBValue(Color) >> BBits) << BBits);
+ break;
+ }
PALETTE_UnlockPalette(hpal);
- DC_UnlockDc( hDC );
- }
+ DC_UnlockDc(hDC);
+ }
- return nearest;
+ return nearest;
}
UINT STDCALL NtGdiGetNearestPaletteIndex(HPALETTE hpal,
if (NULL != palGDI)
{
/* Return closest match for the given RGB color */
- index = COLOR_PaletteLookupPixel((LPPALETTEENTRY)palGDI->IndexedColors, palGDI->NumColors, NULL, Color, FALSE);
+ index = COLOR_PaletteLookupPixel(palGDI->IndexedColors, palGDI->NumColors, NULL, Color, FALSE);
PALETTE_UnlockPalette(hpal);
}
PALETTE_UnlockPalette(hpal);
return 0;
}
- memcpy(pe, &palGDI->IndexedColors[StartIndex], Entries * sizeof(PALETTEENTRY));
+ memcpy(pe, palGDI->IndexedColors + StartIndex, Entries * sizeof(PALETTEENTRY));
for (numEntries = 0; numEntries < Entries; numEntries++)
{
if (pe[numEntries].peFlags & 0xF0)
}
UINT STDCALL NtGdiGetSystemPaletteUse(HDC hDC)
-{
- UNIMPLEMENTED;
- return 0;
+{
+ return SystemPaletteUse;
}
/*!
*/
UINT STDCALL NtGdiRealizePalette(HDC hDC)
{
- PPALOBJ palPtr, sysPtr;
+ /*
+ * This function doesn't do any real work now and there's plenty
+ * of bugd in it (calling SetPalette for high/true-color modes,
+ * using DEFAULT_PALETTE instead of the device palette, ...).
+ */
+
+ PALOBJ *palPtr, *sysPtr;
PPALGDI palGDI, sysGDI;
int realized = 0;
PDC dc;
HPALETTE systemPalette;
- PSURFGDI SurfGDI;
BOOLEAN success;
USHORT sysMode, palMode;
if (!dc)
return 0;
- SurfGDI = (PSURFGDI)AccessInternalObject((ULONG)dc->Surface);
systemPalette = NtGdiGetStockObject((INT)DEFAULT_PALETTE);
palGDI = PALETTE_LockPalette(dc->w.hPalette);
- palPtr = (PPALOBJ) palGDI;
+ palPtr = (PALOBJ*) palGDI;
+ /* FIXME - Handle palGDI == NULL!!!! */
// Step 1: Create mapping of system palette\DC palette
+#ifndef NO_MAPPING
realized = PALETTE_SetMapping(palPtr, 0, palGDI->NumColors,
(dc->w.hPalette != hPrimaryPalette) ||
(dc->w.hPalette == NtGdiGetStockObject(DEFAULT_PALETTE)));
+#else
+ realized = 0;
+#endif
sysGDI = PALETTE_LockPalette(systemPalette);
- sysPtr = (PPALOBJ) sysGDI;
+ sysPtr = (PALOBJ*) sysGDI;
+ /* FIXME - Handle sysGDI == NULL!!!!! */
// Step 2:
// The RealizePalette function modifies the palette for the device associated with the specified device context. If the
// Memory managed DC
DbgPrint("win32k: realizepalette unimplemented step 2 for DC_MEMORY");
} else {
- if(SurfGDI->SetPalette)
+ if( ((GDIDEVICE *)dc->GDIDevice)->DriverFunctions.SetPalette)
{
- success = SurfGDI->SetPalette(dc->PDev, sysPtr, 0, 0, sysGDI->NumColors);
+ ASSERT(palGDI->NumColors <= 256);
+ success = ((GDIDEVICE *)dc->GDIDevice)->DriverFunctions.SetPalette(
+ dc->PDev, palPtr, 0, 0, palGDI->NumColors);
}
}
if(dc->w.flags != DC_MEMORY)
{
// Device managed DC
- palPtr->logicalToSystem = IntEngCreateXlate(sysGDI->Mode, palGDI->Mode, systemPalette, dc->w.hPalette);
+ palGDI->logicalToSystem = IntEngCreateXlate(sysMode, palMode, systemPalette, dc->w.hPalette);
}
DC_UnlockDc(hDC);
BOOL STDCALL NtGdiResizePalette(HPALETTE hpal,
UINT Entries)
{
-/* PPALOBJ palPtr = (PPALOBJ)AccessUserObject(hPal);
+/* PALOBJ *palPtr = (PALOBJ*)AccessUserObject(hPal);
UINT cPrevEnt, prevVer;
INT prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
- PXLATEOBJ XlateObj = NULL;
+ XLATEOBJ *XlateObj = NULL;
if(!palPtr) return FALSE;
cPrevEnt = palPtr->logpalette->palNumEntries;
if(XlateObj)
{
- PXLATEOBJ NewXlateObj = (int*) HeapReAlloc(GetProcessHeap(), 0, XlateObj, cEntries * sizeof(int));
+ XLATEOBJ *NewXlateObj = (int*) HeapReAlloc(GetProcessHeap(), 0, XlateObj, cEntries * sizeof(int));
if(NewXlateObj == NULL)
{
ERR("Can not resize logicalToSystem -- out of memory!");
return TRUE; */
UNIMPLEMENTED;
+ return FALSE;
}
/*!
BOOL ForceBackground)
{
PDC dc;
- HPALETTE oldPal;
+ HPALETTE oldPal = NULL;
PPALGDI PalGDI;
// FIXME: mark the palette as a [fore\back]ground pal
PalGDI = PALETTE_LockPalette(hpal);
if (NULL != PalGDI)
{
- PALETTE_UnlockPalette(hpal);
- oldPal = dc->w.hPalette;
- dc->w.hPalette = hpal;
+ /* Is this a valid palette for this depth? */
+ if ((dc->w.bitsPerPixel <= 8 && PAL_INDEXED == PalGDI->Mode)
+ || (8 < dc->w.bitsPerPixel && PAL_INDEXED != PalGDI->Mode))
+ {
+ PALETTE_UnlockPalette(hpal);
+ oldPal = dc->w.hPalette;
+ dc->w.hPalette = hpal;
+ }
+ else
+ {
+ PALETTE_UnlockPalette(hpal);
+ oldPal = NULL;
+ }
}
else
{
BOOL STDCALL NtGdiSetColorAdjustment(HDC hDC,
CONST LPCOLORADJUSTMENT ca)
{
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
+ return FALSE;
}
UINT STDCALL NtGdiSetPaletteEntries(HPALETTE hpal,
{
Entries = numEntries - Start;
}
- memcpy(&palGDI->IndexedColors[Start], pe, Entries * sizeof(PALETTEENTRY));
+ memcpy(palGDI->IndexedColors + Start, pe, Entries * sizeof(PALETTEENTRY));
PALETTE_ValidateFlags(palGDI->IndexedColors, palGDI->NumColors);
- ExFreePool(palGDI->PalObj.logicalToSystem);
- palGDI->PalObj.logicalToSystem = NULL;
+ ExFreePool(palGDI->logicalToSystem);
+ palGDI->logicalToSystem = NULL;
PALETTE_UnlockPalette(hpal);
return Entries;
UINT STDCALL
NtGdiSetSystemPaletteUse(HDC hDC, UINT Usage)
{
- UNIMPLEMENTED;
+ UINT old = SystemPaletteUse;
+
+ /* Device doesn't support colour palettes */
+ if (!(NtGdiGetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE)) {
+ return SYSPAL_ERROR;
+ }
+
+ switch (Usage)
+ {
+ case SYSPAL_NOSTATIC:
+ case SYSPAL_NOSTATIC256:
+ case SYSPAL_STATIC:
+ SystemPaletteUse = Usage;
+ break;
+
+ default:
+ old=SYSPAL_ERROR;
+ break;
+ }
+
+ return old;
}
BOOL STDCALL
NtGdiUnrealizeObject(HGDIOBJ hgdiobj)
{
UNIMPLEMENTED;
+ return FALSE;
}
BOOL STDCALL
{
HWND hWnd;
- hWnd = IntWindowFromDC(hDC);
+ hWnd = (HWND)NtUserCallOneParam((DWORD)hDC, ONEPARAM_ROUTINE_WINDOWFROMDC);
if (hWnd == NULL)
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
}
INT STDCALL COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, INT size,
- PXLATEOBJ XlateObj, COLORREF col, BOOL skipReserved)
+ XLATEOBJ *XlateObj, COLORREF col, BOOL skipReserved)
{
int i, best = 0, diff = 0x7fffffff;
int r, g, b;
for( i = 0; i < size && diff ; i++ )
{
+#if 0
if(!(palPalEntry[i].peFlags & PC_SYS_USED) || (skipReserved && palPalEntry[i].peFlags & PC_SYS_RESERVED))
continue;
+#endif
- r = palPalEntry[i].peRed - GetRValue(col);
- g = palPalEntry[i].peGreen - GetGValue(col);
- b = palPalEntry[i].peBlue - GetBValue(col);
+ r = abs((SHORT)palPalEntry[i].peRed - GetRValue(col));
+ g = abs((SHORT)palPalEntry[i].peGreen - GetGValue(col));
+ b = abs((SHORT)palPalEntry[i].peBlue - GetBValue(col));
r = r*r + g*g + b*b;
COLORREF STDCALL COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
{
- unsigned char spec_type = color >> 24;
- int i;
- PALETTEENTRY *COLOR_sysPal = (PALETTEENTRY*)ReturnSystemPalette();
-
- // we need logical palette for PALETTERGB and PALETTEINDEX colorrefs
-
- if( spec_type == 2 ) /* PALETTERGB */
- color = *(COLORREF*)(palPalEntry + COLOR_PaletteLookupPixel(palPalEntry,size,NULL,color,FALSE));
-
- else if( spec_type == 1 ) /* PALETTEINDEX */
- {
- if( (i = color & 0x0000ffff) >= size )
- {
- DbgPrint("RGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
- color = *(COLORREF*)palPalEntry;
- }
- else color = *(COLORREF*)(palPalEntry + i);
- }
+ INT index;
- color &= 0x00ffffff;
- return (0x00ffffff & *(COLORREF*)(COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
+ index = COLOR_PaletteLookupPixel(palPalEntry, size, NULL, color, FALSE);
+ return RGB(
+ palPalEntry[index].peRed,
+ palPalEntry[index].peGreen,
+ palPalEntry[index].peBlue);
}
int STDCALL COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,