fix winquake color glitc bug
[reactos.git] / reactos / subsys / win32k / objects / color.c
index 53a66d3..19e5f7e 100644 (file)
  *  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.30 2003/12/19 22:58:47 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 "../eng/handle.h"
-#include <include/inteng.h>
-#include <include/color.h>
-#include <include/palette.h>
-#include <include/error.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
@@ -58,14 +47,14 @@ const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] =
   { 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 },
@@ -76,190 +65,116 @@ const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] =
   { 0xff, 0xff, 0xff, PC_SYS_USED }     // last 10
 };
 
-const COLORREF SysColours[] =
-{
-  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 */,
-};
-
-ULONG FASTCALL NtGdiGetSysColor(int nIndex)
-{
-#if 0
-   const PALETTEENTRY *p = COLOR_sysPalTemplate + (nIndex * sizeof(PALETTEENTRY));
-   return RGB(p->peRed, p->peGreen, p->peBlue);
-#else
-  if (nIndex < 0 || sizeof(SysColours) / sizeof(SysColours[0]) < nIndex)
-    {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      return 0;
-    }
-
-  return SysColours[nIndex];
-#endif
-}
-
-HPEN STDCALL NtGdiGetSysColorPen(int nIndex)
+const PALETTEENTRY* FASTCALL COLOR_GetSystemPaletteTemplate(void)
 {
-#if 0
-  COLORREF Col;
-  memcpy(&Col, COLOR_sysPalTemplate + nIndex, sizeof(COLORREF));
-  return(NtGdiCreatePen(PS_SOLID, 1, Col));
-#else
-  static HPEN SysPens[sizeof(SysColours) / sizeof(SysColours[0])];
-
-  if (nIndex < 0 || sizeof(SysColours) / sizeof(SysColours[0]) < nIndex)
-    {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      return NULL;
-    }
-
-  /* FIXME should register this object with DeleteObject() so it
-     can't be deleted */
-  if (NULL == SysPens[nIndex])
-    {
-      SysPens[nIndex] = (HPEN)((DWORD)NtGdiCreatePen(PS_SOLID, 0, SysColours[nIndex]) | 0x00800000);
-    }
-
-  return SysPens[nIndex];
-#endif
+   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  hpal,
-                         UINT  StartIndex,
-                         UINT  Entries,
-                         CONST PPALETTEENTRY  ppe)
-{
-/*
-  if( hPal != NtGdiGetStockObject(DEFAULT_PALETTE) )
-  {
-    PALETTEOBJ* palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPal, PALETTE_MAGIC);
-    if (!palPtr) return FALSE;
-
-    if( (StartIndex + NumEntries) <= palPtr->logpalette->palNumEntries )
-    {
-      UINT u;
-      for( u = 0; u < NumEntries; u++ )
-        palPtr->logpalette->palPalEntry[u + StartIndex] = PaletteColors[u];
-      PALETTE_Driver->pSetMapping(palPtr, StartIndex, NumEntries, hPal != hPrimaryPalette );
-      GDI_ReleaseObj(hPal);
-      return TRUE;
-    }
-    GDI_ReleaseObj(hPal);
-  }
-  return FALSE;
-*/
-  UNIMPLEMENTED;
+    return TRUE;
 }
 
 HPALETTE STDCALL NtGdiCreateHalftonePalette(HDC  hDC)
 {
-  int i, r, g, b;
-  struct {
-    WORD Version;
-    WORD NumberOfEntries;
-    PALETTEENTRY aEntries[256];
-  } Palette;
-
-  Palette.Version = 0x300;
-  Palette.NumberOfEntries = 256;
-  NtGdiGetSystemPaletteEntries(hDC, 0, 256, Palette.aEntries);
-
-  for (r = 0; r < 6; r++) {
-    for (g = 0; g < 6; g++) {
-      for (b = 0; b < 6; b++) {
-        i = r + g*6 + b*36 + 10;
-        Palette.aEntries[i].peRed = r * 51;
-        Palette.aEntries[i].peGreen = g * 51;
-        Palette.aEntries[i].peBlue = b * 51;
-      }
-     }
+   int i, r, g, b;
+   struct {
+      WORD Version;
+      WORD NumberOfEntries;
+      PALETTEENTRY aEntries[256];
+   } Palette;
+
+   Palette.Version = 0x300;
+   Palette.NumberOfEntries = 256;
+   if (NtGdiGetSystemPaletteEntries(hDC, 0, 256, Palette.aEntries) == 0)
+   {
+      return 0;
    }
 
-  for (i = 216; i < 246; i++) {
-    int v = (i - 216) * 8;
-    Palette.aEntries[i].peRed = v;
-    Palette.aEntries[i].peGreen = v;
-    Palette.aEntries[i].peBlue = v;
-  }
+   for (r = 0; r < 6; r++)
+      for (g = 0; g < 6; g++)
+         for (b = 0; b < 6; b++)
+         {
+            i = r + g*6 + b*36 + 10;
+            Palette.aEntries[i].peRed = r * 51;
+            Palette.aEntries[i].peGreen = g * 51;
+            Palette.aEntries[i].peBlue = b * 51;
+         }
+
+   for (i = 216; i < 246; i++)
+   {
+      int v = (i - 216) << 3;
+      Palette.aEntries[i].peRed = v;
+      Palette.aEntries[i].peGreen = v;
+      Palette.aEntries[i].peBlue = v;
+   }
 
-  return NtGdiCreatePalette((LOGPALETTE *)&Palette);
+   return NtGdiCreatePalette((LOGPALETTE *)&Palette);
 }
 
 HPALETTE STDCALL NtGdiCreatePalette(CONST PLOGPALETTE palette)
 {
-  PPALOBJ  PalObj;
+  PPALGDI PalGDI;
 
   HPALETTE NewPalette = PALETTE_AllocPalette(
          PAL_INDEXED,
          palette->palNumEntries,
          (PULONG)palette->palPalEntry,
          0, 0, 0);
-  ULONG size;
 
-  PalObj = (PPALOBJ) PALETTE_LockPalette(NewPalette);
+  PalGDI = (PPALGDI) PALETTE_LockPalette(NewPalette);
+  /* FIXME - Handle PalGDI == NULL!!!! */
 
-  size = sizeof(LOGPALETTE) + (palette->palNumEntries * sizeof(PALETTEENTRY));
-  PalObj->logpalette = ExAllocatePool(NonPagedPool, size);
-  memcpy(PalObj->logpalette, palette, size);
-  PALETTE_ValidateFlags(PalObj->logpalette->palPalEntry, PalObj->logpalette->palNumEntries);
-  PalObj->logicalToSystem = NULL;
+  PALETTE_ValidateFlags(PalGDI->IndexedColors, PalGDI->NumColors);
+  PalGDI->logicalToSystem = NULL;
 
   PALETTE_UnlockPalette(NewPalette);
 
@@ -269,65 +184,77 @@ HPALETTE STDCALL NtGdiCreatePalette(CONST PLOGPALETTE palette)
 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;
-  PPALOBJ palObj;
+   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);
-      palObj = (PPALOBJ) PALETTE_LockPalette(hpal);
-      if (!palObj)
-       {
-         DC_UnlockDc(hDC);
-         return nearest;
-       }
+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(palObj->logpalette->palPalEntry,
-                                         palObj->logpalette->palNumEntries, Color);
+      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,
                                  COLORREF  Color)
 {
-#if 1
   PPALGDI palGDI = (PPALGDI) PALETTE_LockPalette(hpal);
   UINT index  = 0;
 
   if (NULL != palGDI)
     {
       /* Return closest match for the given RGB color */
-      index = COLOR_PaletteLookupPixel((LPPALETTEENTRY)palGDI->IndexedColors, palGDI->NumColors, NULL, Color, FALSE);
-      PALETTE_UnlockPalette(hpal);
-    }
-
-  return index;
-#else
-  PPALOBJ palObj = (PPALOBJ) PALETTE_LockPalette(hpal);
-  UINT index  = 0;
-
-  if (NULL != palObj)
-    {
-      /* Return closest match for the given RGB color */
-      ASSERT(palObj->logpalette != NULL);
-      index = COLOR_PaletteLookupPixel(palObj->logpalette->palPalEntry, palObj->logpalette->palNumEntries, NULL, Color, FALSE);
+      index = COLOR_PaletteLookupPixel(palGDI->IndexedColors, palGDI->NumColors, NULL, Color, FALSE);
       PALETTE_UnlockPalette(hpal);
     }
 
   return index;
-#endif
 }
 
 UINT STDCALL NtGdiGetPaletteEntries(HPALETTE  hpal,
@@ -335,16 +262,16 @@ UINT STDCALL NtGdiGetPaletteEntries(HPALETTE  hpal,
                             UINT  Entries,
                             LPPALETTEENTRY  pe)
 {
-  PPALOBJ palPtr;
+  PPALGDI palGDI;
   UINT numEntries;
 
-  palPtr = (PPALOBJ) PALETTE_LockPalette(hpal);
-  if (NULL == palPtr)
+  palGDI = (PPALGDI) PALETTE_LockPalette(hpal);
+  if (NULL == palGDI)
     {
       return 0;
     }
 
-  numEntries = palPtr->logpalette->palNumEntries;
+  numEntries = palGDI->NumColors;
   if (numEntries < StartIndex + Entries)
     {
       Entries = numEntries - StartIndex;
@@ -356,7 +283,7 @@ UINT STDCALL NtGdiGetPaletteEntries(HPALETTE  hpal,
          PALETTE_UnlockPalette(hpal);
          return 0;
        }
-      memcpy(pe, &palPtr->logpalette->palPalEntry[StartIndex], Entries * sizeof(PALETTEENTRY));
+      memcpy(pe, palGDI->IndexedColors + StartIndex, Entries * sizeof(PALETTEENTRY));
       for (numEntries = 0; numEntries < Entries; numEntries++)
        {
          if (pe[numEntries].peFlags & 0xF0)
@@ -407,9 +334,8 @@ UINT STDCALL NtGdiGetSystemPaletteEntries(HDC  hDC,
 }
 
 UINT STDCALL NtGdiGetSystemPaletteUse(HDC  hDC)
-{
-  UNIMPLEMENTED;
-  return 0;
+{  
+  return SystemPaletteUse;
 }
 
 /*!
@@ -429,12 +355,17 @@ A logical palette is a buffer between color-intensive applications and the syste
 */
 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;
 
@@ -442,18 +373,23 @@ UINT STDCALL NtGdiRealizePalette(HDC hDC)
   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
-  realized = PALETTE_SetMapping(palPtr, 0, palPtr->logpalette->palNumEntries,
+#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
@@ -464,9 +400,11 @@ UINT STDCALL NtGdiRealizePalette(HDC hDC)
     // 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, sysPtr->logpalette->palNumEntries);
+      ASSERT(palGDI->NumColors <= 256);
+      success = ((GDIDEVICE *)dc->GDIDevice)->DriverFunctions.SetPalette(
+        dc->PDev, palPtr, 0, 0, palGDI->NumColors);
     }
   }
 
@@ -480,7 +418,7 @@ UINT STDCALL NtGdiRealizePalette(HDC hDC)
   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);
@@ -491,10 +429,10 @@ UINT STDCALL NtGdiRealizePalette(HDC 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;
@@ -507,7 +445,7 @@ BOOL STDCALL NtGdiResizePalette(HPALETTE  hpal,
 
   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!");
@@ -529,6 +467,7 @@ BOOL STDCALL NtGdiResizePalette(HPALETTE  hpal,
   return TRUE; */
 
   UNIMPLEMENTED;
+  return FALSE;
 }
 
 /*!
@@ -547,7 +486,7 @@ HPALETTE STDCALL NtGdiSelectPalette(HDC  hDC,
                             BOOL  ForceBackground)
 {
   PDC dc;
-  HPALETTE oldPal;
+  HPALETTE oldPal = NULL;
   PPALGDI PalGDI;
 
   // FIXME: mark the palette as a [fore\back]ground pal
@@ -558,9 +497,19 @@ HPALETTE STDCALL NtGdiSelectPalette(HDC  hDC,
       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
        {
@@ -575,7 +524,8 @@ HPALETTE STDCALL NtGdiSelectPalette(HDC  hDC,
 BOOL STDCALL NtGdiSetColorAdjustment(HDC  hDC,
                              CONST LPCOLORADJUSTMENT  ca)
 {
-  UNIMPLEMENTED;
+   UNIMPLEMENTED;
+   return FALSE;
 }
 
 UINT STDCALL NtGdiSetPaletteEntries(HPALETTE  hpal,
@@ -583,13 +533,13 @@ UINT STDCALL NtGdiSetPaletteEntries(HPALETTE  hpal,
                             UINT  Entries,
                             CONST LPPALETTEENTRY  pe)
 {
-  PPALOBJ palPtr;
+  PPALGDI palGDI;
   WORD numEntries;
 
-  palPtr = (PPALOBJ)PALETTE_LockPalette(hpal);
-  if (!palPtr) return 0;
+  palGDI = PALETTE_LockPalette(hpal);
+  if (!palGDI) return 0;
 
-  numEntries = palPtr->logpalette->palNumEntries;
+  numEntries = palGDI->NumColors;
   if (Start >= numEntries)
     {
       PALETTE_UnlockPalette(hpal);
@@ -599,62 +549,78 @@ UINT STDCALL NtGdiSetPaletteEntries(HPALETTE  hpal,
     {
       Entries = numEntries - Start;
     }
-  memcpy(&palPtr->logpalette->palPalEntry[Start], pe, Entries * sizeof(PALETTEENTRY));
-  PALETTE_ValidateFlags(palPtr->logpalette->palPalEntry, palPtr->logpalette->palNumEntries);
-  ExFreePool(palPtr->logicalToSystem);
-  palPtr->logicalToSystem = NULL;
+  memcpy(palGDI->IndexedColors + Start, pe, Entries * sizeof(PALETTEENTRY));
+  PALETTE_ValidateFlags(palGDI->IndexedColors, palGDI->NumColors);
+  ExFreePool(palGDI->logicalToSystem);
+  palGDI->logicalToSystem = NULL;
   PALETTE_UnlockPalette(hpal);
 
   return Entries;
 }
 
-UINT STDCALL NtGdiSetSystemPaletteUse(HDC  hDC,
-                              UINT  Usage)
+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)
+BOOL STDCALL
+NtGdiUnrealizeObject(HGDIOBJ hgdiobj)
 {
-  UNIMPLEMENTED;
+   UNIMPLEMENTED;
+   return FALSE;
 }
 
-BOOL STDCALL NtGdiUpdateColors(HDC  hDC)
+BOOL STDCALL
+NtGdiUpdateColors(HDC hDC)
 {
-  //PDC dc;
-  //HWND hWnd;
-  //int size;
-/*
-  if (!(dc = AccessUserObject(hDC))) return 0;
-  size = dc->GDIInfo->ulNumPalReg;
-//  GDI_ReleaseObj( hDC );
+   HWND hWnd;
 
-  if (Callout.WindowFromDC)
-  {
-    hWnd = Callout.WindowFromDC( 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 && size) Callout.RedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
-  } */
-  // FIXME UNIMPLEMENTED
-  return 0x666;
+   hWnd = (HWND)NtUserCallOneParam((DWORD)hDC, ONEPARAM_ROUTINE_WINDOWFROMDC);
+   if (hWnd == NULL)
+   {
+      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+      return FALSE;
+   }
+   return NtUserRedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);
 }
 
 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;
 
@@ -669,27 +635,13 @@ INT STDCALL COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, INT size,
 
 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,