[win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / objects / bitmaps.c
index 5e5d07f..12f3c2d 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
-/* $Id$ */
 
 #include <w32k.h>
 
@@ -76,7 +75,7 @@ IntGdiCreateBitmap(
     psurfBmp = SURFACE_LockSurface(hBitmap);
     if (psurfBmp == NULL)
     {
-        NtGdiDeleteObject(hBitmap);
+        GreDeleteObject(hBitmap);
         return NULL;
     }
 
@@ -154,7 +153,7 @@ IntCreateCompatibleBitmap(
         {
             DIBSECTION dibs;
             INT Count;
-            PSURFACE psurf = SURFACE_LockSurface(Dc->rosdc.hBitmap);
+            PSURFACE psurf = Dc->dclevel.pSurface;
             Count = BITMAP_GetObject(psurf, sizeof(dibs), &dibs);
 
             if (Count)
@@ -218,12 +217,11 @@ IntCreateCompatibleBitmap(
                         {
                             /* Copy the color table */
                             UINT Index;
-                            PPALGDI PalGDI = PALETTE_LockPalette(psurf->hDIBPalette);
+                            PPALETTE PalGDI = PALETTE_LockPalette(psurf->hDIBPalette);
 
                             if (!PalGDI)
                             {
                                 ExFreePoolWithTag(bi, TAG_TEMP);
-                                SURFACE_UnlockSurface(psurf);
                                 SetLastWin32Error(ERROR_INVALID_HANDLE);
                                 return 0;
                             }
@@ -239,7 +237,6 @@ IntCreateCompatibleBitmap(
                             }
                             PALETTE_UnlockPalette(PalGDI);
                         }
-                        SURFACE_UnlockSurface(psurf);
 
                         Bmp = DIB_CreateDIBSection(Dc,
                                                    bi,
@@ -254,7 +251,6 @@ IntCreateCompatibleBitmap(
                     }
                 }
             }
-            SURFACE_UnlockSurface(psurf);
         }
     }
     return Bmp;
@@ -281,7 +277,7 @@ NtGdiCreateCompatibleBitmap(
     Dc = DC_LockDc(hDC);
 
     DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n",
-           hDC, Width, Height, Dc->ppdev->GDIInfo.cBitsPixel);
+           hDC, Width, Height, Dc->ppdev->gdiinfo.cBitsPixel);
 
     if (NULL == Dc)
     {
@@ -338,8 +334,9 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
     BOOL bInRect = FALSE;
     SURFACE *psurf;
     SURFOBJ *pso;
-    HPALETTE Pal = 0;
-    XLATEOBJ *XlateObj;
+    HPALETTE hpal = 0;
+    PPALETTE ppal;
+    EXLATEOBJ exlo;
     HBITMAP hBmpTmp;
 
     dc = DC_LockDc(hDC);
@@ -361,27 +358,34 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
     if (RECTL_bPointInRect(&dc->rosdc.CombinedClip->rclBounds, XPos, YPos))
     {
         bInRect = TRUE;
-        psurf = SURFACE_LockSurface(dc->rosdc.hBitmap);
-        pso = &psurf->SurfObj;
+        psurf = dc->dclevel.pSurface;
         if (psurf)
         {
-            Pal = psurf->hDIBPalette;
-            if (!Pal) Pal = pPrimarySurface->DevInfo.hpalDefault;
+            pso = &psurf->SurfObj;
+            hpal = psurf->hDIBPalette;
+            if (!hpal) hpal = pPrimarySurface->devinfo.hpalDefault;
+            ppal = PALETTE_ShareLockPalette(hpal);
 
-            /* FIXME: Verify if it shouldn't be PAL_BGR! */
-            XlateObj = (XLATEOBJ*)IntEngCreateXlate(PAL_RGB, 0, NULL, Pal);
-            if (XlateObj)
+            if (psurf->SurfObj.iBitmapFormat == BMF_1BPP && !psurf->hSecure)
             {
-                // check if this DC has a DIB behind it...
-                if (pso->pvScan0) // STYPE_BITMAP == pso->iType
-                {
-                    ASSERT(pso->lDelta);
-                    Result = XLATEOBJ_iXlate(XlateObj,
-                                             DibFunctionsForBitmapFormat[pso->iBitmapFormat].DIB_GetPixel(pso, XPos, YPos));
-                }
-                EngDeleteXlate(XlateObj);
+                /* FIXME: palette should be gpalMono already ! */
+                EXLATEOBJ_vInitialize(&exlo, &gpalMono, &gpalRGB, 0, 0xffffff, 0);
+            }
+            else
+            {
+                EXLATEOBJ_vInitialize(&exlo, ppal, &gpalRGB, 0, 0xffffff, 0);
             }
-            SURFACE_UnlockSurface(psurf);
+
+            // check if this DC has a DIB behind it...
+            if (pso->pvScan0) // STYPE_BITMAP == pso->iType
+            {
+                ASSERT(pso->lDelta);
+                Result = XLATEOBJ_iXlate(&exlo.xlo,
+                                         DibFunctionsForBitmapFormat[pso->iBitmapFormat].DIB_GetPixel(pso, XPos, YPos));
+            }
+
+            EXLATEOBJ_vCleanup(&exlo);
+            PALETTE_ShareUnlockPalette(ppal);
         }
     }
     DC_UnlockDc(dc);
@@ -428,7 +432,7 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
                         SURFACE_UnlockSurface(psurf);
                     }
                 }
-                NtGdiDeleteObject(hBmpTmp);
+                GreDeleteObject(hBmpTmp);
             }
             NtGdiDeleteObjectApp(hDCTmp);
         }
@@ -485,7 +489,7 @@ NtGdiGetBitmapBits(
     OUT OPTIONAL PBYTE pUnsafeBits)
 {
     PSURFACE psurf;
-    LONG  ret;
+    LONG bmSize, ret;
 
     if (pUnsafeBits != NULL && Bytes == 0)
     {
@@ -499,16 +503,19 @@ NtGdiGetBitmapBits(
         return 0;
     }
 
+    bmSize = BITMAP_GetWidthBytes(psurf->SurfObj.sizlBitmap.cx,
+             BitsPerFormat(psurf->SurfObj.iBitmapFormat)) *
+             abs(psurf->SurfObj.sizlBitmap.cy);
+
     /* If the bits vector is null, the function should return the read size */
     if (pUnsafeBits == NULL)
     {
-        ret = psurf->SurfObj.cjBits;
         SURFACE_UnlockSurface(psurf);
-        return ret;
+        return bmSize;
     }
 
     /* Don't copy more bytes than the buffer has */
-    Bytes = min(Bytes, psurf->SurfObj.cjBits);
+    Bytes = min(Bytes, bmSize);
 
     // FIXME: use MmSecureVirtualMemory
     _SEH2_TRY
@@ -546,7 +553,7 @@ IntSetBitmapBits(
         DPRINT("Calling device specific BitmapBits\n");
         if (psurf->DDBitmap->funcs->pBitmapBits)
         {
-            ret = psurf->DDBitmap->funcs->pBitmapBits(hBitmap, 
+            ret = psurf->DDBitmap->funcs->pBitmapBits(hBitmap,
                                                       (void *)Bits,
                                                       Bytes,
                                                       DDB_SET);
@@ -648,6 +655,55 @@ NtGdiSetBitmapDimension(
     return Ret;
 }
 
+VOID IntHandleSpecialColorType(HDC hDC, COLORREF* Color)
+{
+    PDC pdc = NULL;
+    RGBQUAD quad;
+    PALETTEENTRY palEntry;
+    UINT index;
+
+    switch (*Color >> 24)
+    {
+        case 0x10: /* DIBINDEX */
+            if (IntGetDIBColorTable(hDC, LOWORD(*Color), 1, &quad) == 1) 
+            {
+                *Color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
+            }
+            else
+            {
+                /* Out of color table bounds - use black */
+                *Color = RGB(0, 0, 0);
+            }
+            break;
+        case 0x02: /* PALETTERGB */
+            pdc = DC_LockDc(hDC);
+            if (pdc->dclevel.hpal != NtGdiGetStockObject(DEFAULT_PALETTE))
+            {
+                index = NtGdiGetNearestPaletteIndex(pdc->dclevel.hpal, *Color);
+                IntGetPaletteEntries(pdc->dclevel.hpal, index, 1, &palEntry);
+                *Color = RGB(palEntry.peRed, palEntry.peGreen, palEntry.peBlue);
+            }
+            else
+            {
+                /* Use the pure color */
+                *Color = *Color & 0x00FFFFFF;
+            }
+            DC_UnlockDc(pdc);
+            break;
+        case 0x01: /* PALETTEINDEX */
+            pdc = DC_LockDc(hDC);
+            if (IntGetPaletteEntries(pdc->dclevel.hpal, LOWORD(*Color), 1, &palEntry) == 1)
+            {
+                *Color = RGB(palEntry.peRed, palEntry.peGreen, palEntry.peBlue);
+            }
+            DC_UnlockDc(pdc);
+            break;
+        default:
+            DPRINT("Unsupported color type %d passed\n", *Color >> 24);
+            break;
+    }   
+}
+
 BOOL APIENTRY
 GdiSetPixelV(
     HDC hDC,
@@ -655,22 +711,28 @@ GdiSetPixelV(
     INT Y,
     COLORREF Color)
 {
-    HBRUSH NewBrush = NtGdiCreateSolidBrush(Color, NULL);
+    HBRUSH hBrush;
     HGDIOBJ OldBrush;
 
-    if (NewBrush == NULL)
-        return(FALSE);
+    if ((Color & 0xFF000000) != 0)
+    {
+        IntHandleSpecialColorType(hDC, &Color);
+    }
+
+    hBrush = NtGdiCreateSolidBrush(Color, NULL);
+    if (hBrush == NULL)
+        return FALSE;
 
-    OldBrush = NtGdiSelectBrush(hDC, NewBrush);
+    OldBrush = NtGdiSelectBrush(hDC, hBrush);
     if (OldBrush == NULL)
     {
-        NtGdiDeleteObject(NewBrush);
-        return(FALSE);
+        GreDeleteObject(hBrush);
+        return FALSE;
     }
 
     NtGdiPatBlt(hDC, X, Y, 1, 1, PATCOPY);
     NtGdiSelectBrush(hDC, OldBrush);
-    NtGdiDeleteObject(NewBrush);
+    GreDeleteObject(hBrush);
 
     return TRUE;
 }
@@ -798,7 +860,7 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
             {
                 GDIOBJ_UnlockObjByPtr((POBJ)resBitmap);
                 GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
-                NtGdiDeleteObject(res);
+                GreDeleteObject(res);
                 return 0;
             }
             IntGetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
@@ -809,7 +871,7 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
         }
         else
         {
-            NtGdiDeleteObject(res);
+            GreDeleteObject(res);
             res = NULL;
         }
     }
@@ -852,7 +914,30 @@ BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer)
             pds->dsBmih.biHeight = pds->dsBm.bmHeight;
             pds->dsBmih.biPlanes = pds->dsBm.bmPlanes;
             pds->dsBmih.biBitCount = pds->dsBm.bmBitsPixel;
-            pds->dsBmih.biCompression = 0; // FIXME!
+            switch (psurf->SurfObj.iBitmapFormat)
+            {
+                /* FIXME: What about BI_BITFIELDS? */
+                case BMF_1BPP:
+                case BMF_4BPP:
+                case BMF_8BPP:
+                case BMF_16BPP:
+                case BMF_24BPP:
+                case BMF_32BPP:
+                   pds->dsBmih.biCompression = BI_RGB;
+                   break;
+                case BMF_4RLE:
+                   pds->dsBmih.biCompression = BI_RLE4;
+                   break;
+                case BMF_8RLE:
+                   pds->dsBmih.biCompression = BI_RLE8;
+                   break;
+                case BMF_JPEG:
+                   pds->dsBmih.biCompression = BI_JPEG;
+                   break;
+                case BMF_PNG:
+                   pds->dsBmih.biCompression = BI_PNG;
+                   break;
+            }
             pds->dsBmih.biSizeImage = psurf->SurfObj.cjBits;
             pds->dsBmih.biXPelsPerMeter = 0;
             pds->dsBmih.biYPelsPerMeter = 0;
@@ -894,105 +979,4 @@ NtGdiGetDCforBitmap(
     return hDC;
 }
 
-/*
- * @implemented
- */
-HBITMAP
-APIENTRY
-NtGdiSelectBitmap(
-    IN HDC hDC,
-    IN HBITMAP hBmp)
-{
-    PDC pDC;
-    PDC_ATTR pdcattr;
-    HBITMAP hOrgBmp;
-    PSURFACE psurfBmp;
-    HRGN hVisRgn;
-    BOOLEAN bFailed;
-    PGDIBRUSHOBJ pBrush;
-
-    if (hDC == NULL || hBmp == NULL) return NULL;
-
-    pDC = DC_LockDc(hDC);
-    if (!pDC)
-    {
-        return NULL;
-    }
-
-    pdcattr = pDC->pdcattr;
-
-    /* must be memory dc to select bitmap */
-    if (pDC->dctype != DC_TYPE_MEMORY)
-    {
-        DC_UnlockDc(pDC);
-        return NULL;
-    }
-
-    psurfBmp = SURFACE_LockSurface(hBmp);
-    if (!psurfBmp)
-    {
-        DC_UnlockDc(pDC);
-        return NULL;
-    }
-    hOrgBmp = pDC->rosdc.hBitmap;
-
-    /* Release the old bitmap, lock the new one and convert it to a SURF */
-    pDC->rosdc.hBitmap = hBmp;
-
-    // If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
-    pDC->dclevel.pSurface = psurfBmp;
-    psurfBmp->hDC = hDC;
-
-    // if we're working with a DIB, get the palette 
-    // [fixme: only create if the selected palette is null]
-    if (psurfBmp->hSecure)
-    {
-//        pDC->rosdcbitsPerPixel = psurfBmp->dib->dsBmih.biBitCount; ???
-        pDC->rosdc.bitsPerPixel = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
-    }
-    else
-    {
-        pDC->rosdc.bitsPerPixel = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
-    }
-
-    hVisRgn = NtGdiCreateRectRgn(0,
-                                 0,
-                                 psurfBmp->SurfObj.sizlBitmap.cx,
-                                 psurfBmp->SurfObj.sizlBitmap.cy);
-    SURFACE_UnlockSurface(psurfBmp);
-
-    /* Regenerate the XLATEOBJs. */
-    pBrush = BRUSHOBJ_LockBrush(pdcattr->hbrush);
-    if (pBrush)
-    {
-        if (pDC->rosdc.XlateBrush)
-        {
-            EngDeleteXlate(pDC->rosdc.XlateBrush);
-        }
-        pDC->rosdc.XlateBrush = IntGdiCreateBrushXlate(pDC, pBrush, &bFailed);
-        BRUSHOBJ_UnlockBrush(pBrush);
-    }
-
-    pBrush = PENOBJ_LockPen(pdcattr->hpen);
-    if (pBrush)
-    {
-        if (pDC->rosdc.XlatePen)
-        {
-            EngDeleteXlate(pDC->rosdc.XlatePen);
-        }
-        pDC->rosdc.XlatePen = IntGdiCreateBrushXlate(pDC, pBrush, &bFailed);
-        PENOBJ_UnlockPen(pBrush);
-    }
-
-    DC_UnlockDc(pDC);
-
-    if (hVisRgn)
-    {
-        GdiSelectVisRgn(hDC, hVisRgn);
-        NtGdiDeleteObject(hVisRgn);
-    }
-
-    return hOrgBmp;
-}
-
 /* EOF */