[WIN32K]
[reactos.git] / reactos / subsystems / win32 / win32k / objects / palette.c
index 61a50ec..c7656e0 100644 (file)
@@ -7,14 +7,15 @@
  *                    Timo Kreuzer
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
 
 static UINT SystemPaletteUse = SYSPAL_NOSTATIC;  /* the program need save the pallete and restore it */
 
-PALETTE gpalRGB, gpalBGR, gpalMono;
+PALETTE gpalRGB, gpalBGR, gpalMono, gpalRGB555, gpalRGB565, *gppalDefault;
+PPALETTE appalSurfaceDefault[11];
 
 const PALETTEENTRY g_sysPalTemplate[NB_RESERVED_COLORS] =
 {
@@ -56,21 +57,21 @@ unsigned short GetNumberOfBits(unsigned int dwMask)
 }
 
 // Create the system palette
-HPALETTE FASTCALL PALETTE_Init(VOID)
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitPaletteImpl()
 {
     int i;
     HPALETTE hpalette;
     PLOGPALETTE palPtr;
-#ifndef NO_MAPPING
-    PALOBJ *palObj;
-#endif
 
     // create default palette (20 system colors)
     palPtr = ExAllocatePoolWithTag(PagedPool,
                                    sizeof(LOGPALETTE) +
                                        (NB_RESERVED_COLORS * sizeof(PALETTEENTRY)),
                                    TAG_PALETTE);
-    if (!palPtr) return FALSE;
+    if (!palPtr) return STATUS_NO_MEMORY;
 
     palPtr->palVersion = 0x300;
     palPtr->palNumEntries = NB_RESERVED_COLORS;
@@ -85,35 +86,55 @@ HPALETTE FASTCALL PALETTE_Init(VOID)
     hpalette = NtGdiCreatePaletteInternal(palPtr,NB_RESERVED_COLORS);
     ExFreePoolWithTag(palPtr, TAG_PALETTE);
 
-#ifndef NO_MAPPING
-    palObj = (PALOBJ*)PALETTE_LockPalette(hpalette);
-    if (palObj)
-    {
-        if (!(palObj->mapping = ExAllocatePool(PagedPool, sizeof(int) * 20)))
-        {
-            DbgPrint("Win32k: Can not create palette mapping -- out of memory!");
-            return FALSE;
-        }
-        PALETTE_UnlockPalette(palObj);
-    }
-#endif
-
     /*  palette_size = visual->map_entries; */
 
-    gpalRGB.Mode = PAL_RGB;
+    gpalRGB.flFlags = PAL_RGB;
     gpalRGB.RedMask = RGB(0xFF, 0x00, 0x00);
     gpalRGB.GreenMask = RGB(0x00, 0xFF, 0x00);
     gpalRGB.BlueMask = RGB(0x00, 0x00, 0xFF);
+    gpalRGB.BaseObject.ulShareCount = 0;
+    gpalRGB.BaseObject.BaseFlags = 0 ;
 
-    gpalBGR.Mode = PAL_BGR;
+    gpalBGR.flFlags = PAL_BGR;
     gpalBGR.RedMask = RGB(0x00, 0x00, 0xFF);
     gpalBGR.GreenMask = RGB(0x00, 0xFF, 0x00);
     gpalBGR.BlueMask = RGB(0xFF, 0x00, 0x00);
+    gpalBGR.BaseObject.ulShareCount = 0;
+    gpalBGR.BaseObject.BaseFlags = 0 ;
+
+    gpalRGB555.flFlags = PAL_RGB16_555 | PAL_BITFIELDS;
+    gpalRGB555.RedMask = 0x7C00;
+    gpalRGB555.GreenMask = 0x3E0;
+    gpalRGB555.BlueMask = 0x1F;
+    gpalRGB555.BaseObject.ulShareCount = 0;
+    gpalRGB555.BaseObject.BaseFlags = 0 ;
+
+    gpalRGB565.flFlags = PAL_RGB16_565 | PAL_BITFIELDS;
+    gpalRGB565.RedMask = 0xF800;
+    gpalRGB565.GreenMask = 0x7E0;
+    gpalRGB565.BlueMask = 0x1F;
+    gpalRGB565.BaseObject.ulShareCount = 0;
+    gpalRGB565.BaseObject.BaseFlags = 0 ;
 
     memset(&gpalMono, 0, sizeof(PALETTE));
-    gpalMono.Mode = PAL_MONOCHROME;
-
-    return hpalette;
+    gpalMono.flFlags = PAL_MONOCHROME;
+    gpalMono.BaseObject.ulShareCount = 0;
+    gpalMono.BaseObject.BaseFlags = 0 ;
+
+    /* Initialize default surface palettes */
+    gppalDefault = PALETTE_ShareLockPalette(hpalette);
+    appalSurfaceDefault[BMF_1BPP] = &gpalMono;
+    appalSurfaceDefault[BMF_4BPP] = gppalDefault;
+    appalSurfaceDefault[BMF_8BPP] = gppalDefault;
+    appalSurfaceDefault[BMF_16BPP] = &gpalRGB565;
+    appalSurfaceDefault[BMF_24BPP] = &gpalBGR;
+    appalSurfaceDefault[BMF_32BPP] = &gpalBGR;
+    appalSurfaceDefault[BMF_4RLE] = gppalDefault;
+    appalSurfaceDefault[BMF_8RLE] = gppalDefault;
+    appalSurfaceDefault[BMF_JPEG] = &gpalRGB;
+    appalSurfaceDefault[BMF_PNG] = &gpalRGB;
+
+    return STATUS_SUCCESS;
 }
 
 VOID FASTCALL PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, INT size)
@@ -144,7 +165,7 @@ PALETTE_AllocPalette(ULONG Mode,
     NewPalette = PalGDI->BaseObject.hHmgr;
 
     PalGDI->Self = NewPalette;
-    PalGDI->Mode = Mode;
+    PalGDI->flFlags = Mode;
 
     if (NULL != Colors)
     {
@@ -160,20 +181,24 @@ PALETTE_AllocPalette(ULONG Mode,
         RtlCopyMemory(PalGDI->IndexedColors, Colors, sizeof(PALETTEENTRY) * NumColors);
     }
 
-    if (PAL_INDEXED == Mode)
+    if (Mode & PAL_INDEXED)
     {
         PalGDI->NumColors = NumColors;
     }
-    else if (PAL_BITFIELDS == Mode)
+    else if (Mode & PAL_BITFIELDS)
     {
         PalGDI->RedMask = Red;
         PalGDI->GreenMask = Green;
         PalGDI->BlueMask = Blue;
-        
+
         if (Red == 0x7c00 && Green == 0x3E0 && Blue == 0x1F)
-            PalGDI->Mode |= PAL_RGB16_555;
+            PalGDI->flFlags |= PAL_RGB16_555;
         else if (Red == 0xF800 && Green == 0x7E0 && Blue == 0x1F)
-            PalGDI->Mode |= PAL_RGB16_565;
+            PalGDI->flFlags |= PAL_RGB16_565;
+        else if (Red == 0xFF0000 && Green == 0xFF00 && Blue == 0xFF)
+            PalGDI->flFlags |= PAL_BGR;
+        else if (Red == 0xFF && Green == 0xFF00 && Blue == 0xFF0000)
+            PalGDI->flFlags |= PAL_RGB;
     }
 
     PALETTE_UnlockPalette(PalGDI);
@@ -199,7 +224,7 @@ PALETTE_AllocPaletteIndexedRGB(ULONG NumColors,
     NewPalette = PalGDI->BaseObject.hHmgr;
 
     PalGDI->Self = NewPalette;
-    PalGDI->Mode = PAL_INDEXED;
+    PalGDI->flFlags = PAL_INDEXED;
 
     PalGDI->IndexedColors = ExAllocatePoolWithTag(PagedPool,
                                                   sizeof(PALETTEENTRY) * NumColors,
@@ -232,7 +257,7 @@ PALETTE_Cleanup(PVOID ObjectBody)
     PPALETTE pPal = (PPALETTE)ObjectBody;
     if (NULL != pPal->IndexedColors)
     {
-        ExFreePool(pPal->IndexedColors);
+        ExFreePoolWithTag(pPal->IndexedColors, TAG_PALETTE);
     }
 
     return TRUE;
@@ -303,7 +328,7 @@ ULONG
 NTAPI
 PALETTE_ulGetNearestIndex(PALETTE* ppal, ULONG ulColor)
 {
-    if (ppal->Mode & PAL_INDEXED) // use fl & PALINDEXED
+    if (ppal->flFlags & PAL_INDEXED) // use fl & PALINDEXED
         return PALETTE_ulGetNearestPaletteIndex(ppal, ulColor);
     else
         return PALETTE_ulGetNearestBitFieldsIndex(ppal, ulColor);
@@ -315,19 +340,19 @@ PALETTE_vGetBitMasks(PPALETTE ppal, PULONG pulColors)
 {
     ASSERT(pulColors);
 
-    if (ppal->Mode & PAL_INDEXED || ppal->Mode & PAL_RGB)
+    if (ppal->flFlags & PAL_INDEXED || ppal->flFlags & PAL_RGB)
     {
         pulColors[0] = RGB(0xFF, 0x00, 0x00);
         pulColors[1] = RGB(0x00, 0xFF, 0x00);
         pulColors[2] = RGB(0x00, 0x00, 0xFF);
     }
-    else if (ppal->Mode & PAL_BGR)
+    else if (ppal->flFlags & PAL_BGR)
     {
         pulColors[0] = RGB(0x00, 0x00, 0xFF);
         pulColors[1] = RGB(0x00, 0xFF, 0x00);
         pulColors[2] = RGB(0xFF, 0x00, 0x00);
     }
-    else if (ppal->Mode & PAL_BITFIELDS)
+    else if (ppal->flFlags & PAL_BITFIELDS)
     {
         pulColors[0] = ppal->RedMask;
         pulColors[1] = ppal->GreenMask;
@@ -374,7 +399,7 @@ EngCreatePalette(
 {
     HPALETTE Palette;
 
-    Palette = PALETTE_AllocPalette(Mode, NumColors, Colors, Red, Green, Blue);
+       Palette = PALETTE_AllocPalette(Mode, NumColors, Colors, Red, Green, Blue);
     if (Palette != NULL)
     {
         GDIOBJ_SetOwnership(Palette, NULL);
@@ -415,7 +440,7 @@ PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors, ULONG *PaletteEntry
     /* NOTE: PaletteEntry ULONGs are in the same order as PALETTEENTRY. */
     RtlCopyMemory(PaletteEntry, PalGDI->IndexedColors + Start, sizeof(ULONG) * Colors);
 
-    if (PalGDI->Mode & PAL_GAMMACORRECTION)
+    if (PalGDI->flFlags & PAL_GAMMACORRECTION)
         ColorCorrection(PalGDI, (PPALETTEENTRY)PaletteEntry, Colors);
 
     return Colors;
@@ -453,7 +478,7 @@ NtGdiCreatePaletteInternal ( IN LPLOGPALETTE pLogPal, IN UINT cEntries )
     else
     {
         /* FIXME - Handle PalGDI == NULL!!!! */
-        DPRINT1("waring PalGDI is NULL \n");
+        DPRINT1("PalGDI is NULL\n");
     }
   return NewPalette;
 }
@@ -646,17 +671,17 @@ COLORREF APIENTRY NtGdiGetNearestColor(HDC hDC, COLORREF Color)
          return nearest;
       }
 
-      if (palGDI->Mode & PAL_INDEXED)
+      if (palGDI->flFlags & PAL_INDEXED)
       {
          ULONG index;
          index = PALETTE_ulGetNearestPaletteIndex(palGDI, Color);
          nearest = PALETTE_ulGetRGBColorFromIndex(palGDI, index);
       }
-      else if (palGDI->Mode & PAL_RGB || palGDI->Mode & PAL_BGR)
+      else if (palGDI->flFlags & PAL_RGB || palGDI->flFlags & PAL_BGR)
       {
          nearest = Color;
       }
-      else if (palGDI->Mode & PAL_BITFIELDS)
+      else if (palGDI->flFlags & PAL_BITFIELDS)
       {
          RBits = 8 - GetNumberOfBits(palGDI->RedMask);
          GBits = 8 - GetNumberOfBits(palGDI->GreenMask);
@@ -684,7 +709,7 @@ NtGdiGetNearestPaletteIndex(
 
     if (ppal)
     {
-        if (ppal->Mode & PAL_INDEXED)
+        if (ppal->flFlags & PAL_INDEXED)
         {
             /* Return closest match for the given RGB color */
             index = PALETTE_ulGetNearestPaletteIndex(ppal, crColor);
@@ -700,61 +725,39 @@ UINT
 FASTCALL
 IntGdiRealizePalette(HDC hDC)
 {
-  /*
-   * This function doesn't do any real work now and there's plenty
-   * of bugs in it.
-   */
-
-  PPALETTE palGDI, sysGDI;
-  int realized = 0;
-  PDC dc;
-  HPALETTE systemPalette;
-  USHORT sysMode, palMode;
-
-  dc = DC_LockDc(hDC);
-  if (!dc) return 0;
+    UINT i, realize = 0;
+    PDC pdc;
+    PALETTE *ppalSurf, *ppalDC;
 
-  systemPalette = NtGdiGetStockObject(DEFAULT_PALETTE);
-  palGDI = PALETTE_LockPalette(dc->dclevel.hpal);
-
-  if (palGDI == NULL)
-  {
-    DPRINT1("IntGdiRealizePalette(): palGDI is NULL, exiting\n");
-    DC_UnlockDc(dc);
-    return 0;
-  }
+    pdc = DC_LockDc(hDC);
+    if(!pdc)
+    {
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return 0;
+    }
 
-  sysGDI = PALETTE_LockPalette(systemPalette);
+    ppalSurf = pdc->dclevel.pSurface->ppal;
+    ppalDC = pdc->dclevel.ppal;
 
-  if (sysGDI == NULL)
-  {
-    DPRINT1("IntGdiRealizePalette(): sysGDI is NULL, exiting\n");
-    PALETTE_UnlockPalette(palGDI);
-    DC_UnlockDc(dc);
-    return 0;
-  }
+    if(!(ppalSurf->flFlags & PAL_INDEXED))
+    {
+        // FIXME : set error?
+        goto cleanup;
+    }
 
-  // The RealizePalette function modifies the palette for the device associated with the specified device context. If the
-  // device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device
-  // context is a display DC, the physical palette for that device is modified.
-  if(dc->dctype == DC_TYPE_MEMORY)
-  {
-    // Memory managed DC
-    DPRINT1("RealizePalette unimplemented for memory managed DCs\n");
-  } else
-  {
-    DPRINT1("RealizePalette unimplemented for device DCs\n");
-  }
+    ASSERT(ppalDC->flFlags & PAL_INDEXED);
 
-  // need to pass this to IntEngCreateXlate with palettes unlocked
-  sysMode = sysGDI->Mode;
-  palMode = palGDI->Mode;
-  PALETTE_UnlockPalette(sysGDI);
-  PALETTE_UnlockPalette(palGDI);
+    // FIXME : should we resize ppalSurf if it's too small?
+    realize = (ppalDC->NumColors < ppalSurf->NumColors) ? ppalDC->NumColors : ppalSurf->NumColors;
 
-  DC_UnlockDc(dc);
+    for(i=0; i<realize; i++)
+    {
+        InterlockedExchange((LONG*)&ppalSurf->IndexedColors[i], *(LONG*)&ppalDC->IndexedColors[i]);
+    }
 
-  return realized;
+cleanup:
+    DC_UnlockDc(pdc);
+    return realize;
 }
 
 UINT APIENTRY
@@ -771,7 +774,7 @@ IntAnimatePalette(HPALETTE hPal,
         UINT pal_entries;
         HDC hDC;
         PDC dc;
-        PWINDOW_OBJECT Wnd;
+        PWND Wnd;
         const PALETTEENTRY *pptr = PaletteColors;
 
         palPtr = (PPALETTE)PALETTE_LockPalette(hPal);
@@ -870,7 +873,7 @@ IntGetSystemPaletteEntries(HDC  hDC,
 
     if (Entries == 0)
     {
-        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+        EngSetLastError(ERROR_INVALID_PARAMETER);
         return 0;
     }
 
@@ -880,14 +883,14 @@ IntGetSystemPaletteEntries(HDC  hDC,
         if (Entries != EntriesSize / sizeof(pe[0]))
         {
             /* Integer overflow! */
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
+            EngSetLastError(ERROR_INVALID_PARAMETER);
             return 0;
         }
     }
 
     if (!(dc = DC_LockDc(hDC)))
     {
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
+        EngSetLastError(ERROR_INVALID_HANDLE);
         return 0;
     }
 
@@ -981,7 +984,7 @@ NtGdiDoPalette(
 
        if (pUnsafeEntries)
        {
-               pEntries = ExAllocatePool(PagedPool, cEntries * sizeof(PALETTEENTRY));
+               pEntries = ExAllocatePoolWithTag(PagedPool, cEntries * sizeof(PALETTEENTRY), TAG_PALETTE);
                if (!pEntries)
                        return 0;
                if (bInbound)
@@ -993,7 +996,7 @@ NtGdiDoPalette(
                        }
                        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
                        {
-                               ExFreePool(pEntries);
+                               ExFreePoolWithTag(pEntries, TAG_PALETTE);
                                _SEH2_YIELD(return 0);
                        }
                        _SEH2_END
@@ -1047,7 +1050,7 @@ NtGdiDoPalette(
                        }
                        _SEH2_END
                }
-               ExFreePool(pEntries);
+               ExFreePoolWithTag(pEntries, TAG_PALETTE);
        }
 
        return ret;
@@ -1090,7 +1093,7 @@ BOOL
 APIENTRY
 NtGdiUpdateColors(HDC hDC)
 {
-   PWINDOW_OBJECT Wnd;
+   PWND Wnd;
    BOOL calledFromUser, ret;
    USER_REFERENCE_ENTRY Ref;
 
@@ -1103,7 +1106,7 @@ NtGdiUpdateColors(HDC hDC)
    Wnd = UserGetWindowObject(IntWindowFromDC(hDC));
    if (Wnd == NULL)
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+      EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
 
       if (!calledFromUser){
          UserLeave();