[WIN32K]
authorJérôme Gardou <jerome.gardou@reactos.org>
Tue, 1 Mar 2011 01:03:58 +0000 (01:03 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Tue, 1 Mar 2011 01:03:58 +0000 (01:03 +0000)
  - Raster operations in user mode are on higher bytes, whereas they are on lower bytes for drivers. Try to clarify this situation.
  - Add sanity check about what was said previously.
  - Implement masking in EngBitBlt
  - Rewrite NtGdiMaskBlt accordingly
  - Realize the palette when selecting it into a device DC.
  - When applying raster operation, do so only on 24 bits, we don't support alpha channel in win32k
This fixes VLC pink icons, Timo's MaskBlt tests and probably a lot of other things.
[SHELL32]
  - Use correct (?) raster operations for drawing sjortcuts.
Also note that now NtGdiMaskBlt locks the device contexts : this should avoid some race conditions, such as icons drawn on top of windows and the like.
Win32k sucks less.
So does reactos.
Dedicated to Timo. Sleep well, mate.

svn path=/trunk/; revision=50941

20 files changed:
reactos/dll/win32/shell32/iconcache.c
reactos/subsystems/win32/win32k/dib/dib.c
reactos/subsystems/win32/win32k/dib/dib.h
reactos/subsystems/win32/win32k/dib/dib1bpp.c
reactos/subsystems/win32/win32k/dib/stretchblt.c
reactos/subsystems/win32/win32k/eng/bitblt.c
reactos/subsystems/win32/win32k/eng/copybits.c
reactos/subsystems/win32/win32k/eng/mouse.c
reactos/subsystems/win32/win32k/eng/stretchblt.c
reactos/subsystems/win32/win32k/include/color.h
reactos/subsystems/win32/win32k/include/inteng.h
reactos/subsystems/win32/win32k/ntuser/painting.c
reactos/subsystems/win32/win32k/objects/bitblt.c
reactos/subsystems/win32/win32k/objects/dcobjs.c
reactos/subsystems/win32/win32k/objects/dibobj.c
reactos/subsystems/win32/win32k/objects/drawing.c
reactos/subsystems/win32/win32k/objects/fillshap.c
reactos/subsystems/win32/win32k/objects/freetype.c
reactos/subsystems/win32/win32k/objects/palette.c
reactos/subsystems/win32/win32k/objects/polyfill.c

index a57c33e..01e84c9 100644 (file)
@@ -180,8 +180,8 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
     if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor)) goto fail;
     if (!MaskBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
                  ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
     if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor)) goto fail;
     if (!MaskBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
                  ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
-                 ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0, 
-                 MAKEROP4(SRCCOPY, 0xAA0000)))
+                 ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0,
+                 MAKEROP4(0xAA0000, SRCCOPY)))
     {
         goto fail;
     }
     {
         goto fail;
     }
index 2066c9e..3776787 100644 (file)
@@ -87,11 +87,12 @@ DIB_FUNCTIONS DibFunctionsForBitmapFormat[] =
   }
 };
 
   }
 };
 
+
 ULONG
 DIB_DoRop(ULONG Rop, ULONG Dest, ULONG Source, ULONG Pattern)
 {
   ULONG ResultNibble;
 ULONG
 DIB_DoRop(ULONG Rop, ULONG Dest, ULONG Source, ULONG Pattern)
 {
   ULONG ResultNibble;
-  ULONG Result;
+  ULONG Result = 0;
   ULONG i;
 static const ULONG ExpandDest[16] =
     {
   ULONG i;
 static const ULONG ExpandDest[16] =
     {
@@ -151,31 +152,34 @@ static const ULONG ExpandDest[16] =
       0xF0F0F0F0 /* 1111 */,
     };
 
       0xF0F0F0F0 /* 1111 */,
     };
 
-  /* Optimized code for the various named rop codes. */
-  switch (Rop)
+    Rop &=0xFF;
+    switch(Rop)
     {
     {
-    case ROP3_TO_ROP4(BLACKNESS):   return(0);
-    case ROP3_TO_ROP4(NOTSRCERASE): return(~(Dest | Source));
-    case ROP3_TO_ROP4(NOTSRCCOPY):  return(~Source);
-    case ROP3_TO_ROP4(SRCERASE):    return((~Dest) & Source);
-    case ROP3_TO_ROP4(DSTINVERT):   return(~Dest);
-    case ROP3_TO_ROP4(PATINVERT):   return(Dest ^ Pattern);
-    case ROP3_TO_ROP4(SRCINVERT):   return(Dest ^ Source);
-    case ROP3_TO_ROP4(SRCAND):      return(Dest & Source);
-    case ROP3_TO_ROP4(MERGEPAINT):  return(Dest | (~Source));
-    case ROP3_TO_ROP4(SRCPAINT):    return(Dest | Source);
-    case ROP3_TO_ROP4(MERGECOPY):   return(Source & Pattern);
-    case ROP3_TO_ROP4(SRCCOPY):     return(Source);
-    case ROP3_TO_ROP4(PATCOPY):     return(Pattern);
-    case ROP3_TO_ROP4(PATPAINT):    return(Dest | (~Source) | Pattern);
-    case ROP3_TO_ROP4(WHITENESS):   return(0xFFFFFFFF);
+
+        /* Optimized code for the various named rop codes. */
+        case R3_OPINDEX_NOOP:        return(Dest);
+        case R3_OPINDEX_BLACKNESS:   return(0);
+        case R3_OPINDEX_NOTSRCERASE: return(~(Dest | Source));
+        case R3_OPINDEX_NOTSRCCOPY:  return(~Source);
+        case R3_OPINDEX_SRCERASE:    return((~Dest) & Source);
+        case R3_OPINDEX_DSTINVERT:   return(~Dest);
+        case R3_OPINDEX_PATINVERT:   return(Dest ^ Pattern);
+        case R3_OPINDEX_SRCINVERT:   return(Dest ^ Source);
+        case R3_OPINDEX_SRCAND:      return(Dest & Source);
+        case R3_OPINDEX_MERGEPAINT:  return(Dest | (~Source));
+        case R3_OPINDEX_SRCPAINT:    return(Dest | Source);
+        case R3_OPINDEX_MERGECOPY:   return(Source & Pattern);
+        case R3_OPINDEX_SRCCOPY:     return(Source);
+        case R3_OPINDEX_PATCOPY:     return(Pattern);
+        case R3_OPINDEX_PATPAINT:    return(Dest | (~Source) | Pattern);
+        case R3_OPINDEX_WHITENESS:   return(0xFFFFFFFF);
     }
     }
+
   /* Expand the ROP operation to all four bytes */
   /* Expand the ROP operation to all four bytes */
-  Rop &= 0xFF;
   Rop |= (Rop << 24) | (Rop << 16) | (Rop << 8);
   /* Do the operation on four bits simultaneously. */
   Result = 0;
   Rop |= (Rop << 24) | (Rop << 16) | (Rop << 8);
   /* Do the operation on four bits simultaneously. */
   Result = 0;
-  for (i = 0; i < 8; i++)
+  for (i = 0; i < 6; i++)
   {
     ResultNibble = Rop & ExpandDest[Dest & 0xF] & ExpandSource[Source & 0xF] & ExpandPattern[Pattern & 0xF];
     Result |= (((ResultNibble & 0xFF000000) ? 0x8 : 0x0) | ((ResultNibble & 0x00FF0000) ? 0x4 : 0x0) |
   {
     ResultNibble = Rop & ExpandDest[Dest & 0xF] & ExpandSource[Source & 0xF] & ExpandPattern[Pattern & 0xF];
     Result |= (((ResultNibble & 0xFF000000) ? 0x8 : 0x0) | ((ResultNibble & 0x00FF0000) ? 0x4 : 0x0) |
index 4ae455b..5db2f04 100644 (file)
@@ -31,7 +31,7 @@ typedef struct _BLTINFO
   POINTL SourcePoint;
   BRUSHOBJ *Brush;
   POINTL BrushOrigin;
   POINTL SourcePoint;
   BRUSHOBJ *Brush;
   POINTL BrushOrigin;
-  ULONG Rop4;
+  ROP4 Rop4;
 } BLTINFO, *PBLTINFO;
 
 typedef VOID (*PFN_DIB_PutPixel)(SURFOBJ*,LONG,LONG,ULONG);
 } BLTINFO, *PBLTINFO;
 
 typedef VOID (*PFN_DIB_PutPixel)(SURFOBJ*,LONG,LONG,ULONG);
index b924112..b245c52 100644 (file)
@@ -380,7 +380,7 @@ DIB_1BPP_BitBlt(PBLTINFO BltInfo)
           Pattern |= (DIB_GetSourceIndex(PatternObj, (X + BrushOrigin.x + k) % PatternWidth, PatternY) << (31 - k));
       }
 
           Pattern |= (DIB_GetSourceIndex(PatternObj, (X + BrushOrigin.x + k) % PatternWidth, PatternY) << (31 - k));
       }
 
-      Dest = DIB_DoRop(Rop4, Dest, Source, Pattern);
+      Dest = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern);
       Dest &= ~((1 << (31 - NoBits)) - 1);
       Dest |= *((PBYTE)DestBits) & ((1 << (31 - NoBits)) - 1);
 
       Dest &= ~((1 << (31 - NoBits)) - 1);
       Dest |= *((PBYTE)DestBits) & ((1 << (31 - NoBits)) - 1);
 
index b6d479d..45a5b8f 100644 (file)
@@ -43,6 +43,8 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *Ma
 
   LONG PatternX = 0, PatternY = 0;
 
 
   LONG PatternX = 0, PatternY = 0;
 
+  ASSERT(IS_VALID_ROP4(ROP));
+
   BOOL UsesSource = ROP4_USES_SOURCE(ROP);
   BOOL UsesPattern = ROP4_USES_PATTERN(ROP);
 
   BOOL UsesSource = ROP4_USES_SOURCE(ROP);
   BOOL UsesPattern = ROP4_USES_PATTERN(ROP);
 
@@ -122,7 +124,7 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *Ma
       {
         sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth;
         if (sx < 0 || sy < 0 ||
       {
         sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth;
         if (sx < 0 || sy < 0 ||
-          MaskSurf->sizlBitmap.cx < sx || MaskSurf->sizlBitmap.cy < sy || 
+          MaskSurf->sizlBitmap.cx < sx || MaskSurf->sizlBitmap.cy < sy ||
           fnMask_GetPixel(MaskSurf, sx, sy) != 0)
         {
           CanDraw = FALSE;
           fnMask_GetPixel(MaskSurf, sx, sy) != 0)
         {
           CanDraw = FALSE;
@@ -137,10 +139,10 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *Ma
         {
           Source = XLATEOBJ_iXlate(ColorTranslation, fnSource_GetPixel(SourceSurf, sx, sy));
         }
         {
           Source = XLATEOBJ_iXlate(ColorTranslation, fnSource_GetPixel(SourceSurf, sx, sy));
         }
-        else 
+        else
         {
           Source = 0;
         {
           Source = 0;
-          CanDraw = (ROP3_TO_ROP4(SRCCOPY) != ROP);
+          CanDraw = ((ROP & 0xFF) != R3_OPINDEX_SRCCOPY);
         }
       }
 
         }
       }
 
index 029f55e..6b6ee51 100644 (file)
@@ -27,11 +27,11 @@ typedef BOOLEAN (APIENTRY *PBLTRECTFUNC)(SURFOBJ* OutputObj,
 
 static BOOLEAN APIENTRY
 BltMask(SURFOBJ* psoDest,
 
 static BOOLEAN APIENTRY
 BltMask(SURFOBJ* psoDest,
-        SURFOBJ* psoSource, // unused
+        SURFOBJ* psoSource,
         SURFOBJ* psoMask,
         SURFOBJ* psoMask,
-        XLATEOBJ* ColorTranslation,  // unused
+        XLATEOBJ* ColorTranslation,
         RECTL* prclDest,
         RECTL* prclDest,
-        POINTL* pptlSource, // unused
+        POINTL* pptlSource,
         POINTL* pptlMask,
         BRUSHOBJ* pbo,
         POINTL* pptlBrush,
         POINTL* pptlMask,
         BRUSHOBJ* pbo,
         POINTL* pptlBrush,
@@ -46,19 +46,21 @@ BltMask(SURFOBJ* psoDest,
     PSURFACE psurfPattern;
     ULONG PatternWidth = 0, PatternHeight = 0;
     LONG PatternX0 = 0, PatternX = 0, PatternY = 0;
     PSURFACE psurfPattern;
     ULONG PatternWidth = 0, PatternHeight = 0;
     LONG PatternX0 = 0, PatternX = 0, PatternY = 0;
+    LONG SrcX = 0, SrcY = 0;
     PFN_DIB_PutPixel fnDest_PutPixel = NULL;
     PFN_DIB_PutPixel fnDest_PutPixel = NULL;
-    PFN_DIB_GetPixel fnPattern_GetPixel = NULL;
-    ULONG Pattern = 0;
+    PFN_DIB_GetPixel fnPattern_GetPixel = NULL, fnSrc_GetPixel = NULL, fnDest_GetPixel;
+    ULONG Pattern = 0, Source = 0, Dest = 0;
     HBITMAP hbmPattern;
     HBITMAP hbmPattern;
+    DWORD fgndRop, bkgndRop;
 
 
-    ASSERT(psoSource == NULL);
-    ASSERT(pptlSource == NULL);
+    ASSERT(IS_VALID_ROP4(Rop4));
 
 
-    if (psoMask == NULL)
-    {
-        return FALSE;
-    }
+    fgndRop = ROP4_FGND(Rop4);
+    bkgndRop = ROP4_BKGND(Rop4);
 
 
+    //DPRINT1("Rop4 : 0x%08x\n", Rop4);
+
+    /* Determine pattern */
     if (pbo && pbo->iSolidColor == 0xFFFFFFFF)
     {
         pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
     if (pbo && pbo->iSolidColor == 0xFFFFFFFF)
     {
         pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
@@ -80,6 +82,18 @@ BltMask(SURFOBJ* psoDest,
     fjMaskBit0 = 0x80 >> (pptlMask->x & 0x07);
 
     fnDest_PutPixel = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_PutPixel;
     fjMaskBit0 = 0x80 >> (pptlMask->x & 0x07);
 
     fnDest_PutPixel = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_PutPixel;
+    fnDest_GetPixel = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_GetPixel;
+
+    /* Do we have a source */
+    if(psoSource)
+    {
+        /* Sanity check */
+        ASSERT(ROP4_USES_SOURCE(Rop4));
+        fnSrc_GetPixel = DibFunctionsForBitmapFormat[psoSource->iBitmapFormat].DIB_GetPixel;
+        SrcY = pptlSource->y;
+        SrcX = pptlSource->x;
+    }
+
     if (psurfPattern)
     {
         PatternY = (prclDest->top - pptlBrush->y) % PatternHeight;
     if (psurfPattern)
     {
         PatternY = (prclDest->top - pptlBrush->y) % PatternHeight;
@@ -92,48 +106,64 @@ BltMask(SURFOBJ* psoDest,
         {
             PatternX0 += PatternWidth;
         }
         {
             PatternX0 += PatternWidth;
         }
+        PatternX = PatternX0;
+    }
+    else
+    {
+        Pattern = pbo ? pbo->iSolidColor : 0;
+    }
 
 
-        for (y = prclDest->top; y < prclDest->bottom; y++)
+    for (y = prclDest->top; y < prclDest->bottom; y++)
+    {
+        pjMskCurrent = pjMskLine;
+        fjMaskBit = fjMaskBit0;
+
+        for (x = prclDest->left; x < prclDest->right; x++)
         {
         {
-            pjMskCurrent = pjMskLine;
-            fjMaskBit = fjMaskBit0;
-            PatternX = PatternX0;
+            Rop4 = (*pjMskCurrent & fjMaskBit) ? fgndRop : bkgndRop;
 
 
-            for (x = prclDest->left; x < prclDest->right; x++)
+            if(psurfPattern)
             {
             {
-                if (*pjMskCurrent & fjMaskBit)
-                {
-                    fnDest_PutPixel(psoDest, x, y,
-                        fnPattern_GetPixel(psoPattern, PatternX, PatternY));
-                }
-                fjMaskBit = _rotr8(fjMaskBit, 1);
-                pjMskCurrent += (fjMaskBit >> 7);
+                if(ROP4_USES_PATTERN(Rop4))
+                    Pattern = fnPattern_GetPixel(psoPattern, PatternX, PatternY);
                 PatternX++;
                 PatternX %= PatternWidth;
             }
                 PatternX++;
                 PatternX %= PatternWidth;
             }
-            pjMskLine += psoMask->lDelta;
-            PatternY++;
-            PatternY %= PatternHeight;
-        }
-    }
-    else
-    {
-        Pattern = pbo ? pbo->iSolidColor : 0;
-        for (y = prclDest->top; y < prclDest->bottom; y++)
-        {
-            pjMskCurrent = pjMskLine;
-            fjMaskBit = fjMaskBit0;
 
 
-            for (x = prclDest->left; x < prclDest->right; x++)
+            if(psoSource)
             {
             {
-                if (*pjMskCurrent & fjMaskBit)
+                if(ROP4_USES_SOURCE(Rop4))
                 {
                 {
-                     fnDest_PutPixel(psoDest, x, y, Pattern);
+                    Source = XLATEOBJ_iXlate(ColorTranslation,
+                                             fnSrc_GetPixel(psoSource, SrcX, SrcY));
                 }
                 }
-                fjMaskBit = _rotr8(fjMaskBit, 1);
-                pjMskCurrent += (fjMaskBit >> 7);
+                SrcX++;
             }
             }
-            pjMskLine += psoMask->lDelta;
+
+            if(ROP4_USES_DEST(Rop4))
+                Dest = fnDest_GetPixel(psoDest, x, y);
+
+            fnDest_PutPixel(psoDest,
+                            x,
+                            y,
+                            DIB_DoRop(Rop4,
+                                      Dest,
+                                      Source,
+                                      Pattern));
+            fjMaskBit = _rotr8(fjMaskBit, 1);
+            pjMskCurrent += (fjMaskBit >> 7);
+        }
+        pjMskLine += psoMask->lDelta;
+        if(psurfPattern)
+        {
+            PatternY++;
+            PatternY %= PatternHeight;
+            PatternX = PatternX0;
+        }
+        if(psoSource)
+        {
+            SrcY++;
+            SrcX = pptlSource->x;
         }
     }
 
         }
     }
 
@@ -153,7 +183,7 @@ BltPatCopy(SURFOBJ* Dest,
            POINTL* MaskPoint,
            BRUSHOBJ* pbo,
            POINTL* BrushPoint,
            POINTL* MaskPoint,
            BRUSHOBJ* pbo,
            POINTL* BrushPoint,
-           ROP4 Rop4)
+           DWORD Rop4)
 {
     // These functions are assigned if we're working with a DIB
     // The assigned functions depend on the bitsPerPixel of the DIB
 {
     // These functions are assigned if we're working with a DIB
     // The assigned functions depend on the bitsPerPixel of the DIB
@@ -188,7 +218,7 @@ CallDibBitBlt(SURFOBJ* OutputObj,
     BltInfo.DestRect = *OutputRect;
     BltInfo.SourcePoint = *InputPoint;
 
     BltInfo.DestRect = *OutputRect;
     BltInfo.SourcePoint = *InputPoint;
 
-    if (ROP3_TO_ROP4(SRCCOPY) == Rop4)
+    if ((Rop4 & 0xFF) == R3_OPINDEX_SRCCOPY)
         return DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
 
     BltInfo.Brush = pbo;
         return DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
 
     BltInfo.Brush = pbo;
@@ -244,7 +274,7 @@ NtGdiEngBitBlt(
                 IN POINTL  *pptlMask,
                 IN BRUSHOBJ  *pbo,
                 IN POINTL  *pptlBrush,
                 IN POINTL  *pptlMask,
                 IN BRUSHOBJ  *pbo,
                 IN POINTL  *pptlBrush,
-                IN ROP4  rop4    )
+                IN ROP4 Rop4)
 {
     RECTL  rclTrg;
     POINTL ptlSrc;
 {
     RECTL  rclTrg;
     POINTL ptlSrc;
@@ -272,7 +302,7 @@ NtGdiEngBitBlt(
     }
     _SEH2_END;
 
     }
     _SEH2_END;
 
-    return  EngBitBlt(psoTrg, psoSrc, psoMask, pco, pxlo, &rclTrg, &ptlSrc, &ptlMask, pbo, &ptlBrush, rop4);
+    return  EngBitBlt(psoTrg, psoSrc, psoMask, pco, pxlo, &rclTrg, &ptlSrc, &ptlMask, pbo, &ptlBrush, Rop4);
 }
 
 /*
 }
 
 /*
@@ -289,7 +319,7 @@ EngBitBlt(SURFOBJ *DestObj,
           POINTL *MaskOrigin,
           BRUSHOBJ *pbo,
           POINTL *BrushOrigin,
           POINTL *MaskOrigin,
           BRUSHOBJ *pbo,
           POINTL *BrushOrigin,
-          ROP4 rop4)
+          ROP4 Rop4)
 {
     BYTE               clippingType;
     RECTL              CombinedRect;
 {
     BYTE               clippingType;
     RECTL              CombinedRect;
@@ -306,16 +336,20 @@ EngBitBlt(SURFOBJ *DestObj,
     unsigned           i;
     POINTL             Pt;
     ULONG              Direction;
     unsigned           i;
     POINTL             Pt;
     ULONG              Direction;
-    BOOL               UsesSource;
+    BOOL               UsesSource, UsesMask;
     POINTL             AdjustedBrushOrigin;
 
     POINTL             AdjustedBrushOrigin;
 
-    UsesSource = ROP4_USES_SOURCE(rop4);
-    if (R4_NOOP == rop4)
+    UsesSource = ROP4_USES_SOURCE(Rop4);
+    UsesMask = ROP4_USES_MASK(Rop4);
+
+    if (Rop4 == ROP4_NOOP)
     {
         /* Copy destination onto itself: nop */
         return TRUE;
     }
 
     {
         /* Copy destination onto itself: nop */
         return TRUE;
     }
 
+    //DPRINT1("Rop4 : 0x%08x\n", Rop4);
+
     OutputRect = *DestRect;
     if (OutputRect.right < OutputRect.left)
     {
     OutputRect = *DestRect;
     if (OutputRect.right < OutputRect.left)
     {
@@ -434,11 +468,11 @@ EngBitBlt(SURFOBJ *DestObj,
         clippingType = ClipRegion->iDComplexity;
     }
 
         clippingType = ClipRegion->iDComplexity;
     }
 
-    if (R4_MASK == rop4)
+    if (UsesMask)
     {
         BltRectFunc = BltMask;
     }
     {
         BltRectFunc = BltMask;
     }
-    else if (ROP3_TO_ROP4(PATCOPY) == rop4)
+    else if ((Rop4 & 0xFF) == R3_OPINDEX_PATCOPY)
     {
         if (pbo && pbo->iSolidColor == 0xFFFFFFFF)
             BltRectFunc = CallDibBitBlt;
     {
         if (pbo && pbo->iSolidColor == 0xFFFFFFFF)
             BltRectFunc = CallDibBitBlt;
@@ -456,7 +490,7 @@ EngBitBlt(SURFOBJ *DestObj,
         case DC_TRIVIAL:
             Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
                                  &OutputRect, &InputPoint, MaskOrigin, pbo,
         case DC_TRIVIAL:
             Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
                                  &OutputRect, &InputPoint, MaskOrigin, pbo,
-                                 &AdjustedBrushOrigin, rop4);
+                                 &AdjustedBrushOrigin, Rop4);
             break;
         case DC_RECT:
             /* Clip the blt to the clip rectangle */
             break;
         case DC_RECT:
             /* Clip the blt to the clip rectangle */
@@ -470,7 +504,7 @@ EngBitBlt(SURFOBJ *DestObj,
                 Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
                 Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
                                      &CombinedRect, &Pt, MaskOrigin, pbo,
                 Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top;
                 Ret = (*BltRectFunc)(OutputObj, InputObj, Mask, ColorTranslation,
                                      &CombinedRect, &Pt, MaskOrigin, pbo,
-                                     &AdjustedBrushOrigin, rop4);
+                                     &AdjustedBrushOrigin, Rop4);
             }
             break;
         case DC_COMPLEX:
             }
             break;
         case DC_COMPLEX:
@@ -511,7 +545,7 @@ EngBitBlt(SURFOBJ *DestObj,
                         Ret = (*BltRectFunc)(OutputObj, InputObj, Mask,
                                              ColorTranslation, &CombinedRect, &Pt,
                                              MaskOrigin, pbo, &AdjustedBrushOrigin,
                         Ret = (*BltRectFunc)(OutputObj, InputObj, Mask,
                                              ColorTranslation, &CombinedRect, &Pt,
                                              MaskOrigin, pbo, &AdjustedBrushOrigin,
-                                             rop4) && Ret;
+                                             Rop4) && Ret;
                     }
                 }
             }
                     }
                 }
             }
@@ -534,7 +568,7 @@ IntEngBitBlt(
     POINTL *pptlMask,
     BRUSHOBJ *pbo,
     POINTL *pptlBrush,
     POINTL *pptlMask,
     BRUSHOBJ *pbo,
     POINTL *pptlBrush,
-    ROP4 rop4)
+    ROP4 Rop4)
 {
     SURFACE *psurfTrg;
     SURFACE *psurfSrc = NULL;
 {
     SURFACE *psurfTrg;
     SURFACE *psurfSrc = NULL;
@@ -550,6 +584,11 @@ IntEngBitBlt(
     rclClipped = *prclTrg;
     RECTL_vMakeWellOrdered(&rclClipped);
 
     rclClipped = *prclTrg;
     RECTL_vMakeWellOrdered(&rclClipped);
 
+    //DPRINT1("Rop4 : 0x%08x\n", Rop4);
+
+    /* Sanity check */
+    ASSERT(IS_VALID_ROP4(Rop4));
+
     if (pco)
     {
         /* Clip target rect against the bounds of the clipping region */
     if (pco)
     {
         /* Clip target rect against the bounds of the clipping region */
@@ -564,7 +603,7 @@ IntEngBitBlt(
             pco = NULL;
     }
 
             pco = NULL;
     }
 
-    if (ROP4_USES_SOURCE(rop4))
+    if (ROP4_USES_SOURCE(Rop4))
     {
         ASSERT(psoSrc);
         psurfSrc = CONTAINING_RECORD(psoSrc, SURFACE, SurfObj);
     {
         ASSERT(psoSrc);
         psurfSrc = CONTAINING_RECORD(psoSrc, SURFACE, SurfObj);
@@ -614,7 +653,7 @@ IntEngBitBlt(
                         pptlMask,
                         pbo,
                         pptlBrush,
                         pptlMask,
                         pbo,
                         pptlBrush,
-                        rop4);
+                        Rop4);
 
     // FIXME: cleanup temp surface!
 
 
     // FIXME: cleanup temp surface!
 
@@ -820,7 +859,7 @@ EngMaskBitBlt(SURFOBJ *psoDest,
             else
                 Ret = BltMask(psoOutput, NULL, psoInput, DestColorTranslation,
                               &OutputRect, NULL, &InputPoint, pbo, &AdjustedBrushOrigin,
             else
                 Ret = BltMask(psoOutput, NULL, psoInput, DestColorTranslation,
                               &OutputRect, NULL, &InputPoint, pbo, &AdjustedBrushOrigin,
-                              R4_MASK);
+                              ROP4_MASK);
             break;
         case DC_RECT:
             // Clip the blt to the clip rectangle
             break;
         case DC_RECT:
             // Clip the blt to the clip rectangle
@@ -840,7 +879,7 @@ EngMaskBitBlt(SURFOBJ *psoDest,
                 else
                 {
                     Ret = BltMask(psoOutput, NULL, psoInput, DestColorTranslation,
                 else
                 {
                     Ret = BltMask(psoOutput, NULL, psoInput, DestColorTranslation,
-                                  &CombinedRect, NULL, &Pt, pbo, &AdjustedBrushOrigin, R4_MASK);
+                                  &CombinedRect, NULL, &Pt, pbo, &AdjustedBrushOrigin, ROP4_MASK);
                 }
             }
             break;
                 }
             }
             break;
@@ -889,7 +928,7 @@ EngMaskBitBlt(SURFOBJ *psoDest,
                             Ret = BltMask(psoOutput, NULL, psoInput,
                                           DestColorTranslation, &CombinedRect, NULL,
                                           &Pt, pbo, &AdjustedBrushOrigin,
                             Ret = BltMask(psoOutput, NULL, psoInput,
                                           DestColorTranslation, &CombinedRect, NULL,
                                           &Pt, pbo, &AdjustedBrushOrigin,
-                                          R4_MASK) && Ret;
+                                          ROP4_MASK) && Ret;
                         }
                     }
                 }
                         }
                     }
                 }
@@ -954,7 +993,7 @@ IntEngMaskBlt(SURFOBJ *psoDest,
        but the VMware driver doesn't hook that call. */
     IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
                    DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
        but the VMware driver doesn't hook that call. */
     IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
                    DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
-                   R4_NOOP);
+                   ROP4_NOOP);
 
     ret = EngMaskBitBlt(psoDest, psoMask, ClipRegion, DestColorTranslation, SourceColorTranslation,
                         &OutputRect, &InputPoint, pbo, BrushOrigin);
 
     ret = EngMaskBitBlt(psoDest, psoMask, ClipRegion, DestColorTranslation, SourceColorTranslation,
                         &OutputRect, &InputPoint, pbo, BrushOrigin);
@@ -962,7 +1001,7 @@ IntEngMaskBlt(SURFOBJ *psoDest,
     /* Dummy BitBlt to let driver know that something has changed. */
     IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
                    DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
     /* Dummy BitBlt to let driver know that something has changed. */
     IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
                    DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
-                   R4_NOOP);
+                   ROP4_NOOP);
 
     return ret;
 }
 
     return ret;
 }
index afb2f16..1200c1c 100644 (file)
@@ -92,7 +92,7 @@ EngCopyBits(SURFOBJ *psoDest,
         // If CopyBits wasn't hooked, BitBlt must be
         ret = IntEngBitBlt(psoDest, psoSource,
                            NULL, Clip, ColorTranslation, DestRect, SourcePoint,
         // If CopyBits wasn't hooked, BitBlt must be
         ret = IntEngBitBlt(psoDest, psoSource,
                            NULL, Clip, ColorTranslation, DestRect, SourcePoint,
-                           NULL, NULL, NULL, ROP3_TO_ROP4(SRCCOPY));
+                           NULL, NULL, NULL, ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
 
         goto cleanup;
     }
 
         goto cleanup;
     }
@@ -111,7 +111,7 @@ EngCopyBits(SURFOBJ *psoDest,
     BltInfo.SourceSurface = psoSource;
     BltInfo.PatternSurface = NULL;
     BltInfo.XlateSourceToDest = ColorTranslation;
     BltInfo.SourceSurface = psoSource;
     BltInfo.PatternSurface = NULL;
     BltInfo.XlateSourceToDest = ColorTranslation;
-    BltInfo.Rop4 = SRCCOPY;
+    BltInfo.Rop4 = ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY);
 
     switch (clippingType)
     {
 
     switch (clippingType)
     {
index b2db0e6..00dc033 100644 (file)
@@ -175,7 +175,7 @@ IntHideMousePointer(
                  &ptlSave,
                  NULL,
                  NULL,
                  &ptlSave,
                  NULL,
                  NULL,
-                 ROP3_TO_ROP4(SRCCOPY));
+                 ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
 }
 
 VOID
 }
 
 VOID
@@ -228,7 +228,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
                  NULL,
                  NULL,
                  NULL,
                  NULL,
                  NULL,
                  NULL,
-                 ROP3_TO_ROP4(SRCCOPY));
+                 ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
 
     /* Blt the pointer on the screen. */
     if (pgp->psurfColor)
 
     /* Blt the pointer on the screen. */
     if (pgp->psurfColor)
@@ -243,7 +243,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
                      NULL,
                      NULL,
                      NULL,
                      NULL,
                      NULL,
                      NULL,
-                     ROP3_TO_ROP4(SRCAND));
+                     ROP4_FROM_INDEX(R3_OPINDEX_SRCAND));
 
         IntEngBitBlt(psoDest,
                      &pgp->psurfColor->SurfObj,
 
         IntEngBitBlt(psoDest,
                      &pgp->psurfColor->SurfObj,
@@ -255,7 +255,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
                      NULL,
                      NULL,
                      NULL,
                      NULL,
                      NULL,
                      NULL,
-                     ROP3_TO_ROP4(SRCINVERT));
+                     ROP4_FROM_INDEX(R3_OPINDEX_SRCINVERT));
     }
     else
     {
     }
     else
     {
@@ -269,7 +269,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
                      NULL,
                      NULL,
                      NULL,
                      NULL,
                      NULL,
                      NULL,
-                     ROP3_TO_ROP4(SRCAND));
+                     ROP4_FROM_INDEX(R3_OPINDEX_SRCAND));
 
         rclPointer.top += pgp->Size.cy;
 
 
         rclPointer.top += pgp->Size.cy;
 
@@ -283,7 +283,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
                      NULL,
                      NULL,
                      NULL,
                      NULL,
                      NULL,
                      NULL,
-                     ROP3_TO_ROP4(SRCINVERT));
+                     ROP4_FROM_INDEX(R3_OPINDEX_SRCINVERT));
     }
 }
 
     }
 }
 
@@ -337,7 +337,7 @@ EngSetPointerShape(
         rectl.bottom = sizel.cy;
 
         /* Calculate lDelta for our surfaces. */
         rectl.bottom = sizel.cy;
 
         /* Calculate lDelta for our surfaces. */
-        lDelta = WIDTH_BYTES_ALIGN32(sizel.cx, 
+        lDelta = WIDTH_BYTES_ALIGN32(sizel.cx,
                                       BitsPerFormat(pso->iBitmapFormat));
 
         /* Create a bitmap for saving the pixels under the cursor. */
                                       BitsPerFormat(pso->iBitmapFormat));
 
         /* Create a bitmap for saving the pixels under the cursor. */
index a6f3d4f..1b4a7f9 100644 (file)
@@ -104,7 +104,7 @@ EngStretchBltROP(
     IN POINTL  *MaskOrigin,
     IN ULONG  Mode,
     IN BRUSHOBJ *pbo,
     IN POINTL  *MaskOrigin,
     IN ULONG  Mode,
     IN BRUSHOBJ *pbo,
-    IN DWORD ROP4)
+    IN ROP4 Rop4)
 {
     RECTL              InputRect;
     RECTL              OutputRect;
 {
     RECTL              InputRect;
     RECTL              OutputRect;
@@ -116,7 +116,7 @@ EngStretchBltROP(
     PSTRETCHRECTFUNC   BltRectFunc;
     BOOLEAN            Ret = TRUE;
     POINTL             AdjustedBrushOrigin;
     PSTRETCHRECTFUNC   BltRectFunc;
     BOOLEAN            Ret = TRUE;
     POINTL             AdjustedBrushOrigin;
-    BOOL               UsesSource = ROP4_USES_SOURCE(ROP4);
+    BOOL               UsesSource = ROP4_USES_SOURCE(Rop4);
 
     BYTE               clippingType;
     RECTL              ClipRect;
 
     BYTE               clippingType;
     RECTL              ClipRect;
@@ -132,6 +132,13 @@ EngStretchBltROP(
     LONG SrcHeight;
     LONG SrcWidth;
 
     LONG SrcHeight;
     LONG SrcWidth;
 
+    if (Rop4 == ROP4_NOOP)
+    {
+        /* Copy destination onto itself: nop */
+        return TRUE;
+    }
+
+
     /* Determine clipping type */
     if (ClipRegion == (CLIPOBJ *) NULL)
     {
     /* Determine clipping type */
     if (ClipRegion == (CLIPOBJ *) NULL)
     {
@@ -142,12 +149,6 @@ EngStretchBltROP(
         clippingType = ClipRegion->iDComplexity;
     }
 
         clippingType = ClipRegion->iDComplexity;
     }
 
-    if (ROP4 == R4_NOOP)
-    {
-        /* Copy destination onto itself: nop */
-        return TRUE;
-    }
-
     OutputRect = *prclDest;
     if (OutputRect.right < OutputRect.left)
     {
     OutputRect = *prclDest;
     if (OutputRect.right < OutputRect.left)
     {
@@ -257,7 +258,7 @@ EngStretchBltROP(
         case DC_TRIVIAL:
             Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
                          ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
         case DC_TRIVIAL:
             Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
                          ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
-                         pbo, &AdjustedBrushOrigin, ROP4);
+                         pbo, &AdjustedBrushOrigin, Rop4);
             break;
         case DC_RECT:
             // Clip the blt to the clip rectangle
             break;
         case DC_RECT:
             // Clip the blt to the clip rectangle
@@ -278,7 +279,7 @@ EngStretchBltROP(
                            MaskOrigin,
                            pbo,
                            &AdjustedBrushOrigin,
                            MaskOrigin,
                            pbo,
                            &AdjustedBrushOrigin,
-                           ROP4);
+                           Rop4);
             }
             break;
         case DC_COMPLEX:
             }
             break;
         case DC_COMPLEX:
@@ -323,7 +324,7 @@ EngStretchBltROP(
                            MaskOrigin,
                            pbo,
                            &AdjustedBrushOrigin,
                            MaskOrigin,
                            pbo,
                            &AdjustedBrushOrigin,
-                           ROP4);
+                           Rop4);
                     }
                 }
             }
                     }
                 }
             }
@@ -371,7 +372,7 @@ EngStretchBlt(
         MaskOrigin,
         Mode,
         NULL,
         MaskOrigin,
         Mode,
         NULL,
-        ROP3_TO_ROP4(SRCCOPY));
+        ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
 }
 
 BOOL APIENTRY
 }
 
 BOOL APIENTRY
@@ -385,7 +386,7 @@ IntEngStretchBlt(SURFOBJ *psoDest,
                  POINTL *pMaskOrigin,
                  BRUSHOBJ *pbo,
                  POINTL *BrushOrigin,
                  POINTL *pMaskOrigin,
                  BRUSHOBJ *pbo,
                  POINTL *BrushOrigin,
-                 ROP4 ROP)
+                 DWORD Rop4)
 {
     BOOLEAN ret;
     COLORADJUSTMENT ca;
 {
     BOOLEAN ret;
     COLORADJUSTMENT ca;
@@ -395,7 +396,7 @@ IntEngStretchBlt(SURFOBJ *psoDest,
     RECTL InputClippedRect;
     RECTL InputRect;
     RECTL OutputRect;
     RECTL InputClippedRect;
     RECTL InputRect;
     RECTL OutputRect;
-    BOOL UsesSource = ROP4_USES_SOURCE(ROP);
+    BOOL UsesSource = ROP4_USES_SOURCE(Rop4);
     LONG InputClWidth, InputClHeight, InputWidth, InputHeight;
 
     ASSERT(psoDest);
     LONG InputClWidth, InputClHeight, InputWidth, InputHeight;
 
     ASSERT(psoDest);
@@ -403,6 +404,9 @@ IntEngStretchBlt(SURFOBJ *psoDest,
     ASSERT(psurfDest);
     ASSERT(DestRect);
 
     ASSERT(psurfDest);
     ASSERT(DestRect);
 
+    /* Sanity check */
+    ASSERT(IS_VALID_ROP4(Rop4));
+
     InputClippedRect = *DestRect;
     if (InputClippedRect.right < InputClippedRect.left)
     {
     InputClippedRect = *DestRect;
     if (InputClippedRect.right < InputClippedRect.left)
     {
@@ -485,7 +489,7 @@ IntEngStretchBlt(SURFOBJ *psoDest,
                                                  &MaskOrigin,
                                                  COLORONCOLOR,
                                                  pbo,
                                                  &MaskOrigin,
                                                  COLORONCOLOR,
                                                  pbo,
-                                                 ROP);
+                                                 Rop4);
     }
 
     if (! ret)
     }
 
     if (! ret)
@@ -502,7 +506,7 @@ IntEngStretchBlt(SURFOBJ *psoDest,
                                &MaskOrigin,
                                COLORONCOLOR,
                                pbo,
                                &MaskOrigin,
                                COLORONCOLOR,
                                pbo,
-                               ROP);
+                               Rop4);
     }
 
     return ret;
     }
 
     return ret;
index 0972f2e..faf88a7 100644 (file)
@@ -27,7 +27,7 @@ typedef struct _COLORSPACE
 typedef struct _COLORTRANSFORMOBJ
 {
   BASEOBJECT BaseObject;
 typedef struct _COLORTRANSFORMOBJ
 {
   BASEOBJECT BaseObject;
-  HANDLE     hColorTransform; 
+  HANDLE     hColorTransform;
 } GDICLRXFORM, COLORTRANSFORMOBJ, *PCOLORTRANSFORMOBJ;
 
 extern HCOLORSPACE hStockColorSpace;
 } GDICLRXFORM, COLORTRANSFORMOBJ, *PCOLORTRANSFORMOBJ;
 
 extern HCOLORSPACE hStockColorSpace;
@@ -36,6 +36,6 @@ const PALETTEENTRY* FASTCALL COLOR_GetSystemPaletteTemplate (VOID);
 COLORREF APIENTRY COLOR_LookupNearestColor (PALETTEENTRY* palPalEntry, INT size, COLORREF color);
 INT APIENTRY COLOR_PaletteLookupExactIndex (PALETTEENTRY* palPalEntry, INT size, COLORREF col);
 INT APIENTRY COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, INT size, XLATEOBJ *XlateObj, COLORREF col, BOOL skipReserved);
 COLORREF APIENTRY COLOR_LookupNearestColor (PALETTEENTRY* palPalEntry, INT size, COLORREF color);
 INT APIENTRY COLOR_PaletteLookupExactIndex (PALETTEENTRY* palPalEntry, INT size, COLORREF col);
 INT APIENTRY COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, INT size, XLATEOBJ *XlateObj, COLORREF col, BOOL skipReserved);
-UINT FASTCALL IntGdiRealizePalette (HDC);
+UINT FASTCALL IntGdiRealizePalette (PDC);
 HCOLORSPACE FASTCALL IntGdiCreateColorSpace(PLOGCOLORSPACEEXW);
 BOOL FASTCALL IntGdiDeleteColorSpace(HCOLORSPACE);
 HCOLORSPACE FASTCALL IntGdiCreateColorSpace(PLOGCOLORSPACEEXW);
 BOOL FASTCALL IntGdiDeleteColorSpace(HCOLORSPACE);
index 1d8610d..4b360b0 100644 (file)
@@ -17,19 +17,40 @@ typedef struct tagSPAN
   ULONG Width;
 } SPAN, *PSPAN;
 
   ULONG Width;
 } SPAN, *PSPAN;
 
-#define R3_OPINDEX_SRCCOPY 0xcc
-#define R3_OPINDEX_NOOP 0xaa
-#define R4_NOOP ((R3_OPINDEX_NOOP << 8) | R3_OPINDEX_NOOP)
-#define R4_MASK ((R3_OPINDEX_NOOP << 8) | R3_OPINDEX_SRCCOPY)
+#define R3_OPINDEX_NOOP         0xAA
+
+#define R3_OPINDEX_BLACKNESS    0x00
+#define R3_OPINDEX_NOTSRCERASE  0x11
+#define R3_OPINDEX_NOTSRCCOPY   0x33
+#define R3_OPINDEX_SRCERASE     0x44
+#define R3_OPINDEX_DSTINVERT    0x55
+#define R3_OPINDEX_PATINVERT    0x5A
+#define R3_OPINDEX_SRCINVERT    0x66
+#define R3_OPINDEX_SRCAND       0x88
+#define R3_OPINDEX_MERGEPAINT   0xBB
+#define R3_OPINDEX_MERGECOPY    0xC0
+#define R3_OPINDEX_SRCCOPY      0xCC
+#define R3_OPINDEX_SRCPAINT     0xEE
+#define R3_OPINDEX_PATCOPY      0xF0
+#define R3_OPINDEX_PATPAINT     0xFB
+#define R3_OPINDEX_WHITENESS    0xFF
 
 #define ROP2_TO_MIX(Rop2) (((Rop2) << 8) | (Rop2))
 
 #define ROP2_TO_MIX(Rop2) (((Rop2) << 8) | (Rop2))
-#define ROP3_USES_DEST(Rop3)   ((((Rop3) & 0xAA0000) >> 1) != ((Rop3) & 0x550000))
-#define ROP4_USES_DEST(Rop4)   (((((Rop4) & 0xAA) >> 1) != ((Rop4) & 0x55)) || ((((Rop4) & 0xAA00) >> 1) != ((Rop4) & 0x5500)))
-#define ROP3_USES_SOURCE(Rop3) ((((Rop3) & 0xCC0000) >> 2) != ((Rop3) & 0x330000))
-#define ROP4_USES_SOURCE(Rop4) (((((Rop4) & 0xCC) >> 2) != ((Rop4) & 0x33)) || ((((Rop4) & 0xCC00) >> 2) != ((Rop4) & 0x3300)))
-#define ROP3_USES_PATTERN(Rop3) ((((Rop3) & 0xF00000) >> 4) != ((Rop3) & 0x0F0000))
+
+#define ROP4_FROM_INDEX(index) ((index) | ((index) << 8))
+
+#define ROP4_USES_SOURCE(Rop4)  (((((Rop4) & 0xCC00) >> 2) != ((Rop4) & 0x3300)) || ((((Rop4) & 0xCC) >> 2) != ((Rop4) & 0x33)))
+#define ROP4_USES_MASK(Rop4)    (((Rop4) & 0xFF00) != (((Rop4) & 0xff) << 8))
+#define ROP4_USES_DEST(Rop4)    (((((Rop4) & 0xAA) >> 1) != ((Rop4) & 0x55)) || ((((Rop4) & 0xAA00) >> 1) != ((Rop4) & 0x5500)))
 #define ROP4_USES_PATTERN(Rop4) (((((Rop4) & 0xF0) >> 4) != ((Rop4) & 0x0F)) || ((((Rop4) & 0xF000) >> 4) != ((Rop4) & 0x0F00)))
 #define ROP4_USES_PATTERN(Rop4) (((((Rop4) & 0xF0) >> 4) != ((Rop4) & 0x0F)) || ((((Rop4) & 0xF000) >> 4) != ((Rop4) & 0x0F00)))
-#define ROP3_TO_ROP4(Rop3) ((((Rop3) >> 8) & 0xff00) | (((Rop3) >> 16) & 0x00ff))
+
+#define IS_VALID_ROP4(rop) (((rop) & 0xFFFF0000) == 0)
+
+#define ROP4_FGND(Rop4)    ((Rop4) & 0x00FF)
+#define ROP4_BKGND(Rop4)    (((Rop4) & 0xFF00) >> 8)
+
+#define ROP4_NOOP (R3_OPINDEX_NOOP | (R3_OPINDEX_NOOP << 8))
+#define ROP4_MASK (R3_OPINDEX_SRCCOPY | (R3_OPINDEX_NOOP << 8))
 
 /* Definitions of IntEngXxx functions */
 
 
 /* Definitions of IntEngXxx functions */
 
index beedd93..8692a03 100644 (file)
@@ -307,7 +307,7 @@ co_IntPaintWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
 /*
  * IntInvalidateWindows
  *
 /*
  * IntInvalidateWindows
  *
- * Internal function used by IntRedrawWindow, UserRedrawDesktop, 
+ * Internal function used by IntRedrawWindow, UserRedrawDesktop,
  * co_WinPosSetWindowPos, IntValidateParent, co_UserRedrawWindow.
  */
 VOID FASTCALL
  * co_WinPosSetWindowPos, IntValidateParent, co_UserRedrawWindow.
  */
 VOID FASTCALL
@@ -759,7 +759,7 @@ IntPrintWindow(
        xSrc = 0;
        ySrc = 0;
     }
        xSrc = 0;
        ySrc = 0;
     }
-    
+
     // TODO: Setup Redirection for Print.
     return FALSE;
 
     // TODO: Setup Redirection for Print.
     return FALSE;
 
@@ -1951,7 +1951,11 @@ UserRealizePalette(HDC hdc)
   HWND hWnd;
   DWORD Ret;
 
   HWND hWnd;
   DWORD Ret;
 
-  Ret = IntGdiRealizePalette(hdc);
+  PDC pdc = DC_LockDc(hdc);
+  if(!pdc)
+    return 0;
+
+  Ret = IntGdiRealizePalette(pdc);
   if (Ret) // There was a change.
   {
       hWnd = IntWindowFromDC(hdc);
   if (Ret) // There was a change.
   {
       hWnd = IntWindowFromDC(hdc);
@@ -1960,6 +1964,7 @@ UserRealizePalette(HDC hdc)
          UserSendNotifyMessage((HWND)HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hWnd, 0);
       }
   }
          UserSendNotifyMessage((HWND)HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hWnd, 0);
       }
   }
+  DC_UnlockDc(pdc);
   return Ret;
 }
 
   return Ret;
 }
 
@@ -2065,7 +2070,7 @@ NtUserPrintWindow(
     HDC  hdcBlt,
     UINT nFlags)
 {
     HDC  hdcBlt,
     UINT nFlags)
 {
-    PWND Window;   
+    PWND Window;
     BOOL Ret = FALSE;
 
     UserEnterExclusive();
     BOOL Ret = FALSE;
 
     UserEnterExclusive();
@@ -2075,7 +2080,7 @@ NtUserPrintWindow(
        Window = UserGetWindowObject(hwnd);
        // TODO: Add Desktop and MessageBox check via FNID's.
        if ( Window )
        Window = UserGetWindowObject(hwnd);
        // TODO: Add Desktop and MessageBox check via FNID's.
        if ( Window )
-       { 
+       {
           /* Validate flags and check it as a mask for 0 or 1. */
           if ( (nFlags & PW_CLIENTONLY) == nFlags)
              Ret = IntPrintWindow( Window, hdcBlt, nFlags);
           /* Validate flags and check it as a mask for 0 or 1. */
           if ( (nFlags & PW_CLIENTONLY) == nFlags)
              Ret = IntPrintWindow( Window, hdcBlt, nFlags);
index 0f77537..1fa1d55 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
 #define NDEBUG
 #include <debug.h>
 
+#define ROP_USES_SOURCE(Rop)  (((((Rop) & 0xCC0000) >> 2) != ((Rop) & 0x330000)) || ((((Rop) & 0xCC000000) >> 2) != ((Rop) & 0x33000000)))
+#define ROP_USES_MASK(Rop)    (((Rop) & 0xFF000000) != (((Rop) & 0xff0000) << 8))
 
 
+#define FIXUP_ROP(Rop) if(((Rop) & 0xFF000000) == 0) Rop = MAKEROP4((Rop), (Rop))
+#define ROP_TO_ROP4(Rop) ((Rop) >> 16)
 
 BOOL APIENTRY
 NtGdiAlphaBlend(
 
 BOOL APIENTRY
 NtGdiAlphaBlend(
@@ -169,144 +173,21 @@ NtGdiBitBlt(
     IN DWORD crBackColor,
     IN FLONG fl)
 {
     IN DWORD crBackColor,
     IN FLONG fl)
 {
-    PDC DCDest;
-    PDC DCSrc = NULL;
-    HDC ahDC[2];
-    PGDIOBJ apObj[2];
-    PDC_ATTR pdcattr = NULL;
-    SURFACE *BitmapDest, *BitmapSrc = NULL;
-    RECTL DestRect, SourceRect;
-    POINTL SourcePoint;
-    BOOL Status = FALSE;
-    EXLATEOBJ exlo;
-    XLATEOBJ *XlateObj = NULL;
-    BOOL UsesSource = ROP3_USES_SOURCE(ROP);
-
-    DPRINT("Locking DCs\n");
-    ahDC[0] = hDCDest;
-    ahDC[1] = hDCSrc ;
-    GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
-    DCDest = apObj[0];
-    DCSrc = apObj[1];
-
-    if (NULL == DCDest)
-    {
-        if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
-        DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest);
-        return FALSE;
-    }
-
-    if (DCDest->dctype == DC_TYPE_INFO)
-    {
-        if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
-        GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
-        /* Yes, Windows really returns TRUE in this case */
-        return TRUE;
-    }
-
-    if (UsesSource)
-    {
-        if (NULL == DCSrc)
-        {
-            GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
-            DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
-            return FALSE;
-        }
-        if (DCSrc->dctype == DC_TYPE_INFO)
-        {
-            GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
-            GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
-            /* Yes, Windows really returns TRUE in this case */
-            return TRUE;
-        }
-    }
-    else if(DCSrc)
-    {
-        DPRINT1("Getting a valid Source handle without using source!!!\n");
-        GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
-        DCSrc = NULL ;
-    }
-
-    pdcattr = DCDest->pdcattr;
-
-    DestRect.left   = XDest;
-    DestRect.top    = YDest;
-    DestRect.right  = XDest+Width;
-    DestRect.bottom = YDest+Height;
-    IntLPtoDP(DCDest, (LPPOINT)&DestRect, 2);
-
-    DestRect.left   += DCDest->ptlDCOrig.x;
-    DestRect.top    += DCDest->ptlDCOrig.y;
-    DestRect.right  += DCDest->ptlDCOrig.x;
-    DestRect.bottom += DCDest->ptlDCOrig.y;
-
-    SourcePoint.x = XSrc;
-    SourcePoint.y = YSrc;
-
-    if (UsesSource)
-    {
-        IntLPtoDP(DCSrc, (LPPOINT)&SourcePoint, 1);
-
-        SourcePoint.x += DCSrc->ptlDCOrig.x;
-        SourcePoint.y += DCSrc->ptlDCOrig.y;
-        /* Calculate Source Rect */
-        SourceRect.left = SourcePoint.x;
-        SourceRect.top = SourcePoint.y;
-        SourceRect.right = SourcePoint.x + DestRect.right - DestRect.left;
-        SourceRect.bottom = SourcePoint.y + DestRect.bottom - DestRect.top ;
-    }
-
-    /* Prepare blit */
-    DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
-
-    if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
-        DC_vUpdateFillBrush(DCDest);
-
-    /* Determine surfaces to be used in the bitblt */
-    BitmapDest = DCDest->dclevel.pSurface;
-    if (!BitmapDest)
-        goto cleanup;
-
-    if (UsesSource)
-    {
-        {
-            BitmapSrc = DCSrc->dclevel.pSurface;
-            if (!BitmapSrc)
-                goto cleanup;
-        }
-    }
-
-    /* Create the XLATEOBJ. */
-    if (UsesSource)
-    {
-        EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
-        XlateObj = &exlo.xlo;
-    }
-
-    /* Perform the bitblt operation */
-    Status = IntEngBitBlt(&BitmapDest->SurfObj,
-                          BitmapSrc ? &BitmapSrc->SurfObj : NULL,
-                          NULL,
-                          DCDest->rosdc.CombinedClip,
-                          XlateObj,
-                          &DestRect,
-                          &SourcePoint,
-                          NULL,
-                          &DCDest->eboFill.BrushObject,
-                          &DCDest->dclevel.pbrFill->ptOrigin,
-                          ROP3_TO_ROP4(ROP));
-
-    if (UsesSource)
-        EXLATEOBJ_vCleanup(&exlo);
-cleanup:
-    DC_vFinishBlit(DCDest, DCSrc);
-    if (UsesSource)
-    {
-        GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
-    }
-    GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
-
-    return Status;
+    /* Forward to NtGdiMaskBlt */
+    // TODO : what's fl for?
+    return NtGdiMaskBlt(hDCDest,
+                        XDest,
+                        YDest,
+                        Width,
+                        Height,
+                        hDCSrc,
+                        XSrc,
+                        YSrc,
+                        NULL,
+                        0,
+                        0,
+                        ROP,
+                        crBackColor);
 }
 
 BOOL APIENTRY
 }
 
 BOOL APIENTRY
@@ -414,86 +295,6 @@ done:
     return Ret;
 }
 
     return Ret;
 }
 
-/***********************************************************************
-* MaskBlt
-* Ported from WINE by sedwards 11-4-03
-*
-* Someone thought it would be faster to do it here and then switch back
-* to GDI32. I dunno. Write a test and let me know.
-* A. It should be in here!
-*/
-
-static const DWORD ROP3Table[256] =
-{
-  0x000042, 0x010289, 0x020C89, 0x0300AA, 0x040C88, 0x0500A9, 0x060865, 0x0702C5,
-  0x080F08, 0x090245, 0x0A0329, 0x0B0B2A, 0x0C0324, 0x0D0B25, 0x0E08A5, 0x0F0001,
-  0x100C85, 0x1100A6, 0x120868, 0x1302C8, 0x140869, 0x1502C9, 0x165CCA, 0x171D54,
-  0x180D59, 0x191CC8, 0x1A06C5, 0x1B0768, 0x1C06CA, 0x1D0766, 0x1E01A5, 0x1F0385,
-  0x200F09, 0x210248, 0x220326, 0x230B24, 0x240D55, 0x251CC5, 0x2606C8, 0x271868,
-  0x280369, 0x2916CA, 0x2A0CC9, 0x2B1D58, 0x2C0784, 0x2D060A, 0x2E064A, 0x2F0E2A,
-  0x30032A, 0x310B28, 0x320688, 0x330008, 0x3406C4, 0x351864, 0x3601A8, 0x370388,
-  0x38078A, 0x390604, 0x3A0644, 0x3B0E24, 0x3C004A, 0x3D18A4, 0x3E1B24, 0x3F00EA,
-  0x400F0A, 0x410249, 0x420D5D, 0x431CC4, 0x440328, 0x450B29, 0x4606C6, 0x47076A,
-  0x480368, 0x4916C5, 0x4A0789, 0x4B0605, 0x4C0CC8, 0x4D1954, 0x4E0645, 0x4F0E25,
-  0x500325, 0x510B26, 0x5206C9, 0x530764, 0x5408A9, 0x550009, 0x5601A9, 0x570389,
-  0x580785, 0x590609, 0x5A0049, 0x5B18A9, 0x5C0649, 0x5D0E29, 0x5E1B29, 0x5F00E9,
-  0x600365, 0x6116C6, 0x620786, 0x630608, 0x640788, 0x650606, 0x660046, 0x6718A8,
-  0x6858A6, 0x690145, 0x6A01E9, 0x6B178A, 0x6C01E8, 0x6D1785, 0x6E1E28, 0x6F0C65,
-  0x700CC5, 0x711D5C, 0x720648, 0x730E28, 0x740646, 0x750E26, 0x761B28, 0x7700E6,
-  0x7801E5, 0x791786, 0x7A1E29, 0x7B0C68, 0x7C1E24, 0x7D0C69, 0x7E0955, 0x7F03C9,
-  0x8003E9, 0x810975, 0x820C49, 0x831E04, 0x840C48, 0x851E05, 0x8617A6, 0x8701C5,
-  0x8800C6, 0x891B08, 0x8A0E06, 0x8B0666, 0x8C0E08, 0x8D0668, 0x8E1D7C, 0x8F0CE5,
-  0x900C45, 0x911E08, 0x9217A9, 0x9301C4, 0x9417AA, 0x9501C9, 0x960169, 0x97588A,
-  0x981888, 0x990066, 0x9A0709, 0x9B07A8, 0x9C0704, 0x9D07A6, 0x9E16E6, 0x9F0345,
-  0xA000C9, 0xA11B05, 0xA20E09, 0xA30669, 0xA41885, 0xA50065, 0xA60706, 0xA707A5,
-  0xA803A9, 0xA90189, 0xAA0029, 0xAB0889, 0xAC0744, 0xAD06E9, 0xAE0B06, 0xAF0229,
-  0xB00E05, 0xB10665, 0xB21974, 0xB30CE8, 0xB4070A, 0xB507A9, 0xB616E9, 0xB70348,
-  0xB8074A, 0xB906E6, 0xBA0B09, 0xBB0226, 0xBC1CE4, 0xBD0D7D, 0xBE0269, 0xBF08C9,
-  0xC000CA, 0xC11B04, 0xC21884, 0xC3006A, 0xC40E04, 0xC50664, 0xC60708, 0xC707AA,
-  0xC803A8, 0xC90184, 0xCA0749, 0xCB06E4, 0xCC0020, 0xCD0888, 0xCE0B08, 0xCF0224,
-  0xD00E0A, 0xD1066A, 0xD20705, 0xD307A4, 0xD41D78, 0xD50CE9, 0xD616EA, 0xD70349,
-  0xD80745, 0xD906E8, 0xDA1CE9, 0xDB0D75, 0xDC0B04, 0xDD0228, 0xDE0268, 0xDF08C8,
-  0xE003A5, 0xE10185, 0xE20746, 0xE306EA, 0xE40748, 0xE506E5, 0xE61CE8, 0xE70D79,
-  0xE81D74, 0xE95CE6, 0xEA02E9, 0xEB0849, 0xEC02E8, 0xED0848, 0xEE0086, 0xEF0A08,
-  0xF00021, 0xF10885, 0xF20B05, 0xF3022A, 0xF40B0A, 0xF50225, 0xF60265, 0xF708C5,
-  0xF802E5, 0xF90845, 0xFA0089, 0xFB0A09, 0xFC008A, 0xFD0A0A, 0xFE02A9, 0xFF0062,
-};
-
-static __inline BYTE
-SwapROP3_SrcDst(BYTE bRop3)
-{
-    return (bRop3 & 0x99) | ((bRop3 & 0x22) << 1) | ((bRop3 & 0x44) >> 1);
-}
-
-#define FRGND_ROP3(ROP4)    ((ROP4) & 0x00FFFFFF)
-#define BKGND_ROP3(ROP4)    (ROP3Table[(SwapROP3_SrcDst((ROP4)>>24)) & 0xFF])
-#define DSTCOPY    0x00AA0029
-#define DSTERASE    0x00220326 /* dest = dest & (~src) : DSna */
-
-/* NOTE: An alternative algorithm could use a pattern brush, created from
- * the mask bitmap and then use raster operation 0xCA to combine the fore
- * and background bitmaps. In this case erasing the bits beforehand would be
- * unneccessary. On the other hand the Operation does not provide an optimized
- * version in the DIB code, while SRCAND and SRCPAINT do.
- * A fully correct implementation would call Eng/DrvBitBlt, but our
- * EngBitBlt completely ignores the mask surface.
- *
- * Msk Fg Bk => x
- *  P  S  D        DPSDxax
- * ------------------------------------------
- *  0  0  0     0  0000xax = 000ax = 00x = 0
- *  0  0  1     1  1001xax = 101ax = 10x = 1
- *  0  1  0     0  0010xax = 001ax = 00x = 0
- *  0  1  1     1  1011xax = 100ax = 10x = 1
- *  1  0  0     0  0100xax = 010ax = 00x = 0
- *  1  0  1     0  1101xax = 111ax = 11x = 0
- *  1  1  0     1  0110xax = 011ax = 01x = 1
- *  1  1  1     1  1111xax = 110ax = 10x = 1
- *
- * Operation index = 11001010 = 0xCA = PSaDPnao = DPSDxax
- *                                     ^ no, this is not random letters, its reverse Polish notation
- */
-
 BOOL APIENTRY
 NtGdiMaskBlt(
     HDC hdcDest,
 BOOL APIENTRY
 NtGdiMaskBlt(
     HDC hdcDest,
@@ -510,97 +311,188 @@ NtGdiMaskBlt(
     DWORD dwRop,
     IN DWORD crBackColor)
 {
     DWORD dwRop,
     IN DWORD crBackColor)
 {
-    HBITMAP hbmFore, hbmBack;
-    HDC hdcMask, hdcFore, hdcBack;
-    PDC pdc;
-    HBRUSH hbr;
-    COLORREF crFore, crBack;
-
-    if (!hbmMask)
-        return NtGdiBitBlt(hdcDest,
-                           nXDest,
-                           nYDest,
-                           nWidth,
-                           nHeight,
-                           hdcSrc,
-                           nXSrc,
-                           nYSrc,
-                           FRGND_ROP3(dwRop),
-                           crBackColor,
-                           0);
-
-    /* Lock the dest DC */
-    pdc = DC_LockDc(hdcDest);
-    if (!pdc) return FALSE;
-
-    /* Get brush and colors from dest dc */
-    hbr = pdc->pdcattr->hbrush;
-    crFore = pdc->pdcattr->crForegroundClr;
-    crBack = pdc->pdcattr->crBackgroundClr;
-
-    /* Unlock the DC */
-    DC_UnlockDc(pdc);
+    PDC DCDest;
+    PDC DCSrc = NULL;
+    HDC ahDC[2];
+    PGDIOBJ apObj[2];
+    PDC_ATTR pdcattr = NULL;
+    SURFACE *BitmapDest, *BitmapSrc = NULL, *psurfMask = NULL;
+    RECTL DestRect, SourceRect;
+    POINTL SourcePoint, MaskPoint;
+    BOOL Status = FALSE;
+    EXLATEOBJ exlo;
+    XLATEOBJ *XlateObj = NULL;
+    BOOL UsesSource = ROP_USES_SOURCE(dwRop);
+    BOOL UsesMask;
 
 
-    /* 1. Create mask bitmap's dc */
-    hdcMask = NtGdiCreateCompatibleDC(hdcDest);
-    NtGdiSelectBitmap(hdcMask, hbmMask);
+    FIXUP_ROP(dwRop);
 
 
-    /* 2. Create masked Background bitmap */
+    UsesMask = ROP_USES_MASK(dwRop);
 
 
-    /* 2.1 Create bitmap */
-    hdcBack = NtGdiCreateCompatibleDC(hdcDest);
-    hbmBack = NtGdiCreateCompatibleBitmap(hdcDest, nWidth, nHeight);
-    NtGdiSelectBitmap(hdcBack, hbmBack);
+    //DPRINT1("dwRop : 0x%08x\n", dwRop);
 
 
-    /* 2.2 Copy source bitmap */
-    NtGdiSelectBrush(hdcBack, hbr);
-    IntGdiSetBkColor(hdcBack, crBack);
-    IntGdiSetTextColor(hdcBack, crFore);
-    NtGdiBitBlt(hdcBack, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY, 0, 0);
+    /* Take care of mask bitmap */
+    if(hbmMask)
+    {
+        psurfMask = SURFACE_LockSurface(hbmMask);
+        if(!psurfMask)
+        {
+            EngSetLastError(ERROR_INVALID_HANDLE);
+            return FALSE;
+        }
+    }
 
 
-    /* 2.3 Do the background rop */
-    NtGdiBitBlt(hdcBack, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, BKGND_ROP3(dwRop), 0, 0);
+    if(UsesMask)
+    {
+        if(!psurfMask)
+        {
+            EngSetLastError(ERROR_INVALID_PARAMETER);
+            return FALSE;
+        }
+        if(gajBitsPerFormat[psurfMask->SurfObj.iBitmapFormat] != 1)
+        {
+            EngSetLastError(ERROR_INVALID_PARAMETER);
+            SURFACE_UnlockSurface(psurfMask);
+            return FALSE;
+        }
+    }
+    else if(psurfMask)
+    {
+        DPRINT1("Getting Mask bitmap without needing it?\n");
+        SURFACE_UnlockSurface(psurfMask);
+        psurfMask = NULL;
+    }
+    MaskPoint.x = xMask;
+    MaskPoint.y = yMask;
 
 
-    /* 2.4 Erase the foreground pixels */
-    IntGdiSetBkColor(hdcBack, RGB(0xFF, 0xFF, 0xFF));
-    IntGdiSetTextColor(hdcBack, RGB(0, 0, 0));
-    NtGdiBitBlt(hdcBack, 0, 0, nWidth, nHeight, hdcMask, xMask, yMask, SRCAND, 0, 0);
+    /* Take care of source and destination bitmap */
+    DPRINT("Locking DCs\n");
+    ahDC[0] = hdcDest;
+    ahDC[1] = hdcSrc ;
+    GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
+    DCDest = apObj[0];
+    DCSrc = apObj[1];
 
 
-    /* 3. Create masked Foreground bitmap */
+    if (NULL == DCDest)
+    {
+        if(DCSrc) DC_UnlockDc(DCSrc);
+        DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hdcDest);
+        return FALSE;
+    }
 
 
-    /* 3.1 Create bitmap */
-    hdcFore = NtGdiCreateCompatibleDC(hdcDest);
-    hbmFore = NtGdiCreateCompatibleBitmap(hdcDest, nWidth, nHeight);
-    NtGdiSelectBitmap(hdcFore, hbmFore);
+    if (DCDest->dctype == DC_TYPE_INFO)
+    {
+        if(DCSrc) DC_UnlockDc(DCSrc);
+        DC_UnlockDc(DCDest);
+        /* Yes, Windows really returns TRUE in this case */
+        return TRUE;
+    }
 
 
-    /* 3.2 Copy the dest bitmap */
-    NtGdiSelectBrush(hdcFore, hbr);
-    IntGdiSetBkColor(hdcFore, crBack);
-    IntGdiSetTextColor(hdcFore, crFore);
-    NtGdiBitBlt(hdcFore, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY, 0, 0);
+    if (UsesSource)
+    {
+        if (NULL == DCSrc)
+        {
+            DC_UnlockDc(DCDest);
+            DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hdcSrc);
+            return FALSE;
+        }
+        if (DCSrc->dctype == DC_TYPE_INFO)
+        {
+            DC_UnlockDc(DCDest);
+            DC_UnlockDc(DCSrc);
+            /* Yes, Windows really returns TRUE in this case */
+            return TRUE;
+        }
+    }
+    else if(DCSrc)
+    {
+        DPRINT("Getting a valid Source handle without using source!!!\n");
+        DC_UnlockDc(DCSrc);
+        DCSrc = NULL ;
+    }
 
 
-    /* 2.3 Do the foreground rop */
-    NtGdiBitBlt(hdcFore, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop), 0,0);
+    pdcattr = DCDest->pdcattr;
 
 
-    /* 2.4 Erase the background pixels */
-    IntGdiSetBkColor(hdcFore, RGB(0, 0, 0));
-    IntGdiSetTextColor(hdcFore, RGB(0xFF, 0xFF, 0xFF));
-    NtGdiBitBlt(hdcFore, 0, 0, nWidth, nHeight, hdcMask, xMask, yMask, SRCAND, 0, 0);
+    DestRect.left   = nXDest;
+    DestRect.top    = nYDest;
+    DestRect.right  = nXDest + nWidth;
+    DestRect.bottom = nYDest + nHeight;
+    IntLPtoDP(DCDest, (LPPOINT)&DestRect, 2);
 
 
-    /* 3. Combine the fore and background into the background bitmap */
-    NtGdiBitBlt(hdcBack, 0, 0, nWidth, nHeight, hdcFore, 0, 0, SRCPAINT, 0, 0);
+    DestRect.left   += DCDest->ptlDCOrig.x;
+    DestRect.top    += DCDest->ptlDCOrig.y;
+    DestRect.right  += DCDest->ptlDCOrig.x;
+    DestRect.bottom += DCDest->ptlDCOrig.y;
 
 
-    /* 4. Copy the result to hdcDest */
-    NtGdiBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcBack, 0, 0, SRCCOPY, 0, 0);
+    SourcePoint.x = nXSrc;
+    SourcePoint.y = nYSrc;
 
 
-    /* 5. delete all temp objects */
-    NtGdiDeleteObjectApp(hdcBack);
-    NtGdiDeleteObjectApp(hdcFore);
-    NtGdiDeleteObjectApp(hdcMask);
-    GreDeleteObject(hbmFore);
-    GreDeleteObject(hbmBack);
+    if (UsesSource)
+    {
+        IntLPtoDP(DCSrc, (LPPOINT)&SourcePoint, 1);
 
 
-    return TRUE;
+        SourcePoint.x += DCSrc->ptlDCOrig.x;
+        SourcePoint.y += DCSrc->ptlDCOrig.y;
+        /* Calculate Source Rect */
+        SourceRect.left = SourcePoint.x;
+        SourceRect.top = SourcePoint.y;
+        SourceRect.right = SourcePoint.x + DestRect.right - DestRect.left;
+        SourceRect.bottom = SourcePoint.y + DestRect.bottom - DestRect.top ;
+    }
+
+    /* Prepare blit */
+    DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
+
+    if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+        DC_vUpdateFillBrush(DCDest);
+
+    /* Determine surfaces to be used in the bitblt */
+    BitmapDest = DCDest->dclevel.pSurface;
+    if (!BitmapDest)
+        goto cleanup;
+
+    if (UsesSource)
+    {
+        {
+            BitmapSrc = DCSrc->dclevel.pSurface;
+            if (!BitmapSrc)
+                goto cleanup;
+        }
+    }
+
+    /* Create the XLATEOBJ. */
+    if (UsesSource)
+    {
+        EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
+        XlateObj = &exlo.xlo;
+    }
+
+
+    /* Perform the bitblt operation */
+    Status = IntEngBitBlt(&BitmapDest->SurfObj,
+                          BitmapSrc ? &BitmapSrc->SurfObj : NULL,
+                          psurfMask ? &psurfMask->SurfObj : NULL,
+                          DCDest->rosdc.CombinedClip,
+                          XlateObj,
+                          &DestRect,
+                          &SourcePoint,
+                          &MaskPoint,
+                          &DCDest->eboFill.BrushObject,
+                          &DCDest->dclevel.pbrFill->ptOrigin,
+                          ROP_TO_ROP4(dwRop));
+
+    if (UsesSource)
+        EXLATEOBJ_vCleanup(&exlo);
+cleanup:
+    DC_vFinishBlit(DCDest, DCSrc);
+    if (UsesSource)
+    {
+        DC_UnlockDc(DCSrc);
+    }
+    DC_UnlockDc(DCDest);
+    if(psurfMask) SURFACE_UnlockSurface(psurfMask);
+
+    return Status;
 }
 
 BOOL
 }
 
 BOOL
@@ -655,7 +547,9 @@ GreStretchBltMask(
     EXLATEOBJ exlo;
     XLATEOBJ *XlateObj = NULL;
     POINTL BrushOrigin;
     EXLATEOBJ exlo;
     XLATEOBJ *XlateObj = NULL;
     POINTL BrushOrigin;
-    BOOL UsesSource = ROP3_USES_SOURCE(ROP);
+    BOOL UsesSource = ROP_USES_SOURCE(ROP);
+
+    FIXUP_ROP(ROP);
 
     if (0 == WidthDest || 0 == HeightDest || 0 == WidthSrc || 0 == HeightSrc)
     {
 
     if (0 == WidthDest || 0 == HeightDest || 0 == WidthSrc || 0 == HeightSrc)
     {
@@ -803,7 +697,7 @@ GreStretchBltMask(
                               BitmapMask ? &MaskPoint : NULL,
                               &DCDest->eboFill.BrushObject,
                               &BrushOrigin,
                               BitmapMask ? &MaskPoint : NULL,
                               &DCDest->eboFill.BrushObject,
                               &BrushOrigin,
-                              ROP3_TO_ROP4(ROP));
+                              ROP_TO_ROP4(ROP));
     if (UsesSource)
     {
         EXLATEOBJ_vCleanup(&exlo);
     if (UsesSource)
     {
         EXLATEOBJ_vCleanup(&exlo);
@@ -877,6 +771,8 @@ IntPatBlt(
 
     ASSERT(pbrush);
 
 
     ASSERT(pbrush);
 
+    FIXUP_ROP(dwRop);
+
     if (pbrush->flAttrs & GDIBRUSH_IS_NULL)
     {
         return TRUE;
     if (pbrush->flAttrs & GDIBRUSH_IS_NULL)
     {
         return TRUE;
@@ -934,7 +830,7 @@ IntPatBlt(
         NULL,
         &eboFill.BrushObject,
         &BrushOrigin,
         NULL,
         &eboFill.BrushObject,
         &BrushOrigin,
-        ROP3_TO_ROP4(dwRop));
+        ROP_TO_ROP4(dwRop));
 
     DC_vFinishBlit(pdc, NULL);
 
 
     DC_vFinishBlit(pdc, NULL);
 
@@ -1007,7 +903,7 @@ NtGdiPatBlt(
     PDC_ATTR pdcattr;
     BOOL ret;
 
     PDC_ATTR pdcattr;
     BOOL ret;
 
-    BOOL UsesSource = ROP3_USES_SOURCE(ROP);
+    BOOL UsesSource = ROP_USES_SOURCE(ROP);
     if (UsesSource)
     {
         /* in this case we call on GdiMaskBlt */
     if (UsesSource)
     {
         /* in this case we call on GdiMaskBlt */
index 6975b60..7e6870b 100644 (file)
@@ -179,6 +179,11 @@ GdiSelectPalette(
                                   DIRTY_BACKGROUND | DIRTY_TEXT;
     }
 
                                   DIRTY_BACKGROUND | DIRTY_TEXT;
     }
 
+    if(pdc->dctype == DCTYPE_MEMORY)
+    {
+        IntGdiRealizePalette(pdc);
+    }
+
     PALETTE_ShareUnlockPalette(ppal);
     DC_UnlockDc(pdc);
 
     PALETTE_ShareUnlockPalette(ppal);
     DC_UnlockDc(pdc);
 
index 36c452f..4a5ec9d 100644 (file)
@@ -531,7 +531,7 @@ NtGdiSetDIBitsToDeviceInternal(
                           NULL,
                           NULL,
                           NULL,
                           NULL,
                           NULL,
                           NULL,
-                          ROP3_TO_ROP4(SRCCOPY));
+                          ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY));
 
     /* Cleanup EXLATEOBJ */
     EXLATEOBJ_vCleanup(&exlo);
 
     /* Cleanup EXLATEOBJ */
     EXLATEOBJ_vCleanup(&exlo);
index 86ab4c3..bac849c 100755 (executable)
@@ -1249,7 +1249,7 @@ IntFillRect( DC *dc,
              PBRUSH pbrush,
              BOOL Pen)
 {
              PBRUSH pbrush,
              BOOL Pen)
 {
-    DWORD ROP = PATCOPY;
+    DWORD ROP = ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY);
     RECTL DestRect;
     SURFACE *psurf;
     POINTL BrushOrigin;
     RECTL DestRect;
     SURFACE *psurf;
     POINTL BrushOrigin;
@@ -1291,7 +1291,7 @@ IntFillRect( DC *dc,
         BrushOrigin.y = pbrush->ptOrigin.y;
 
         if (pdcattr->jROP2 == R2_XORPEN)
         BrushOrigin.y = pbrush->ptOrigin.y;
 
         if (pdcattr->jROP2 == R2_XORPEN)
-            ROP = PATINVERT;
+            ROP = ROP4_FROM_INDEX(R3_OPINDEX_PATINVERT);
 
         Ret = IntEngBitBlt(
                   &psurf->SurfObj,
 
         Ret = IntEngBitBlt(
                   &psurf->SurfObj,
@@ -1304,7 +1304,7 @@ IntFillRect( DC *dc,
                   NULL,
                   Pen ? &dc->eboLine.BrushObject : &dc->eboFill.BrushObject,
                   &BrushOrigin,
                   NULL,
                   Pen ? &dc->eboLine.BrushObject : &dc->eboFill.BrushObject,
                   &BrushOrigin,
-                  ROP3_TO_ROP4(ROP));
+                  ROP);
     }
 
     return (int)Ret;
     }
 
     return (int)Ret;
index d5d6469..ae071d2 100644 (file)
@@ -604,7 +604,7 @@ IntRectangle(PDC dc,
                                NULL,
                                &dc->eboFill.BrushObject,
                                &BrushOrigin,
                                NULL,
                                &dc->eboFill.BrushObject,
                                &BrushOrigin,
-                               ROP3_TO_ROP4(PATCOPY));
+                               ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
         }
     }
 
         }
     }
 
index d67405b..4e941ee 100644 (file)
@@ -3269,7 +3269,7 @@ GreExtTextOutW(
             &SourcePoint,
             &dc->eboBackground.BrushObject,
             &BrushOrigin,
             &SourcePoint,
             &dc->eboBackground.BrushObject,
             &BrushOrigin,
-            ROP3_TO_ROP4(PATCOPY));
+            ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
         fuOptions &= ~ETO_OPAQUE;
         DC_vFinishBlit(dc, NULL);
     }
         fuOptions &= ~ETO_OPAQUE;
         DC_vFinishBlit(dc, NULL);
     }
@@ -3514,7 +3514,7 @@ GreExtTextOutW(
                 &SourcePoint,
                 &dc->eboBackground.BrushObject,
                 &BrushOrigin,
                 &SourcePoint,
                 &dc->eboBackground.BrushObject,
                 &BrushOrigin,
-                ROP3_TO_ROP4(PATCOPY));
+                ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
             MouseSafetyOnDrawEnd(dc->ppdev);
             BackgroundLeft = DestRect.right;
 
             MouseSafetyOnDrawEnd(dc->ppdev);
             BackgroundLeft = DestRect.right;
 
index c7656e0..59b1643 100644 (file)
@@ -723,26 +723,18 @@ NtGdiGetNearestPaletteIndex(
 
 UINT
 FASTCALL
 
 UINT
 FASTCALL
-IntGdiRealizePalette(HDC hDC)
+IntGdiRealizePalette(PDC pdc)
 {
     UINT i, realize = 0;
 {
     UINT i, realize = 0;
-    PDC pdc;
     PALETTE *ppalSurf, *ppalDC;
 
     PALETTE *ppalSurf, *ppalDC;
 
-    pdc = DC_LockDc(hDC);
-    if(!pdc)
-    {
-        EngSetLastError(ERROR_INVALID_HANDLE);
-        return 0;
-    }
-
     ppalSurf = pdc->dclevel.pSurface->ppal;
     ppalDC = pdc->dclevel.ppal;
 
     if(!(ppalSurf->flFlags & PAL_INDEXED))
     {
         // FIXME : set error?
     ppalSurf = pdc->dclevel.pSurface->ppal;
     ppalDC = pdc->dclevel.ppal;
 
     if(!(ppalSurf->flFlags & PAL_INDEXED))
     {
         // FIXME : set error?
-        goto cleanup;
+        return 0;
     }
 
     ASSERT(ppalDC->flFlags & PAL_INDEXED);
     }
 
     ASSERT(ppalDC->flFlags & PAL_INDEXED);
@@ -755,8 +747,6 @@ IntGdiRealizePalette(HDC hDC)
         InterlockedExchange((LONG*)&ppalSurf->IndexedColors[i], *(LONG*)&ppalDC->IndexedColors[i]);
     }
 
         InterlockedExchange((LONG*)&ppalSurf->IndexedColors[i], *(LONG*)&ppalDC->IndexedColors[i]);
     }
 
-cleanup:
-    DC_UnlockDc(pdc);
     return realize;
 }
 
     return realize;
 }
 
@@ -810,11 +800,9 @@ IntAnimatePalette(HPALETTE hPal,
         {
             if (dc->dclevel.hpal == hPal)
             {
         {
             if (dc->dclevel.hpal == hPal)
             {
-                DC_UnlockDc(dc);
-                IntGdiRealizePalette(hDC);
+                IntGdiRealizePalette(dc);
             }
             }
-            else
-                DC_UnlockDc(dc);
+            DC_UnlockDc(dc);
         }
         UserReleaseDC(Wnd,hDC, FALSE);
     }
         }
         UserReleaseDC(Wnd,hDC, FALSE);
     }
index 1f6196a..e1b3380 100644 (file)
@@ -606,14 +606,14 @@ IntFillPolygon(
     BRUSHOBJ *BrushObj,
     CONST PPOINT Points,
     int Count,
     BRUSHOBJ *BrushObj,
     CONST PPOINT Points,
     int Count,
-    RECTL DestRect, 
+    RECTL DestRect,
     POINTL *BrushOrigin)
 {
     FILL_EDGE_LIST *list = 0;
     FILL_EDGE *ActiveHead = 0;
     FILL_EDGE *pLeft, *pRight;
     int ScanLine;
     POINTL *BrushOrigin)
 {
     FILL_EDGE_LIST *list = 0;
     FILL_EDGE *ActiveHead = 0;
     FILL_EDGE *pLeft, *pRight;
     int ScanLine;
-  
+
     //DPRINT("IntFillPolygon\n");
 
     /* Create Edge List. */
     //DPRINT("IntFillPolygon\n");
 
     /* Create Edge List. */
@@ -657,11 +657,11 @@ IntFillPolygon(
                                  NULL,
                                  BrushObj,
                                  BrushOrigin,
                                  NULL,
                                  BrushObj,
                                  BrushOrigin,
-                                 ROP3_TO_ROP4(PATCOPY));
+                                 ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
             }
             pLeft = pRight->pNext;
             pRight = pLeft ? pLeft->pNext : NULL;
             }
             pLeft = pRight->pNext;
             pRight = pLeft ? pLeft->pNext : NULL;
-        }   
+        }
     }
 
     /* Free Edge List. If any are left. */
     }
 
     /* Free Edge List. If any are left. */