Identation corrected, many fixes and minor improvements, initial DIB support
authorJason Filby <jason.filby@gmail.com>
Sat, 31 Mar 2001 15:35:08 +0000 (15:35 +0000)
committerJason Filby <jason.filby@gmail.com>
Sat, 31 Mar 2001 15:35:08 +0000 (15:35 +0000)
svn path=/trunk/; revision=1753

42 files changed:
reactos/subsys/win32k/dib/dib.h [new file with mode: 0644]
reactos/subsys/win32k/dib/dib24bpp.c [new file with mode: 0644]
reactos/subsys/win32k/dib/dib4bpp.c [new file with mode: 0644]
reactos/subsys/win32k/eng/bitblt.c
reactos/subsys/win32k/eng/brush.c
reactos/subsys/win32k/eng/brush.h
reactos/subsys/win32k/eng/clip.c
reactos/subsys/win32k/eng/copybits.c
reactos/subsys/win32k/eng/device.c
reactos/subsys/win32k/eng/enum.c
reactos/subsys/win32k/eng/enum.h
reactos/subsys/win32k/eng/handle.c
reactos/subsys/win32k/eng/handle.h
reactos/subsys/win32k/eng/lineto.c
reactos/subsys/win32k/eng/mem.c
reactos/subsys/win32k/eng/objects.h
reactos/subsys/win32k/eng/paint.c
reactos/subsys/win32k/eng/palette.c
reactos/subsys/win32k/eng/surface.c
reactos/subsys/win32k/eng/xlate.c
reactos/subsys/win32k/freetype/grfont.c
reactos/subsys/win32k/ldr/loader.c
reactos/subsys/win32k/main/dllmain.c
reactos/subsys/win32k/makefile
reactos/subsys/win32k/misc/driver.c
reactos/subsys/win32k/objects/bezier.c
reactos/subsys/win32k/objects/bitmaps.c
reactos/subsys/win32k/objects/brush.c
reactos/subsys/win32k/objects/color.c
reactos/subsys/win32k/objects/coord.c
reactos/subsys/win32k/objects/dc.c
reactos/subsys/win32k/objects/dib.c [new file with mode: 0644]
reactos/subsys/win32k/objects/fillshap.c
reactos/subsys/win32k/objects/gdiobj.c
reactos/subsys/win32k/objects/line.c
reactos/subsys/win32k/objects/objconv.c
reactos/subsys/win32k/objects/palette.c [new file with mode: 0644]
reactos/subsys/win32k/objects/path.c
reactos/subsys/win32k/objects/pen.c
reactos/subsys/win32k/objects/print.c
reactos/subsys/win32k/objects/region.c
reactos/subsys/win32k/objects/text.c

diff --git a/reactos/subsys/win32k/dib/dib.h b/reactos/subsys/win32k/dib/dib.h
new file mode 100644 (file)
index 0000000..f59ca4a
--- /dev/null
@@ -0,0 +1,17 @@
+static unsigned char notmask[2] = { 0x0f, 0xf0 };
+static unsigned char altnotmask[2] = { 0xf0, 0x0f };
+
+typedef VOID  (*PFN_DIB_PutPixel)(SURFOBJ *, LONG, LONG, ULONG);
+typedef ULONG (*PFN_DIB_GetPixel)(SURFOBJ *, LONG, LONG);
+typedef VOID  (*PFN_DIB_HLine)   (SURFOBJ *, LONG, LONG, LONG, ULONG);
+typedef VOID  (*PFN_DIB_VLine)   (SURFOBJ *, LONG, LONG, LONG, ULONG);
+
+VOID DIB_4BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, BYTE c);
+BYTE DIB_4BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y);
+VOID DIB_4BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, BYTE c);
+VOID DIB_4BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, BYTE c);
+
+VOID DIB_24BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, RGBTRIPLE c);
+RGBTRIPLE DIB_24BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y);
+VOID DIB_24BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, RGBTRIPLE c);
+VOID DIB_24BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, RGBTRIPLE c);
diff --git a/reactos/subsys/win32k/dib/dib24bpp.c b/reactos/subsys/win32k/dib/dib24bpp.c
new file mode 100644 (file)
index 0000000..99dd063
--- /dev/null
@@ -0,0 +1,134 @@
+#undef WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdlib.h>
+#include <win32k/bitmaps.h>
+#include <win32k/debug.h>
+#include <debug.h>
+#include <ddk/winddi.h>
+#include "..\eng\objects.h"
+#include "dib.h"
+
+VOID DIB_24BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, RGBTRIPLE c)
+{
+  PBYTE byteaddr = SurfObj->pvBits + y * SurfObj->lDelta;
+  PRGBTRIPLE addr = (PRGBTRIPLE)byteaddr + x;
+
+  *addr = c;
+}
+
+RGBTRIPLE DIB_24BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y)
+{
+  PBYTE byteaddr = SurfObj->pvBits + y * SurfObj->lDelta;
+  PRGBTRIPLE addr = (PRGBTRIPLE)byteaddr + x;
+
+  return *addr;
+}
+
+VOID DIB_24BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, RGBTRIPLE c)
+{
+  PBYTE byteaddr = SurfObj->pvBits + y * SurfObj->lDelta;
+  PRGBTRIPLE addr = (PRGBTRIPLE)byteaddr + x1;
+  LONG cx = x1;
+
+  while(cx <= x2) {
+    *addr = c;
+    ++addr;
+    ++cx;
+  }
+}
+
+VOID DIB_24BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, RGBTRIPLE c)
+{
+  PBYTE byteaddr = SurfObj->pvBits + y1 * SurfObj->lDelta;
+  PRGBTRIPLE addr = (PRGBTRIPLE)byteaddr + x;
+  ULONG  lDelta = SurfObj->lDelta;
+
+  byteaddr = (PBYTE)addr;
+  while(y1++ <= y2) {
+    *addr = c;
+
+    byteaddr += lDelta;
+    addr = (PRGBTRIPLE)byteaddr;
+  }
+}
+
+VOID DIB_24BPP_BltTo_24BPP(PSURFOBJ dstpsd, LONG dstx, LONG dsty, LONG w, LONG h,
+  PSURFOBJ srcpsd, LONG srcx, LONG srcy)
+{
+  PRGBTRIPLE  dst;
+  PRGBTRIPLE  src;
+  PBYTE  bytedst;
+  PBYTE  bytesrc;
+  int  i;
+  int  dlDelta = dstpsd->lDelta;
+  int  slDelta = srcpsd->lDelta;
+
+  bytedst = (char *)dstpsd->pvBits + dsty * dlDelta;
+  bytesrc = (char *)srcpsd->pvBits + srcy * slDelta;
+  dst = (PRGBTRIPLE)bytedst + dstx;
+  src = (PRGBTRIPLE)bytesrc + srcx;
+
+  while(--h >= 0) {
+    PRGBTRIPLE  d = dst;
+    PRGBTRIPLE  s = src;
+    LONG  dx = dstx;
+    LONG  sx = srcx;
+    for(i=0; i<w; ++i) {
+      *d = *s;
+      ++d;
+      ++s;
+    }
+    dst += dlDelta;
+    src += slDelta;
+  }
+}
+
+BOOLEAN DIB_To_24BPP_Bitblt(  SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
+        SURFGDI *DestGDI,  SURFGDI *SourceGDI,
+        PRECTL  DestRect,  POINTL  *SourcePoint,
+        ULONG   Delta,     XLATEOBJ *ColorTranslation)
+{
+  ULONG    i, j, sx, xColor, f1;
+  PBYTE    DestBits, SourceBits_24BPP, DestLine, SourceLine_24BPP;
+  PRGBTRIPLE  SPDestBits, SPSourceBits_24BPP, SPDestLine, SPSourceLine_24BPP; // specially for 24-to-24 blit
+  PBYTE    SourceBits_4BPP, SourceBits_8BPP, SourceLine_4BPP, SourceLine_8BPP;
+  PWORD    SourceBits_16BPP, SourceLine_16BPP;
+  PDWORD    SourceBits_32BPP, SourceLine_32BPP;
+
+  DestBits = DestSurf->pvBits + (DestRect->top * DestSurf->lDelta) + DestRect->left * 3;
+
+  switch(SourceGDI->BitsPerPixel)
+  {
+    case 4:
+      SourceBits_4BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x;
+
+      for (j=DestRect->top; j<DestRect->bottom; j++)
+      {
+        SourceLine_4BPP = SourceBits_4BPP;
+        DestLine = DestBits;
+        sx = SourcePoint->x;
+        f1 = sx & 1;
+
+        for (i=DestRect->left; i<DestRect->right; i++)
+        {
+          xColor = XLATEOBJ_iXlate(ColorTranslation,
+              (*SourceLine_4BPP & altnotmask[sx&1]) >> (4 * (1-(sx & 1))));
+          *DestLine++ = xColor & 0xff;
+          *(PWORD)DestLine = xColor >> 8;
+          DestLine += 2;
+          if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
+          sx++;
+        }
+
+        SourceBits_4BPP += SourceSurf->lDelta;
+        DestBits += DestSurf->lDelta;
+      }
+      break;
+
+    default:
+      DbgPrint("DIB_24BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
+      return FALSE;
+  }
+
+  return TRUE;
+}
diff --git a/reactos/subsys/win32k/dib/dib4bpp.c b/reactos/subsys/win32k/dib/dib4bpp.c
new file mode 100644 (file)
index 0000000..dd0f530
--- /dev/null
@@ -0,0 +1,129 @@
+#undef WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdlib.h>
+#include <win32k/bitmaps.h>
+#include <win32k/debug.h>
+#include <debug.h>
+#include <ddk/winddi.h>
+#include "..\eng\objects.h"
+#include "dib.h"
+
+VOID DIB_4BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, BYTE c)
+{
+  unsigned char *vp;
+  unsigned char mask;
+  PBYTE addr = SurfObj->pvBits;
+
+  addr += (x>>1) + y * SurfObj->lDelta;
+  *addr = (*addr & notmask[x&1]) | (c << ((1-(x&1))<<2));
+}
+
+BYTE DIB_4BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y)
+{
+  PBYTE addr = SurfObj->pvBits;
+
+  return (addr[(x>>1) + y * SurfObj->lDelta] >> ((1-(x&1))<<2) ) & 0x0f;
+}
+
+VOID DIB_4BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, BYTE c)
+{
+  PBYTE  addr = SurfObj->pvBits + (x1>>1) + y * SurfObj->lDelta;
+  LONG  cx = x1;
+
+  while(cx <= x2) {
+    *addr = (*addr & notmask[x1&1]) | (c << ((1-(x1&1))<<2));
+    if((++x1 & 1) == 0)
+      ++addr;
+    ++cx;
+  }
+}
+
+VOID DIB_4BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, BYTE c)
+{
+  PBYTE  addr = SurfObj->pvBits;
+  int  lDelta = SurfObj->lDelta;
+
+  addr += (x>>1) + y1 * lDelta;
+  while(y1++ <= y2) {
+    *addr = (*addr & notmask[x&1]) | (c << ((1-(x&1))<<2));
+    addr += lDelta;
+  }
+}
+
+BOOLEAN DIB_To_4BPP_Bitblt(  SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
+        SURFGDI *DestGDI,  SURFGDI *SourceGDI,
+        PRECTL  DestRect,  POINTL  *SourcePoint,
+        ULONG   Delta,     XLATEOBJ *ColorTranslation)
+{
+  ULONG    i, j, sx, f1, f2, xColor;
+  PBYTE    SourceBits_24BPP, SourceLine_24BPP;
+  PBYTE    DestBits, DestLine, SourceBits_4BPP, SourceBits_8BPP, SourceLine_4BPP, SourceLine_8BPP;
+  PWORD    SourceBits_16BPP, SourceLine_16BPP;
+  PDWORD    SourceBits_32BPP, SourceLine_32BPP;
+
+  DestBits = DestSurf->pvBits + (DestRect->left>>1) + DestRect->top * DestSurf->lDelta;
+
+  switch(SourceGDI->BitsPerPixel)
+  {
+    case 4:
+      SourceBits_4BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x;
+
+      for (j=DestRect->top; j<DestRect->bottom; j++)
+      {
+        SourceLine_4BPP = SourceBits_4BPP;
+        DestLine = DestBits;
+        sx = SourcePoint->x;
+        f1 = sx & 1;
+        f2 = DestRect->left & 1;
+
+        // FIXME: handle odd begin pixel
+
+        for (i=DestRect->left; i<DestRect->right; i++)
+        {
+          if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
+          if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; *DestLine = *SourceLine_4BPP; }
+          sx++;
+        }
+
+        // FIXME: handle odd end pixel
+
+        SourceBits_4BPP += SourceSurf->lDelta;
+        DestBits += DestSurf->lDelta;
+      }
+      break;
+
+    case 24:
+      SourceBits_24BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x * 3;
+
+      for (j=DestRect->top; j<DestRect->bottom; j++)
+      {
+        SourceLine_24BPP = SourceBits_24BPP;
+        DestLine = DestBits;
+        sx = SourcePoint->x;
+        f1 = sx & 1;
+        f2 = DestRect->left & 1;
+
+        for (i=DestRect->left; i<DestRect->right; i++)
+        {
+          xColor = (*(SourceLine_24BPP + 2) << 0x10) +
+             (*(SourceLine_24BPP + 1) << 0x08) +
+             (*(SourceLine_24BPP));
+          *DestLine = (*DestLine & notmask[i&1]) |
+            ((XLATEOBJ_iXlate(ColorTranslation, xColor)) << ((4 * (1-(sx & 1)))));
+          if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; }
+          SourceLine_24BPP+=3;
+          sx++;
+        }
+
+        SourceBits_24BPP += SourceSurf->lDelta;
+        DestBits += DestSurf->lDelta;
+      }
+      break;
+
+    default:
+      DbgPrint("DIB_4BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
+      return FALSE;
+  }
+
+  return TRUE;
+}
index b46b6a3..3e80def 100644 (file)
 #include "enum.h"
 #include "objects.h"
 
-VOID BitBltCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
-                SURFGDI *DestGDI,  SURFGDI *SourceGDI,
-                PRECTL  DestRect,  POINTL  *SourcePoint,
-                ULONG   Delta)
-{
-   ULONG dy, leftOfSource, leftOfDest, Width, CopyPos;
-
-   // FIXME: Get ColorTranslation passed here and do something with it
-
-   leftOfSource = SourcePoint->x * SourceGDI->BytesPerPixel;
-   leftOfDest   = DestRect->left * DestGDI->BytesPerPixel;
-   Width        = (DestRect->right - DestRect->left) * DestGDI->BytesPerPixel;
-   CopyPos      = leftOfDest;
-
-   for(dy=DestRect->top; dy<DestRect->bottom; dy++)
-   {
-      RtlCopyMemory(DestSurf->pvBits+CopyPos,
-                    SourceSurf->pvBits+CopyPos,
-                    Width);
-
-      CopyPos += Delta;
-   }
-}
-
 BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
-
 {
-   static const RECTL rclEmpty = { 0, 0, 0, 0 };
+  static const RECTL rclEmpty = { 0, 0, 0, 0 };
 
-   prcDst->left  = max(prcSrc1->left, prcSrc2->left);
-   prcDst->right = min(prcSrc1->right, prcSrc2->right);
+  prcDst->left  = max(prcSrc1->left, prcSrc2->left);
+  prcDst->right = min(prcSrc1->right, prcSrc2->right);
 
-   if (prcDst->left < prcDst->right)
-   {
-      prcDst->top    = max(prcSrc1->top, prcSrc2->top);
-      prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
+  if (prcDst->left < prcDst->right)
+  {
+    prcDst->top    = max(prcSrc1->top, prcSrc2->top);
+    prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
 
-      if (prcDst->top < prcDst->bottom)
-         return(TRUE);
-   }
+    if (prcDst->top < prcDst->bottom) return(TRUE);
+  }
 
-   *prcDst = rclEmpty;
+  *prcDst = rclEmpty;
 
-   return(FALSE);
+  return(FALSE);
 }
 
+
 BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
                SURFOBJ *Mask, CLIPOBJ *ClipRegion,
                XLATEOBJ *ColorTranslation, RECTL *DestRect,
                POINTL *SourcePoint, POINTL *MaskRect,
                BRUSHOBJ *Brush, POINTL *BrushOrigin, ROP4 rop4)
 {
-   BYTE      clippingType;
-   RECTL     rclTmp;
-   POINTL    ptlTmp;
-   RECT_ENUM RectEnum;
-   BOOL      EnumMore;
-   SURFGDI   *DestGDI, *SourceGDI;
-   BOOLEAN   canCopyBits;
-
-   // If we don't have to do anything special, we can punt to DrvCopyBits
-   // if it exists
-   if( (Mask == NULL)        && (MaskRect == NULL) && (Brush == NULL) &&
-       (BrushOrigin == NULL) && (rop4 == 0) )
-   {
-     canCopyBits = TRUE;
-   } else
-     canCopyBits = FALSE;
-
-   // FIXME: Use XLATEOBJ to translate source bitmap into destination bitmap's
-   //        format. Call DrvDitherColor function where necessary and if available
-
-   // FIXME: If canCopyBits == TRUE AND the driver has a DrvCopyBits then
-   //        punt to EngCopyBits and not the driver's DrvCopyBits just yet so
-   //        that the EngCopyBits can take care of the clipping drivers
-   //        DrvCopyBits
-
-   // FIXME: Don't punt to DrvBitBlt straight away. Instead, mark a typedef'd
-   //        function to go there instead of the Engine's bltting function
-   //        so as to do the clipping for the driver
-
-   // Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap
-   if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
-   {
-      // Destination surface is device managed
-      if(Dest->iType!=STYPE_BITMAP)
-      {
-         DestGDI = AccessInternalObjectFromUserObject(Dest);
-
-         if ((DestGDI->CopyBits!=NULL) && (canCopyBits == TRUE))
-         {
-            return DestGDI->CopyBits(Dest, Source, ClipRegion,
-                                     ColorTranslation, DestRect, SourcePoint);
-         }
-
-         if (DestGDI->BitBlt!=NULL)
-         {
-            return DestGDI->BitBlt(Dest, Source, Mask, ClipRegion,
-                                   ColorTranslation, DestRect, SourcePoint,
-                                   MaskRect, Brush, BrushOrigin, rop4);
-         }
-      }
-
-      // Source surface is device managed
-      if(Source->iType!=STYPE_BITMAP)
-      {
-         SourceGDI = AccessInternalObjectFromUserObject(Source);
-
-         if ((SourceGDI->CopyBits!=NULL) && (canCopyBits == TRUE))
-         {
-            return SourceGDI->CopyBits(Dest, Source, ClipRegion,
-                                       ColorTranslation, DestRect, SourcePoint);
-         }
-
-         if (SourceGDI->BitBlt!=NULL)
-         {
-            return SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion,
-                                     ColorTranslation, DestRect, SourcePoint,
-                                     MaskRect, Brush, BrushOrigin, rop4);
-         }
-
-
-         // Should never get here, if it's not GDI managed then the device
-         // should take care of it
-
-         // FIXME: Error message here
-      }
-
-   }
-
-   DestGDI   = AccessInternalObjectFromUserObject(Dest);
-   SourceGDI = AccessInternalObjectFromUserObject(Source);
-
-   // Determine clipping type
-   if (ClipRegion == (CLIPOBJ *) NULL)
-   {
-      clippingType = DC_TRIVIAL;
-   } else {
-      clippingType = ClipRegion->iDComplexity;
-   }
-
-   // We don't handle color translation just yet
-
-   if ((rop4 == 0x0000CCCC) &&
-       ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL)))
-   {
-      switch(clippingType)
-      {
-         case DC_TRIVIAL:
-            BitBltCopy(Dest,     Source,
-                       DestGDI,  SourceGDI,
-                       DestRect, SourcePoint, Source->lDelta);
-
-            return(TRUE);
-
-         case DC_RECT:
-
-            // Clip the blt to the clip rectangle
-
-            EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds);
-
-            ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
-            ptlTmp.y = SourcePoint->y + rclTmp.top  - DestRect->top;
-
-            BitBltCopy(Dest,    Source,
-                       DestGDI, SourceGDI,
-                       &rclTmp, &ptlTmp, Source->lDelta);
-
-            return(TRUE);
-
-         case DC_COMPLEX:
-
-            CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES,
-            CD_ANY, ENUM_RECT_LIMIT);
-
-            do {
-               EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
-               (PVOID) &RectEnum);
-
-               if (RectEnum.c > 0)
-               {
-                  RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
-                  RECTL* prcl    = &RectEnum.arcl[0];
-
-                  do {
-                     EngIntersectRect(prcl, prcl, DestRect);
-
-                     ptlTmp.x = SourcePoint->x + prcl->left
-                                - DestRect->left;
-                     ptlTmp.y = SourcePoint->y + prcl->top
-                                - DestRect->top;
-
-                     BitBltCopy(Dest,    Source,
-                                DestGDI, SourceGDI,
-                                prcl, &ptlTmp, Source->lDelta);
-
-                     prcl++;
-
-                  } while (prcl < prclEnd);
-               }
-
-            } while(EnumMore);
-
-            return(TRUE);
-      }
-   }
-
-   return(FALSE);
+  BYTE      clippingType;
+  RECTL     rclTmp;
+  POINTL    ptlTmp;
+  RECT_ENUM RectEnum;
+  BOOL      EnumMore;
+  PSURFGDI  DestGDI, SourceGDI;
+  HSURF     hTemp;
+  PSURFOBJ  TempSurf;
+  BOOLEAN   canCopyBits;
+  POINTL    TempPoint;
+  RECTL     TempRect;
+  SIZEL     TempSize;
+
+  SourceGDI = AccessInternalObjectFromUserObject(Source);
+
+  // If we don't have to do anything special, we can punt to DrvCopyBits
+  // if it exists
+  if( (Mask == NULL)        && (MaskRect == NULL) && (Brush == NULL) &&
+      (BrushOrigin == NULL) && (rop4 == 0) )
+  {
+    canCopyBits = TRUE;
+  } else
+    canCopyBits = FALSE;
+
+  // Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap, IF:
+  // * The destination bitmap is not managed by the GDI OR
+  if(Dest->iType != STYPE_BITMAP)
+  {
+    // Destination surface is device managed
+    DestGDI = AccessInternalObjectFromUserObject(Dest);
+
+    if (DestGDI->BitBlt!=NULL)
+    {
+      // The destination is device managed, therefore get the source into a format compatible surface
+      TempPoint.x = 0;
+      TempPoint.y = 0;
+      TempRect.top    = 0;
+      TempRect.left   = 0;
+      TempRect.bottom = DestRect->bottom - DestRect->top;
+      TempRect.right  = DestRect->right - DestRect->left;
+      TempSize.cx = TempRect.right;
+      TempSize.cy = TempRect.bottom;
+
+      hTemp = EngCreateBitmap(TempSize,
+                   DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)),
+                   Dest->iBitmapFormat, 0, NULL);
+      TempSurf = AccessUserObject(hTemp);
+
+      // FIXME: Skip creating a TempSurf if we have the same BPP and palette
+      EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, SourcePoint, NULL, NULL, NULL, 0);
+
+      return DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion,
+                             NULL, DestRect, &TempPoint,
+                             MaskRect, Brush, BrushOrigin, rop4);
+    }
+  }
+
+  // * The source bitmap is not managed by the GDI and we didn't already obtain it using EngCopyBits from the device
+  if(Source->iType != STYPE_BITMAP && SourceGDI->CopyBits == NULL)
+  {
+    if (SourceGDI->BitBlt!=NULL)
+    {
+      // Request the device driver to return the bitmap in a format compatible with the device
+      return SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion,
+                               NULL, DestRect, SourcePoint,
+                               MaskRect, Brush, BrushOrigin, rop4);
+
+      // Convert the surface from the driver into the required destination surface
+    }
+  }
+
+  DestGDI   = AccessInternalObjectFromUserObject(Dest);
+  SourceGDI = AccessInternalObjectFromUserObject(Source);
+
+  // Determine clipping type
+  if (ClipRegion == (CLIPOBJ *) NULL)
+  {
+    clippingType = DC_TRIVIAL;
+  } else {
+    clippingType = ClipRegion->iDComplexity;
+  }
+
+  // We don't handle color translation just yet [we dont have to.. REMOVE REMOVE REMOVE]
+  switch(clippingType)
+  {
+    case DC_TRIVIAL:
+      CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation);
+      return(TRUE);
+
+    case DC_RECT:
+
+      // Clip the blt to the clip rectangle
+      EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds);
+
+      ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
+      ptlTmp.y = SourcePoint->y + rclTmp.top  - DestRect->top;
+
+      return(TRUE);
+
+    case DC_COMPLEX:
+
+      CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
+
+      do {
+        EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
+
+        if (RectEnum.c > 0)
+        {
+          RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
+          RECTL* prcl    = &RectEnum.arcl[0];
+
+          do {
+            EngIntersectRect(prcl, prcl, DestRect);
+
+            ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
+            ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
+
+            prcl++;
+
+          } while (prcl < prclEnd);
+        }
+
+      } while(EnumMore);
+
+    return(TRUE);
+  }
+
+  return(FALSE);
 }
index 404d230..727b234 100644 (file)
 PVOID BRUSHOBJ_pvAllocRbrush(IN PBRUSHOBJ  BrushObj,
                              IN ULONG  ObjSize)
 {
-   BrushObj->pvRbrush=EngAllocMem(0, ObjSize, 0);
-   return BrushObj->pvRbrush;
+  BrushObj->pvRbrush=EngAllocMem(0, ObjSize, 0);
+  return BrushObj->pvRbrush;
 }
 
 PVOID BRUSHOBJ_pvGetRbrush(IN PBRUSHOBJ  BrushObj)
 {
-   return BrushObj->pvRbrush;
+  return BrushObj->pvRbrush;
 }
index f67461e..d6b73ab 100644 (file)
@@ -1,23 +1,23 @@
 typedef struct  _BRUSHINST
 {
-   // We need to removed ajC0-3 when color pattern code is complete!!!
-   //
-   BYTE    ajC0[8];  // Color bits for plane 0
-   BYTE    ajC1[8];  // Color bits for plane 1
-   BYTE    ajC2[8];  // Color bits for plane 2
-   BYTE    ajC3[8];  // Color bits for plane 3
+  // We need to removed ajC0-3 when color pattern code is complete!!!
+  //
+  BYTE    ajC0[8];  // Color bits for plane 0
+  BYTE    ajC1[8];  // Color bits for plane 1
+  BYTE    ajC2[8];  // Color bits for plane 2
+  BYTE    ajC3[8];  // Color bits for plane 3
 
-   BYTE    ajPattern[32];       // Color bits for the mask
-   USHORT  usStyle;  // Brush style
-   BYTE    fjAccel;  // Accelerator flags
-   BYTE    jFgColor; // Current foreground color
-   BYTE    jBkColor; // Current background color
-   BYTE    RealWidth;//
-   BYTE    YShiftValue;       //
-   BYTE    jOldBrushRealized; //
-   DWORD   Width;    // Width of brush
-   DWORD   Height;
-   BYTE    *pPattern;     //Pointer to realized mono pattern
+  BYTE    ajPattern[32];       // Color bits for the mask
+  USHORT  usStyle;  // Brush style
+  BYTE    fjAccel;  // Accelerator flags
+  BYTE    jFgColor; // Current foreground color
+  BYTE    jBkColor; // Current background color
+  BYTE    RealWidth;//
+  BYTE    YShiftValue;       //
+  BYTE    jOldBrushRealized; //
+  DWORD   Width;    // Width of brush
+  DWORD   Height;
+  BYTE    *pPattern;     //Pointer to realized mono pattern
 } BRUSHINST;
 
 #define BRI_SOLID           0
index c4b7445..1e3a3dc 100644 (file)
 CLIPOBJ *EngCreateClipRegion(ULONG NumRects, RECTL Rects[],
                              ULONG Mode, ULONG Options)
 {
-   HCLIP NewClip;
-   CLIPOBJ *ClipObj;
-   CLIPGDI *ClipGDI;
-
-   ClipObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
-   ClipGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPGDI), NULL);
-
-   NewClip = CreateGDIHandle(ClipGDI, ClipObj);
-
-   ClipGDI->NumRegionRects  = NumRects;
-   ClipGDI->RegionRects     = Rects;
-   ClipObj->iMode           = Mode;
-   ClipObj->fjOptions       = Options;
-   ClipObj->iDComplexity    = DC_TRIVIAL;
-
-   if(NumRects == 1)
-   {
-      ClipObj->iFComplexity = FC_RECT;
-      ClipObj->iDComplexity = DC_RECT;
-
-      // FIXME: Is this correct??
-      ClipObj->rclBounds = Rects[0];
-   } else
-   {
-      ClipObj->iDComplexity = DC_COMPLEX;
-      if(NumRects <= 4)
-      {
-         ClipObj->iFComplexity = FC_RECT4;
-      } else
-      {
-         ClipObj->iFComplexity = FC_COMPLEX;
-      }
-   }
-
-   return ClipObj;
+  HCLIP NewClip;
+  CLIPOBJ *ClipObj;
+  CLIPGDI *ClipGDI;
+
+  ClipObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
+  ClipGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPGDI), NULL);
+
+  NewClip = CreateGDIHandle(ClipGDI, ClipObj);
+
+  ClipGDI->NumRegionRects  = NumRects;
+  ClipGDI->RegionRects     = Rects;
+  ClipObj->iMode           = Mode;
+  ClipObj->fjOptions       = Options;
+  ClipObj->iDComplexity    = DC_TRIVIAL;
+
+  if(NumRects == 1)
+  {
+    ClipObj->iFComplexity = FC_RECT;
+    ClipObj->iDComplexity = DC_RECT;
+
+    // FIXME: Is this correct??
+    ClipObj->rclBounds = Rects[0];
+  } else
+  {
+    ClipObj->iDComplexity = DC_COMPLEX;
+    if(NumRects <= 4)
+    {
+      ClipObj->iFComplexity = FC_RECT4;
+    } else
+    {
+      ClipObj->iFComplexity = FC_COMPLEX;
+    }
+  }
+
+  return ClipObj;
 }
 
 VOID EngDeleteClipRegion(CLIPOBJ *ClipObj)
 {
-   HCLIP HClip      = AccessHandleFromUserObject(ClipObj);
-   CLIPGDI *ClipGDI = AccessInternalObject(HClip);
+  HCLIP HClip      = AccessHandleFromUserObject(ClipObj);
+  CLIPGDI *ClipGDI = AccessInternalObject(HClip);
 
-   EngFreeMem(ClipGDI);
-   EngFreeMem(ClipObj);
-   FreeGDIHandle(HClip);
+  EngFreeMem(ClipGDI);
+  EngFreeMem(ClipObj);
+  FreeGDIHandle(HClip);
 }
 
 VOID EngIntersectClipRegion(CLIPOBJ *ClipObj, ULONG NumRects, RECTL *IntersectRects)
 {
-   CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
-
-   ClipGDI->NumIntersectRects = NumRects;
-   ClipGDI->IntersectRects    = IntersectRects;
-
-   if(NumRects == 1)
-   {
-      ClipObj->iDComplexity = DC_RECT;
-      ClipObj->rclBounds = IntersectRects[0];
-   } else
-   {
-      ClipObj->iDComplexity = DC_COMPLEX;
-      ClipGDI->IntersectRects = IntersectRects;
-   }
+  CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
+
+  ClipGDI->NumIntersectRects = NumRects;
+  ClipGDI->IntersectRects    = IntersectRects;
+
+  if(NumRects == 1)
+  {
+    ClipObj->iDComplexity = DC_RECT;
+    ClipObj->rclBounds = IntersectRects[0];
+  } else
+  {
+    ClipObj->iDComplexity = DC_COMPLEX;
+    ClipGDI->IntersectRects = IntersectRects;
+  }
 }
 
 CLIPOBJ *EngCreateClip(VOID)
 {
-   return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
+  return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
 }
 
 VOID EngDeleteClip(CLIPOBJ *ClipRegion)
 {
-   EngFreeMem(ClipRegion);
+  EngFreeMem(ClipRegion);
 }
 
 ULONG CLIPOBJ_cEnumStart(IN PCLIPOBJ ClipObj, IN BOOL ShouldDoAll,
                          IN ULONG ClipType,   IN ULONG BuildOrder,
                          IN ULONG MaxRects)
 {
-   CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
+  CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
 
-   ClipGDI->EnumPos     = 0;
-   ClipGDI->EnumRects.c = MaxRects;
+  ClipGDI->EnumPos     = 0;
+  ClipGDI->EnumRects.c = MaxRects;
 
-   // Return the number of rectangles enumerated
-   if(ClipGDI->EnumRects.c>MaxRects)
-   {
-      ClipGDI->EnumRects.c = 0xFFFFFFFF;
-   }
+  // Return the number of rectangles enumerated
+  if(ClipGDI->EnumRects.c>MaxRects)
+  {
+    ClipGDI->EnumRects.c = 0xFFFFFFFF;
+  }
 
-   return ClipGDI->EnumRects.c;
+  return ClipGDI->EnumRects.c;
 }
 
 BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj, IN ULONG ObjSize,
                    OUT ULONG *EnumRects)
 {
-   CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
+  CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
 
-   ClipGDI->EnumPos++;
+  ClipGDI->EnumPos++;
 
-   if(ClipGDI->EnumPos > ClipGDI->EnumRects.c)
-   {
-      return FALSE;
-   } else
-      return TRUE;
+  if(ClipGDI->EnumPos > ClipGDI->EnumRects.c)
+  {
+    return FALSE;
+  } else
+    return TRUE;
 }
index ad49979..7edf7bb 100644 (file)
 #include <ddk/winddi.h>
 #include "objects.h"
 #include "enum.h"
+#include "../dib/dib.h"
 
-VOID CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
-                  SURFGDI *DestGDI,  SURFGDI *SourceGDI,
-                  PRECTL  DestRect,  POINTL  *SourcePoint,
-                  ULONG   Delta,     XLATEOBJ *ColorTranslation)
+BOOLEAN CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
+                     SURFGDI *DestGDI,  SURFGDI *SourceGDI,
+                     PRECTL  DestRect,  POINTL  *SourcePoint,
+                     ULONG   Delta,     XLATEOBJ *ColorTranslation)
 {
-   ULONG dy, leftOfSource, leftOfDest, Width, SourceBPP, DestBPP, RGBulong = 0, idxColor, i, TrivialCopy = 0;
-   BYTE  *SourcePos, *SourceInitial, *DestPos, *DestInitial;
-
-   // FIXME: Get ColorTranslation passed here and do something with it
-
-   if(ColorTranslation == NULL)
-   {
-      TrivialCopy = 1;
-   } else if(ColorTranslation->flXlate & XO_TRIVIAL)
-   {
-      TrivialCopy = 1;
-   }
-
-   leftOfSource = SourcePoint->x * SourceGDI->BytesPerPixel;
-   leftOfDest   = DestRect->left * DestGDI->BytesPerPixel;
-   Width        = (DestRect->right - DestRect->left) * DestGDI->BytesPerPixel;
-
-   if(TrivialCopy == 1)
-   {
-      for(dy=DestRect->top; dy<DestRect->bottom; dy++)
-      {
-         memcpy(DestSurf->pvBits+Delta*dy+leftOfDest,
-                SourceSurf->pvBits+Delta*dy+leftOfSource,
-                Width);
-      }
-   } else
-   if(ColorTranslation->flXlate & XO_TABLE)
-   {
-      SourceBPP = bytesPerPixel(SourceSurf->iBitmapFormat);
-      DestBPP   = bytesPerPixel(DestSurf->iBitmapFormat);
-
-      SourcePos = SourceSurf->pvBits +
-                  (SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x * SourceBPP);
-      SourceInitial = SourcePos;
-
-      DestPos = DestSurf->pvBits +
-                ((DestRect->bottom - DestRect->top) * DestSurf->lDelta) + (DestRect->left * DestBPP);
-      DestInitial = DestPos;
-
-      for(i=DestRect->left; i<DestRect->right; i++)
-      {
-         memcpy(&RGBulong, SourcePos, SourceBPP);
-         idxColor = XLATEOBJ_iXlate(ColorTranslation, RGBulong);
-         memcpy(DestPos, &idxColor, DestBPP);
-
-         SourcePos+=SourceBPP;
-         DestPos+=DestBPP;
-      }
-      SourcePos = SourceInitial + SourceSurf->lDelta;
-      DestPos   = DestInitial   + DestSurf->lDelta;
-   }
+  ULONG DestWidth, DestHeight, CurrentDestLine, CurrentSourceLine, CurrentDestCol, CurrentSourceCol, i, TranslationPixel;
+
+  PFN_DIB_GetPixel Source_DIB_GetPixel;
+  PFN_DIB_PutPixel Dest_DIB_PutPixel;
+
+  DestWidth  = DestRect->right - DestRect->left;
+  DestHeight = DestRect->bottom - DestRect->top;
+  CurrentSourceCol = SourcePoint->x;
+  CurrentSourceLine = SourcePoint->y;
+
+  // Assign GetPixel DIB function according to bytes per pixel
+  switch(DestGDI->BitsPerPixel)
+  {
+    case 4:
+      return DIB_To_4BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
+                                DestRect, SourcePoint, Delta, ColorTranslation);
+      break;
+
+    case 24:
+      return DIB_To_24BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
+                                 DestRect, SourcePoint, Delta, ColorTranslation);
+      break;
+
+    default:
+      return FALSE;
+  }
+
+  return TRUE;
 }
 
 BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
                  CLIPOBJ *Clip, XLATEOBJ *ColorTranslation,
                  RECTL *DestRect, POINTL *SourcePoint)
 {
-   SURFGDI   *DestGDI, *SourceGDI;
-   BYTE      clippingType;
-   RECTL     rclTmp;
-   POINTL    ptlTmp;
-   RECT_ENUM RectEnum;
-   BOOL      EnumMore;
-
-   // FIXME: Do color translation -- refer to eng\bitblt.c
-
-   // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
-   //        mark the copy block function to be DrvCopyBits instead of the
-   //        GDI's copy bit function so as to remove clipping from the
-   //        driver's responsibility
-
-   // If one of the surfaces isn't managed by the GDI
-   if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
-   {
-
-      // Destination surface is device managed
-      if(Dest->iType!=STYPE_BITMAP)
+  SURFGDI   *DestGDI, *SourceGDI;
+  BYTE      clippingType;
+  RECTL     rclTmp;
+  POINTL    ptlTmp;
+  RECT_ENUM RectEnum;
+  BOOL      EnumMore;
+
+  // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
+  //        mark the copy block function to be DrvCopyBits instead of the
+  //        GDI's copy bit function so as to remove clipping from the
+  //        driver's responsibility
+
+  // If one of the surfaces isn't managed by the GDI
+  if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
+  {
+    // Destination surface is device managed
+    if(Dest->iType!=STYPE_BITMAP)
+    {
+      DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
+
+      if (DestGDI->CopyBits!=NULL)
       {
-         DestGDI = AccessInternalObjectFromUserObject(Dest);
-
-         if (DestGDI->CopyBits!=NULL)
-         {
-            return DestGDI->CopyBits(Dest, Source, Clip,
-                                     ColorTranslation, DestRect, SourcePoint);
-         }
+        return DestGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
       }
+    }
 
-      // Source surface is device managed
-      if(Source->iType!=STYPE_BITMAP)
-      {
-         SourceGDI = AccessInternalObjectFromUserObject(Source);
+    // Source surface is device managed
+    if(Source->iType!=STYPE_BITMAP)
+    {
+      SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
 
-         if (SourceGDI->CopyBits!=NULL)
-         {
-            return SourceGDI->CopyBits(Dest, Source, Clip,
-                                       ColorTranslation, DestRect, SourcePoint);
-         }
+      if (SourceGDI->CopyBits!=NULL)
+      {
+        return SourceGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
       }
+    }
 
-      // If CopyBits wasn't hooked, BitBlt must be
-      return EngBitBlt(Dest, Source,
-                       NULL, Clip, ColorTranslation, DestRect, SourcePoint,
-                       NULL, NULL, NULL, NULL);
-   }
-
-   // Determine clipping type
-   if (Clip == (CLIPOBJ *) NULL)
-   {
-      clippingType = DC_TRIVIAL;
-   } else {
-      clippingType = Clip->iDComplexity;
-   }
-
-   // We only handle XO_TABLE translations at the momement
-   if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL) ||
-       (ColorTranslation->flXlate & XO_TABLE))
-   {
-      SourceGDI = AccessInternalObjectFromUserObject(Source);
-      DestGDI   = AccessInternalObjectFromUserObject(Dest);
-
-      switch(clippingType)
-      {
-         case DC_TRIVIAL:
-            CopyBitsCopy(Dest,     Source,
-                         DestGDI,  SourceGDI,
-                         DestRect, SourcePoint, Source->lDelta, ColorTranslation);
+    // If CopyBits wasn't hooked, BitBlt must be
+    return EngBitBlt(Dest, Source,
+                     NULL, Clip, ColorTranslation, DestRect, SourcePoint,
+                     NULL, NULL, NULL, NULL);
+  }
 
-            return(TRUE);
+  // Determine clipping type
+  if (Clip == (CLIPOBJ *) NULL)
+  {
+    clippingType = DC_TRIVIAL;
+  } else {
+    clippingType = Clip->iDComplexity;
+  }
 
-         case DC_RECT:
+  // We only handle XO_TABLE translations at the momement
+  if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL) ||
+      (ColorTranslation->flXlate & XO_TABLE))
+  {
+    SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
+    DestGDI   = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
 
-            // Clip the blt to the clip rectangle
+    switch(clippingType)
+    {
+      case DC_TRIVIAL:
+        CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation);
+        return(TRUE);
 
-            EngIntersectRect(&rclTmp, DestRect, &Clip->rclBounds);
+      case DC_RECT:
+        // Clip the blt to the clip rectangle
+        EngIntersectRect(&rclTmp, DestRect, &Clip->rclBounds);
 
-            ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
-            ptlTmp.y = SourcePoint->y + rclTmp.top  - DestRect->top;
+        ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
+        ptlTmp.y = SourcePoint->y + rclTmp.top  - DestRect->top;
 
-            CopyBitsCopy(Dest,    Source,
-                         DestGDI, SourceGDI,
-                         &rclTmp, &ptlTmp, Source->lDelta, ColorTranslation);
+        CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, &rclTmp, &ptlTmp, Source->lDelta, ColorTranslation);
 
-            return(TRUE);
+        return(TRUE);
 
-         case DC_COMPLEX:
+      case DC_COMPLEX:
 
-            CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES,
-            CD_ANY, ENUM_RECT_LIMIT);
+        CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
 
-            do {
-               EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum),
-               (PVOID) &RectEnum);
+        do {
+          EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
 
-               if (RectEnum.c > 0)
-               {
-                  RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
-                  RECTL* prcl    = &RectEnum.arcl[0];
+          if (RectEnum.c > 0)
+          {
+            RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
+            RECTL* prcl    = &RectEnum.arcl[0];
 
-                  do {
-                     EngIntersectRect(prcl, prcl, DestRect);
+            do {
+              EngIntersectRect(prcl, prcl, DestRect);
 
-                     ptlTmp.x = SourcePoint->x + prcl->left
-                                - DestRect->left;
-                     ptlTmp.y = SourcePoint->y + prcl->top
-                                - DestRect->top;
+              ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
+              ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
 
-                     CopyBitsCopy(Dest,    Source,
-                                  DestGDI, SourceGDI,
-                                  prcl, &ptlTmp, Source->lDelta, ColorTranslation);
+              if(!CopyBitsCopy(Dest, Source, DestGDI, SourceGDI,
+                               prcl, &ptlTmp, Source->lDelta, ColorTranslation)) return FALSE;
 
-                     prcl++;
+              prcl++;
 
-                  } while (prcl < prclEnd);
-               }
+              } while (prcl < prclEnd);
+            }
 
-            } while(EnumMore);
+          } while(EnumMore);
 
-            return(TRUE);
-      }
-   }
+          return(TRUE);
+    }
+  }
 
-   return FALSE;
+  return FALSE;
 }
index ca67bec..b5ee1b9 100644 (file)
 #include <ddk/ntddk.h>
 
 DWORD STDCALL EngDeviceIoControl(
-   HANDLE  hDevice,
-   DWORD   dwIoControlCode,
-   LPVOID  lpInBuffer,
-   DWORD   nInBufferSize,
-   LPVOID  lpOutBuffer,
-   DWORD   nOutBufferSize,
-   DWORD *lpBytesReturned)
+  HANDLE  hDevice,
+  DWORD   dwIoControlCode,
+  LPVOID  lpInBuffer,
+  DWORD   nInBufferSize,
+  LPVOID  lpOutBuffer,
+  DWORD   nOutBufferSize,
+  DWORD *lpBytesReturned)
 {
-   PIRP Irp;
-   NTSTATUS Status;
-   KEVENT Event;
-   IO_STATUS_BLOCK Iosb;
-   PDRIVER_OBJECT DriverObject;
-
-   DriverObject = hDevice;
-
-   KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
-
-   Irp = IoBuildDeviceIoControlRequest(dwIoControlCode,
-                                       DriverObject->DeviceObject,
-                                       lpInBuffer,
-                                       nInBufferSize,
-                                       lpOutBuffer,
-                                       nOutBufferSize,
-                                       FALSE,
-                                       &Event,
-                                       &Iosb);
-
-   Status = IoCallDriver(DriverObject->DeviceObject, Irp);
-
-   if (Status == STATUS_PENDING)
-   {
-     (void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
-   }
-
-   return (Status);
+  PIRP Irp;
+  NTSTATUS Status;
+  KEVENT Event;
+  IO_STATUS_BLOCK Iosb;
+  PDRIVER_OBJECT DriverObject;
+
+  DriverObject = hDevice;
+
+  KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
+
+  Irp = IoBuildDeviceIoControlRequest(dwIoControlCode, DriverObject->DeviceObject, lpInBuffer, nInBufferSize,
+                                      lpOutBuffer, nOutBufferSize, FALSE, &Event, &Iosb);
+
+  Status = IoCallDriver(DriverObject->DeviceObject, Irp);
+
+  if (Status == STATUS_PENDING)
+  {
+    (void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
+  }
+
+  return (Status);
 }
index bae69a2..5707544 100644 (file)
@@ -16,19 +16,19 @@ ULONG CLIPOBJ_cEnumStart(IN PCLIPOBJ  ClipObj,
                          IN ULONG  BuildOrder,
                          IN ULONG  MaxRects)
 {
-   // Sets the parameters for enumerating rectables in the given clip region
+  // Sets the parameters for enumerating rectables in the given clip region
 
-   ULONG enumCount = 0;
-   ENUMRECTS enumRects;
+  ULONG enumCount = 0;
+  ENUMRECTS enumRects;
 
-   // MUCH WORK TO DO HERE
+  // MUCH WORK TO DO HERE
 
-   // Return the number of rectangles enumerated
-   if(enumCount>MaxRects)
-   {
-     enumCount = 0xFFFFFFFF;
-   }
-   return enumCount;
+  // Return the number of rectangles enumerated
+  if(enumCount>MaxRects)
+  {
+    enumCount = 0xFFFFFFFF;
+  }
+  return enumCount;
 }
 
 BOOL CLIPOBJ_bEnum(IN PCLIPOBJ  ClipObj,
index cb1d68e..0a2dab6 100644 (file)
@@ -2,6 +2,6 @@
 
 typedef struct _RECT_ENUM
 {
-   ULONG c;
-   RECTL arcl[ENUM_RECT_LIMIT];
+  ULONG c;
+  RECTL arcl[ENUM_RECT_LIMIT];
 } RECT_ENUM;
index 50ea896..d060dfc 100644 (file)
 
 ULONG CreateGDIHandle(PVOID InternalObject, PVOID UserObject)
 {
-   ULONG NewHandle = HandleCounter++;
+  ULONG NewHandle = HandleCounter++;
 
-   GDIHandles[NewHandle].InternalObject = InternalObject;
-   GDIHandles[NewHandle].UserObject     = UserObject;
+  GDIHandles[NewHandle].InternalObject = InternalObject;
+  GDIHandles[NewHandle].UserObject     = UserObject;
 
-   return NewHandle;
+  return NewHandle;
 }
 
 VOID FreeGDIHandle(ULONG Handle)
 {
-   GDIHandles[Handle].InternalObject = NULL;
-   GDIHandles[Handle].UserObject     = NULL;
+  GDIHandles[Handle].InternalObject = NULL;
+  GDIHandles[Handle].UserObject     = NULL;
 }
 
 PVOID AccessInternalObject(ULONG Handle)
 {
-   return GDIHandles[Handle].InternalObject;
+  return GDIHandles[Handle].InternalObject;
 }
 
 PVOID AccessUserObject(ULONG Handle)
 {
-   return GDIHandles[Handle].UserObject;
+  return GDIHandles[Handle].UserObject;
 }
 
 PVOID AccessInternalObjectFromUserObject(PVOID UserObject)
 {
-   ULONG i;
+  ULONG i;
 
-   for(i=0; i<MAX_GDI_HANDLES; i++)
-   {
-      if(GDIHandles[i].UserObject == UserObject)
-         return GDIHandles[i].InternalObject;
-   }
+  for(i=0; i<MAX_GDI_HANDLES; i++)
+  {
+    if(GDIHandles[i].UserObject == UserObject) return GDIHandles[i].InternalObject;
+  }
 
-   return NULL;
+  return NULL;
 }
 
 ULONG AccessHandleFromUserObject(PVOID UserObject)
 {
-   ULONG i;
+  ULONG i;
 
-   for(i=0; i<MAX_GDI_HANDLES; i++)
-   {
-      if(GDIHandles[i].UserObject == UserObject)
-         return i;
-   }
+  for(i=0; i<MAX_GDI_HANDLES; i++)
+  {
+    if(GDIHandles[i].UserObject == UserObject) return i;
+  }
 
-   return INVALID_HANDLE;
+  return INVALID_HANDLE;
 }
index c7ca00c..e8a66c0 100644 (file)
@@ -9,9 +9,9 @@
  */
 
 typedef struct _GDI_HANDLE {
-   ULONG Handle;
-   PVOID InternalObject;
-   PVOID UserObject;
+  ULONG Handle;
+  PVOID InternalObject;
+  PVOID UserObject;
 } GDI_HANDLE, *PGDI_HANDLE;
 
 #define INVALID_HANDLE  0
index afa6a3b..326c662 100644 (file)
 #include <ddk/winddi.h>
 #include "objects.h"
+#include "../dib/dib.h"
 
 // POSSIBLE FIXME: Switch X and Y's so that drawing a line doesn't try to draw from 150 to 50 (negative dx)
 
-VOID LinePoint(SURFOBJ *Surface, SURFGDI *SurfGDI,
-               LONG x, LONG y, ULONG iColor)
+BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush,
+               LONG x1, LONG y1, LONG x2, LONG y2,
+               RECTL *RectBounds, MIX mix)
 {
-   ULONG offset;
+  SURFGDI *SurfGDI;
+  LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error, hx, vy;
 
-   offset = (Surface->lDelta*y)+(x*SurfGDI->BytesPerPixel);
+  // These functions are assigned if we're working with a DIB
+  // The assigned functions depend on the bitsPerPixel of the DIB
+  PFN_DIB_PutPixel DIB_PutPixel;
+  PFN_DIB_HLine    DIB_HLine;
+  PFN_DIB_VLine    DIB_VLine;
 
-   memcpy(Surface->pvBits+offset,
-          &iColor, SurfGDI->BytesPerPixel);
-}
-
-BOOL EngHLine(SURFOBJ *Surface, SURFGDI *SurfGDI,
-              LONG x, LONG y, LONG len, ULONG iColor)
-{
-   ULONG offset, ix;
+  SurfGDI = AccessInternalObjectFromUserObject(Surface);
 
-   offset = (Surface->lDelta*y)+(x*SurfGDI->BytesPerPixel);
+  if(Surface->iType!=STYPE_BITMAP)
+  {
+    // Call the driver's DrvLineTo
+    return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
+  }
 
-   for(ix=0; ix<len*SurfGDI->BytesPerPixel; ix+=SurfGDI->BytesPerPixel)
-      memcpy(Surface->pvBits+offset+ix,
-             &iColor, SurfGDI->BytesPerPixel);
+  // Assign DIB functions according to bytes per pixel
+  switch(BitsPerFormat(Surface->iBitmapFormat))
+  {
+    case 4:
+      DIB_PutPixel = DIB_4BPP_PutPixel;
+      DIB_HLine    = DIB_4BPP_HLine;
+      DIB_VLine    = DIB_4BPP_VLine;
+      break;
+
+    case 24:
+      DIB_PutPixel = DIB_24BPP_PutPixel;
+      DIB_HLine    = DIB_24BPP_HLine;
+      DIB_VLine    = DIB_24BPP_VLine;
+      break;
+
+    default:
+      DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
+               BitsPerFormat(Surface->iBitmapFormat));
+      return FALSE;
+  }
+
+  // FIXME: Implement clipping
+
+  x=x1;
+  y=y1;
+  deltax=x2-x1;
+  deltay=y2-y1;
+
+  if(deltax<0)
+  {
+    xchange=-1;
+    deltax=-deltax;
+    hx = x2;
+  } else
+  {
+    xchange=1;
+    hx = x1;
+  }
 
-   return TRUE;
-}
+  if(deltay<0)
+  {
+    ychange=-1;
+    deltay=-deltay;
+    vy = y2;
+  } else
+  {
+    ychange=1;
+    vy = y1;
+  }
 
-BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush,
-               LONG x1, LONG y1, LONG x2, LONG y2,
-               RECTL *RectBounds, MIX mix)
-{
-   SURFGDI *SurfGDI;
-   LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error;
-
-   SurfGDI = AccessInternalObjectFromUserObject(Surface);
-
-   if(Surface->iType!=STYPE_BITMAP)
-   {
-      // Call the driver's DrvLineTo
-      return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2,
-                             RectBounds, mix);
-   }
-
-   // FIXME: Implement clipping
-
-   if(y1==y2) return EngHLine(Surface, SurfGDI, x1, y1, (x2-x1), Brush->iSolidColor);
-
-   x=x1;
-   y=y1;
-   deltax=x2-x1;
-   deltay=y2-y1;
-
-   if(deltax<0)
-   {
-      xchange=-1;
-      deltax=-deltax;
-   } else
-   {
-      xchange=1;
-   }
-
-   if(deltay<0)
-   {
-      ychange=-1;
-      deltay=-deltay;
-   } else
-   {
-      ychange=1;
-   };
+  if(y1==y2) { DIB_HLine(Surface, hx, hx + deltax, y1, Brush->iSolidColor); return TRUE; }
+  if(x1==x2) { DIB_VLine(Surface, x1, vy, vy + deltay, Brush->iSolidColor); return TRUE; }
 
   error=0;
   i=0;
 
   if(deltax<deltay)
   {
-     length=deltay+1;
-     while(i<length)
-     {
-        LinePoint(Surface, SurfGDI, x, y, Brush->iSolidColor);
-        y=y+ychange;
-        error=error+deltax;
-
-        if(error>deltay)
-        {
-           x=x+xchange;
-           error=error-deltay;
-        }
-        i=i+1;
-     }
+    length=deltay+1;
+    while(i<length)
+    {
+      DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
+      y=y+ychange;
+      error=error+deltax;
+
+      if(error>deltay)
+      {
+        x=x+xchange;
+        error=error-deltay;
+      }
+      i=i+1;
+    }
   } else
   {
     length=deltax+1;
     while(i<length)
     {
-         LinePoint(Surface, SurfGDI, x, y, Brush->iSolidColor);
-         x=x+xchange;
-         error=error+deltay;
-         if(error>deltax)
-         {
-            y=y+ychange;
-            error=error-deltax;
-         }
-         i=i+1;
+      DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
+      x=x+xchange;
+      error=error+deltay;
+      if(error>deltax)
+      {
+        y=y+ychange;
+        error=error-deltax;
       }
-   }
+      i=i+1;
+    }
+  }
 
-   return TRUE;
+  return TRUE;
 }
index 29f483a..2c1a56d 100644 (file)
 
 PVOID STDCALL EngAllocMem(ULONG Flags, ULONG MemSize, ULONG Tag)
 {
-   PVOID newMem;
+  PVOID newMem;
 
-   newMem = ExAllocatePoolWithTag(NonPagedPool, MemSize, Tag); // FIXME: Use PagedPool when it is implemented
+  newMem = ExAllocatePoolWithTag(NonPagedPool, MemSize, Tag); // FIXME: Use PagedPool when it is implemented
 
-   if(Flags == FL_ZERO_MEMORY)
-   {
-     RtlZeroMemory(newMem, MemSize);
-   }
+  if(Flags == FL_ZERO_MEMORY)
+  {
+    RtlZeroMemory(newMem, MemSize);
+  }
 
-   return newMem;
+  return newMem;
 }
 
 VOID STDCALL EngFreeMem(PVOID Mem)
 {
-   ExFreePool(Mem);
+  ExFreePool(Mem);
 }
 
 PVOID STDCALL EngAllocUserMem(ULONG cj, ULONG tag)
 {
-/*   PVOID newMem;
+/*  PVOID newMem;
 
-   return ZwAllocateVirtualMemory(mycurrentprocess, newMem, 0, cj,
-     MEM_COMMIT, PAGE_READWRITE); */
+  return ZwAllocateVirtualMemory(mycurrentprocess, newMem, 0, cj,
+    MEM_COMMIT, PAGE_READWRITE); */
 
-   return NULL;
+  return NULL;
 }
 
 VOID STDCALL EngFreeUserMem(PVOID pv)
 {
-/*   ZwFreeVirtualMemory (mycurrentprocess, pv, 0, MEM_DECOMMIT); */
+/*  ZwFreeVirtualMemory (mycurrentprocess, pv, 0, MEM_DECOMMIT); */
 }
-
index a263b77..461a60d 100644 (file)
@@ -13,18 +13,18 @@ typedef struct _BRUSHGDI {
 } BRUSHGDI;
 
 typedef struct _CLIPGDI {
-   ULONG NumRegionRects;
-   ULONG NumIntersectRects;
-   RECTL *RegionRects;
-   RECTL *IntersectRects;
+  ULONG NumRegionRects;
+  ULONG NumIntersectRects;
+  RECTL *RegionRects;
+  RECTL *IntersectRects;
 
-   ULONG EnumPos;
-   ENUMRECTS EnumRects;
+  ULONG EnumPos;
+  ENUMRECTS EnumRects;
 } CLIPGDI, *PCLIPGDI;
 
 typedef struct _DRVFUNCTIONSGDI {
-   HDEV  hdev;
-   DRVFN Functions[INDEX_LAST];
+  HDEV  hdev;
+  DRVFN Functions[INDEX_LAST];
 } DRVFUNCTIONSGDI;
 
 typedef struct _FLOATGDI {
@@ -36,12 +36,12 @@ typedef struct _FONTGDI {
 } FONTGDI;
 
 typedef struct _PALGDI {
-   ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
-   ULONG NumColors;
-   ULONG *IndexedColors;
-   ULONG RedMask;
-   ULONG GreenMask;
-   ULONG BlueMask;
+  ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
+  ULONG NumColors;
+  ULONG *IndexedColors;
+  ULONG RedMask;
+  ULONG GreenMask;
+  ULONG BlueMask;
 } PALGDI, *PPALGDI;
 
 typedef struct _PATHGDI {
@@ -88,21 +88,24 @@ typedef VOID (*PFN_MovePointer)(PSURFOBJ, LONG, LONG, PRECTL);
 
 typedef HBITMAP (*PFN_CreateDeviceBitmap)(DHPDEV, SIZEL, ULONG);
 
+typedef BOOL (*PFN_SetPalette)(DHPDEV, PALOBJ*, ULONG, ULONG, ULONG);
+
 typedef struct _SURFGDI {
-   BYTE  BytesPerPixel;
-
-   PFN_BitBlt BitBlt;
-   PFN_StretchBlt StretchBlt;
-   PFN_TextOut TextOut;
-   PFN_Paint Paint;
-   PFN_StrokePath StrokePath;
-   PFN_FillPath FillPath;
-   PFN_StrokeAndFillPath StrokeAndFillPath;
-   PFN_LineTo LineTo;
-   PFN_CopyBits CopyBits;
-   PFN_Synchronize Synchronize;
-   BOOL SynchronizeAccess;
-   PFN_CreateDeviceBitmap CreateDeviceBitmap;
+  INT BitsPerPixel;
+
+  PFN_BitBlt BitBlt;
+  PFN_StretchBlt StretchBlt;
+  PFN_TextOut TextOut;
+  PFN_Paint Paint;
+  PFN_StrokePath StrokePath;
+  PFN_FillPath FillPath;
+  PFN_StrokeAndFillPath StrokeAndFillPath;
+  PFN_LineTo LineTo;
+  PFN_CopyBits CopyBits;
+  PFN_Synchronize Synchronize;
+  BOOL SynchronizeAccess;
+  PFN_CreateDeviceBitmap CreateDeviceBitmap;
+  PFN_SetPalette SetPalette;
 } SURFGDI, *PSURFGDI;
 
 typedef struct _XFORMGDI {
@@ -110,10 +113,10 @@ typedef struct _XFORMGDI {
 } XFORMGDI;
 
 typedef struct _XLATEGDI {
-   HPALETTE DestPal;
-   HPALETTE SourcePal;
+  HPALETTE DestPal;
+  HPALETTE SourcePal;
 
-   ULONG *translationTable;
+  ULONG *translationTable;
 } XLATEGDI;
 
 // List of GDI objects
index 6b8500b..996861a 100644 (file)
 
 BOOL FillSolid(SURFOBJ *Surface, PRECTL Dimensions, ULONG iColor)
 {
-   ULONG x, y, LineWidth, leftOfBitmap;
-   SURFGDI *SurfaceGDI;
+  ULONG x, y, LineWidth, leftOfBitmap;
+  SURFGDI *SurfaceGDI;
 
-   SurfaceGDI = AccessInternalObjectFromUserObject(Surface);
-   LineWidth  = Dimensions->right - Dimensions->left;
+  SurfaceGDI = AccessInternalObjectFromUserObject(Surface);
+  LineWidth  = Dimensions->right - Dimensions->left;
 
-   for (y = Dimensions->top; y < Dimensions->bottom; y++)
-   {
-      EngHLine(Surface, SurfaceGDI, Dimensions->left, y, LineWidth, iColor);
-   }
+  for (y = Dimensions->top; y < Dimensions->bottom; y++)
+  {
+//      EngHLine(Surface, SurfaceGDI, Dimensions->left, y, LineWidth, iColor);
+  }
 
-   return TRUE;
+  return TRUE;
 }
 
 BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
                BRUSHINST *BrushInst, POINTL *BrushPoint)
 {
-   RECT_ENUM RectEnum;
-   BOOL EnumMore;
+  RECT_ENUM RectEnum;
+  BOOL EnumMore;
 
-   switch(ClipRegion->iMode) {
+  switch(ClipRegion->iMode) {
 
-      case TC_RECTANGLES:
+    case TC_RECTANGLES:
 
-      /* Rectangular clipping can be handled without enumeration.
-         Note that trivial clipping is not possible, since the clipping
-         region defines the area to fill */
+    /* Rectangular clipping can be handled without enumeration.
+       Note that trivial clipping is not possible, since the clipping
+       region defines the area to fill */
 
-      if (ClipRegion->iDComplexity == DC_RECT)
-      {
-         FillSolid(Surface, &ClipRegion->rclBounds, iColor);
-      } else {
+    if (ClipRegion->iDComplexity == DC_RECT)
+    {
+      FillSolid(Surface, &ClipRegion->rclBounds, iColor);
+    } else {
 
-         /* Enumerate all the rectangles and draw them */
+      /* Enumerate all the rectangles and draw them */
+      CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
 
-         CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY,
-                            ENUM_RECT_LIMIT);
+      do {
+        EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
+        FillSolid(Surface, &RectEnum.arcl[0], iColor);
+      } while (EnumMore);
+    }
 
-         do {
-            EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
+    return(TRUE);
 
-            FillSolid(Surface, &RectEnum.arcl[0], iColor);
-
-         } while (EnumMore);
-      }
-
-      return(TRUE);
-
-      default:
-         return(FALSE);
-   }
+    default:
+       return(FALSE);
+  }
 }
 
 BOOL EngPaint(IN SURFOBJ *Surface, IN CLIPOBJ *ClipRegion,
               IN BRUSHOBJ *Brush,  IN POINTL *BrushOrigin,
               IN MIX  Mix)
 {
-   SURFGDI *SurfGDI;
+  SURFGDI *SurfGDI;
 
-   // Is the surface's Paint function hooked?
-   SurfGDI = AccessInternalObjectFromUserObject(Surface);
+  // Is the surface's Paint function hooked?
+  SurfGDI = AccessInternalObjectFromUserObject(Surface);
 
-   if((Surface->iType!=STYPE_BITMAP) && (SurfGDI->Paint!=NULL))
-   {
-      // Call the driver's DrvPaint
-      return SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix);
-   }
+  if((Surface->iType!=STYPE_BITMAP) && (SurfGDI->Paint!=NULL))
+  {
+    // Call the driver's DrvPaint
+    return SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix);
+  }
 
-   // FIXME: We only support a brush's solid color attribute
-   return(EngPaintRgn(Surface, ClipRegion, Brush->iSolidColor, Mix, NULL,
-      BrushOrigin));
+  // FIXME: We only support a brush's solid color attribute
+  return(EngPaintRgn(Surface, ClipRegion, Brush->iSolidColor, Mix, NULL, BrushOrigin));
 }
 
 BOOL EngEraseSurface(SURFOBJ *Surface, RECTL *Rect, ULONG iColor)
 {
-   return FillSolid(Surface, Rect, iColor);
+  return FillSolid(Surface, Rect, iColor);
 }
index 70964bd..2acfe5d 100644 (file)
@@ -18,59 +18,65 @@ HPALETTE EngCreatePalette(ULONG  Mode,
                           ULONG  Green,
                           ULONG  Blue)
 {
-   HPALETTE NewPalette;
-   PALOBJ *PalObj;
-   PALGDI *PalGDI;
-
-   PalObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALOBJ), NULL);
-   PalGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALGDI), NULL);
-
-   NewPalette = CreateGDIHandle(PalGDI, PalObj);
-
-   PalGDI->Mode = Mode;
-
-   if(Mode==PAL_INDEXED)
-   {
-      PalGDI->NumColors     = NumColors;
-      PalGDI->IndexedColors = Colors;
-   } else
-   if(Mode==PAL_BITFIELDS)
-   {
-      PalGDI->RedMask   = Red;
-      PalGDI->GreenMask = Green;
-      PalGDI->BlueMask  = Blue;
-   }
-
-   return NewPalette;
+  HPALETTE NewPalette;
+  PALOBJ *PalObj;
+  PALGDI *PalGDI;
+
+  PalObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALOBJ), NULL);
+  PalGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALGDI), NULL);
+
+  NewPalette = CreateGDIHandle(PalGDI, PalObj);
+
+  PalGDI->Mode = Mode;
+
+  if(Colors != NULL)
+  {
+    PalGDI->IndexedColors = ExAllocatePool(NonPagedPool, sizeof(ULONG)*NumColors);
+    RtlCopyMemory(PalGDI->IndexedColors, Colors, sizeof(ULONG)*NumColors);
+  }
+
+  if(Mode==PAL_INDEXED)
+  {
+    PalGDI->NumColors     = NumColors;
+    PalGDI->IndexedColors = Colors;
+  } else
+  if(Mode==PAL_BITFIELDS)
+  {
+    PalGDI->RedMask   = Red;
+    PalGDI->GreenMask = Green;
+    PalGDI->BlueMask  = Blue;
+  }
+
+  return NewPalette;
 }
 
 BOOL EngDeletePalette(IN HPALETTE Palette)
 {
-   PALOBJ *PalObj;
-   PALGDI *PalGDI;
+  PALOBJ *PalObj;
+  PALGDI *PalGDI;
 
-   PalGDI = AccessInternalObject(Palette);
-   PalObj = AccessInternalObject(Palette);
+  PalGDI = AccessInternalObject(Palette);
+  PalObj = AccessInternalObject(Palette);
 
-   EngFreeMem(PalGDI);
-   EngFreeMem(PalObj);
-   FreeGDIHandle(Palette);
+  EngFreeMem(PalGDI);
+  EngFreeMem(PalObj);
+  FreeGDIHandle(Palette);
 
-   return TRUE;
+  return TRUE;
 }
 
 ULONG PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors,
                         ULONG  *PaletteEntry)
 {
-   ULONG i, entry;
-   PALGDI *PalGDI;
+  ULONG i, entry;
+  PALGDI *PalGDI;
 
-   PalGDI = AccessInternalObjectFromUserObject(PalObj);
+  PalGDI = AccessInternalObjectFromUserObject(PalObj);
 
-   for(i=Start; i<Colors; i++)
-   {
-      PaletteEntry[i] = PalGDI->IndexedColors[i];
-   }
+  for(i=Start; i<Colors; i++)
+  {
+    PaletteEntry[i] = PalGDI->IndexedColors[i];
+  }
 
-   return Colors;
+  return Colors;
 }
index a7c18f5..14b7248 100644 (file)
@@ -6,64 +6,72 @@
  * PROGRAMER:         Jason Filby
  * REVISION HISTORY:
  *                 3/7/1999: Created
+ *                 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
+ * TESTING TO BE DONE:
+ * - Create a GDI bitmap with all formats, perform all drawing operations on them, render to VGA surface
+ *   refer to \test\microwin\src\engine\devdraw.c for info on correct pixel plotting for various formats
  */
 
 #include <ddk/winddi.h>
 #include <win32k/dc.h>
 #include "objects.h"
 
-BYTE bytesPerPixel(ULONG Format)
+INT BitsPerFormat(ULONG Format)
 {
-   // FIXME: GDI bitmaps are supposed to be pixel-packed. Right now if the
-   // pixel size if < 1 byte we expand it to 1 byte
-
-   if(Format==BMF_1BPP)
-   {
-      return 1;
-   } else
-   if((Format==BMF_4BPP) || (Format==BMF_4RLE))
-   {
-      return 1;
-   } else
-   if((Format==BMF_8BPP) || (Format==BMF_8RLE))
-   {
-      return 1;
-   } else
-   if(Format==BMF_16BPP)
-   {
-      return 2;
-   } else
-   if(Format==BMF_24BPP)
-   {
-      return 3;
-   } else
-   if(Format==BMF_32BPP)
-   {
-      return 4;
-   }
-
-   return 0;
+  switch(Format)
+  {
+    case BMF_1BPP: return 1;
+    case BMF_4BPP:
+    case BMF_4RLE: return 4;
+    case BMF_8BPP:
+    case BMF_8RLE: return 8;
+    case BMF_16BPP: return 16;
+    case BMF_24BPP: return 24;
+    case BMF_32BPP: return 32;
+    default: return 0;
+  }
+}
+
+ULONG BitmapFormat(WORD Bits, DWORD Compression)
+{
+  switch(Compression)
+  {
+    case BI_RGB:
+      switch(Bits)
+      {
+        case 1: return BMF_1BPP;
+        case 4: return BMF_4BPP;
+        case 8: return BMF_8BPP;
+        case 16: return BMF_16BPP;
+        case 24: return BMF_24BPP;
+        case 32: return BMF_32BPP;
+      }
+
+    case BI_RLE4: return BMF_4RLE;
+    case BI_RLE8: return BMF_8RLE;
+
+    default: return 0;
+  }
 }
 
 VOID InitializeHooks(SURFGDI *SurfGDI)
 {
-   SurfGDI->BitBlt   = NULL;
-   SurfGDI->CopyBits = NULL;
-   SurfGDI->CreateDeviceBitmap = NULL;
+  SurfGDI->BitBlt   = NULL;
+  SurfGDI->CopyBits = NULL;
+  SurfGDI->CreateDeviceBitmap = NULL;
+  SurfGDI->SetPalette = NULL;
 }
 
 HBITMAP EngCreateDeviceBitmap(DHSURF dhsurf, SIZEL Size, ULONG Format)
 {
-   HBITMAP NewBitmap;
-   SURFOBJ *SurfObj;
-
-   NewBitmap = EngCreateBitmap(Size, bytesPerPixel(Format) * Size.cx, Format, 0, NULL);
-   SurfObj = AccessUserObject(NewBitmap);
-   SurfObj->dhpdev = dhsurf;
+  HBITMAP NewBitmap;
+  SURFOBJ *SurfObj;
 
-   return NewBitmap;
+  NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
+  SurfObj = (PVOID)AccessUserObject(NewBitmap);
+  SurfObj->dhpdev = dhsurf;
 
-   return 0;
+  return NewBitmap;
 }
 
 HBITMAP EngCreateBitmap(IN SIZEL  Size,
@@ -72,141 +80,134 @@ HBITMAP EngCreateBitmap(IN SIZEL  Size,
                         IN ULONG  Flags,
                         IN PVOID  Bits)
 {
-   HBITMAP NewBitmap;
-   SURFOBJ *SurfObj;
-   SURFGDI *SurfGDI;
-
-   SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
-   SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
-
-   NewBitmap = CreateGDIHandle(SurfGDI, SurfObj);
-
-   InitializeHooks(SurfGDI);
-   SurfGDI->BytesPerPixel = bytesPerPixel(Format);
-
-   SurfObj->lDelta = ((bytesPerPixel(Format) * Width) + 31) & ~31; // round up 4 bytes
-   SurfObj->cjBits = SurfObj->lDelta * Size.cy;
-
-   if(Bits!=NULL)
-   {
-      SurfObj->pvBits = Bits;
-   } else
-   {
-      if(Flags & BMF_USERMEM)
+  HBITMAP NewBitmap;
+  SURFOBJ *SurfObj;
+  SURFGDI *SurfGDI;
+
+  SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), 0);
+  SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), 0);
+
+  NewBitmap = (PVOID)CreateGDIHandle(SurfGDI, SurfObj);
+
+  InitializeHooks(SurfGDI);
+  SurfGDI->BitsPerPixel = BitsPerFormat(Format);
+  SurfObj->lDelta = Width;
+  SurfObj->cjBits = SurfObj->lDelta * Size.cy;
+
+  if(Bits!=NULL)
+  {
+    SurfObj->pvBits = Bits;
+  } else
+  {
+    if(Flags & BMF_USERMEM)
+    {
+      SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
+    } else {
+      if(Flags & BMF_NOZEROINIT)
       {
-         SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
+        SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
       } else {
-         if(Flags & BMF_NOZEROINIT)
-         {
-            SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
-         } else {
-            SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
-         }
+        SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
       }
-   }
+    }
+  }
 
-   SurfObj->dhsurf = 0; // device managed surface
-   SurfObj->hsurf  = 0;
-   SurfObj->sizlBitmap = Size;
-   SurfObj->iBitmapFormat = Format;
-   SurfObj->iType = STYPE_BITMAP;
+  SurfObj->dhsurf = 0; // device managed surface
+  SurfObj->hsurf  = 0;
+  SurfObj->sizlBitmap = Size;
+  SurfObj->iBitmapFormat = Format;
+  SurfObj->iType = STYPE_BITMAP;
 
-   // Use flags to determine bitmap type -- TOP_DOWN or whatever
+  // Use flags to determine bitmap type -- TOP_DOWN or whatever
 
-   return NewBitmap;
+  return NewBitmap;
 }
 
 HSURF EngCreateDeviceSurface(DHSURF dhsurf, SIZEL Size, ULONG Format)
 {
-   HSURF   NewSurface;
-   SURFOBJ *SurfObj;
-   SURFGDI *SurfGDI;
-
-   SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
-   SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
+  HSURF   NewSurface;
+  SURFOBJ *SurfObj;
+  SURFGDI *SurfGDI;
 
-   NewSurface = CreateGDIHandle(SurfGDI, SurfObj);
+  SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
+  SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
 
-   InitializeHooks(SurfGDI);
+  NewSurface = CreateGDIHandle(SurfGDI, SurfObj);
 
-   SurfGDI->BytesPerPixel = bytesPerPixel(Format);
+  InitializeHooks(SurfGDI);
 
-   SurfObj->dhsurf = dhsurf;
-   SurfObj->hsurf  = dhsurf; // FIXME: Is this correct??
-   SurfObj->sizlBitmap = Size;
-   SurfObj->iBitmapFormat = Format;
-   SurfObj->lDelta = SurfGDI->BytesPerPixel * Size.cx;
-   SurfObj->iType = STYPE_DEVICE;
+  SurfGDI->BitsPerPixel = BitsPerFormat(Format);
+  SurfObj->dhsurf = dhsurf;
+  SurfObj->hsurf  = dhsurf; // FIXME: Is this correct??
+  SurfObj->sizlBitmap = Size;
+  SurfObj->iBitmapFormat = Format;
+  SurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
+  SurfObj->iType = STYPE_DEVICE;
 
-   return NewSurface;
+  return NewSurface;
 }
 
 PFN DriverFunction(DRVENABLEDATA *DED, ULONG DriverFunc)
 {
-   ULONG i;
-
-   for(i=0; i<DED->c; i++)
-   {
-      if(DED->pdrvfn[i].iFunc == DriverFunc)
-         return DED->pdrvfn[i].pfn;
-   }
-   return NULL;
+  ULONG i;
+
+  for(i=0; i<DED->c; i++)
+  {
+    if(DED->pdrvfn[i].iFunc == DriverFunc)
+      return DED->pdrvfn[i].pfn;
+  }
+  return NULL;
 }
 
 BOOL EngAssociateSurface(HSURF Surface, HDEV Dev, ULONG Hooks)
 {
-   SURFOBJ *SurfObj;
-   SURFGDI *SurfGDI;
-
-// it looks like this Dev is actually a pointer to the DC!
-   PDC Dc = (PDC)Dev;
-DbgPrint("Associate 1\n");
-//   DRVENABLEDATA *DED;
-
-   SurfGDI = AccessInternalObject(Surface);
-   SurfObj = AccessUserObject(Surface);
-
-//   DED = AccessInternalObject(Dev);
-
-   // Associate the hdev
-   SurfObj->hdev = Dev;
-
-   // Hook up specified functions
-   if(Hooks & HOOK_BITBLT)            SurfGDI->BitBlt            = Dc->DriverFunctions.BitBlt;
-   if(Hooks & HOOK_STRETCHBLT)        SurfGDI->StretchBlt        = Dc->DriverFunctions.StretchBlt;
-   if(Hooks & HOOK_TEXTOUT)           SurfGDI->TextOut           = Dc->DriverFunctions.TextOut;
-   if(Hooks & HOOK_PAINT)             SurfGDI->Paint             = Dc->DriverFunctions.Paint;
-   if(Hooks & HOOK_STROKEPATH)        SurfGDI->StrokePath        = Dc->DriverFunctions.StrokePath;
-   if(Hooks & HOOK_FILLPATH)          SurfGDI->FillPath          = Dc->DriverFunctions.FillPath;
-   if(Hooks & HOOK_STROKEANDFILLPATH) SurfGDI->StrokeAndFillPath = Dc->DriverFunctions.StrokeAndFillPath;
-   if(Hooks & HOOK_LINETO)            SurfGDI->LineTo            = Dc->DriverFunctions.LineTo;
-   if(Hooks & HOOK_COPYBITS)          SurfGDI->CopyBits          = Dc->DriverFunctions.CopyBits;
-   if(Hooks & HOOK_SYNCHRONIZE)       SurfGDI->Synchronize       = Dc->DriverFunctions.Synchronize;
-   if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE;
-
-   SurfGDI->CreateDeviceBitmap = Dc->DriverFunctions.CreateDeviceBitmap;
-
-   return TRUE;
+  SURFOBJ *SurfObj;
+  SURFGDI *SurfGDI;
+
+  PDC Dc = (PDC)Dev;
+
+  SurfGDI = (PVOID)AccessInternalObject(Surface);
+  SurfObj = (PVOID)AccessUserObject(Surface);
+
+  // Associate the hdev
+  SurfObj->hdev = Dev;
+
+  // Hook up specified functions
+  if(Hooks & HOOK_BITBLT)            SurfGDI->BitBlt            = Dc->DriverFunctions.BitBlt;
+  if(Hooks & HOOK_STRETCHBLT)        SurfGDI->StretchBlt        = Dc->DriverFunctions.StretchBlt;
+  if(Hooks & HOOK_TEXTOUT)           SurfGDI->TextOut           = Dc->DriverFunctions.TextOut;
+  if(Hooks & HOOK_PAINT)             SurfGDI->Paint             = Dc->DriverFunctions.Paint;
+  if(Hooks & HOOK_STROKEPATH)        SurfGDI->StrokePath        = Dc->DriverFunctions.StrokePath;
+  if(Hooks & HOOK_FILLPATH)          SurfGDI->FillPath          = Dc->DriverFunctions.FillPath;
+  if(Hooks & HOOK_STROKEANDFILLPATH) SurfGDI->StrokeAndFillPath = Dc->DriverFunctions.StrokeAndFillPath;
+  if(Hooks & HOOK_LINETO)            SurfGDI->LineTo            = Dc->DriverFunctions.LineTo;
+  if(Hooks & HOOK_COPYBITS)          SurfGDI->CopyBits          = Dc->DriverFunctions.CopyBits;
+  if(Hooks & HOOK_SYNCHRONIZE)       SurfGDI->Synchronize       = Dc->DriverFunctions.Synchronize;
+  if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE;
+
+  SurfGDI->CreateDeviceBitmap = Dc->DriverFunctions.CreateDeviceBitmap;
+  SurfGDI->SetPalette = Dc->DriverFunctions.SetPalette;
+
+  return TRUE;
 }
 
 BOOL EngDeleteSurface(HSURF Surface)
 {
-   SURFOBJ *SurfObj;
-   SURFGDI *SurfGDI;
+  SURFOBJ *SurfObj;
+  SURFGDI *SurfGDI;
 
-   SurfGDI = AccessInternalObject(Surface);
-   SurfObj = AccessUserObject(Surface);
+  SurfGDI = AccessInternalObject(Surface);
+  SurfObj = AccessUserObject(Surface);
 
-   EngFreeMem(SurfGDI);
-   EngFreeMem(SurfObj);
-   FreeGDIHandle(Surface);
+  EngFreeMem(SurfGDI);
+  EngFreeMem(SurfObj);
+  FreeGDIHandle(Surface);
 
-   return TRUE;
+  return TRUE;
 }
 
 SURFOBJ *EngLockSurface(HSURF Surface)
 {
-   // FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
-
-   return AccessUserObject(Surface);
+  // FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
+  return AccessUserObject(Surface);
 }
index bb0339f..c007e25 100644 (file)
@@ -18,251 +18,249 @@ ULONG CCMLastSourceColor = 0, CCMLastColorMatch = 0;
 
 ULONG RGBtoULONG(BYTE Red, BYTE Green, BYTE Blue)
 {
-   return ((Red & 0xff) << 16) | ((Green & 0xff) << 8) | (Blue & 0xff);
+  return ((Red & 0xff) << 16) | ((Green & 0xff) << 8) | (Blue & 0xff);
 }
 
 ULONG BGRtoULONG(BYTE Blue, BYTE Green, BYTE Red)
 {
-   return ((Blue & 0xff) << 16) | ((Green & 0xff) << 8) | (Red & 0xff);
+  return ((Blue & 0xff) << 16) | ((Green & 0xff) << 8) | (Red & 0xff);
 }
 
 INT abs(INT nm)
 {
-   if(nm<0)
-   {
-      return nm * -1;
-   } else
-   {
-      return nm;
-   }
+  if(nm<0)
+  {
+    return nm * -1;
+  } else
+  {
+    return nm;
+  }
 }
 
 // FIXME: If the caller knows that the destinations are indexed and not RGB
 // then we should cache more than one value. Same with the source.
 
+// Takes indexed palette and a
 ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors,
                         ULONG NumColors)
 {
-   PVIDEO_CLUTDATA cSourceColor;
-   PVIDEO_CLUTDATA cDestColors;
-   ULONG bestMatch = 256, idx = 0, i;
-   ULONG rt;
+  PVIDEO_CLUTDATA cSourceColor;
+  PVIDEO_CLUTDATA cDestColors;
+  ULONG bestMatch = 256, idx = 0, i;
+  ULONG rt;
 
-   // Simple cache -- only one value because we don't want to waste time
-   // if the colors aren't very sequential
+  // Simple cache -- only one value because we don't want to waste time
+  // if the colors aren't very sequential
 
-   if(SourceColor == CCMLastSourceColor)
-   {
-      return CCMLastColorMatch;
-   }
+  if(SourceColor == CCMLastSourceColor)
+  {
+    return CCMLastColorMatch;
+  }
 
-   cSourceColor  = &SourceColor;
+  cSourceColor  = &SourceColor;
 
-   for (i=0; i<NumColors; i++)
-   {
-      cDestColors = &DestColors[i];
+  for (i=0; i<NumColors; i++)
+  {
+    cDestColors = &DestColors[i];
 
-      rt = ( abs(cSourceColor->Red   - cDestColors->Red)   +
-             abs(cSourceColor->Green - cDestColors->Green) +
-             abs(cSourceColor->Blue  - cDestColors->Blue) ) / 3;
+    rt = ( abs(cSourceColor->Red   - cDestColors->Red)   +
+           abs(cSourceColor->Green - cDestColors->Green) +
+           abs(cSourceColor->Blue  - cDestColors->Blue) ) / 3;
 
-      if(rt<=bestMatch)
-      {
-         idx = i;
-         bestMatch = rt;
-      }
-   }
+    if(rt<=bestMatch)
+    {
+      idx = i;
+      bestMatch = rt;
+    }
+  }
 
-   CCMLastSourceColor = SourceColor;
-   CCMLastColorMatch  = idx;
+  CCMLastSourceColor = SourceColor;
+  CCMLastColorMatch  = idx;
 
-   return idx;
+  return idx;
 }
 
 VOID IndexedToIndexedTranslationTable(ULONG *TranslationTable,
                                       PALGDI *PalDest, PALGDI *PalSource)
 {
-   ULONG i;
+  ULONG i;
 
-   for(i=0; i<PalSource->NumColors; i++)
-   {
-      TranslationTable[i] = ClosestColorMatch(PalSource->IndexedColors[i],
-         PalDest->IndexedColors, PalDest->NumColors);
-   }
+  for(i=0; i<PalSource->NumColors; i++)
+  {
+    TranslationTable[i] = ClosestColorMatch(PalSource->IndexedColors[i], PalDest->IndexedColors, PalDest->NumColors);
+  }
 }
 
 XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
                          HPALETTE PaletteDest, HPALETTE PaletteSource)
 {
-   // FIXME: Add support for BGR conversions
-
-   HPALETTE NewXlate;
-   XLATEOBJ *XlateObj;
-   XLATEGDI *XlateGDI;
-   PALGDI   *SourcePalGDI, *DestPalGDI;
-   ULONG    IndexedColors;
-
-   XlateObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEOBJ), NULL);
-   XlateGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEGDI), NULL);
-
-   NewXlate = CreateGDIHandle(XlateGDI, XlateObj);
-
-   if(SourcePalType == PAL_INDEXED)
-   {
-      SourcePalGDI = AccessInternalObject(PaletteSource);
-   } else
-   if(DestPalType == PAL_INDEXED)
-   {
-      DestPalGDI   = AccessInternalObject(PaletteDest);
-   }
-
-   XlateObj->iSrcType = SourcePalType;
-   XlateObj->iDstType = DestPalType;
-
-   // Store handles of palettes in internal Xlate GDI object (or NULLs)
-   XlateGDI->DestPal   = PaletteDest;
-   XlateGDI->SourcePal = PaletteSource;
-
-   XlateObj->flXlate = 0;
-
-   // If source and destination palettes are the same or if they're RGB/BGR
-   if( (PaletteDest == PaletteSource) ||
-       ((DestPalType == PAL_RGB) && (SourcePalType == PAL_RGB)) ||
-       ((DestPalType == PAL_BGR) && (SourcePalType == PAL_BGR)) )
-   {
-      XlateObj->flXlate |= XO_TRIVIAL;
-   }
-
-   // Prepare the translation table
-   if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
-   {
-      XlateObj->flXlate |= XO_TABLE;
-
-      if (SourcePalType == PAL_INDEXED) IndexedColors = SourcePalGDI->NumColors;
-      if (DestPalType   == PAL_INDEXED) IndexedColors = DestPalGDI->NumColors;
-
-      XlateGDI->translationTable = EngAllocMem(
-         FL_ZERO_MEMORY, sizeof(ULONG)*IndexedColors, NULL);
-   }
-
-   // Source palette is indexed
-   if(XlateObj->iSrcType == PAL_INDEXED)
-   {
-      if(XlateObj->iDstType == PAL_INDEXED)
-      {
-         // Converting from indexed to indexed
-         IndexedToIndexedTranslationTable(XlateGDI->translationTable,
-                                          DestPalGDI, SourcePalGDI);
-      } else
+  // FIXME: Add support for BGR conversions
+
+  HPALETTE NewXlate;
+  XLATEOBJ *XlateObj;
+  XLATEGDI *XlateGDI;
+  PALGDI   *SourcePalGDI, *DestPalGDI;
+  ULONG    IndexedColors;
+
+  XlateObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEOBJ), NULL);
+  XlateGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEGDI), NULL);
+
+  NewXlate = CreateGDIHandle(XlateGDI, XlateObj);
+
+  if(SourcePalType == PAL_INDEXED)
+  {
+    SourcePalGDI = AccessInternalObject(PaletteSource);
+  } else
+  if(DestPalType == PAL_INDEXED)
+  {
+    DestPalGDI   = AccessInternalObject(PaletteDest);
+  }
+
+  XlateObj->iSrcType = SourcePalType;
+  XlateObj->iDstType = DestPalType;
+
+  // Store handles of palettes in internal Xlate GDI object (or NULLs)
+  XlateGDI->DestPal   = PaletteDest;
+  XlateGDI->SourcePal = PaletteSource;
+
+  XlateObj->flXlate = 0;
+
+  // If source and destination palettes are the same or if they're RGB/BGR
+  if( (PaletteDest == PaletteSource) ||
+      ((DestPalType == PAL_RGB) && (SourcePalType == PAL_RGB)) ||
+      ((DestPalType == PAL_BGR) && (SourcePalType == PAL_BGR)) )
+  {
+    XlateObj->flXlate |= XO_TRIVIAL;
+    return XlateObj;
+  }
+
+  // Prepare the translation table
+  if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
+  {
+    XlateObj->flXlate |= XO_TABLE;
+
+    if (SourcePalType == PAL_INDEXED) IndexedColors = SourcePalGDI->NumColors;
+    if (DestPalType   == PAL_INDEXED) IndexedColors = DestPalGDI->NumColors;
+
+    XlateGDI->translationTable = EngAllocMem(FL_ZERO_MEMORY, sizeof(ULONG)*IndexedColors, NULL);
+  }
+
+  // Source palette is indexed
+  if(XlateObj->iSrcType == PAL_INDEXED)
+  {
+    if(XlateObj->iDstType == PAL_INDEXED)
+    {
+      // Converting from indexed to indexed
+      IndexedToIndexedTranslationTable(XlateGDI->translationTable, DestPalGDI, SourcePalGDI);
+    } else
       if(XlateObj->iDstType == PAL_RGB)
       {
-         // FIXME: Is this necessary? I think the driver has to call this
-         // function anyways if pulXlate is NULL and Source is PAL_INDEXED
+        // FIXME: Is this necessary? I think the driver has to call this
+        // function anyways if pulXlate is NULL and Source is PAL_INDEXED
 
-         // Converting from indexed to RGB
+        // Converting from indexed to RGB
 
-         XLATEOBJ_cGetPalette(XlateObj, XO_SRCPALETTE,
-                              SourcePalGDI->NumColors,
-                              XlateGDI->translationTable);
+        XLATEOBJ_cGetPalette(XlateObj, XO_SRCPALETTE,
+                             SourcePalGDI->NumColors,
+                             XlateGDI->translationTable);
       }
 
-      XlateObj->pulXlate = XlateGDI->translationTable;
-   }
+    XlateObj->pulXlate = XlateGDI->translationTable;
+  }
 
-   // Source palette is RGB
-   if(XlateObj->iSrcType == PAL_RGB)
-   {
-      if(XlateObj->iDstType == PAL_INDEXED)
-      {
-         // FIXME: Is this necessary? I think the driver has to call this
-         // function anyways if pulXlate is NULL and Dest is PAL_INDEXED
-
-         // Converting from RGB to indexed
-         XLATEOBJ_cGetPalette(XlateObj, XO_DESTPALETTE,
-                              DestPalGDI->NumColors,
-                              XlateGDI->translationTable);
-      }
-   }
+  // Source palette is RGB
+  if(XlateObj->iSrcType == PAL_RGB)
+  {
+    if(XlateObj->iDstType == PAL_INDEXED)
+    {
+      // FIXME: Is this necessary? I think the driver has to call this
+      // function anyways if pulXlate is NULL and Dest is PAL_INDEXED
 
-   // FIXME: Add support for XO_TO_MONO
+      // Converting from RGB to indexed
+      XLATEOBJ_cGetPalette(XlateObj, XO_DESTPALETTE, DestPalGDI->NumColors, XlateGDI->translationTable);
+    }
+  }
 
-   return XlateObj;
+  // FIXME: Add support for XO_TO_MONO
+  return XlateObj;
 }
 
 EngDeleteXlate(XLATEOBJ *XlateObj)
 {
-   HPALETTE HXlate    = AccessHandleFromUserObject(XlateObj);
-   XLATEGDI *XlateGDI = AccessInternalObject(HXlate);
+  HPALETTE HXlate    = AccessHandleFromUserObject(XlateObj);
+  XLATEGDI *XlateGDI = AccessInternalObject(HXlate);
 
-   if(XlateGDI->translationTable!=NULL)
-   {
-      EngFreeMem(XlateGDI->translationTable);
-   }
+  if(XlateGDI->translationTable!=NULL)
+  {
+    EngFreeMem(XlateGDI->translationTable);
+  }
 
-   EngFreeMem(XlateGDI);
-   EngFreeMem(XlateObj);
-   FreeGDIHandle(HXlate);
+  EngFreeMem(XlateGDI);
+  EngFreeMem(XlateObj);
+  FreeGDIHandle(HXlate);
 }
 
 ULONG *XLATEOBJ_piVector(XLATEOBJ *XlateObj)
 {
-   XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
+  XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
 
+  if(XlateObj->iSrcType == PAL_INDEXED)
+  {
+    return XlateGDI->translationTable;
+  }
 
-   if(XlateObj->iSrcType == PAL_INDEXED)
-   {
-      return XlateGDI->translationTable;
-   }
-
-   return NULL;
+  return NULL;
 }
 
 ULONG XLATEOBJ_iXlate(XLATEOBJ *XlateObj, ULONG Color)
 {
-   PALGDI   *PalGDI;
-   XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
-
-   if(XlateObj->iSrcType == PAL_RGB)
-   {
-      // FIXME: should we cache colors used often?
-      // FIXME: won't work if destination isn't indexed
-
-      // Extract the destination palette
-      PalGDI = AccessInternalObject(XlateGDI->DestPal);
-
-      // Return closest match for the given RGB color
-      return ClosestColorMatch(Color, PalGDI->IndexedColors, PalGDI->NumColors);
-   } else
-
-   if(XlateObj->iSrcType == PAL_INDEXED)
-   {
-      return XlateGDI->translationTable[Color];
-   }
-
-   return 0;
+  PALGDI   *PalGDI;
+  XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
+
+  if(XlateObj->flXlate & XO_TRIVIAL)
+  {
+    return Color;
+  } else
+  if(XlateObj->iSrcType == PAL_RGB)
+  {
+    // FIXME: should we cache colors used often?
+    // FIXME: won't work if destination isn't indexed
+
+    // Extract the destination palette
+    PalGDI = AccessInternalObject(XlateGDI->DestPal);
+
+    // Return closest match for the given RGB color
+    return ClosestColorMatch(Color, PalGDI->IndexedColors, PalGDI->NumColors);
+  } else
+  if(XlateObj->iSrcType == PAL_INDEXED)
+  {
+    return XlateGDI->translationTable[Color];
+  }
+
+  return 0;
 }
 
 ULONG XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj,
                            ULONG PalOutType, ULONG cPal, ULONG *OutPal)
 {
-   ULONG i;
-   HPALETTE HPal;
-   XLATEGDI *XlateGDI;
-   PALGDI *PalGDI;
-
-   XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
-
-   if(PalOutType == XO_SRCPALETTE)
-   {
-      HPal = XlateGDI->SourcePal;
-   } else
-   if(PalOutType == XO_DESTPALETTE)
-   {
-      HPal = XlateGDI->DestPal;
-   }
-
-   PalGDI = AccessInternalObject(HPal);
-   RtlCopyMemory(OutPal, PalGDI->IndexedColors, sizeof(ULONG)*cPal);
-
-   return i;
+  ULONG i;
+  HPALETTE HPal;
+  XLATEGDI *XlateGDI;
+  PALGDI *PalGDI;
+
+  XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
+
+  if(PalOutType == XO_SRCPALETTE)
+  {
+    HPal = XlateGDI->SourcePal;
+  } else
+  if(PalOutType == XO_DESTPALETTE)
+  {
+    HPal = XlateGDI->DestPal;
+  }
+
+  PalGDI = AccessInternalObject(HPal);
+  RtlCopyMemory(OutPal, PalGDI->IndexedColors, sizeof(ULONG)*cPal);
+
+  return i;
 }
index 4ef4640..365c0b0 100644 (file)
@@ -285,9 +285,11 @@ void CreateCellCharSurface()
    surfgdi         = ExAllocatePool(NonPagedPool, sizeof(SURFGDI));
 
    hCharCellBitmap = W32kCreateBitmap(8, 8, 1, 8, NULL); // 8x8, 1 plane, 8 bits per pel
+
    pbo = BITMAPOBJ_HandleToPtr(hCharCellBitmap);
 
-   BitmapToSurf(surfgdi, CharCellSurfObj, pbo); // Make the bitmap a surface
+// VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
+   BitmapToSurf(0, surfgdi, CharCellSurfObj, pbo); // Make the bitmap a surface
 }
 
 void  grWriteCellChar(PSURFOBJ  target,
index 731b5b8..5e5c2b7 100644 (file)
@@ -1,27 +1,22 @@
-/* $Id: loader.c,v 1.5 2000/08/26 16:21:28 ekohl Exp $
+/* $Id: loader.c,v 1.6 2001/03/31 15:35:07 jfilby Exp $
  *
  */
 
 #include <ddk/ntddk.h>
 #include <ddk/winddi.h>
 
-
 HANDLE
 STDCALL
 EngLoadImage (LPWSTR DriverName)
 {
-   SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
-   NTSTATUS Status;
-
-   RtlInitUnicodeString (&GdiDriverInfo.DriverName,
-                        DriverName);
-   Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
-                                   &GdiDriverInfo,
-                                   sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
-   if (!NT_SUCCESS(Status))
-       return NULL;
-
-   return (HANDLE)GdiDriverInfo.ImageAddress;
+  SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
+  NTSTATUS Status;
+
+  RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName);
+  Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
+  if (!NT_SUCCESS(Status)) return NULL;
+
+  return (HANDLE)GdiDriverInfo.ImageAddress;
 }
 
 
@@ -29,20 +24,16 @@ HANDLE
 STDCALL
 EngLoadModule(LPWSTR ModuleName)
 {
-   SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
-   NTSTATUS Status;
+  SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
+  NTSTATUS Status;
 
-   // FIXME: should load as readonly
+  // FIXME: should load as readonly
 
-   RtlInitUnicodeString (&GdiDriverInfo.DriverName,
-                        ModuleName);
-   Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
-                                   &GdiDriverInfo,
-                                   sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
-   if (!NT_SUCCESS(Status))
-       return NULL;
+  RtlInitUnicodeString (&GdiDriverInfo.DriverName, ModuleName);
+  Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
+  if (!NT_SUCCESS(Status)) return NULL;
 
-   return (HANDLE)GdiDriverInfo.ImageAddress;
+  return (HANDLE)GdiDriverInfo.ImageAddress;
 }
 
 /* EOF */
index 4f733f1..c387941 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: dllmain.c,v 1.17 2000/09/08 19:39:31 ekohl Exp $
+/* $Id: dllmain.c,v 1.18 2001/03/31 15:35:08 jfilby Exp $
  * 
  *  Entry Point for win32k.sys
  */
 NTSTATUS
 STDCALL
 DllMain (
-       IN      PDRIVER_OBJECT  DriverObject,
-       IN      PUNICODE_STRING RegistryPath
-       )
+  IN   PDRIVER_OBJECT  DriverObject,
+  IN   PUNICODE_STRING RegistryPath)
 {
-       BOOLEAN Result;
+  BOOLEAN Result;
 
-       DbgPrint("Win32 kernel mode driver\n");
+  DbgPrint("Win32 kernel mode driver\n");
 
-       /*
-        * Register user mode call interface
-        * (system service table index = 1)
-        */
-       Result = KeAddSystemServiceTable (Win32kSSDT,
-                                         NULL,
-                                         NUMBER_OF_SYSCALLS,
-                                         Win32kSSPT,
-                                         1);
-       if (Result == FALSE)
-       {
-               DbgPrint("Adding system services failed!\n");
-               return STATUS_UNSUCCESSFUL;
-       }
+  /*
+   * Register user mode call interface
+   * (system service table index = 1)
+   */
+  Result = KeAddSystemServiceTable (Win32kSSDT, NULL, NUMBER_OF_SYSCALLS, Win32kSSPT, 1);
+  if (Result == FALSE)
+  {
+    DbgPrint("Adding system services failed!\n");
+    return STATUS_UNSUCCESSFUL;
+  }
 
-       DbgPrint("System services added successfully!\n");
-       return STATUS_SUCCESS;
+  DbgPrint("System services added successfully!\n");
+  return STATUS_SUCCESS;
 }
 
 
@@ -57,14 +52,19 @@ BOOLEAN
 STDCALL
 W32kInitialize (VOID)
 {
+  // FIXME: Retrieve name from registry
+  EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys");
 
-       // FIXME: Retrieve name from registry
-       EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys");
+  // Create surface used to draw the internal font onto
+  CreateCellCharSurface();
 
-       // Create surface used to draw the internal font onto
-       CreateCellCharSurface();
+  // Create stock objects, ie. precreated objects commonly used by win32 applications
+  CreateStockObjects();
 
-       return TRUE;
+  // Initialize FreeType library
+  if(!InitFontSupport()) return FALSE;
+
+  return TRUE;
 }
 
 /* EOF */
index 4027606..d1cef87 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.27 2000/11/20 19:59:14 ekohl Exp $
+# $Id: makefile,v 1.28 2001/03/31 15:35:07 jfilby Exp $
 #
 # WIN32K.SYS build spec
 #
@@ -6,8 +6,13 @@ PATH_TO_TOP = ../..
 
 TARGET=win32k
 
+# from atheos appserver makefile
+COPTS   = -pipe -O3 -I./freetype2-beta8/include -c -Wall
+
 CFLAGS = -I.
 
+#define FT_FLAT_COMPILE
+
 ENG_OBJECTS= eng/debug.o eng/mem.o eng/brush.o eng/bitblt.o eng/clip.o eng/copybits.o \
                 eng/device.o eng/handle.o eng/lineto.o eng/paint.o eng/palette.o \
                eng/surface.o eng/xlate.o
@@ -20,14 +25,19 @@ OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o  \
                   objects/line.o objects/metafile.o objects/paint.o  \
                   objects/path.o objects/pen.o objects/print.o  \
                   objects/region.o objects/text.o objects/wingl.o \
-                  objects/bezier.o objects/objconv.o
-FREETYPE_OBJECTS =     freetype/grfont.o
-
+                  objects/bezier.o objects/objconv.o objects/dib.o objects/palette.o
+DIB_OBJECTS = dib/dib4bpp.o dib/dib24bpp.o
+FREETYPE_OBJECTS = freetype/grfont.o freetype/ctype.o \
+       freetype/ftsystem.o freetype/ftdebug.o freetype/ftinit.o freetype/ftbase.o \
+       freetype/ftglyph.o freetype/ftmm.o freetype/autohint.o freetype/cff.o \
+       freetype/type1cid.o freetype/psnames.o freetype/raster1.o freetype/sfnt.o \
+       freetype/smooth.o freetype/truetype.o freetype/winfnt.o freetype/type1z.o
 RESOURCE_OBJECT = $(TARGET).coff
 STUBS_OBJECTS = stubs/stubs.o
 
 OBJECTS = $(ENG_OBJECTS) $(MAIN_OBJECTS) $(MISC_OBJECTS) $(LDR_OBJECTS) $(OBJECTS_OBJECTS)  \
-          $(RESOURCE_OBJECT) $(STUBS_OBJECTS) $(MATH_OBJECTS) $(FLOAT_OBJECTS) $(FREETYPE_OBJECTS)
+          $(RESOURCE_OBJECT) $(STUBS_OBJECTS) $(MATH_OBJECTS) $(FLOAT_OBJECTS) $(FREETYPE_OBJECTS) \
+          $(DIB_OBJECTS)
 
 all: $(TARGET).sys
 
@@ -116,4 +126,3 @@ $(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
 #WIN32_LEAN_AND_MEAN = yes
 #WARNINGS_ARE_ERRORS = yes
 include ../../rules.mak
-
index 3666992..cea2f1a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: driver.c,v 1.15 2000/08/26 16:22:04 ekohl Exp $
+/* $Id: driver.c,v 1.16 2001/03/31 15:35:08 jfilby Exp $
  * 
  * GDI Driver support routines
  * (mostly swiped from Wine)
@@ -34,28 +34,23 @@ BOOL  DRIVER_RegisterDriver(LPCWSTR  Name, PGD_ENABLEDRIVER  EnableDriver)
 {
   PGRAPHICS_DRIVER  Driver = ExAllocatePool(NonPagedPool, sizeof(*Driver));
   DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
-  if (!Driver) 
-    {
-      return  FALSE;
-    }
+  if (!Driver)  return  FALSE;
   Driver->ReferenceCount = 0;
   Driver->EnableDriver = EnableDriver;
   if (Name)
-    {
-      Driver->Name = ExAllocatePool(PagedPool, 
-                                    (wcslen(Name) + 1) * sizeof(WCHAR));
-      wcscpy(Driver->Name, Name);
-      Driver->Next  = DriverList;
-      DriverList = Driver;
-      return  TRUE;
-    }
+  {
+    Driver->Name = ExAllocatePool(PagedPool, (wcslen(Name) + 1) * sizeof(WCHAR));
+    wcscpy(Driver->Name, Name);
+    Driver->Next  = DriverList;
+    DriverList = Driver;
+    return  TRUE;
+  }
   
   if (GenericDriver != NULL)
-    {
-      ExFreePool(Driver);
-      
-      return  FALSE;
-    }
+  {
+    ExFreePool(Driver);
+    return  FALSE;
+  }
   
   GenericDriver = Driver;
   return  TRUE;
@@ -69,22 +64,18 @@ PGD_ENABLEDRIVER  DRIVER_FindDDIDriver(LPCWSTR  Name)
 
   /* First see if the driver hasn't already been loaded */
   while (Driver && Name)
+  {
+    if (!_wcsicmp( Driver->Name, Name)) 
     {
-      if (!_wcsicmp( Driver->Name, Name)) 
-        {
-          return Driver->EnableDriver;
-        }
-      Driver = Driver->Next;
+      return Driver->EnableDriver;
     }
+    Driver = Driver->Next;
+  }
 
   /* If not, then load it */
-  RtlInitUnicodeString (&GdiDriverInfo.DriverName,
-                       (LPWSTR)Name);
-  Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
-                                  &GdiDriverInfo,
-                                  sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
-   if (!NT_SUCCESS(Status))
-       return NULL;
+  RtlInitUnicodeString (&GdiDriverInfo.DriverName, (LPWSTR)Name);
+  Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
+  if (!NT_SUCCESS(Status)) return NULL;
 
   DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
   return (PGD_ENABLEDRIVER)GdiDriverInfo.EntryPoint;
@@ -182,35 +173,31 @@ HANDLE DRIVER_FindMPDriver(LPCWSTR  Name)
   PMP_DRIVERENTRY PMP_DriverEntry;
 
   /* Phase 1 */
-  RtlInitUnicodeString (&GdiDriverInfo.DriverName,
-                       L"\\SystemRoot\\system32\\drivers\\vgamp.sys");
-  Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
-                                  &GdiDriverInfo,
-                                  sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
+  RtlInitUnicodeString (&GdiDriverInfo.DriverName, L"\\SystemRoot\\system32\\drivers\\vgamp.sys");
+  Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
   if (!NT_SUCCESS(Status))
      return NULL;
 
   /* Phase 2 */
   if (Name[0] != '\\')
+  {
+    lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR) + 10 * sizeof(WCHAR));
+    wcscpy(lName, L"\\??\\");
+    if (!wcscmp (Name, L"DISPLAY"))
     {
-      lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR) + 
-                             10 * sizeof(WCHAR));
-      wcscpy(lName, L"\\??\\");
-      if (!wcscmp (Name, L"DISPLAY"))
-        {
-           /* FIXME: Read this information from the registry ??? */
-           wcscat(lName, L"DISPLAY1");
-        }
-      else
-        {
-           wcscat(lName, Name);
-        }
+      /* FIXME: Read this information from the registry ??? */
+      wcscat(lName, L"DISPLAY1");
     }
-  else
+    else
     {
-      lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR));
-      wcscpy(lName, Name);
+      wcscat(lName, Name);
     }
+  }
+  else
+  {
+    lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR));
+    wcscpy(lName, Name);
+  }
   
   /* Phase 3 */
   DriverObject = ExAllocatePool(NonPagedPool,sizeof(DRIVER_OBJECT));
@@ -234,44 +221,44 @@ BOOL  DRIVER_UnregisterDriver(LPCWSTR  Name)
   PGRAPHICS_DRIVER  Driver = NULL;
   
   if (Name)
+  {
+    if (DriverList != NULL)
     {
-      if (DriverList != NULL)
+      if (!_wcsicmp(DriverList->Name, Name))
+      {
+        Driver = DriverList;
+        DriverList = DriverList->Next;
+      }
+      else
+      {
+        Driver = DriverList;
+        while (Driver->Next && _wcsicmp(Driver->Name, Name))
         {
-          if (!_wcsicmp(DriverList->Name, Name))
-            {
-              Driver = DriverList;
-              DriverList = DriverList->Next;
-            }
-          else
-            {
-              Driver = DriverList;
-              while (Driver->Next && _wcsicmp(Driver->Name, Name))
-                {
-                  Driver = Driver->Next;
-                }
-            }
+          Driver = Driver->Next;
         }
+      }
     }
+  }
   else
-    {    
-      if (GenericDriver != NULL)
-        {
-          Driver = GenericDriver;
-          GenericDriver = NULL;
-        }
+  {    
+    if (GenericDriver != NULL)
+    {
+      Driver = GenericDriver;
+      GenericDriver = NULL;
     }
+  }
   
   if (Driver != NULL)
-    {
-      ExFreePool(Driver->Name);
-      ExFreePool(Driver);
+  {
+    ExFreePool(Driver->Name);
+    ExFreePool(Driver);
       
-      return  TRUE;
-    }
+    return  TRUE;
+  }
   else
-    {
-      return  FALSE;
-    }
+  {
+    return  FALSE;
+  }
 }
 
 INT  DRIVER_ReferenceDriver (LPCWSTR  Name)
@@ -279,14 +266,14 @@ INT  DRIVER_ReferenceDriver (LPCWSTR  Name)
   GRAPHICS_DRIVER *Driver = DriverList;
   
   while (Driver && Name)
+  {
+    DPRINT( "Comparting %S to %S\n", Driver->Name, Name );
+    if (!_wcsicmp( Driver->Name, Name)) 
     {
-      DPRINT( "Comparting %S to %S\n", Driver->Name, Name );
-      if (!_wcsicmp( Driver->Name, Name)) 
-        {
-          return ++Driver->ReferenceCount;
-        }
-      Driver = Driver->Next;
+      return ++Driver->ReferenceCount;
     }
+    Driver = Driver->Next;
+  }
   DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
   assert( GenericDriver != 0 );
   return ++GenericDriver->ReferenceCount;
@@ -297,14 +284,14 @@ INT  DRIVER_UnreferenceDriver (LPCWSTR  Name)
   GRAPHICS_DRIVER *Driver = DriverList;
   
   while (Driver && Name)
+  {
+    DPRINT( "Comparting %S to %S\n", Driver->Name, Name );
+    if (!_wcsicmp( Driver->Name, Name)) 
     {
-      DPRINT( "Comparting %S to %S\n", Driver->Name, Name );
-      if (!_wcsicmp( Driver->Name, Name)) 
-        {
-          return --Driver->ReferenceCount;
-        }
-      Driver = Driver->Next;
+      return --Driver->ReferenceCount;
     }
+    Driver = Driver->Next;
+  }
   DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
   assert( GenericDriver != 0 );
   return --GenericDriver->ReferenceCount;
index d557086..9337783 100644 (file)
@@ -41,8 +41,8 @@
  * */
 
 #define BEZIERMIDDLE(Mid, P1, P2) \
-    (Mid).x=((P1).x+(P2).x + 1)/2;\
-    (Mid).y=((P1).y+(P2).y + 1)/2;
+  (Mid).x=((P1).x+(P2).x + 1)/2;\
+  (Mid).y=((P1).y+(P2).y + 1)/2;
     
 /**********************************************************
 * BezierCheck helper function to check
 */
 static BOOL BezierCheck( int level, POINT *Points)
 { 
-    INT dx, dy;
-    dx=Points[3].x-Points[0].x;
-    dy=Points[3].y-Points[0].y;
-    if(abs(dy)<=abs(dx)){/* shallow line */
-        /* check that control points are between begin and end */
-        if(Points[1].x < Points[0].x){
-            if(Points[1].x < Points[3].x)
-                return FALSE;
-        }else
-            if(Points[1].x > Points[3].x)
-                return FALSE;
-        if(Points[2].x < Points[0].x){
-            if(Points[2].x < Points[3].x)
-                return FALSE;
-        }else
-            if(Points[2].x > Points[3].x)
-                return FALSE;
-        dx=BEZIERSHIFTDOWN(dx);
-        if(!dx) return TRUE;
-        if(abs(Points[1].y-Points[0].y-(dy/dx)*
-                BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL ||
-           abs(Points[2].y-Points[0].y-(dy/dx)*
-                   BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL )
-            return FALSE;
-        else
-            return TRUE;
-    }else{ /* steep line */
-        /* check that control points are between begin and end */
-        if(Points[1].y < Points[0].y){
-            if(Points[1].y < Points[3].y)
-                return FALSE;
-        }else
-            if(Points[1].y > Points[3].y)
-                return FALSE;
-        if(Points[2].y < Points[0].y){
-            if(Points[2].y < Points[3].y)
-                return FALSE;
-        }else
-            if(Points[2].y > Points[3].y)
-                return FALSE;
-        dy=BEZIERSHIFTDOWN(dy);
-        if(!dy) return TRUE;
-        if(abs(Points[1].x-Points[0].x-(dx/dy)*
-                BEZIERSHIFTDOWN(Points[1].y-Points[0].y)) > BEZIERPIXEL ||
-           abs(Points[2].x-Points[0].x-(dx/dy)*
-                   BEZIERSHIFTDOWN(Points[2].y-Points[0].y)) > BEZIERPIXEL )
-            return FALSE;
-        else
-            return TRUE;
+  INT dx, dy;
+
+  dx=Points[3].x-Points[0].x;
+  dy=Points[3].y-Points[0].y;
+  if(abs(dy)<=abs(dx)) {/* shallow line */
+    /* check that control points are between begin and end */
+    if(Points[1].x < Points[0].x){
+      if(Points[1].x < Points[3].x) return FALSE;
+    }else
+    if(Points[1].x > Points[3].x) return FALSE;
+    if(Points[2].x < Points[0].x) {
+      if(Points[2].x < Points[3].x) return FALSE;
+    } else
+      if(Points[2].x > Points[3].x) return FALSE;
+      dx=BEZIERSHIFTDOWN(dx);
+      if(!dx) return TRUE;
+      if(abs(Points[1].y-Points[0].y-(dy/dx)*
+        BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL ||
+        abs(Points[2].y-Points[0].y-(dy/dx)*
+        BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL) return FALSE;
+      else
+        return TRUE;
+    } else{ /* steep line */
+      /* check that control points are between begin and end */
+      if(Points[1].y < Points[0].y){
+        if(Points[1].y < Points[3].y) return FALSE;
+      } else
+        if(Points[1].y > Points[3].y) return FALSE;
+      if(Points[2].y < Points[0].y){
+        if(Points[2].y < Points[3].y) return FALSE;
+      } else
+        if(Points[2].y > Points[3].y) return FALSE;
+      dy=BEZIERSHIFTDOWN(dy);
+      if(!dy) return TRUE;
+      if(abs(Points[1].x-Points[0].x-(dx/dy)*
+        BEZIERSHIFTDOWN(Points[1].y-Points[0].y)) > BEZIERPIXEL ||
+        abs(Points[2].x-Points[0].x-(dx/dy)*
+        BEZIERSHIFTDOWN(Points[2].y-Points[0].y)) > BEZIERPIXEL ) return FALSE;
+      else
+        return TRUE;
     }
 }
     
@@ -112,37 +103,37 @@ static BOOL BezierCheck( int level, POINT *Points)
 static void GDI_InternalBezier( POINT *Points, POINT **PtsOut, INT *dwOut,
                                INT *nPtsOut, INT level )
 {
-    if(*nPtsOut == *dwOut) {
-        *dwOut *= 2;
-       *PtsOut = ExAllocatePool(NonPagedPool, *dwOut * sizeof(POINT));
-    }
+  if(*nPtsOut == *dwOut) {
+    *dwOut *= 2;
+    *PtsOut = ExAllocatePool(NonPagedPool, *dwOut * sizeof(POINT));
+  }
 
-    if(!level || BezierCheck(level, Points)) {
-        if(*nPtsOut == 0) {
-            (*PtsOut)[0].x = BEZIERSHIFTDOWN(Points[0].x);
-            (*PtsOut)[0].y = BEZIERSHIFTDOWN(Points[0].y);
-            *nPtsOut = 1;
-        }
-       (*PtsOut)[*nPtsOut].x = BEZIERSHIFTDOWN(Points[3].x);
-        (*PtsOut)[*nPtsOut].y = BEZIERSHIFTDOWN(Points[3].y);
-        (*nPtsOut) ++;
-    } else {
-        POINT Points2[4]; /* for the second recursive call */
-        Points2[3]=Points[3];
-        BEZIERMIDDLE(Points2[2], Points[2], Points[3]);
-        BEZIERMIDDLE(Points2[0], Points[1], Points[2]);
-        BEZIERMIDDLE(Points2[1],Points2[0],Points2[2]);
+  if(!level || BezierCheck(level, Points)) {
+    if(*nPtsOut == 0) {
+      (*PtsOut)[0].x = BEZIERSHIFTDOWN(Points[0].x);
+      (*PtsOut)[0].y = BEZIERSHIFTDOWN(Points[0].y);
+       *nPtsOut = 1;
+    }
+    (*PtsOut)[*nPtsOut].x = BEZIERSHIFTDOWN(Points[3].x);
+    (*PtsOut)[*nPtsOut].y = BEZIERSHIFTDOWN(Points[3].y);
+    (*nPtsOut) ++;
+  } else {
+    POINT Points2[4]; /* for the second recursive call */
+    Points2[3]=Points[3];
+    BEZIERMIDDLE(Points2[2], Points[2], Points[3]);
+    BEZIERMIDDLE(Points2[0], Points[1], Points[2]);
+    BEZIERMIDDLE(Points2[1],Points2[0],Points2[2]);
 
-        BEZIERMIDDLE(Points[1], Points[0],  Points[1]);
-        BEZIERMIDDLE(Points[2], Points[1], Points2[0]);
-        BEZIERMIDDLE(Points[3], Points[2], Points2[1]);
+    BEZIERMIDDLE(Points[1], Points[0],  Points[1]);
+    BEZIERMIDDLE(Points[2], Points[1], Points2[0]);
+    BEZIERMIDDLE(Points[3], Points[2], Points2[1]);
 
-        Points2[0]=Points[3];
+    Points2[0]=Points[3];
 
-        /* do the two halves */
-        GDI_InternalBezier(Points, PtsOut, dwOut, nPtsOut, level-1);
-        GDI_InternalBezier(Points2, PtsOut, dwOut, nPtsOut, level-1);
-    }
+    /* do the two halves */
+    GDI_InternalBezier(Points, PtsOut, dwOut, nPtsOut, level-1);
+    GDI_InternalBezier(Points2, PtsOut, dwOut, nPtsOut, level-1);
+  }
 }
 
 /***********************************************************************
@@ -171,23 +162,23 @@ static void GDI_InternalBezier( POINT *Points, POINT **PtsOut, INT *dwOut,
  */
 POINT *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut )
 {
-    POINT *out;
-    INT Bezier, dwOut = BEZIER_INITBUFSIZE, i;
+  POINT *out;
+  INT Bezier, dwOut = BEZIER_INITBUFSIZE, i;
 
-    if((count - 1) % 3 != 0) {
-       return NULL;
-    }
-    *nPtsOut = 0;
-    out = ExAllocatePool(NonPagedPool, dwOut * sizeof(POINT));
-    for(Bezier = 0; Bezier < (count-1)/3; Bezier++) {
-       POINT ptBuf[4];
-       memcpy(ptBuf, Points + Bezier * 3, sizeof(POINT) * 4);
-       for(i = 0; i < 4; i++) {
-           ptBuf[i].x = BEZIERSHIFTUP(ptBuf[i].x);
-           ptBuf[i].y = BEZIERSHIFTUP(ptBuf[i].y);
-       }
-        GDI_InternalBezier( ptBuf, &out, &dwOut, nPtsOut, BEZIERMAXDEPTH );
+  if((count - 1) % 3 != 0) {
+    return NULL;
+  }
+  *nPtsOut = 0;
+  out = ExAllocatePool(NonPagedPool, dwOut * sizeof(POINT));
+  for(Bezier = 0; Bezier < (count-1)/3; Bezier++) {
+    POINT ptBuf[4];
+    memcpy(ptBuf, Points + Bezier * 3, sizeof(POINT) * 4);
+    for(i = 0; i < 4; i++) {
+      ptBuf[i].x = BEZIERSHIFTUP(ptBuf[i].x);
+      ptBuf[i].y = BEZIERSHIFTUP(ptBuf[i].y);
     }
+    GDI_InternalBezier( ptBuf, &out, &dwOut, nPtsOut, BEZIERMAXDEPTH );
+  }
 
-    return out;
+  return out;
 }
index 21b15db..3690f43 100644 (file)
@@ -1,10 +1,9 @@
-
-
 #undef WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <stdlib.h>
 #include <win32k/bitmaps.h>
 //#include <win32k/debug.h>
+#include "../eng/objects.h"
 
 #define NDEBUG
 #include <debug.h>
@@ -19,15 +18,19 @@ BOOL STDCALL W32kBitBlt(HDC  hDCDest,
                  INT  YSrc,
                  DWORD  ROP)
 {
-  PDC          DCDest = DC_HandleToPtr(hDCDest);
-  PDC          DCSrc  = DC_HandleToPtr(hDCSrc);
-  PSURFOBJ     SurfDest;
-  PSURFOBJ     SurfSrc;
-  RECTL                DestRect;
-  POINTL       SourcePoint;
-  PBITMAPOBJ   DestBitmapObj;
-  PBITMAPOBJ   SrcBitmapObj;
-  BOOL         Status, SurfDestAlloc, SurfSrcAlloc;
+  PDC DCDest = DC_HandleToPtr(hDCDest);
+  PDC DCSrc  = DC_HandleToPtr(hDCSrc);
+  PSURFOBJ SurfDest, SurfSrc;
+  PSURFGDI SurfGDIDest, SurfGDISrc;
+  RECTL DestRect;
+  POINTL SourcePoint;
+  PBITMAPOBJ DestBitmapObj;
+  PBITMAPOBJ SrcBitmapObj;
+  BOOL Status, SurfDestAlloc, SurfSrcAlloc;
+  PPALOBJ DCLogPal;
+  PPALGDI PalDestGDI, PalSourceGDI;
+  PXLATEOBJ XlateObj = NULL;
+  HPALETTE SourcePalette, DestPalette;
 
   DestRect.left   = XDest;
   DestRect.top    = YDest;
@@ -40,32 +43,44 @@ BOOL STDCALL W32kBitBlt(HDC  hDCDest,
   SurfDestAlloc = FALSE;
   SurfSrcAlloc  = FALSE;
 
-DPRINT("Get surfdest.. ");
+  // Determine surfaces to be used in the bitblt
+  SurfDest = AccessUserObject(DCDest->Surface);
+  SurfSrc  = AccessUserObject(DCSrc->Surface);
 
-  // Get the SurfDest
-  if(DCDest->Surface != NULL)
-  {
-    // Use the DC's surface if it has one
-    SurfDest = AccessUserObject(DCDest->Surface);
-  } else
-    return FALSE;
+  SurfGDIDest = AccessInternalObjectFromUserObject(SurfDest);
+  SurfGDISrc  = AccessInternalObjectFromUserObject(SurfSrc);
+
+  // Retrieve the logical palette of the destination DC
+  DCLogPal = AccessUserObject(DCDest->w.hPalette);
 
-DPRINT("Get surfsrc.. ");
+  if(DCLogPal)
+    if(DCLogPal->logicalToSystem)
+      XlateObj = DCLogPal->logicalToSystem;
 
-  // Get the SurfSrc
-  if(DCSrc->Surface != NULL)
+  // If the source and destination formats differ, create an XlateObj [what if we already have one??]
+  if((BitsPerFormat(SurfDest->iBitmapFormat) != BitsPerFormat(SurfSrc->iBitmapFormat)) && (XlateObj == NULL))
   {
-DPRINT("from DC's surface\n");
+    if(DCDest->w.hPalette != 0)
+    {
+      DestPalette = DCDest->w.hPalette;
+    } else
+      DestPalette = W32kGetStockObject(DEFAULT_PALETTE);
 
-    // Use the DC's surface if it has one
-    SurfSrc = AccessUserObject(DCSrc->Surface);
-  } else
-    return FALSE;
+    if(DCSrc->w.hPalette != 0)
+    {
+      SourcePalette = DCSrc->w.hPalette;
+    } else
+      SourcePalette = W32kGetStockObject(DEFAULT_PALETTE);
+
+    PalDestGDI   = AccessInternalObject(DestPalette);
+    PalSourceGDI = AccessInternalObject(SourcePalette);
 
+    XlateObj = EngCreateXlate(PalDestGDI->Mode, PalSourceGDI->Mode, DestPalette, SourcePalette);
+  }
 
-DPRINT("Go to EngBitBlt\n");
-  Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, NULL,
-                       &DestRect, &SourcePoint, NULL, NULL, NULL, NULL); // FIXME: Color translation (xlateobj)
+  // Perform the bitblt operation
+
+  Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, NULL);
 
   if(SurfDestAlloc == TRUE) ExFreePool(SurfDest);
   if(SurfSrcAlloc  == TRUE) ExFreePool(SurfSrc);
@@ -87,35 +102,35 @@ HBITMAP STDCALL W32kCreateBitmap(INT  Width,
 
   /* Check parameters */
   if (!Height || !Width) 
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
   if (Planes != 1) 
-    {
-      UNIMPLEMENTED;
-      return  0;
-    }
+  {
+    UNIMPLEMENTED;
+    return  0;
+  }
   if (Height < 0) 
-    {
-      Height = -Height;
-    }
+  {
+    Height = -Height;
+  }
   if (Width < 0) 
-    {
-      Width = -Width;
-    }
+  {
+    Width = -Width;
+  }
 
   /* Create the BITMAPOBJ */
   bmp = BITMAPOBJ_AllocBitmap ();
   if (!bmp) 
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
 
   DPRINT("W32kCreateBitmap:%dx%d, %d (%d BPP) colors returning %08x\n", Width, Height,
          1 << (Planes * BitsPerPel), BitsPerPel, bmp);
 
-  bmp->size.cx = 0;
-  bmp->size.cy = 0;
+  bmp->size.cx = Width;
+  bmp->size.cy = Height;
   bmp->bitmap.bmType = 0;
   bmp->bitmap.bmWidth = Width;
   bmp->bitmap.bmHeight = Height;
@@ -131,12 +146,9 @@ HBITMAP STDCALL W32kCreateBitmap(INT  Width,
   bmp->bitmap.bmBits = ExAllocatePool(PagedPool, bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight);
 
   if (Bits) /* Set bitmap bits */
-    {
-      W32kSetBitmapBits(hBitmap, 
-                        Height * bmp->bitmap.bmWidthBytes,
-                        Bits);
-    }
-
+  {
+    W32kSetBitmapBits(hBitmap, Height * bmp->bitmap.bmWidthBytes, Bits);
+  }
 
   return  hBitmap;
 }
@@ -151,36 +163,31 @@ HBITMAP STDCALL W32kCreateCompatibleBitmap(HDC hDC,
   hbmpRet = 0;
   dc = DC_HandleToPtr (hDC);
 
-  DPRINT("W32kCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC, Width, Height, dc->w.bitsPerPixel);
+  DbgPrint("W32kCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC, Width, Height, dc->w.bitsPerPixel);
 
   if (!dc)
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
   if ((Width >= 0x10000) || (Height >= 0x10000)) 
-    {
-      DPRINT("got bad width %d or height %d, please look for reason\n",
-             Width, Height);
-    } 
+  {
+    DPRINT("got bad width %d or height %d, please look for reason\n", Width, Height);
+  }
   else 
+  {
+    /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
+    if (!Width || !Height)
     {
-      /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
-      if (!Width || !Height)
-        {
-          hbmpRet = W32kCreateBitmap (1, 1, 1, 1, NULL);
-        }
-      else 
-        {
-          hbmpRet = W32kCreateBitmap (Width, 
-                                      Height, 
-                                      1, 
-                                      dc->w.bitsPerPixel, 
-                                      NULL);
-        }
+      hbmpRet = W32kCreateBitmap (1, 1, 1, 1, NULL);
+    }
+    else 
+    {
+      hbmpRet = W32kCreateBitmap(Width, Height, 1, dc->w.bitsPerPixel, NULL);
     }
+  }
   DPRINT ("\t\t%04x\n", hbmpRet);
   DC_UnlockDC (hDC);
-  
+
   return hbmpRet;
 }
 
@@ -193,26 +200,6 @@ HBITMAP STDCALL W32kCreateBitmapIndirect(CONST BITMAP  *BM)
                            BM->bmBits);
 }
 
-HBITMAP STDCALL W32kCreateDIBitmap(HDC  hDC,
-                            CONST BITMAPINFOHEADER  *bmih,
-                            DWORD  Init,
-                            CONST VOID  *bInit,
-                            CONST BITMAPINFO  *bmi,
-                            UINT  Usage)
-{
-  UNIMPLEMENTED;
-}
-
-HBITMAP STDCALL W32kCreateDIBSection(HDC hDC,
-                              CONST BITMAPINFO  *bmi,
-                              UINT  Usage,
-                              VOID  *Bits,
-                              HANDLE  hSection,
-                              DWORD  dwOffset)
-{
-  UNIMPLEMENTED;
-}
-
 HBITMAP STDCALL W32kCreateDiscardableBitmap(HDC  hDC,
                                      INT  Width,
                                      INT  Height)
@@ -238,83 +225,6 @@ BOOL STDCALL W32kFloodFill(HDC  hDC,
   UNIMPLEMENTED;
 }
 
-LONG STDCALL W32kGetBitmapBits(HBITMAP  hBitmap,
-                        LONG  Count,
-                        LPVOID  Bits)
-{
-  PBITMAPOBJ  bmp;
-  LONG  height, ret;
-  
-  bmp = BITMAPOBJ_HandleToPtr (hBitmap);
-  if (!bmp) 
-    {
-      return 0;
-    }
-    
-  /* If the bits vector is null, the function should return the read size */
-  if (Bits == NULL)
-    {
-      return bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight;
-    }
-
-  if (Count < 0) 
-    {
-      DPRINT ("(%ld): Negative number of bytes passed???\n", Count);
-      Count = -Count;
-    }
-
-  /* Only get entire lines */
-  height = Count / bmp->bitmap.bmWidthBytes;
-  if (height > bmp->bitmap.bmHeight) 
-    {
-      height = bmp->bitmap.bmHeight;
-    }
-  Count = height * bmp->bitmap.bmWidthBytes;
-  if (Count == 0)
-    {
-      DPRINT("Less then one entire line requested\n");
-      BITMAPOBJ_UnlockBitmap (hBitmap);
-      return  0;
-    }
-
-  DPRINT("(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
-         hBitmap, Count, Bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
-         1 << bmp->bitmap.bmBitsPixel, height );
-#if 0
-  /* FIXME: Call DDI CopyBits here if available  */
-  if(bmp->DDBitmap) 
-    {
-      DPRINT("Calling device specific BitmapBits\n");
-      if(bmp->DDBitmap->funcs->pBitmapBits)
-        {
-          ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, bits, count,
-                                                  DDB_GET);
-        }
-      else 
-        {
-          ERR_(bitmap)("BitmapBits == NULL??\n");
-          ret = 0;
-        }
-    } 
-  else 
-#endif
-    {
-      if(!bmp->bitmap.bmBits) 
-        {
-          DPRINT ("Bitmap is empty\n");
-          ret = 0;
-        } 
-      else 
-        {
-          memcpy(Bits, bmp->bitmap.bmBits, Count);
-          ret = Count;
-        }
-    }
-  BITMAPOBJ_UnlockBitmap (hBitmap);
-
-  return  ret;
-}
-
 BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP  hBitmap,
                                LPSIZE  Dimension)
 {
@@ -322,9 +232,9 @@ BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP  hBitmap,
   
   bmp = BITMAPOBJ_HandleToPtr (hBitmap);
   if (bmp == NULL) 
-    {
-      return FALSE;
-    }
+  {
+    return FALSE;
+  }
   
   *Dimension = bmp->size;
   BITMAPOBJ_UnlockBitmap (hBitmap);
@@ -332,25 +242,6 @@ BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP  hBitmap,
   return  TRUE;
 }
 
-UINT STDCALL W32kGetDIBColorTable(HDC  hDC,
-                           UINT  StartIndex,
-                           UINT  Entries,
-                           RGBQUAD  *Colors)
-{
-  UNIMPLEMENTED;
-}
-
-INT STDCALL W32kGetDIBits(HDC  hDC,
-                   HBITMAP hBitmap,
-                   UINT  StartScan,
-                   UINT  ScanLines,
-                   LPVOID  Bits,
-                   LPBITMAPINFO   bi,
-                   UINT  Usage)
-{
-  UNIMPLEMENTED;
-}
-
 COLORREF STDCALL W32kGetPixel(HDC  hDC,
                        INT  XPos,
                        INT  YPos)
@@ -397,22 +288,22 @@ LONG STDCALL W32kSetBitmapBits(HBITMAP  hBitmap,
   
   bmp = BITMAPOBJ_HandleToPtr (hBitmap);
   if (bmp == NULL || Bits == NULL)
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
 
   if (Bytes < 0) 
-    {
-      DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes );
-      Bytes = -Bytes;
-    }
+  {
+    DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes );
+    Bytes = -Bytes;
+  }
 
   /* Only get entire lines */
   height = Bytes / bmp->bitmap.bmWidthBytes;
   if (height > bmp->bitmap.bmHeight) 
-    {
-      height = bmp->bitmap.bmHeight;
-    }
+  {
+    height = bmp->bitmap.bmHeight;
+  }
   Bytes = height * bmp->bitmap.bmWidthBytes;
   DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
           hBitmap, 
@@ -426,39 +317,36 @@ LONG STDCALL W32kSetBitmapBits(HBITMAP  hBitmap,
 #if 0
   /* FIXME: call DDI specific function here if available  */
   if(bmp->DDBitmap) 
+  {
+    DPRINT ("Calling device specific BitmapBits\n");
+    if (bmp->DDBitmap->funcs->pBitmapBits)
     {
-      DPRINT ("Calling device specific BitmapBits\n");
-      if (bmp->DDBitmap->funcs->pBitmapBits)
-        {
-          ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap, 
-                                                  (void *) Bits,
-                                                  Bytes, 
-                                                  DDB_SET);
-        } 
-      else 
-        {
-          DPRINT ("BitmapBits == NULL??\n");
-          ret = 0;
-        }
+      ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap, (void *) Bits, Bytes, DDB_SET);
     } 
+    else 
+    {
+      DPRINT ("BitmapBits == NULL??\n");
+      ret = 0;
+    }
+  } 
   else
 #endif
     {
       /* FIXME: Alloc enough for entire bitmap */
       if (bmp->bitmap.bmBits == NULL)
-        {
-          bmp->bitmap.bmBits = ExAllocatePool (PagedPool, Bytes);
-        }
+      {
+        bmp->bitmap.bmBits = ExAllocatePool (PagedPool, Bytes);
+      }
       if(!bmp->bitmap.bmBits) 
-        {
-          DPRINT ("Unable to allocate bit buffer\n");
-          ret = 0;
-        
+      {
+        DPRINT ("Unable to allocate bit buffer\n");
+        ret = 0;
+      } 
       else 
-        {
-          memcpy(bmp->bitmap.bmBits, Bits, Bytes);
-          ret = Bytes;
-        }
+      {
+        memcpy(bmp->bitmap.bmBits, Bits, Bytes);
+        ret = Bytes;
+      }
     }
   BITMAPOBJ_UnlockBitmap (hBitmap);
 
@@ -474,14 +362,14 @@ BOOL STDCALL W32kSetBitmapDimensionEx(HBITMAP  hBitmap,
   
   bmp = BITMAPOBJ_HandleToPtr (hBitmap);
   if (bmp == NULL) 
-    {
-      return FALSE;
-    }
+  {
+    return FALSE;
+  }
   
   if (Size) 
-    {
-      *Size = bmp->size;
-    }
+  {
+    *Size = bmp->size;
+  }
   bmp->size.cx = Width;
   bmp->size.cy = Height;
   BITMAPOBJ_UnlockBitmap (hBitmap);
@@ -489,41 +377,6 @@ BOOL STDCALL W32kSetBitmapDimensionEx(HBITMAP  hBitmap,
   return TRUE;
 }
 
-UINT STDCALL W32kSetDIBColorTable(HDC  hDC,
-                           UINT  StartIndex,
-                           UINT  Entries,
-                           CONST RGBQUAD  *Colors)
-{
-  UNIMPLEMENTED;
-}
-
-INT STDCALL W32kSetDIBits(HDC  hDC,
-                   HBITMAP  hBitmap,
-                   UINT  StartScan,
-                   UINT  ScanLines,
-                   CONST VOID  *Bits,
-                   CONST BITMAPINFO  *bmi,
-                   UINT  ColorUse)
-{
-  UNIMPLEMENTED;
-}
-
-INT STDCALL W32kSetDIBitsToDevice(HDC  hDC,
-                           INT  XDest,
-                           INT  YDest,
-                           DWORD  Width,
-                           DWORD  Height,
-                           INT  XSrc,
-                           INT  YSrc,
-                           UINT  StartScan,
-                           UINT  ScanLines,
-                           CONST VOID  *Bits,
-                           CONST BITMAPINFO  *bmi,
-                           UINT  ColorUse)
-{
-  UNIMPLEMENTED;
-}
-
 COLORREF STDCALL W32kSetPixel(HDC  hDC,
                        INT  X,
                        INT  Y,
@@ -555,30 +408,13 @@ BOOL STDCALL W32kStretchBlt(HDC  hDCDest,
   UNIMPLEMENTED;
 }
 
-INT STDCALL W32kStretchDIBits(HDC  hDC,
-                       INT  XDest,
-                       INT  YDest,
-                       INT  DestWidth,
-                       INT  DestHeight,
-                       INT  XSrc,       
-                       INT  YSrc,       
-                       INT  SrcWidth,  
-                       INT  SrcHeight, 
-                       CONST VOID  *Bits,
-                       CONST BITMAPINFO  *BitsInfo,
-                       UINT  Usage,                 
-                       DWORD  ROP)
-{
-  UNIMPLEMENTED;
-}
-
 /*  Internal Functions  */
 
 INT 
 BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
 {
   switch(bpp)
-    {
+  {
     case 1:
       return 2 * ((bmWidth+15) >> 4);
       
@@ -599,7 +435,7 @@ BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
       
     default:
       DPRINT ("stub");
-    }
+  }
 
   return -1;
 }
@@ -612,94 +448,47 @@ HBITMAP  BITMAPOBJ_CopyBitmap(HBITMAP  hBitmap)
 
   bmp = BITMAPOBJ_HandleToPtr (hBitmap);
   if (bmp == NULL) 
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
   res = 0;
   
   bm = bmp->bitmap;
   bm.bmBits = NULL;
   res = W32kCreateBitmapIndirect(&bm);
   if(res) 
-    {
-      char *buf;
+  {
+    char *buf;
       
-      buf = ExAllocatePool (NonPagedPool, bm.bmWidthBytes * bm.bmHeight);
-      W32kGetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
-      W32kSetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
-      ExFreePool (buf);
-    }
+    buf = ExAllocatePool (NonPagedPool, bm.bmWidthBytes * bm.bmHeight);
+    W32kGetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
+    W32kSetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
+    ExFreePool (buf);
+  }
   BITMAPOBJ_UnlockBitmap (hBitmap);
 
   return  res;
 }
 
-/***********************************************************************
- *           DIB_GetDIBWidthBytes
- *
- * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
- * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
- * 11/16/1999 (RJJ) lifted from wine
- */
-int DIB_GetDIBWidthBytes(int  width, int  depth)
+INT BITMAP_GetObject(BITMAPOBJ * bmp, INT count, LPVOID buffer)
 {
-  int words;
-  
-  switch(depth)
-    {
-    case 1:  words = (width + 31) / 32; break;
-    case 4:  words = (width + 7) / 8; break;
-    case 8:  words = (width + 3) / 4; break;
-    case 15:
-    case 16: words = (width + 1) / 2; break;
-    case 24: words = (width * 3 + 3)/4; break;
-      
-    default:
-      DPRINT("(%d): Unsupported depth\n", depth );
-      /* fall through */
-    case 32:
-      words = width;
-    }
-  return 4 * words;
-}
-
-/***********************************************************************
- *           DIB_GetDIBImageBytes
- *
- * Return the number of bytes used to hold the image in a DIB bitmap.
- * 11/16/1999 (RJJ) lifted from wine
- */
-
-int DIB_GetDIBImageBytes (int  width, int  height, int  depth)
-{
-  return DIB_GetDIBWidthBytes( width, depth ) * (height < 0 ? -height : height);
-}
-
-/***********************************************************************
- *           DIB_BitmapInfoSize
- *
- * Return the size of the bitmap info structure including color table.
- * 11/16/1999 (RJJ) lifted from wine
- */
-
-int DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse)
-{
-  int colors;
-
-  if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+  if(bmp->dib)
+  {
+    if(count < sizeof(DIBSECTION))
     {
-      BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
-      colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
-      return sizeof(BITMAPCOREHEADER) + colors *
-        ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
+      if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
     }
-  else  /* assume BITMAPINFOHEADER */
+    else
     {
-      colors = info->bmiHeader.biClrUsed;
-      if (!colors && (info->bmiHeader.biBitCount <= 8))
-        colors = 1 << info->bmiHeader.biBitCount;
-        return sizeof(BITMAPINFOHEADER) + colors *
-               ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
+      if (count > sizeof(DIBSECTION)) count = sizeof(DIBSECTION);
     }
+    memcpy(buffer, bmp->dib, count);
+    return count;
+  }
+  else
+  {
+    if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
+    memcpy(buffer, &bmp->bitmap, count);
+    return count;
+  }
 }
-
index 6924f98..b9a2cfe 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: brush.c,v 1.10 2000/06/29 23:35:53 dwelch Exp $
+/* $Id: brush.c,v 1.11 2001/03/31 15:35:08 jfilby Exp $
  */
 
 
@@ -17,16 +17,17 @@ HBRUSH STDCALL W32kCreateBrushIndirect(CONST LOGBRUSH  *lb)
   PBRUSHOBJ  brushPtr;
   HBRUSH  hBrush;
   
-  hBrush = BRUSHOBJ_AllocBrush ();
+  brushPtr = BRUSHOBJ_AllocBrush();
+  hBrush = BRUSHOBJ_PtrToHandle (brushPtr);
   if (hBrush == NULL)
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
   
-  brushPtr = BRUSHOBJ_HandleToPtr (hBrush);
   brushPtr->logbrush.lbStyle = lb->lbStyle;
   brushPtr->logbrush.lbColor = lb->lbColor;
   brushPtr->logbrush.lbHatch = lb->lbHatch;
+
   BRUSHOBJ_UnlockBrush (hBrush);
   DPRINT("%08x\n", hBrush);
   
@@ -50,29 +51,26 @@ HBRUSH STDCALL W32kCreateDIBPatternBrush(HGLOBAL  hDIBPacked,
 
   /* Make a copy of the bitmap */
   if (!(info = (BITMAPINFO *)GlobalLock( hbitmap ))) 
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
   
 
-    if (info->bmiHeader.biCompression)
-        size = info->bmiHeader.biSizeImage;
-    else
-       size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
-                                   info->bmiHeader.biHeight,
-                                   info->bmiHeader.biBitCount);
-    size += DIB_BitmapInfoSize( info, coloruse );
-
-    if (!(logbrush.lbHatch = (INT)GlobalAlloc16( GMEM_MOVEABLE, size )))
-    {
-       GlobalUnlock16( hbitmap );
-       return 0;
-    }
-    newInfo = (BITMAPINFO *) GlobalLock16( (HGLOBAL16)logbrush.lbHatch );
-    memcpy( newInfo, info, size );
-    GlobalUnlock16( (HGLOBAL16)logbrush.lbHatch );
-    GlobalUnlock( hbitmap );
-    return W32kCreateBrushIndirect( &logbrush );
+  if (info->bmiHeader.biCompression) size = info->bmiHeader.biSizeImage;
+  else
+    size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
+  size += DIB_BitmapInfoSize(info, coloruse);
+
+  if (!(logbrush.lbHatch = (INT)GlobalAlloc16( GMEM_MOVEABLE, size )))
+  {
+    GlobalUnlock16( hbitmap );
+    return 0;
+  }
+  newInfo = (BITMAPINFO *) GlobalLock16((HGLOBAL16)logbrush.lbHatch);
+  memcpy(newInfo, info, size);
+  GlobalUnlock16((HGLOBAL16)logbrush.lbHatch);
+  GlobalUnlock(hbitmap);
+  return W32kCreateBrushIndirect(&logbrush);
 #endif
 }
 
@@ -86,9 +84,9 @@ HBRUSH STDCALL W32kCreateDIBPatternBrushPt(CONST VOID  *PackedDIB,
     
   info = (BITMAPINFO *) PackedDIB;
   if (info == NULL)
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
   DPRINT ("%p %ldx%ld %dbpp\n", 
           info, 
           info->bmiHeader.biWidth,
@@ -102,28 +100,23 @@ HBRUSH STDCALL W32kCreateDIBPatternBrushPt(CONST VOID  *PackedDIB,
   /* Make a copy of the bitmap */
 
   if (info->bmiHeader.biCompression)
-    {
-      size = info->bmiHeader.biSizeImage;
-    }
+  {
+    size = info->bmiHeader.biSizeImage;
+  }
   else
     {
-      size = DIB_GetDIBImageBytes (info->bmiHeader.biWidth,
-                                   info->bmiHeader.biHeight,
-                                   info->bmiHeader.biBitCount);
-    }
+    size = DIB_GetDIBImageBytes (info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
+  }
   size += DIB_BitmapInfoSize (info, Usage);
   
-  logbrush.lbHatch = (INT) 
-    GDIOBJ_PtrToHandle (GDIOBJ_AllocObject (size, GO_MAGIC_DONTCARE),
-                        GO_MAGIC_DONTCARE);
+  logbrush.lbHatch = (INT)GDIOBJ_PtrToHandle (GDIOBJ_AllocObject (size, GO_MAGIC_DONTCARE), GO_MAGIC_DONTCARE);
   if (logbrush.lbHatch == 0)
-    {
-      return 0;
-    }
-  newInfo = (PBITMAPINFO) GDIOBJ_HandleToPtr ((HGDIOBJ) logbrush.lbHatch,
-                                              GO_MAGIC_DONTCARE);
-  memcpy (newInfo, info, size);
-  GDIOBJ_UnlockObject ((HGDIOBJ) logbrush.lbHatch);
+  {
+    return 0;
+  }
+  newInfo = (PBITMAPINFO) GDIOBJ_HandleToPtr ((HGDIOBJ) logbrush.lbHatch, GO_MAGIC_DONTCARE);
+  memcpy(newInfo, info, size);
+  GDIOBJ_UnlockObject((HGDIOBJ)logbrush.lbHatch);
   
   return  W32kCreateBrushIndirect (&logbrush);
 }
@@ -136,9 +129,9 @@ HBRUSH STDCALL W32kCreateHatchBrush(INT  Style,
   DPRINT("%d %06lx\n", Style, Color);
 
   if (Style < 0 || Style >= NB_HATCH_STYLES)
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
   logbrush.lbStyle = BS_HATCHED;
   logbrush.lbColor = Color;
   logbrush.lbHatch = Style;
@@ -153,24 +146,24 @@ HBRUSH STDCALL W32kCreatePatternBrush(HBITMAP  hBitmap)
   DPRINT ("%04x\n", hBitmap);
   logbrush.lbHatch = (INT) BITMAPOBJ_CopyBitmap (hBitmap);
   if(!logbrush.lbHatch)
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
   else
-    {
-      return W32kCreateBrushIndirect( &logbrush );
-    }
+  {
+    return W32kCreateBrushIndirect( &logbrush );
+  }
 }
 
 HBRUSH STDCALL W32kCreateSolidBrush(COLORREF  Color)
 {
-   LOGBRUSH logbrush;
+  LOGBRUSH logbrush;
 
-   logbrush.lbStyle = BS_SOLID;
-   logbrush.lbColor = Color;
-   logbrush.lbHatch = 0;
+  logbrush.lbStyle = BS_SOLID;
+  logbrush.lbColor = Color;
+  logbrush.lbHatch = 0;
 
-   return W32kCreateBrushIndirect(&logbrush);
+  return W32kCreateBrushIndirect(&logbrush);
 }
 
 BOOL STDCALL W32kFixBrushOrgEx(VOID)
index 640ac75..fc0574a 100644 (file)
+// FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping
 
 #undef WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <ddk/ntddk.h>
+#include <ddk/winddi.h>
+#include <win32k/dc.h>
 #include <win32k/color.h>
+#include "../eng/objects.h"
 
 // #define NDEBUG
 #include <win32k/debug1.h>
 
+int COLOR_gapStart = 256;
+int COLOR_gapEnd = -1;
+int COLOR_gapFilled = 0;
+int COLOR_max = 256;
+
+static HPALETTE hPrimaryPalette = 0; // used for WM_PALETTECHANGED
+static HPALETTE hLastRealizedPalette = 0; // UnrealizeObject() needs it
+
+const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] = 
+{
+  // first 10 entries in the system palette
+  // red  green blue  flags
+  { 0x00, 0x00, 0x00, PC_SYS_USED },
+  { 0x80, 0x00, 0x00, PC_SYS_USED },
+  { 0x00, 0x80, 0x00, PC_SYS_USED },
+  { 0x80, 0x80, 0x00, PC_SYS_USED },
+  { 0x00, 0x00, 0x80, PC_SYS_USED },
+  { 0x80, 0x00, 0x80, PC_SYS_USED },
+  { 0x00, 0x80, 0x80, PC_SYS_USED },
+  { 0xc0, 0xc0, 0xc0, PC_SYS_USED },
+  { 0xc0, 0xdc, 0xc0, PC_SYS_USED },
+  { 0xa6, 0xca, 0xf0, PC_SYS_USED },
+
+  // ... c_min/2 dynamic colorcells
+  // ... gap (for sparse palettes)
+  // ... c_min/2 dynamic colorcells
+
+  { 0xff, 0xfb, 0xf0, PC_SYS_USED },
+  { 0xa0, 0xa0, 0xa4, PC_SYS_USED },
+  { 0x80, 0x80, 0x80, PC_SYS_USED },
+  { 0xff, 0x00, 0x00, PC_SYS_USED },
+  { 0x00, 0xff, 0x00, PC_SYS_USED },
+  { 0xff, 0xff, 0x00, PC_SYS_USED },
+  { 0x00, 0x00, 0xff, PC_SYS_USED },
+  { 0xff, 0x00, 0xff, PC_SYS_USED },
+  { 0x00, 0xff, 0xff, PC_SYS_USED },
+  { 0xff, 0xff, 0xff, PC_SYS_USED }     // last 10
+};
+
+const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void)
+{
+  return COLOR_sysPalTemplate;
+}
+
 BOOL STDCALL W32kAnimatePalette(HPALETTE  hpal,
                          UINT  StartIndex,
                          UINT  Entries,
                          CONST PPALETTEENTRY  ppe)
 {
+/*
+  if( hPal != W32kGetStockObject(DEFAULT_PALETTE) )
+  {
+    PALETTEOBJ* palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPal, PALETTE_MAGIC);
+    if (!palPtr) return FALSE;
+
+    if( (StartIndex + NumEntries) <= palPtr->logpalette.palNumEntries )
+    {
+      UINT u;
+      for( u = 0; u < NumEntries; u++ )
+        palPtr->logpalette.palPalEntry[u + StartIndex] = PaletteColors[u];
+      PALETTE_Driver->pSetMapping(palPtr, StartIndex, NumEntries, hPal != hPrimaryPalette );
+      GDI_ReleaseObj(hPal);
+      return TRUE;
+    }
+    GDI_ReleaseObj(hPal);
+  }
+  return FALSE;
+*/
   UNIMPLEMENTED;
 }
 
 HPALETTE STDCALL W32kCreateHalftonePalette(HDC  hDC)
 {
-  UNIMPLEMENTED;
+  int i, r, g, b;
+  struct {
+    WORD Version;
+    WORD NumberOfEntries;
+    PALETTEENTRY aEntries[256];
+  } Palette;
+
+  Palette.Version = 0x300;
+  Palette.NumberOfEntries = 256;
+  W32kGetSystemPaletteEntries(hDC, 0, 256, Palette.aEntries);
+
+  for (r = 0; r < 6; r++) {
+    for (g = 0; g < 6; g++) {
+      for (b = 0; b < 6; b++) {
+        i = r + g*6 + b*36 + 10;
+        Palette.aEntries[i].peRed = r * 51;
+        Palette.aEntries[i].peGreen = g * 51;
+        Palette.aEntries[i].peBlue = b * 51;
+      }    
+     }
+   }
+
+  for (i = 216; i < 246; i++) {
+    int v = (i - 216) * 8;
+    Palette.aEntries[i].peRed = v;
+    Palette.aEntries[i].peGreen = v;
+    Palette.aEntries[i].peBlue = v;
+  }
+
+  return W32kCreatePalette((LOGPALETTE *)&Palette);
 }
 
-HPALETTE STDCALL W32kCreatePalette(CONST PLOGPALETTE lgpl)
+HPALETTE STDCALL W32kCreatePalette(CONST PLOGPALETTE palette)
 {
-  UNIMPLEMENTED;
+  PPALOBJ  PalObj;
+  HPALETTE NewPalette = EngCreatePalette(PAL_INDEXED, palette->palNumEntries, palette->palPalEntry, 0, 0, 0);
+  ULONG size;
+
+  PalObj = AccessUserObject(NewPalette);
+
+  size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
+  memcpy(&PalObj->logpalette, palette, size);
+  PALETTE_ValidateFlags(PalObj->logpalette.palPalEntry, PalObj->logpalette.palNumEntries);
+  PalObj->logicalToSystem = NULL;
+
+  return NewPalette;
 }
 
 BOOL STDCALL W32kGetColorAdjustment(HDC  hDC,
@@ -34,13 +141,43 @@ BOOL STDCALL W32kGetColorAdjustment(HDC  hDC,
 COLORREF STDCALL W32kGetNearestColor(HDC  hDC,
                               COLORREF  Color)
 {
-  UNIMPLEMENTED;
+  COLORREF nearest = CLR_INVALID;
+  PDC dc;
+  PPALOBJ palObj;
+
+  if(DC_HandleToPtr(hDC))
+  {
+    HPALETTE hpal = (dc->w.hPalette)? dc->w.hPalette : W32kGetStockObject(DEFAULT_PALETTE);
+    palObj = AccessUserObject(hpal);
+    if (!palObj) {
+//      GDI_ReleaseObj(hdc);
+      return nearest;
+    }
+
+    nearest = COLOR_LookupNearestColor(palObj->logpalette.palPalEntry,
+                                       palObj->logpalette.palNumEntries, Color);
+
+//    GDI_ReleaseObj( hpal );
+//    GDI_ReleaseObj( hdc );
+  }
+
+  return nearest;
 }
 
 UINT STDCALL W32kGetNearestPaletteIndex(HPALETTE  hpal,
                                  COLORREF  Color)
 {
-  UNIMPLEMENTED;
+  PPALOBJ     palObj = AccessUserObject(hpal);
+  UINT index  = 0;
+
+  if( palObj )
+  {
+    // Return closest match for the given RGB color
+    index = COLOR_PaletteLookupPixel(palObj->logpalette.palPalEntry, palObj->logpalette.palNumEntries, NULL, Color, FALSE);
+//    GDI_ReleaseObj( hpalette );
+  }
+
+  return index;
 }
 
 UINT STDCALL W32kGetPaletteEntries(HPALETTE  hpal,
@@ -48,7 +185,29 @@ UINT STDCALL W32kGetPaletteEntries(HPALETTE  hpal,
                             UINT  Entries,
                             LPPALETTEENTRY  pe)
 {
-  UNIMPLEMENTED;
+  PPALOBJ palPtr;
+  UINT numEntries;
+
+  palPtr = AccessUserObject(hpal);
+  if (!palPtr) return 0;
+
+  numEntries = palPtr->logpalette.palNumEntries;
+  if (StartIndex + Entries > numEntries) Entries = numEntries - StartIndex;
+  if (pe)
+  { 
+    if (StartIndex >= numEntries) 
+    {
+//      GDI_ReleaseObj( hpalette );
+      return 0;
+    }
+    memcpy(pe, &palPtr->logpalette.palPalEntry[StartIndex], Entries * sizeof(PALETTEENTRY));
+    for(numEntries = 0; numEntries < Entries ; numEntries++)
+      if (pe[numEntries].peFlags & 0xF0)
+        pe[numEntries].peFlags = 0;
+  }
+
+//  GDI_ReleaseObj( hpalette );
+  return Entries;
 }
 
 UINT STDCALL W32kGetSystemPaletteEntries(HDC  hDC,
@@ -56,7 +215,33 @@ UINT STDCALL W32kGetSystemPaletteEntries(HDC  hDC,
                                   UINT  Entries,
                                   LPPALETTEENTRY  pe)
 {
-  UNIMPLEMENTED;
+  UINT i;
+  PDC dc;
+/*
+  if (!(dc = AccessUserObject(hdc))) return 0;
+
+  if (!pe)
+  {
+    Entries = dc->devCaps->sizePalette;
+    goto done;
+  }
+
+  if (StartIndex >= dc->devCaps->sizePalette)
+  {
+    Entries = 0;
+    goto done;
+  }
+
+  if (StartIndex + Entries >= dc->devCaps->sizePalette) Entries = dc->devCaps->sizePalette - StartIndex;
+
+  for (i = 0; i < Entries; i++)
+  {
+    *(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry(StartIndex + i);
+  }
+
+  done:
+//    GDI_ReleaseObj(hdc);
+  return count; */
 }
 
 UINT STDCALL W32kGetSystemPaletteUse(HDC  hDC)
@@ -65,13 +250,112 @@ UINT STDCALL W32kGetSystemPaletteUse(HDC  hDC)
 }
 
 UINT STDCALL W32kRealizePalette(HDC  hDC)
+/*
+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. 
+
+A logical palette is a buffer between color-intensive applications and the system, allowing these applications to use as many colors as needed without interfering with colors displayed by other windows.
+
+1= IF DRAWING TO A DEVICE
+-- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
+   the system palette.
+-- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the system palette.
+
+2= IF DRAWING TO A MEMORY DC\BITMAP
+-- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
+   the dc palette.
+-- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the dc palette.
+*/
 {
-  UNIMPLEMENTED;
+  PPALOBJ palPtr, sysPtr;
+  PPALGDI palGDI, sysGDI;
+  int realized = 0;
+  PDC dc = AccessUserObject(hDC);
+  HPALETTE systemPalette;
+  PSURFGDI SurfGDI;
+  BOOLEAN success;
+
+  if (!dc) return 0;
+
+  palPtr = AccessUserObject(dc->w.hPalette);
+  SurfGDI = AccessInternalObjectFromUserObject(dc->Surface);
+  systemPalette = W32kGetStockObject(STOCK_DEFAULT_PALETTE);
+  sysPtr = AccessInternalObject(systemPalette);
+  palGDI = AccessInternalObject(dc->w.hPalette);
+  sysGDI = AccessInternalObject(systemPalette);
+
+  // Step 1: Create mapping of system palette\DC palette
+  realized = PALETTE_SetMapping(palPtr, 0, palPtr->logpalette.palNumEntries,
+               (dc->w.hPalette != hPrimaryPalette) ||
+               (dc->w.hPalette == W32kGetStockObject(DEFAULT_PALETTE)));
+
+  // Step 2:
+  // 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->w.flags == DC_MEMORY)
+  {
+    // Memory managed DC
+    DbgPrint("win32k: realizepalette unimplemented step 2 for DC_MEMORY");
+  } else {
+    if(SurfGDI->SetPalette)
+    {
+      success = SurfGDI->SetPalette(dc->PDev, sysPtr, 0, 0, sysPtr->logpalette.palNumEntries);
+    }
+  }
+
+  // Step 3: Create the XLATEOBJ for device managed DCs
+  if(dc->w.flags != DC_MEMORY)
+  {
+    // Device managed DC
+    palPtr->logicalToSystem = EngCreateXlate(sysGDI->Mode, palGDI->Mode, systemPalette, dc->w.hPalette);
+  }
+
+//  GDI_ReleaseObj(dc->w.hPalette);
+//  GDI_ReleaseObj(hdc);
+
+  return realized;
 }
 
 BOOL STDCALL W32kResizePalette(HPALETTE  hpal,
                         UINT  Entries)
 {
+/*  PPALOBJ palPtr = (PPALOBJ)AccessUserObject(hPal);
+  UINT cPrevEnt, prevVer;
+  INT prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
+  PXLATEOBJ XlateObj = NULL;
+
+  if(!palPtr) return FALSE;
+  cPrevEnt = palPtr->logpalette.palNumEntries;
+  prevVer = palPtr->logpalette.palVersion;
+  prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) + sizeof(int*) + sizeof(GDIOBJHDR);
+  size += sizeof(int*) + sizeof(GDIOBJHDR);
+  XlateObj = palPtr->logicalToSystem;
+    
+  if (!(palPtr = GDI_ReallocObject(size, hPal, palPtr))) return FALSE;
+
+  if(XlateObj)
+  {
+    PXLATEOBJ NewXlateObj = (int*) HeapReAlloc(GetProcessHeap(), 0, XlateObj, cEntries * sizeof(int));
+    if(NewXlateObj == NULL) 
+    {
+      ERR("Can not resize logicalToSystem -- out of memory!");
+      GDI_ReleaseObj( hPal );
+      return FALSE;
+    }
+    palPtr->logicalToSystem = NewXlateObj;
+  }
+
+  if(cEntries > cPrevEnt)
+  {
+    if(XlateObj) memset(palPtr->logicalToSystem + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
+    memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
+    PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), cEntries - cPrevEnt );
+  }
+  palPtr->logpalette.palNumEntries = cEntries;
+  palPtr->logpalette.palVersion = prevVer;
+//    GDI_ReleaseObj( hPal );
+  return TRUE; */
+
   UNIMPLEMENTED;
 }
 
@@ -79,7 +363,15 @@ HPALETTE STDCALL W32kSelectPalette(HDC  hDC,
                             HPALETTE  hpal,
                             BOOL  ForceBackground)
 {
-  UNIMPLEMENTED;
+  PDC dc = AccessUserObject(hDC);
+  HPALETTE oldPal;
+
+  oldPal = dc->w.hPalette;
+  dc->w.hPalette = hpal;
+
+  // FIXME: mark the palette as a [fore\back]ground pal
+
+  return oldPal;
 }
 
 BOOL STDCALL W32kSetColorAdjustment(HDC  hDC,
@@ -93,7 +385,25 @@ UINT STDCALL W32kSetPaletteEntries(HPALETTE  hpal,
                             UINT  Entries,
                             CONST LPPALETTEENTRY  pe)
 {
-  UNIMPLEMENTED;
+  PPALOBJ palPtr;
+  INT numEntries;
+
+  palPtr = AccessUserObject(hpal);
+  if (!palPtr) return 0;
+
+  numEntries = palPtr->logpalette.palNumEntries;
+  if (Start >= numEntries)
+  {
+//    GDI_ReleaseObj( hpalette );
+    return 0;
+  }
+  if (Start + Entries > numEntries) Entries = numEntries - Start;
+  memcpy(&palPtr->logpalette.palPalEntry[Start], pe, Entries * sizeof(PALETTEENTRY));
+  PALETTE_ValidateFlags(palPtr->logpalette.palPalEntry, palPtr->logpalette.palNumEntries);
+  ExFreePool(palPtr->logicalToSystem);
+  palPtr->logicalToSystem = NULL;
+//  GDI_ReleaseObj( hpalette );
+  return Entries;
 }
 
 UINT STDCALL W32kSetSystemPaletteUse(HDC  hDC,
@@ -109,6 +419,81 @@ BOOL STDCALL W32kUnrealizeObject(HGDIOBJ  hgdiobj)
 
 BOOL STDCALL W32kUpdateColors(HDC  hDC)
 {
-  UNIMPLEMENTED;
+  PDC dc;
+  HWND hWnd;
+  int size;
+/*
+  if (!(dc = AccessUserObject(hDC))) return 0;
+  size = dc->devCaps->sizePalette;
+//  GDI_ReleaseObj( hDC );
+
+  if (Callout.WindowFromDC)
+  {
+    hWnd = Callout.WindowFromDC( hDC );
+
+    // Docs say that we have to remap current drawable pixel by pixel
+    // but it would take forever given the speed of XGet/PutPixel.
+    if (hWnd && size) Callout.RedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
+  } */
+  return 0x666;
+}
+
+int COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, int size,
+                             PXLATEOBJ XlateObj, COLORREF col, BOOL skipReserved)
+{
+  int i, best = 0, diff = 0x7fffffff;
+  int r, g, b;
+
+  for( i = 0; i < size && diff ; i++ )
+  {
+    if(!(palPalEntry[i].peFlags & PC_SYS_USED) || (skipReserved && palPalEntry[i].peFlags  & PC_SYS_RESERVED))
+      continue;
+
+    r = palPalEntry[i].peRed - GetRValue(col);
+    g = palPalEntry[i].peGreen - GetGValue(col);
+    b = palPalEntry[i].peBlue - GetBValue(col);
+
+    r = r*r + g*g + b*b;
+
+    if( r < diff ) { best = i; diff = r; }
+  }
+  return (XlateObj->pulXlate) ? XlateObj->pulXlate[best] : best;
 }
 
+COLORREF COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
+{
+  unsigned char spec_type = color >> 24;
+  int i;
+  PALETTEENTRY *COLOR_sysPal = ReturnSystemPalette();
+
+  // we need logical palette for PALETTERGB and PALETTEINDEX colorrefs
+
+  if( spec_type == 2 ) /* PALETTERGB */
+    color = *(COLORREF*)(palPalEntry + COLOR_PaletteLookupPixel(palPalEntry,size,NULL,color,FALSE));
+
+  else if( spec_type == 1 ) /* PALETTEINDEX */
+  {
+    if( (i = color & 0x0000ffff) >= size ) 
+    {
+      DbgPrint("RGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
+      color = *(COLORREF*)palPalEntry;
+    }
+    else color = *(COLORREF*)(palPalEntry + i);
+  }
+
+  color &= 0x00ffffff;
+  return (0x00ffffff & *(COLORREF*)(COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
+}
+
+int COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
+                                   COLORREF col )
+{
+  int i;
+  BYTE r = GetRValue(col), g = GetGValue(col), b = GetBValue(col);
+  for( i = 0; i < size; i++ )
+  {
+    if( palPalEntry[i].peFlags & PC_SYS_USED )  /* skips gap */
+      if(palPalEntry[i].peRed == r && palPalEntry[i].peGreen == g && palPalEntry[i].peBlue == b) return i;
+  }
+  return -1;
+}
index 7398e8d..5966312 100644 (file)
@@ -17,23 +17,17 @@ BOOL STDCALL W32kCombineTransform(LPXFORM  XFormResult,
     
   /* Check for illegal parameters */
   if (!XFormResult || !xform1 || !xform2)
-    {
-      return  FALSE;
-    }
+  {
+    return  FALSE;
+  }
   /* Create the result in a temporary XFORM, since xformResult may be
    * equal to xform1 or xform2 */
-  xformTemp.eM11 = xform1->eM11 * xform2->eM11 +
-    xform1->eM12 * xform2->eM21;
-  xformTemp.eM12 = xform1->eM11 * xform2->eM12 +
-    xform1->eM12 * xform2->eM22;
-  xformTemp.eM21 = xform1->eM21 * xform2->eM11 +
-    xform1->eM22 * xform2->eM21;
-  xformTemp.eM22 = xform1->eM21 * xform2->eM12 +
-    xform1->eM22 * xform2->eM22;
-  xformTemp.eDx  = xform1->eDx  * xform2->eM11 +
-    xform1->eDy  * xform2->eM21 + xform2->eDx;
-  xformTemp.eDy  = xform1->eDx  * xform2->eM12 +
-    xform1->eDy  * xform2->eM22 + xform2->eDy;
+  xformTemp.eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21;
+  xformTemp.eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22;
+  xformTemp.eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21;
+  xformTemp.eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22;
+  xformTemp.eDx  = xform1->eDx  * xform2->eM11 + xform1->eDy  * xform2->eM21 + xform2->eDx;
+  xformTemp.eDy  = xform1->eDx  * xform2->eM12 + xform1->eDy  * xform2->eM22 + xform2->eDy;
 
   /* Copy the result to xformResult */
   *XFormResult = xformTemp;
@@ -57,9 +51,9 @@ W32kGetGraphicsMode(HDC  hDC)
   
   dc = DC_HandleToPtr (hDC);
   if (!dc) 
-    {
-      return  0;
-    }
+  {
+    return  0;
+  }
   
   GraphicsMode = dc->w.GraphicsMode;
   DC_UnlockDC (hDC);
@@ -76,13 +70,13 @@ W32kGetWorldTransform(HDC  hDC,
   
   dc = DC_HandleToPtr (hDC);
   if (!dc)
-    {
-      return  FALSE;
-    }
+  {
+    return  FALSE;
+  }
   if (!XForm)
-    {
-      return  FALSE;
-    }
+  {
+    return  FALSE;
+  }
   *XForm = dc->w.xformWorld2Wnd;
   DC_UnlockDC (hDC);
     
@@ -108,22 +102,22 @@ W32kModifyWorldTransform(HDC  hDC,
   
   dc = DC_HandleToPtr (hDC);
   if (!dc)
-    {
-//      SetLastError( ERROR_INVALID_HANDLE );
-      return  FALSE;
-    }
+  {
+//    SetLastError( ERROR_INVALID_HANDLE );
+    return  FALSE;
+  }
   if (!XForm)
-    {
-      return FALSE;
-    }
+  {
+    return FALSE;
+  }
     
   /* Check that graphics mode is GM_ADVANCED */
   if (dc->w.GraphicsMode!=GM_ADVANCED)
-    {
-      return FALSE;
-    }
+  {
+    return FALSE;
+  }
   switch (Mode)
-    {
+  {
     case MWT_IDENTITY:
       dc->w.xformWorld2Wnd.eM11 = 1.0f;
       dc->w.xformWorld2Wnd.eM12 = 0.0f;
@@ -134,20 +128,16 @@ W32kModifyWorldTransform(HDC  hDC,
       break;
       
     case MWT_LEFTMULTIPLY:
-      W32kCombineTransform(&dc->w.xformWorld2Wnd, 
-                           XForm,
-                           &dc->w.xformWorld2Wnd );
+      W32kCombineTransform(&dc->w.xformWorld2Wnd, XForm, &dc->w.xformWorld2Wnd );
       break;
       
     case MWT_RIGHTMULTIPLY:
-      W32kCombineTransform(&dc->w.xformWorld2Wnd, 
-                           &dc->w.xformWorld2Wnd,
-                           XForm);
+      W32kCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, XForm);
       break;
       
     default:
       return FALSE;
-    }
+  }
   DC_UpdateXforms (dc);
   DC_UnlockDC (hDC);
 
@@ -208,9 +198,9 @@ W32kSetGraphicsMode(HDC  hDC,
   
   dc = DC_HandleToPtr (hDC);
   if (!dc)
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
 
   /* One would think that setting the graphics mode to GM_COMPATIBLE
    * would also reset the world transformation matrix to the unity
@@ -219,9 +209,9 @@ W32kSetGraphicsMode(HDC  hDC,
    */
   
   if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED)) 
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
   ret = dc->w.GraphicsMode;
   dc->w.GraphicsMode = Mode;
   DC_UnlockDC (hDC);
@@ -286,20 +276,20 @@ W32kSetWorldTransform(HDC  hDC,
   
   dc = DC_HandleToPtr (hDC);
   if (!dc)
-    {
-//      SetLastError( ERROR_INVALID_HANDLE );
-      return  FALSE;
-    }
+  {
+//    SetLastError( ERROR_INVALID_HANDLE );
+    return  FALSE;
+  }
   if (!XForm)
-    {
-      return  FALSE;
-    }
+  {
+    return  FALSE;
+  }
     
   /* Check that graphics mode is GM_ADVANCED */
   if (dc->w.GraphicsMode != GM_ADVANCED)
-    {
-      return  FALSE;
-    }
+  {
+    return  FALSE;
+  }
   dc->w.xformWorld2Wnd = *XForm;
   DC_UpdateXforms (dc);
   DC_UnlockDC (hDC);
index 1dd580c..2768ab5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: dc.c,v 1.18 2000/07/07 01:20:53 phreak Exp $
+/* $Id: dc.c,v 1.19 2001/03/31 15:35:08 jfilby Exp $
  *
  * DC.C - Device context functions
  * 
@@ -8,7 +8,6 @@
 #include <windows.h>
 #include <ddk/ntddk.h>
 
-/* FIXME: Surely we should just have one include file that includes all of these.. */
 #include <win32k/bitmaps.h>
 #include <win32k/coord.h>
 #include <win32k/driver.h>
 // #define NDEBUG
 #include <win32k/debug1.h>
 
-void TestEngXxx(PDC Dc)
-{
-  BRUSHOBJ     brushobj;
-  HBITMAP      GDIbmp;
-  SURFOBJ      *SurfObj, *GDIsurf;
-  XLATEOBJ     *RGBtoVGA16, *VGA16toRGB;
-  RECTL                DestBlt, myrect;
-  SIZEL                GDISize;
-  CLIPOBJ      *clipobj;
-  POINTL       SourcePnt;
-  INT          i;
-
-  brushobj.iSolidColor = 1;
-  SurfObj = AccessUserObject(Dc->Surface);
-
-  /* Create a GDI managed bitmap */
-  GDISize.cx = 100;
-  GDISize.cy = 100;
-
-  GDIbmp = EngCreateBitmap(GDISize, GDISize.cx * 3, BMF_24BPP, BMF_TOPDOWN,
-                           NULL);
-
-  // Get GDI surface's object
-  GDIsurf = AccessUserObject(GDIbmp);
-
-  /* Create color translation Xlates */
-
-  // Create color translation for RGB to the VGA's 16 colors
-  RGBtoVGA16 = EngCreateXlate(PAL_INDEXED, PAL_RGB,
-                              Dc->DevInfo.hpalDefault, NULL);
-
-  // Create color translation for RGB to the VGA's 16 colors
-  VGA16toRGB = EngCreateXlate(PAL_RGB, PAL_INDEXED,
-                              NULL, Dc->DevInfo.hpalDefault);
-
-  /* Line Tests */
-
-  // Diagonals
-  EngLineTo(SurfObj, NULL, &brushobj, 0, 0, 639, 479, NULL, NULL);
-  EngLineTo(SurfObj, NULL, &brushobj, 639, 0, 0, 479, NULL, NULL);
-
-  // Border
-  EngLineTo(SurfObj, NULL, &brushobj, 0,   0, 639, 0,   NULL, NULL);
-  EngLineTo(SurfObj, NULL, &brushobj, 639, 0, 639, 479, NULL, NULL);
-  EngLineTo(SurfObj, NULL, &brushobj, 639, 479, 0, 479, NULL, NULL);
-  EngLineTo(SurfObj, NULL, &brushobj, 0, 479,   0,   0, NULL, NULL);
-
-  /* Paint Tests */
-
-  // Colored blocks
-  for (i=0; i<16; i++)
-  {
-     myrect.left=10+i*20;
-     myrect.top=10;
-     myrect.right=30+i*20;
-     myrect.bottom=30;
-     clipobj = EngCreateClipRegion(1, &myrect, TC_RECTANGLES, NULL);
-     brushobj.iSolidColor = i;
-     EngPaint(SurfObj, clipobj, &brushobj, NULL, 0xFF);
-     EngDeleteClipRegion(clipobj);
-  }
-
-  /* BitBlt */
-
-  // Blt VGA to GDI
-  DestBlt.left=0; DestBlt.top=0; DestBlt.right=100, DestBlt.bottom=100;
-  SourcePnt.x=10; SourcePnt.y=10;
-  EngBitBlt(GDIsurf, SurfObj, NULL, NULL, VGA16toRGB,  &DestBlt, &SourcePnt,
-            NULL, NULL, NULL, NULL);
-
-  // Blt to VGA again
-  DestBlt.left=300; DestBlt.top=300; DestBlt.right=400, DestBlt.bottom=400;
-  SourcePnt.x=0; SourcePnt.y=0;
-  EngBitBlt(SurfObj, GDIsurf, NULL, NULL, RGBtoVGA16,  &DestBlt, &SourcePnt,
-            NULL, NULL, NULL, NULL);
-}
-
 /* FIXME: DCs should probably be thread safe  */
 
 /*
@@ -112,9 +34,9 @@ func_type STDCALL  func_name( HDC hdc ) \
   func_type  ft;                    \
   PDC  dc = DC_HandleToPtr( hdc );  \
   if (!dc)                          \
-    {                               \
-      return 0;                     \
-    }                               \
+  {                                 \
+    return 0;                       \
+  }                                 \
   ft = dc->dc_field;                \
   DC_UnlockDC(dc);                  \
   return ft;                        \
@@ -129,9 +51,9 @@ BOOL STDCALL  func_name( HDC hdc, LP##type pt ) \
 {                                   \
   PDC  dc = DC_HandleToPtr( hdc );  \
   if (!dc)                          \
-    {                               \
-      return FALSE;                 \
-    }                               \
+  {                                 \
+    return FALSE;                   \
+  }                                 \
   ((LPPOINT)pt)->x = dc->ret_x;     \
   ((LPPOINT)pt)->y = dc->ret_y;     \
   DC_UnlockDC(dc);                  \
@@ -144,25 +66,31 @@ INT STDCALL  func_name( HDC hdc, INT mode ) \
   INT  prevMode;                            \
   PDC  dc = DC_HandleToPtr( hdc );          \
   if(!dc)                                   \
-    {                                       \
-      return 0;                             \
-    }                                       \
-  if ((mode < min_val) || (mode > max_val))  \
-    {                                       \
-      return 0;                             \
-    }                                       \
-    prevMode = dc->dc_field;                \
-    dc->dc_field = mode;                    \
-    DC_UnlockDC(hdc);                          \
-    return prevMode;                        \
+  {                                         \
+    return 0;                               \
+  }                                         \
+  if ((mode < min_val) || (mode > max_val)) \
+  {                                         \
+    return 0;                               \
+  }                                         \
+  prevMode = dc->dc_field;                  \
+  dc->dc_field = mode;                      \
+  DC_UnlockDC(hdc);                         \
+  return prevMode;                          \
 }
 
 //  ---------------------------------------------------------  File Statics
 
+static HDC hDISPLAY_DC = NULL; // handle to the DISPLAY HDC
 static void  W32kSetDCState16(HDC  hDC, HDC  hDCSave);
 
 //  -----------------------------------------------------  Public Functions
 
+HDC RetrieveDisplayHDC()
+{
+  return hDISPLAY_DC;
+}
+
 BOOL STDCALL  W32kCancelDC(HDC  hDC)
 {
   UNIMPLEMENTED;
@@ -170,31 +98,37 @@ BOOL STDCALL  W32kCancelDC(HDC  hDC)
 
 HDC STDCALL  W32kCreateCompatableDC(HDC  hDC)
 {
-  PDC  NewDC, OrigDC;
+  PDC  NewDC, OrigDC = NULL;
   HBITMAP  hBitmap;
 
-  OrigDC = DC_HandleToPtr(hDC);
-  if (OrigDC == NULL)
+  if(hDC == NULL)
+  {
+    // The OrigDC is one the DC created to reference the DISPLAY (we assume such a DC exists)
+    if(hDISPLAY_DC != NULL)
+      OrigDC = DC_HandleToPtr(hDISPLAY_DC);
+  } else {
+    OrigDC = DC_HandleToPtr(hDC);
+    if (OrigDC == NULL)
     {
       return  0;
     }
-  
+  }
+
   /*  Allocate a new DC based on the original DC's device  */
   NewDC = DC_AllocDC(OrigDC->DriverName);
+
   if (NewDC == NULL) 
-    {
-      DC_UnlockDC(OrigDC);
-      
-      return  NULL;
-    }
-  DRIVER_ReferenceDriver (NewDC->DriverName);
-  
+  {
+    DC_UnlockDC(OrigDC);
+    return  NULL;
+    DRIVER_ReferenceDriver (NewDC->DriverName);
+  }
+
   /* Copy information from original DC to new DC  */
   NewDC->hSelf = NewDC;
 
   /* FIXME: Should this DC request its own PDEV?  */
   NewDC->PDev = OrigDC->PDev;
-
   NewDC->DMW = OrigDC->DMW;
   memcpy(NewDC->FillPatternSurfaces, 
          OrigDC->FillPatternSurfaces,
@@ -203,9 +137,9 @@ HDC STDCALL  W32kCreateCompatableDC(HDC  hDC)
   NewDC->DevInfo = OrigDC->DevInfo;
 
   /* FIXME: Should this DC request its own surface?  */
+  /* Yes, in fact, a 1x1 monochrome surface (to be implemented..) */
   NewDC->Surface = OrigDC->Surface;
 
-  NewDC->DriverFunctions = OrigDC->DriverFunctions;
   /* DriverName is copied in the AllocDC routine  */
   NewDC->DeviceDriver = OrigDC->DeviceDriver;
   NewDC->wndOrgX = OrigDC->wndOrgX;
@@ -221,16 +155,17 @@ HDC STDCALL  W32kCreateCompatableDC(HDC  hDC)
 
   /* Create default bitmap */
   if (!(hBitmap = W32kCreateBitmap( 1, 1, 1, 1, NULL )))
-    {
-      DC_FreeDC(NewDC);
-      DC_UnlockDC(OrigDC);
+  {
+    DC_FreeDC(NewDC);
+    DC_UnlockDC(OrigDC);
       
-      return NULL;
-    }
+    return NULL;
+  }
   NewDC->w.flags        = DC_MEMORY;
-  NewDC->w.bitsPerPixel = 1; /* FIXME: OrigDC->w.bitsPerPixel ? */
+  NewDC->w.bitsPerPixel = 1;
   NewDC->w.hBitmap      = hBitmap;
   NewDC->w.hFirstBitmap = hBitmap;
+  NewDC->w.hPalette = OrigDC->w.hPalette;
 
   DC_UnlockDC(NewDC);
   DC_UnlockDC(OrigDC);
@@ -247,76 +182,76 @@ HDC STDCALL  W32kCreateDC(LPCWSTR  Driver,
   PDC  NewDC;
   HDC  hDC = NULL;
   DRVENABLEDATA  DED;
-int i; // DELETEME
+  HDC hNewDC;
 
   /*  Check for existing DC object  */
   if ((NewDC = DC_FindOpenDC(Driver)) != NULL)
-    {
-      hDC = DC_PtrToHandle(NewDC);
-      return  W32kCreateCompatableDC(hDC);
-    }
+  {
+    hDC = DC_PtrToHandle(NewDC);
+    return  W32kCreateCompatableDC(hDC);
+  }
 
-DPRINT("NAME: %S\n", Driver);
+  DPRINT("NAME: %S\n", Driver); // FIXME: Should not crash if NULL
   
   /*  Allocate a DC object  */
   if ((NewDC = DC_AllocDC(Driver)) == NULL)
-    {
-      return  NULL;
-    }
+  {
+    return  NULL;
+  }
 
   /*  Open the miniport driver  */
   if ((NewDC->DeviceDriver = DRIVER_FindMPDriver(Driver)) == NULL)
-    {
-      DPRINT("FindMPDriver failed\n");
-      goto Failure;
-    }
+  {
+    DPRINT("FindMPDriver failed\n");
+    goto Failure;
+  }
 
   /*  Get the DDI driver's entry point  */
   /*  FIXME: Retrieve DDI driver name from registry */
   if ((GDEnableDriver = DRIVER_FindDDIDriver(L"\\??\\C:\\reactos\\system32\\drivers\\vgaddi.dll")) == NULL)
-    {
-      DPRINT("FindDDIDriver failed\n");
-      goto Failure;
-    }
+  {
+    DPRINT("FindDDIDriver failed\n");
+    goto Failure;
+  }
 
   /*  Call DDI driver's EnableDriver function  */
   RtlZeroMemory(&DED, sizeof(DED));
 
   if (!GDEnableDriver(DDI_DRIVER_VERSION, sizeof(DED), &DED))
-    {
-      DPRINT("DrvEnableDriver failed\n");
-      goto Failure;
-    }
-DPRINT("Building DDI Functions\n");
+  {
+    DPRINT("DrvEnableDriver failed\n");
+    goto Failure;
+  }
+  DPRINT("Building DDI Functions\n");
 
   /*  Construct DDI driver function dispatch table  */
   if (!DRIVER_BuildDDIFunctions(&DED, &NewDC->DriverFunctions))
-    {
-      DPRINT("BuildDDIFunctions failed\n");
-      goto Failure;
-    }
+  {
+    DPRINT("BuildDDIFunctions failed\n");
+    goto Failure;
+  }
 
   /*  Allocate a phyical device handle from the driver  */
   if (Device != NULL)
-    {
-DPRINT("Device in u: %u\n", Device);
-//      wcsncpy(NewDC->DMW.dmDeviceName, Device, DMMAXDEVICENAME); FIXME: this crashes everything?
-    }
+  {
+    DPRINT("Device in u: %u\n", Device);
+//    wcsncpy(NewDC->DMW.dmDeviceName, Device, DMMAXDEVICENAME); FIXME: this crashes everything?
+  }
   NewDC->DMW.dmSize = sizeof(NewDC->DMW);
   NewDC->DMW.dmFields = 0x000fc000;
 
   /* FIXME: get mode selection information from somewhere  */
   
   NewDC->DMW.dmLogPixels = 96;
-  NewDC->DMW.dmBitsPerPel = 8;
+  NewDC->DMW.dmBitsPerPel = 4;
   NewDC->DMW.dmPelsWidth = 640;
   NewDC->DMW.dmPelsHeight = 480;
   NewDC->DMW.dmDisplayFlags = 0;
   NewDC->DMW.dmDisplayFrequency = 0;
 
-  NewDC->w.bitsPerPixel = 8; // FIXME: set this here??
+  NewDC->w.bitsPerPixel = 4; // FIXME: set this here??
 
-DPRINT("Enabling PDev\n");
+  DPRINT("Enabling PDev\n");
 
   NewDC->PDev = NewDC->DriverFunctions.EnablePDev(&NewDC->DMW,
                                                   L"",
@@ -330,34 +265,39 @@ DPRINT("Enabling PDev\n");
                                                   L"",
                                                   NewDC->DeviceDriver);
   if (NewDC->PDev == NULL)
-    {
-      DPRINT("DrvEnablePDEV failed\n");
-      goto Failure;
-    }
+  {
+    DPRINT("DrvEnablePDEV failed\n");
+    goto Failure;
+  }
 
-DPRINT("calling completePDev\n");
+  DPRINT("calling completePDev\n");
 
   /*  Complete initialization of the physical device  */
   NewDC->DriverFunctions.CompletePDev(NewDC->PDev, NewDC);
 
-DPRINT("calling DRIVER_ReferenceDriver\n");
+  DPRINT("calling DRIVER_ReferenceDriver\n");
 
   DRIVER_ReferenceDriver (Driver);
 
-DPRINT("calling EnableSurface\n");
+  DPRINT("calling EnableSurface\n");
 
   /*  Enable the drawing surface  */
   NewDC->Surface = NewDC->DriverFunctions.EnableSurface(NewDC->PDev); // hsurf
+  NewDC->w.hPalette = NewDC->DevInfo.hpalDefault;
 
-DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel);
-
-  /* Test EngXxx functions */
-//  TestEngXxx(NewDC);
+  DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel);
 
   /*  Initialize the DC state  */
   DC_InitDC(NewDC);
+  hNewDC = DC_PtrToHandle(NewDC);
 
-  return  DC_PtrToHandle(NewDC);
+  // If we've created a DC for the DISPLAY, save the reference for later CreateCompatibleDC(NULL... usage
+  if(wcscmp(Driver, "DISPLAY")) // FIXME: this works.. but shouldn't we compare to L"DISPLAY" ? (which doesn't work..)
+  {
+    hDISPLAY_DC = hNewDC;
+  }
+
+  return hNewDC;
 
 Failure:
   DC_FreeDC(NewDC);
@@ -383,59 +323,60 @@ BOOL STDCALL W32kDeleteDC(HDC  DCHandle)
       return  FALSE;
     }
   DPRINT( "Deleting DC\n" );
-  if (!DRIVER_UnreferenceDriver (DCToDelete->DriverName))
-    {
-      DPRINT( "No more references to driver, reseting display\n" );
-      DCToDelete->DriverFunctions.DisableSurface(DCToDelete->PDev);
-      CHECKPOINT;
-      DCToDelete->DriverFunctions.AssertMode( DCToDelete->PDev, FALSE );
-      CHECKPOINT;
-      DCToDelete->DriverFunctions.DisablePDev(DCToDelete->PDev);
-    }
+  if ((!DRIVER_UnreferenceDriver (DCToDelete->DriverName)) &&
+      (!(DCToDelete->w.flags & DC_MEMORY))) // Don't reset the display if its a memory DC
+  {
+    DPRINT( "No more references to driver, reseting display\n" );
+    DCToDelete->DriverFunctions.DisableSurface(DCToDelete->PDev);
+    CHECKPOINT;
+    DCToDelete->DriverFunctions.AssertMode( DCToDelete->PDev, FALSE );
+    CHECKPOINT;
+    DCToDelete->DriverFunctions.DisablePDev(DCToDelete->PDev);
+  }
   CHECKPOINT;
   /*  First delete all saved DCs  */
   while (DCToDelete->saveLevel)
-    {
-      PDC  savedDC;
-      HDC  savedHDC;
+  {
+    PDC  savedDC;
+    HDC  savedHDC;
       
-      savedHDC = GDIOBJ_GetNextObject (DCHandle, GO_DC_MAGIC);
-      savedDC = DC_HandleToPtr (savedHDC);
-      if (savedDC == NULL)
-        {
-          break;
-        }
-      GDIOBJ_SetNextObject (DCHandle, GO_DC_MAGIC, GDIOBJ_GetNextObject (savedHDC, GO_DC_MAGIC));
-      DCToDelete->saveLevel--;
-      DC_UnlockDC (savedDC);
-      W32kDeleteDC (savedHDC);
+    savedHDC = GDIOBJ_GetNextObject (DCHandle, GO_DC_MAGIC);
+    savedDC = DC_HandleToPtr (savedHDC);
+    if (savedDC == NULL)
+    {
+      break;
     }
+    GDIOBJ_SetNextObject (DCHandle, GO_DC_MAGIC, GDIOBJ_GetNextObject (savedHDC, GO_DC_MAGIC));
+    DCToDelete->saveLevel--;
+    DC_UnlockDC (savedDC);
+    W32kDeleteDC (savedHDC);
+  }
   
   /*  Free GDI resources allocated to this DC  */
   if (!(DCToDelete->w.flags & DC_SAVED))
+  {
+    /*      DC_UnlockDC (DCToDelete);
+    W32kSelectObject (DCHandle, STOCK_BLACK_PEN);
+    W32kSelectObject (DCHandle, STOCK_WHITE_BRUSH);
+    W32kSelectObject (DCHandle, STOCK_SYSTEM_FONT);
+    DC_LockDC (DCHandle); W32kSelectObject does not recognize stock objects yet  */ 
+    if (DCToDelete->w.flags & DC_MEMORY) 
     {
-      /*      DC_UnlockDC (DCToDelete);
-      W32kSelectObject (DCHandle, STOCK_BLACK_PEN);
-      W32kSelectObject (DCHandle, STOCK_WHITE_BRUSH);
-      W32kSelectObject (DCHandle, STOCK_SYSTEM_FONT);
-      DC_LockDC (DCHandle); W32kSelectObject does not recognize stock objects yet  */ 
-      if (DCToDelete->w.flags & DC_MEMORY) 
-        {
-          W32kDeleteObject (DCToDelete->w.hFirstBitmap);
-        }
+      W32kDeleteObject (DCToDelete->w.hFirstBitmap);
     }
+  }
   if (DCToDelete->w.hClipRgn) 
-    {
-      W32kDeleteObject (DCToDelete->w.hClipRgn);
-    }
+  {
+    W32kDeleteObject (DCToDelete->w.hClipRgn);
+  }
   if (DCToDelete->w.hVisRgn) 
-    {
-      W32kDeleteObject (DCToDelete->w.hVisRgn);
-    }
+  {
+    W32kDeleteObject (DCToDelete->w.hVisRgn);
+  }
   if (DCToDelete->w.hGCClipRgn) 
-    {
-      W32kDeleteObject (DCToDelete->w.hGCClipRgn);
-    }
+  {
+    W32kDeleteObject (DCToDelete->w.hGCClipRgn);
+  }
 #if 0 /* FIXME */
   PATH_DestroyGdiPath (&DCToDelete->w.path);
 #endif
@@ -447,27 +388,27 @@ BOOL STDCALL W32kDeleteDC(HDC  DCHandle)
 
 BOOL STDCALL  W32kDeleteObject(HGDIOBJ hObject)
 {
-   PGDIOBJ Obj;
-   PGDIOBJHDR ObjHdr;
-
-   Obj = GDIOBJ_HandleToPtr( hObject, GO_MAGIC_DONTCARE );
-   if( !Obj )
+  PGDIOBJ Obj;
+  PGDIOBJHDR ObjHdr;
+
+  Obj = GDIOBJ_HandleToPtr( hObject, GO_MAGIC_DONTCARE );
+  if( !Obj )
+    return FALSE;
+  ObjHdr = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR));
+  switch( ObjHdr->wMagic )
+  {
+    case GO_BITMAP_MAGIC: {
+      DPRINT( "Deleting bitmap\n" );
+      ExFreePool( ((PBITMAPOBJ)Obj)->bitmap.bmBits );
+      BITMAPOBJ_FreeBitmap( Obj );
+      break;
+    }
+    default: {
+      DPRINT( "W32kDeleteObject: Deleting object of unknown type %x\n", ObjHdr->wMagic );
       return FALSE;
-   ObjHdr = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR));
-   switch( ObjHdr->wMagic )
-      {
-      case GO_BITMAP_MAGIC: {
-        DPRINT( "Deleting bitmap\n" );
-        ExFreePool( ((PBITMAPOBJ)Obj)->bitmap.bmBits );
-        BITMAPOBJ_FreeBitmap( Obj );
-        break;
-      }
-      default: {
-       DPRINT( "W32kDeleteObject: Deleting object of unknown type %x\n", ObjHdr->wMagic );
-       return FALSE;
-      }
-      }
-   return TRUE;
+    }
+  }
+  return TRUE;
 }
 
 INT STDCALL W32kDrawEscape(HDC  hDC,
@@ -505,14 +446,14 @@ BOOL STDCALL W32kGetDCOrgEx(HDC  hDC,
   DC * dc;
 
   if (!Point) 
-    {
-      return FALSE;
-    }
+  {
+    return FALSE;
+  }
   dc = DC_HandleToPtr(hDC);
   if (dc == NULL) 
-    {
-      return FALSE;
-    }
+  {
+    return FALSE;
+  }
 
   Point->x = Point->y = 0;
 
@@ -529,16 +470,16 @@ HDC STDCALL W32kGetDCState16(HDC  hDC)
     
   dc = DC_HandleToPtr(hDC);
   if (dc == NULL) 
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
   
   newdc = DC_AllocDC(NULL);
   if (newdc == NULL)
-    {
-      DC_UnlockDC(hDC);
-      return 0;
-    }
+  {
+    DC_UnlockDC(hDC);
+    return 0;
+  }
 
   newdc->w.flags            = dc->w.flags | DC_SAVED;
 #if 0
@@ -608,14 +549,14 @@ HDC STDCALL W32kGetDCState16(HDC  hDC)
   newdc->w.hGCClipRgn = newdc->w.hVisRgn = 0;
 #endif
   if (dc->w.hClipRgn)
-    {
-      newdc->w.hClipRgn = W32kCreateRectRgn( 0, 0, 0, 0 );
-      W32kCombineRgn( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
-    }
+  {
+    newdc->w.hClipRgn = W32kCreateRectRgn( 0, 0, 0, 0 );
+    W32kCombineRgn( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
+  }
   else
-    {
-      newdc->w.hClipRgn = 0;
-    }
+  {
+    newdc->w.hClipRgn = 0;
+  }
   DC_UnlockDC(hDC);
   
   return  newdc->hSelf;
@@ -630,64 +571,64 @@ INT STDCALL W32kGetDeviceCaps(HDC  hDC,
     
   dc = DC_HandleToPtr(hDC);
   if (dc == NULL) 
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
 
   /* Device capabilities for the printer */
   switch (Index)
-    {
+  {
     case PHYSICALWIDTH:
       if(W32kEscape(hDC, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0)
-        {
-          return pt.x;
-        }
+      {
+        return pt.x;
+      }
       break;
       
     case PHYSICALHEIGHT:
       if(W32kEscape(hDC, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0)
-        {
-          return pt.y;
-        }
+      {
+        return pt.y;
+      }
       break;
       
     case PHYSICALOFFSETX:
       if(W32kEscape(hDC, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0)
-        {
-          return pt.x;
-        }
+      {
+        return pt.x;
+      }
       break;
       
     case PHYSICALOFFSETY:
       if(W32kEscape(hDC, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0)
-        {
-          return pt.y;
-        }
+      {
+        return pt.y;
+      }
       break;
       
     case SCALINGFACTORX:
       if(W32kEscape(hDC, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0)
-        {
-          return pt.x;
-        }
+      {
+        return pt.x;
+      }
       break;
       
     case SCALINGFACTORY:
       if(W32kEscape(hDC, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0)
-        {
-          return pt.y;
-        }
+      {
+        return pt.y;
+      }
       break;
-    }
+  }
 
-    if ((Index < 0) || (Index > sizeof(DEVICECAPS) - sizeof(WORD)))
-    {
-      DC_UnlockDC(hDC);
-      return 0;
-    }
+  if ((Index < 0) || (Index > sizeof(DEVICECAPS) - sizeof(WORD)))
+  {
+    DC_UnlockDC(hDC);
+    return 0;
+  }
     
- DPRINT("(%04x,%d): returning %d\n",
-        hDC, Index, *(WORD *)(((char *)dc->w.devCaps) + Index));
 DPRINT("(%04x,%d): returning %d\n",
+         hDC, Index, *(WORD *)(((char *)dc->w.devCaps) + Index));
   ret = *(WORD *)(((char *)dc->w.devCaps) + Index);
 
   DC_UnlockDC(hDC);
@@ -697,27 +638,155 @@ INT STDCALL W32kGetDeviceCaps(HDC  hDC,
 DC_GET_VAL( INT, W32kGetMapMode, w.MapMode )
 DC_GET_VAL( INT, W32kGetPolyFillMode, w.polyFillMode )
 
-INT STDCALL  W32kGetObject(HGDIOBJ  hGDIObj,
-                           INT  BufSize,
-                           LPVOID  Object)
+INT STDCALL W32kGetObjectA(HANDLE handle, INT count, LPVOID buffer)
 {
-  UNIMPLEMENTED;
+  GDIOBJHDR * ptr;
+  INT result = 0;
+
+  if (!count) return 0;
+  if (!(ptr = GDIOBJ_HandleToPtr(handle, GO_MAGIC_DONTCARE))) return 0;
+
+  switch(ptr->wMagic)
+  {
+/*    case GO_PEN_MAGIC:
+      result = PEN_GetObject((PENOBJ *)ptr, count, buffer);
+      break;
+    case GO_BRUSH_MAGIC: 
+      result = BRUSH_GetObject((BRUSHOBJ *)ptr, count, buffer);
+      break; */
+    case GO_BITMAP_MAGIC: 
+      result = BITMAP_GetObject((BITMAPOBJ *)ptr, count, buffer);
+      break;
+/*    case GO_FONT_MAGIC:
+      result = FONT_GetObjectA((FONTOBJ *)ptr, count, buffer);
+
+      // FIXME: Fix the LOGFONT structure for the stock fonts
+
+      if ( (handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE) )
+        FixStockFontSizeA(handle, count, buffer);
+      break;
+    case GO_PALETTE_MAGIC:
+      result = PALETTE_GetObject((PALETTEOBJ *)ptr, count, buffer);
+      break; */
+
+    case GO_REGION_MAGIC:
+    case GO_DC_MAGIC:
+    case GO_DISABLED_DC_MAGIC:
+    case GO_META_DC_MAGIC:
+    case GO_METAFILE_MAGIC:
+    case GO_METAFILE_DC_MAGIC:
+    case GO_ENHMETAFILE_MAGIC:
+    case GO_ENHMETAFILE_DC_MAGIC:
+      // FIXME("Magic %04x not implemented\n", ptr->wMagic);
+      break;
+
+    default:
+      DbgPrint("Invalid GDI Magic %04x\n", ptr->wMagic);
+      break;
+  }
+  GDIOBJ_UnlockObject(handle);
+  return result;
+}
+
+INT STDCALL W32kGetObjectW(HANDLE handle, INT count, LPVOID buffer)
+{
+  GDIOBJHDR * ptr;
+  INT result = 0;
+
+  if (!count) return 0;
+  if (!(ptr = GDIOBJ_HandleToPtr(handle, GO_MAGIC_DONTCARE))) return 0;
+
+  switch(ptr->wMagic)
+  {
+/*    case GO_PEN_MAGIC:
+      result = PEN_GetObject((PENOBJ *)ptr, count, buffer);
+      break;
+    case GO_BRUSH_MAGIC: 
+      result = BRUSH_GetObject((BRUSHOBJ *)ptr, count, buffer);
+       break; */
+    case GO_BITMAP_MAGIC: 
+      result = BITMAP_GetObject((BITMAPOBJ *)ptr, count, buffer);
+      break;
+/*    case GO_FONT_MAGIC:
+      result = FONT_GetObjectW((FONTOBJ *)ptr, count, buffer);
+
+      // Fix the LOGFONT structure for the stock fonts
+
+      if ( (handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE) )
+      FixStockFontSizeW(handle, count, buffer);
+    break;
+    case GO_PALETTE_MAGIC:
+      result = PALETTE_GetObject((PALETTEOBJ *)ptr, count, buffer);
+      break; */
+    default:
+      // FIXME("Magic %04x not implemented\n", ptr->wMagic);
+      break;
+  }
+  GDIOBJ_UnlockObject(handle);
+  return result;
 }
  
-DWORD STDCALL  W32kGetObjectType(HGDIOBJ  hGDIObj)
+INT STDCALL W32kGetObject(HANDLE handle, INT count, LPVOID buffer)
 {
-  UNIMPLEMENTED;
+  return W32kGetObjectW(handle, count, buffer);
 }
 
-DC_GET_VAL( INT, W32kGetRelAbs, w.relAbsMode )
-DC_GET_VAL( INT, W32kGetROP2, w.ROPmode )
-DC_GET_VAL( INT, W32kGetStretchBltMode, w.stretchBltMode )
-
-HGDIOBJ STDCALL  W32kGetStockObject(INT  Object)
+DWORD STDCALL W32kGetObjectType(HANDLE handle)
 {
-  UNIMPLEMENTED;
+  GDIOBJHDR * ptr;
+  INT result = 0;
+
+  if (!(ptr = GDIOBJ_HandleToPtr(handle, GO_MAGIC_DONTCARE))) return 0;
+    
+  switch(ptr->wMagic)
+  {
+    case GO_PEN_MAGIC:
+      result = OBJ_PEN;
+      break;
+    case GO_BRUSH_MAGIC: 
+      result = OBJ_BRUSH;
+      break;
+    case GO_BITMAP_MAGIC: 
+      result = OBJ_BITMAP;
+      break;
+    case GO_FONT_MAGIC:
+      result = OBJ_FONT;
+      break;
+    case GO_PALETTE_MAGIC:
+      result = OBJ_PAL;
+      break;
+    case GO_REGION_MAGIC:
+      result = OBJ_REGION;
+      break;
+    case GO_DC_MAGIC:
+      result = OBJ_DC;
+      break;
+    case GO_META_DC_MAGIC:
+      result = OBJ_METADC;
+      break;
+    case GO_METAFILE_MAGIC:
+      result = OBJ_METAFILE;
+      break;
+    case GO_METAFILE_DC_MAGIC:
+     result = OBJ_METADC;
+      break;
+    case GO_ENHMETAFILE_MAGIC:
+      result = OBJ_ENHMETAFILE;
+      break;
+    case GO_ENHMETAFILE_DC_MAGIC:
+      result = OBJ_ENHMETADC;
+      break;
+    default:
+      // FIXME("Magic %04x not implemented\n", ptr->wMagic);
+      break;
+  }
+  GDIOBJ_UnlockObject(handle);
+  return result;
 }
 
+DC_GET_VAL( INT, W32kGetRelAbs, w.relAbsMode )
+DC_GET_VAL( INT, W32kGetROP2, w.ROPmode )
+DC_GET_VAL( INT, W32kGetStretchBltMode, w.stretchBltMode )
 DC_GET_VAL( UINT, W32kGetTextAlign, w.textAlign )
 DC_GET_VAL( COLORREF, W32kGetTextColor, w.textColor )
 DC_GET_VAL_EX( W32kGetViewportExtEx, vportExtX, vportExtY, SIZE )
@@ -737,49 +806,47 @@ BOOL STDCALL W32kRestoreDC(HDC  hDC, INT  SaveLevel)
 
   dc = DC_HandleToPtr(hDC);
   if(!dc) 
-    {
-      return FALSE;
-    }
+  {
+    return FALSE;
+  }
   
   if (SaveLevel == -1) 
-    {
-      SaveLevel = dc->saveLevel;
-    }
+  {
+    SaveLevel = dc->saveLevel;
+  }
   
   if ((SaveLevel < 1) || (SaveLevel > dc->saveLevel))
-    {
-      DC_UnlockDC(hDC);
-      
-      return FALSE;
-    }
+  {
+    DC_UnlockDC(hDC);
+    return FALSE;
+  }
     
   success = TRUE;
   while (dc->saveLevel >= SaveLevel)
-    {
-      HDC hdcs = GDIOBJ_GetNextObject (hDC, GO_DC_MAGIC);
+  {
+    HDC hdcs = GDIOBJ_GetNextObject (hDC, GO_DC_MAGIC);
       
-      dcs = DC_HandleToPtr (hdcs);
-      if (dcs == NULL)
+    dcs = DC_HandleToPtr (hdcs);
+    if (dcs == NULL)
+    {
+      DC_UnlockDC (hDC);
+      return FALSE;
+    }
+    GDIOBJ_SetNextObject (hDC, GO_DC_MAGIC, GDIOBJ_GetNextObject (hdcs, GO_DC_MAGIC));
+    if (--dc->saveLevel < SaveLevel)
+      {
+        W32kSetDCState16 (hDC, hdcs);
+#if 0
+        if (!PATH_AssignGdiPath( &dc->w.path, &dcs->w.path ))
         {
-          DC_UnlockDC (hDC);
-          
-          return FALSE;
+          /* FIXME: This might not be quite right, since we're
+           * returning FALSE but still destroying the saved DC state */
+          success = FALSE;
         }
-      GDIOBJ_SetNextObject (hDC, GO_DC_MAGIC, GDIOBJ_GetNextObject (hdcs, GO_DC_MAGIC));
-      if (--dc->saveLevel < SaveLevel)
-        {
-          W32kSetDCState16 (hDC, hdcs);
-#if 0
-          if (!PATH_AssignGdiPath( &dc->w.path, &dcs->w.path ))
-            {
-              /* FIXME: This might not be quite right, since we're
-               * returning FALSE but still destroying the saved DC state */
-              success = FALSE;
-            }
 #endif
-        }
-      W32kDeleteDC (hdcs);
-    }
+      }
+    W32kDeleteDC (hdcs);
+  }
   DC_UnlockDC (hDC);
   
   return  success;
@@ -793,16 +860,15 @@ INT STDCALL W32kSaveDC(HDC  hDC)
 
   dc = DC_HandleToPtr (hDC);
   if (dc == NULL)
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
 
   if (!(hdcs = W32kGetDCState16 (hDC)))
-    {
-      DC_UnlockDC (hDC);
-      
-      return 0;
-    }
+  {
+    DC_UnlockDC (hDC);
+    return 0;
+  }
   dcs = DC_HandleToPtr (hdcs);
 
 #if 0
@@ -813,12 +879,12 @@ INT STDCALL W32kSaveDC(HDC  hDC)
      * when copying paths).
      */
   if (!PATH_AssignGdiPath (&dcs->w.path, &dc->w.path))
-    {
-      DC_UnlockDC (hdc);
-      DC_UnlockDC (hdcs);
-      W32kDeleteDC (hdcs);
-      return 0;
-    }
+  {
+    DC_UnlockDC (hdc);
+    DC_UnlockDC (hdcs);
+    W32kDeleteDC (hdcs);
+    return 0;
+  }
 #endif
     
   GDIOBJ_SetNextObject (hdcs, GO_DC_MAGIC, GDIOBJ_GetNextObject (hDC, GO_DC_MAGIC));
@@ -832,61 +898,81 @@ INT STDCALL W32kSaveDC(HDC  hDC)
 
 HGDIOBJ STDCALL W32kSelectObject(HDC  hDC, HGDIOBJ  hGDIObj)
 {
-   HGDIOBJ   objOrg;
-   GDIOBJHDR *GdiObjHdr;
-   BITMAPOBJ *pb;
-   PSURFOBJ  surfobj;
-   PSURFGDI  surfgdi;
-   PDC dc;
-
-   if(!hDC || !hGDIObj) return NULL;
-
-   dc = DC_HandleToPtr(hDC);
-   GdiObjHdr = hGDIObj;
-
-   // FIXME: Get object handle from GDIObj and use it instead of GDIObj below?
-
-   switch(GdiObjHdr->wMagic) {
-      case GO_PEN_MAGIC:
-         objOrg = (HGDIOBJ)dc->w.hPen;
-         dc->w.hPen = hGDIObj;
-         break;
-      case GO_BRUSH_MAGIC:
-         objOrg = (HGDIOBJ)dc->w.hBrush;
-         dc->w.hBrush = (BRUSHOBJ *)GdiObjHdr;
-         break;
+  HGDIOBJ   objOrg;
+  GDIOBJHDR *GdiObjHdr;
+  BITMAPOBJ *pb;
+  PSURFOBJ  surfobj;
+  PSURFGDI  surfgdi;
+  PDC dc;
+  PPENOBJ pen;
+  PXLATEOBJ XlateObj;
+  PPALGDI PalGDI;
+
+  if(!hDC || !hGDIObj) return NULL;
+
+  dc = DC_HandleToPtr(hDC);
+  GdiObjHdr = hGDIObj;
+
+  // FIXME: Get object handle from GDIObj and use it instead of GDIObj below?
+
+  switch(GdiObjHdr->wMagic) {
+    case GO_PEN_MAGIC:
+      objOrg = (HGDIOBJ)dc->w.hPen;
+      dc->w.hPen = hGDIObj;
+
+      // Convert the color of the pen to the format of the DC
+      PalGDI = AccessInternalObject(dc->w.hPalette);
+      XlateObj = EngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL);
+      pen = GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC);
+      pen->logpen.lopnColor = XLATEOBJ_iXlate(XlateObj, pen->logpen.lopnColor);
+      break;
+    case GO_BRUSH_MAGIC:
+      objOrg = (HGDIOBJ)dc->w.hBrush;
+      dc->w.hBrush = (BRUSHOBJ *)GdiObjHdr;
+      break;
       case GO_FONT_MAGIC:
-         objOrg = (HGDIOBJ)dc->w.hFont;
-         dc->w.hFont = (FONTOBJ *)GdiObjHdr;
-         break;
-      case GO_BITMAP_MAGIC:
-         // must be memory dc to select bitmap
-         if (!(dc->w.flags & DC_MEMORY))
-            return NULL;
-         objOrg = (HGDIOBJ)dc->w.hBitmap;
-
-         // setup mem dc for drawing into bitmap
-         pb   = BITMAPOBJ_HandleToPtr(GdiObjHdr);
-         surfobj = ExAllocatePool(PagedPool, sizeof(SURFOBJ));
-         surfgdi = ExAllocatePool(PagedPool, sizeof(SURFGDI));
-         BitmapToSurf(surfgdi, surfobj, pb);
-
-         dc->w.hBitmap = (BITMAPOBJ *)GdiObjHdr;
-         dc->Surface   = CreateGDIHandle(surfgdi, surfobj);
-
-         break;
+      objOrg = (HGDIOBJ)dc->w.hFont;
+      dc->w.hFont = (FONTOBJ *)GdiObjHdr;
+      break;
+    case GO_BITMAP_MAGIC:
+      // must be memory dc to select bitmap
+      if (!(dc->w.flags & DC_MEMORY)) return NULL;
+      objOrg = (HGDIOBJ)dc->w.hBitmap;
+
+      // setup mem dc for drawing into bitmap
+      pb   = BITMAPOBJ_HandleToPtr(GdiObjHdr);
+      surfobj = ExAllocatePool(PagedPool, sizeof(SURFOBJ));
+      surfgdi = ExAllocatePool(PagedPool, sizeof(SURFGDI));
+
+      BitmapToSurf(hDC, surfgdi, surfobj, pb); // Put the bitmap in a surface
+      dc->w.hBitmap = CreateGDIHandle(surfgdi, surfobj); // Assign the DC's bitmap
+      dc->Surface = dc->w.hBitmap;
+
+      // if we're working with a DIB, get the palette [fixme: only create if the selected palette is null]
+      if(pb->dib)
+      {
+        if((pb->dib->dsBmih.biBitCount > 8) && (pb->dib->dsBmih.biBitCount < 24))
+        {
+          dc->w.hPalette = EngCreatePalette(PAL_BITFIELDS, pb->dib->dsBmih.biClrUsed, NULL, 0, 0, 0);
+        } else
+        if(pb->dib->dsBmih.biBitCount >= 24)
+        {
+          dc->w.hPalette = EngCreatePalette(PAL_RGB, pb->dib->dsBmih.biClrUsed, NULL, 0, 0, 0);
+        }
+      }
+      break;
 #if UPDATEREGIONS
-      case GO_REGION_MAGIC:
-         /* objOrg = (HGDIOBJ)hDC->region; */
-         objOrg = NULL;        /* FIXME? hDC->region is destroyed below */
-         SelectClipRgn(hDC, (HRGN)GdiObjHdr);
-         break;
+    case GO_REGION_MAGIC:
+      /* objOrg = (HGDIOBJ)hDC->region; */
+      objOrg = NULL; /* FIXME? hDC->region is destroyed below */
+      SelectClipRgn(hDC, (HRGN)GdiObjHdr);
+      break;
 #endif
-      default:
+    default:
       return NULL;
-   }
+  }
 
-   return objOrg;
+  return objOrg;
 }
 
 DC_SET_MODE( W32kSetBkMode, w.backgroundMode, TRANSPARENT, OPAQUE ) 
@@ -901,9 +987,9 @@ COLORREF STDCALL W32kSetBkColor(HDC hDC, COLORREF color)
   PDC  dc = DC_HandleToPtr(hDC);
   
   if (!dc) 
-    {
-      return 0x80000000;
-    }
+  {
+    return 0x80000000;
+  }
   
   oldColor = dc->w.backgroundColor;
   dc->w.backgroundColor = color;
@@ -918,24 +1004,22 @@ static void  W32kSetDCState16(HDC  hDC, HDC  hDCSave)
     
   dc = DC_HandleToPtr(hDC);
   if (dc == NULL)
-    {
-      return;
-    }
+  {
+    return;
+  }
   
   dcs = DC_HandleToPtr(hDCSave);
   if (dcs == NULL)
-    {
-      DC_UnlockDC(hDC);
-      
-      return;
-    }
+  {
+    DC_UnlockDC(hDC);
+    return;
+  }
   if (!dcs->w.flags & DC_SAVED)
-    {
-      DC_UnlockDC(hDC);
-      DC_UnlockDC(hDCSave);
-      
-      return;
-    }
+  {
+    DC_UnlockDC(hDC);
+    DC_UnlockDC(hDCSave);
+    return;
+  }
 
   dc->w.flags            = dcs->w.flags & ~DC_SAVED;
 
@@ -993,28 +1077,28 @@ static void  W32kSetDCState16(HDC  hDC, HDC  hDCSave)
   dc->vportExtY          = dcs->vportExtY;
   
   if (!(dc->w.flags & DC_MEMORY)) 
-    {
-      dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
-    }
+  {
+    dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
+  }
   
 #if 0
   if (dcs->w.hClipRgn)
+  {
+    if (!dc->w.hClipRgn) 
     {
-      if (!dc->w.hClipRgn) 
-        {
-          dc->w.hClipRgn = W32kCreateRectRgn( 0, 0, 0, 0 );
-        }
-      W32kCombineRgn( dc->w.hClipRgn, dcs->w.hClipRgn, 0, RGN_COPY );
+      dc->w.hClipRgn = W32kCreateRectRgn( 0, 0, 0, 0 );
     }
+    W32kCombineRgn( dc->w.hClipRgn, dcs->w.hClipRgn, 0, RGN_COPY );
+  }
   else
+  {
+    if (dc->w.hClipRgn) 
     {
-      if (dc->w.hClipRgn) 
-        {
-          W32kDeleteObject( dc->w.hClipRgn );
-        }
-      
-      dc->w.hClipRgn = 0;
+      W32kDeleteObject( dc->w.hClipRgn );
     }
+      
+    dc->w.hClipRgn = 0;
+  }
   CLIPPING_UpdateGCRegion( dc );
 #endif
   
@@ -1041,23 +1125,29 @@ PDC  DC_AllocDC(LPCWSTR  Driver)
   
   NewDC = (PDC) GDIOBJ_AllocObject(sizeof(DC), GO_DC_MAGIC);
   if (NewDC == NULL)
-    {
-      return  NULL;
-    }
+  {
+    return  NULL;
+  }
   if (Driver != NULL)
-    {
-      NewDC->DriverName = ExAllocatePool(PagedPool, 
-                                         (wcslen(Driver) + 1) * sizeof(WCHAR));
-      wcscpy(NewDC->DriverName, Driver);
-    }
+  {
+    NewDC->DriverName = ExAllocatePool(PagedPool, (wcslen(Driver) + 1) * sizeof(WCHAR));
+    wcscpy(NewDC->DriverName, Driver);
+  }
   
   return  NewDC;
 }
 
 PDC  DC_FindOpenDC(LPCWSTR  Driver)
 {
-  /*  FIXME  */
-  return  NULL;
+  /*  FIXME: This is just a hack to return the pointer to the DISPLAY DC.. must cater for others too!  */
+
+  if(wcscmp(Driver, "DISPLAY"))
+  {
+    return DC_HandleToPtr(hDISPLAY_DC);
+  }
+
+  return NULL;
+
 }
 
 void  DC_InitDC(PDC  DCToInit)
@@ -1078,9 +1168,9 @@ void  DC_FreeDC(PDC  DCToFree)
 {
   ExFreePool(DCToFree->DriverName);
   if (!GDIOBJ_FreeObject((PGDIOBJ)DCToFree, GO_DC_MAGIC))
-    {
-       DPRINT("DC_FreeDC failed\n");
-    }
+  {
+    DPRINT("DC_FreeDC failed\n");
+  }
 }
 
 void 
@@ -1096,19 +1186,14 @@ DC_UpdateXforms(PDC  dc)
   xformWnd2Vport.eM12 = 0.0;
   xformWnd2Vport.eM21 = 0.0;
   xformWnd2Vport.eM22 = scaleY;
-  xformWnd2Vport.eDx  = (FLOAT)dc->vportOrgX -
-    scaleX * (FLOAT)dc->wndOrgX;
-  xformWnd2Vport.eDy  = (FLOAT)dc->vportOrgY -
-    scaleY * (FLOAT)dc->wndOrgY;
+  xformWnd2Vport.eDx  = (FLOAT)dc->vportOrgX - scaleX * (FLOAT)dc->wndOrgX;
+  xformWnd2Vport.eDy  = (FLOAT)dc->vportOrgY - scaleY * (FLOAT)dc->wndOrgY;
   
   /* Combine with the world transformation */
-  W32kCombineTransform(&dc->w.xformWorld2Vport, 
-                       &dc->w.xformWorld2Wnd,
-                       &xformWnd2Vport );
+  W32kCombineTransform(&dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd, &xformWnd2Vport);
   
   /* Create inverse of world-to-viewport transformation */
-  dc->w.vport2WorldValid = DC_InvertXform(&dc->w.xformWorld2Vport,
-                                          &dc->w.xformVport2World);
+  dc->w.vport2WorldValid = DC_InvertXform(&dc->w.xformWorld2Vport, &dc->w.xformVport2World);
 }
 
 BOOL 
@@ -1117,21 +1202,18 @@ DC_InvertXform(const XFORM *xformSrc,
 {
   FLOAT  determinant;
   
-  determinant = xformSrc->eM11*xformSrc->eM22 -
-    xformSrc->eM12*xformSrc->eM21;
+  determinant = xformSrc->eM11*xformSrc->eM22 - xformSrc->eM12*xformSrc->eM21;
   if (determinant > -1e-12 && determinant < 1e-12)
-    {
-      return  FALSE;
-    }
+  {
+    return  FALSE;
+  }
   
   xformDest->eM11 =  xformSrc->eM22 / determinant;
   xformDest->eM12 = -xformSrc->eM12 / determinant;
   xformDest->eM21 = -xformSrc->eM21 / determinant;
   xformDest->eM22 =  xformSrc->eM11 / determinant;
-  xformDest->eDx  = -xformSrc->eDx * xformDest->eM11 -
-    xformSrc->eDy * xformDest->eM21;
-  xformDest->eDy  = -xformSrc->eDx * xformDest->eM12 -
-    xformSrc->eDy * xformDest->eM22;
+  xformDest->eDx  = -xformSrc->eDx * xformDest->eM11 - xformSrc->eDy * xformDest->eM21;
+  xformDest->eDy  = -xformSrc->eDx * xformDest->eM12 - xformSrc->eDy * xformDest->eM22;
   
   return  TRUE;
 }
diff --git a/reactos/subsys/win32k/objects/dib.c b/reactos/subsys/win32k/objects/dib.c
new file mode 100644 (file)
index 0000000..9dd584c
--- /dev/null
@@ -0,0 +1,703 @@
+#undef WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdlib.h>
+#include <win32k/bitmaps.h>
+#include <win32k/debug.h>
+#include <debug.h>
+#include "../eng/objects.h"
+#include <ntos/minmax.h>
+
+UINT STDCALL W32kSetDIBColorTable(HDC  hDC,
+                           UINT  StartIndex,
+                           UINT  Entries,
+                           CONST RGBQUAD  *Colors)
+{
+  PDC dc;
+  PALETTEENTRY * palEntry;
+  PPALOBJ palette;
+  RGBQUAD *end;
+
+  if (!(dc = AccessUserObject(hDC))) return 0;
+
+  if (!(palette = AccessUserObject(dc->DevInfo.hpalDefault)))
+  {
+//    GDI_ReleaseObj( hdc );
+    return 0;
+  }
+
+  // Transfer color info
+
+  if (dc->w.bitsPerPixel <= 8) {
+    palEntry = palette->logpalette.palPalEntry + StartIndex;
+    if (StartIndex + Entries > (1 << dc->w.bitsPerPixel))
+      Entries = (1 << dc->w.bitsPerPixel) - StartIndex;
+
+    if (StartIndex + Entries > palette->logpalette.palNumEntries)
+      Entries = palette->logpalette.palNumEntries - StartIndex;
+
+    for (end = Colors + Entries; Colors < end; palEntry++, Colors++)
+    {
+      palEntry->peRed   = Colors->rgbRed;
+      palEntry->peGreen = Colors->rgbGreen;
+      palEntry->peBlue  = Colors->rgbBlue;
+    }
+  } else {
+    Entries = 0;
+  }
+
+//  GDI_ReleaseObj(dc->DevInfo.hpalDefault);
+//  GDI_ReleaseObj(hdc);
+
+  return Entries;
+}
+
+// Converts a DIB to a device-dependent bitmap
+INT STDCALL W32kSetDIBits(HDC  hDC,
+                   HBITMAP  hBitmap,
+                   UINT  StartScan,
+                   UINT  ScanLines,
+                   CONST VOID  *Bits,
+                   CONST BITMAPINFO  *bmi,
+                   UINT  ColorUse)
+{
+  DC *dc;
+  BITMAPOBJ *bitmap;
+  HBITMAP SourceBitmap, DestBitmap;
+  INT result;
+  BOOL copyBitsResult;
+  PSURFOBJ DestSurf, SourceSurf;
+  PSURFGDI DestGDI;
+  SIZEL        SourceSize;
+  POINTL ZeroPoint;
+  RECTL        DestRect;
+  PXLATEOBJ XlateObj;
+  PPALGDI hDCPalette;
+  RGBQUAD *lpRGB;
+  HPALETTE DDB_Palette, DIB_Palette;
+  USHORT DDB_Palette_Type, DIB_Palette_Type;
+
+
+  // Check parameters
+  if (!(dc = DC_HandleToPtr(hDC))) return 0;
+
+  if (!(bitmap = (BITMAPOBJ *)GDIOBJ_HandleToPtr(hBitmap, GO_BITMAP_MAGIC)))
+  {
+    // GDI_ReleaseObj(hDC);
+    return 0;
+  }
+
+  // Get RGB values
+  if (ColorUse == DIB_PAL_COLORS) 
+    lpRGB = DIB_MapPaletteColors(hDC, bmi);
+  else
+    lpRGB = &bmi->bmiColors[0];
+
+  // Create a temporary surface for the destination bitmap
+  DestSurf   = ExAllocatePool(PagedPool, sizeof(SURFOBJ));
+  DestGDI    = ExAllocatePool(PagedPool, sizeof(SURFGDI));
+  DestBitmap = CreateGDIHandle(DestGDI, DestSurf);
+
+  BitmapToSurf(hDC, DestGDI, DestSurf, bitmap);
+
+  // Create source surface
+  SourceSize.cx = bmi->bmiHeader.biWidth;
+  SourceSize.cy = bmi->bmiHeader.biHeight;
+  SourceBitmap = EngCreateBitmap(SourceSize, DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount),
+                                 BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
+                                 0, Bits);
+  SourceSurf = AccessUserObject(SourceBitmap);
+
+  // Destination palette obtained from the hDC
+  hDCPalette = AccessInternalObject(dc->DevInfo.hpalDefault);
+  DDB_Palette_Type = hDCPalette->Mode;
+  DDB_Palette = dc->DevInfo.hpalDefault;
+
+  // Source palette obtained from the BITMAPINFO
+  DIB_Palette = BuildDIBPalette(bmi, &DIB_Palette_Type);
+
+  // Determine XLATEOBJ for color translation
+  XlateObj = EngCreateXlate(DDB_Palette_Type, DIB_Palette_Type, DDB_Palette, DIB_Palette);
+
+  // Determine destination rectangle and source point
+  ZeroPoint.x = 0;
+  ZeroPoint.y = 0;
+  DestRect.top = 0;
+  DestRect.left        = 0;
+  DestRect.right       = SourceSize.cx;
+  DestRect.bottom      = SourceSize.cy;
+
+  copyBitsResult = EngCopyBits(DestSurf, SourceSurf, NULL, XlateObj, &DestRect, &ZeroPoint);
+
+  // Clean up
+  EngDeleteSurface(SourceBitmap);
+  EngDeleteSurface(DestBitmap);
+
+//  if (ColorUse == DIB_PAL_COLORS) 
+//    WinFree((LPSTR)lpRGB);
+
+//  GDI_ReleaseObj(hBitmap); unlock?
+//  GDI_ReleaseObj(hDC);
+
+  return result;
+}
+
+INT STDCALL W32kSetDIBitsToDevice(HDC  hDC,
+                           INT  XDest,
+                           INT  YDest,
+                           DWORD  Width,
+                           DWORD  Height,
+                           INT  XSrc,
+                           INT  YSrc,
+                           UINT  StartScan,
+                           UINT  ScanLines,
+                           CONST VOID  *Bits,
+                           CONST BITMAPINFO  *bmi,
+                           UINT  ColorUse)
+{
+
+}
+
+UINT STDCALL W32kGetDIBColorTable(HDC  hDC,
+                           UINT  StartIndex,
+                           UINT  Entries,
+                           RGBQUAD  *Colors)
+{
+  UNIMPLEMENTED;
+}
+
+// Converts a device-dependent bitmap to a DIB
+INT STDCALL W32kGetDIBits(HDC  hDC,
+                   HBITMAP hBitmap,
+                   UINT  StartScan,
+                   UINT  ScanLines,
+                   LPVOID  Bits,
+                   LPBITMAPINFO   bi,
+                   UINT  Usage)
+{
+  UNIMPLEMENTED;
+}
+
+INT STDCALL W32kStretchDIBits(HDC  hDC,
+                       INT  XDest,
+                       INT  YDest,
+                       INT  DestWidth,
+                       INT  DestHeight,
+                       INT  XSrc,       
+                       INT  YSrc,       
+                       INT  SrcWidth,  
+                       INT  SrcHeight, 
+                       CONST VOID  *Bits,
+                       CONST BITMAPINFO  *BitsInfo,
+                       UINT  Usage,                 
+                       DWORD  ROP)
+{
+  UNIMPLEMENTED;
+}
+
+LONG STDCALL W32kGetBitmapBits(HBITMAP  hBitmap,
+                        LONG  Count,
+                        LPVOID  Bits)
+{
+  PBITMAPOBJ  bmp;
+  LONG  height, ret;
+  
+  bmp = BITMAPOBJ_HandleToPtr (hBitmap);
+  if (!bmp) 
+  {
+    return 0;
+  }
+    
+  /* If the bits vector is null, the function should return the read size */
+  if (Bits == NULL)
+  {
+    return bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight;
+  }
+
+  if (Count < 0) 
+  {
+    DPRINT ("(%ld): Negative number of bytes passed???\n", Count);
+    Count = -Count;
+  }
+
+  /* Only get entire lines */
+  height = Count / bmp->bitmap.bmWidthBytes;
+  if (height > bmp->bitmap.bmHeight) 
+  {
+    height = bmp->bitmap.bmHeight;
+  }
+  Count = height * bmp->bitmap.bmWidthBytes;
+  if (Count == 0)
+  {
+    DPRINT("Less then one entire line requested\n");
+    BITMAPOBJ_UnlockBitmap (hBitmap);
+    return  0;
+  }
+
+  DPRINT("(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
+         hBitmap, Count, Bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
+         1 << bmp->bitmap.bmBitsPixel, height );
+#if 0
+  /* FIXME: Call DDI CopyBits here if available  */
+  if(bmp->DDBitmap) 
+  {
+    DPRINT("Calling device specific BitmapBits\n");
+    if(bmp->DDBitmap->funcs->pBitmapBits)
+    {
+      ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, bits, count,
+                                              DDB_GET);
+    }
+    else 
+    {
+      ERR_(bitmap)("BitmapBits == NULL??\n");
+      ret = 0;
+    }
+  } 
+  else 
+#endif
+  {
+    if(!bmp->bitmap.bmBits) 
+    {
+      DPRINT ("Bitmap is empty\n");
+      ret = 0;
+    } 
+    else 
+    {
+      memcpy(Bits, bmp->bitmap.bmBits, Count);
+      ret = Count;
+    }
+  }
+  BITMAPOBJ_UnlockBitmap (hBitmap);
+
+  return  ret;
+}
+
+// The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
+// The DDB that is created will be whatever bit depth your reference DC is
+HBITMAP STDCALL W32kCreateDIBitmap(HDC hdc, const BITMAPINFOHEADER *header,
+                               DWORD init, LPCVOID bits, const BITMAPINFO *data,
+                               UINT coloruse)
+{
+  HBITMAP handle;
+  BOOL fColor;
+  DWORD width;
+  int height;
+  WORD bpp;
+  WORD compr;
+
+  if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
+  if (height < 0) height = -height;
+
+  // Check if we should create a monochrome or color bitmap.
+  // We create a monochrome bitmap only if it has exactly 2
+  // colors, which are black followed by white, nothing else.
+  // In all other cases, we create a color bitmap.
+
+  if (bpp != 1) fColor = TRUE;
+  else if ((coloruse != DIB_RGB_COLORS) ||
+           (init != CBM_INIT) || !data) fColor = FALSE;
+  else
+  {
+    if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
+    {
+      RGBQUAD *rgb = data->bmiColors;
+      DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
+
+      // Check if the first color of the colormap is black
+      if ((col == RGB(0, 0, 0)))
+      {
+        rgb++;
+        col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
+        // If the second color is white, create a monochrome bitmap
+        fColor =  (col != RGB(0xff,0xff,0xff));
+      }
+      // Note : If the first color of the colormap is white 
+      // followed by black, we have to create a color bitmap. 
+      // If we don't the white will be displayed in black later on!
+    else fColor = TRUE;
+  }
+  else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+  {
+    RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
+    DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
+
+    if ((col == RGB(0,0,0)))
+    {
+      rgb++;
+      col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
+      fColor = (col != RGB(0xff,0xff,0xff));
+    }
+    else fColor = TRUE;
+  }
+  else
+  {
+      DbgPrint("(%ld): wrong size for data\n", data->bmiHeader.biSize );
+      return 0;
+    }
+  }
+
+  // Now create the bitmap
+
+  if (fColor)
+  {
+    handle = W32kCreateCompatibleBitmap(RetrieveDisplayHDC(), width, height);
+  }
+  else handle = W32kCreateBitmap(width, height, 1, 1, NULL);
+
+  if (!handle) return 0;
+
+  if (init == CBM_INIT)
+  {
+    W32kSetDIBits(hdc, handle, 0, height, bits, data, coloruse);
+  }
+
+  return handle;
+}
+
+HBITMAP STDCALL W32kCreateDIBSection(HDC hDC,
+                              CONST BITMAPINFO  *bmi,
+                              UINT  Usage,
+                              VOID  *Bits,
+                              HANDLE  hSection,
+                              DWORD  dwOffset)
+{
+  HBITMAP hbitmap = 0;
+  DC *dc;
+  BOOL bDesktopDC = FALSE;
+
+  // If the reference hdc is null, take the desktop dc
+  if (hDC == 0)
+  {
+    hDC = W32kCreateCompatableDC(0);
+    bDesktopDC = TRUE;
+  }
+
+  if ((dc = DC_HandleToPtr(hDC)))
+  {
+    hbitmap = DIB_CreateDIBSection(dc, bmi, Usage, Bits, hSection, dwOffset, 0);
+    DC_UnlockDC (hDC);
+  }
+
+  if (bDesktopDC)
+    W32kDeleteDC(hDC);
+
+  return hbitmap;
+}
+
+HBITMAP DIB_CreateDIBSection(
+  PDC dc, BITMAPINFO *bmi, UINT usage,
+  LPVOID *bits, HANDLE section,
+  DWORD offset, DWORD ovr_pitch)
+{
+  HBITMAP res = 0;
+  BITMAPOBJ *bmp = NULL;
+  DIBSECTION *dib = NULL;
+  int *colorMap = NULL;
+  int nColorMap;
+  
+  // Fill BITMAP32 structure with DIB data
+  BITMAPINFOHEADER *bi = &bmi->bmiHeader;
+  INT effHeight, totalSize;
+  BITMAP bm;
+  
+  DbgPrint("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
+       bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
+       bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
+  
+  effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
+  bm.bmType = 0;
+  bm.bmWidth = bi->biWidth;
+  bm.bmHeight = effHeight;
+  bm.bmWidthBytes = ovr_pitch ? ovr_pitch : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
+
+  bm.bmPlanes = bi->biPlanes;
+  bm.bmBitsPixel = bi->biBitCount;
+  bm.bmBits = NULL;
+  
+  // Get storage location for DIB bits.  Only use biSizeImage if it's valid and
+  // we're dealing with a compressed bitmap.  Otherwise, use width * height.
+  totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
+    ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
+
+/*
+  if (section)
+    bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS, 
+                             0L, offset, totalSize);
+  else if (ovr_pitch && offset)
+    bm.bmBits = (LPVOID) offset;
+  else { */
+    offset = 0;
+/*    bm.bmBits = VirtualAlloc(NULL, totalSize, 
+                            MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); */
+
+  bm.bmBits = ExAllocatePool(NonPagedPool, totalSize);
+
+/*  } */
+
+  if (usage == DIB_PAL_COLORS) memcpy(bmi->bmiColors, (UINT *)DIB_MapPaletteColors(dc, bmi), sizeof(UINT *));
+
+  // Allocate Memory for DIB and fill structure
+  if (bm.bmBits)
+    dib = ExAllocatePool(PagedPool, sizeof(DIBSECTION));
+    RtlZeroMemory(dib, sizeof(DIBSECTION));
+
+  if (dib)
+  {
+    dib->dsBm = bm;
+    dib->dsBmih = *bi;
+    dib->dsBmih.biSizeImage = totalSize;
+
+    /* Set dsBitfields values */
+    if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
+    {
+      dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
+    }
+    else switch(bi->biBitCount)
+    {
+      case 16:
+        dib->dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
+        dib->dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
+        dib->dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
+        break;
+
+      case 24:
+        dib->dsBitfields[0] = 0xff;
+        dib->dsBitfields[1] = 0xff00;
+        dib->dsBitfields[2] = 0xff0000;
+        break;
+
+      case 32:
+        dib->dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
+        dib->dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
+        dib->dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
+        break;
+    }
+    dib->dshSection = section;
+    dib->dsOffset = offset;
+  }
+
+  // Create Device Dependent Bitmap and add DIB pointer
+  if (dib) 
+  {
+    res = W32kCreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
+    if (res)
+    {
+      bmp = BITMAPOBJ_HandleToPtr (res);
+      if (bmp)
+      {
+        bmp->dib = (DIBSECTION *) dib;
+      }
+    }
+  }
+
+  // Clean up in case of errors
+  if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
+  {
+    DbgPrint("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n", res, bmp, dib, bm.bmBits);
+/*      if (bm.bmBits)
+      {
+      if (section)
+        UnmapViewOfFile(bm.bmBits), bm.bmBits = NULL;
+      else if (!offset)
+      VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
+    } */
+      
+    if (colorMap) { ExFreePool(colorMap); colorMap = NULL; }
+    if (dib) { ExFreePool(dib); dib = NULL; }
+    if (bmp) { BITMAPOBJ_UnlockBitmap(res); bmp = NULL; }
+    if (res) { GDIOBJ_FreeObject(res, GO_BITMAP_MAGIC); res = 0; }
+  }
+
+  // Install fault handler, if possible
+/*  if (bm.bmBits)
+  {
+    if (VIRTUAL_SetFaultHandler(bm.bmBits, DIB_FaultHandler, (LPVOID)res))
+    {
+      if (section || offset)
+      {
+        DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
+        if (dib) dib->status = DIB_AppMod;
+      }
+      else
+      {
+        DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
+        if (dib) dib->status = DIB_InSync;
+      }
+    }
+  } */
+
+  // Return BITMAP handle and storage location
+  if (bmp) BITMAPOBJ_UnlockBitmap(res);
+  if (bm.bmBits && bits) *bits = bm.bmBits;
+  return res;
+}
+
+/***********************************************************************
+ *           DIB_GetDIBWidthBytes
+ *
+ * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
+ * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
+ * 11/16/1999 (RJJ) lifted from wine
+ */
+int DIB_GetDIBWidthBytes(int  width, int  depth)
+{
+  int words;
+  
+  switch(depth)
+  {
+    case 1:  words = (width + 31) / 32; break;
+    case 4:  words = (width + 7) / 8; break;
+    case 8:  words = (width + 3) / 4; break;
+    case 15:
+    case 16: words = (width + 1) / 2; break;
+    case 24: words = (width * 3 + 3)/4; break;
+      
+    default:
+      DPRINT("(%d): Unsupported depth\n", depth );
+      /* fall through */
+    case 32:
+      words = width;
+  }
+  return 4 * words;
+}
+
+/***********************************************************************
+ *           DIB_GetDIBImageBytes
+ *
+ * Return the number of bytes used to hold the image in a DIB bitmap.
+ * 11/16/1999 (RJJ) lifted from wine
+ */
+
+int DIB_GetDIBImageBytes (int  width, int  height, int  depth)
+{
+  return DIB_GetDIBWidthBytes( width, depth ) * (height < 0 ? -height : height);
+}
+
+/***********************************************************************
+ *           DIB_BitmapInfoSize
+ *
+ * Return the size of the bitmap info structure including color table.
+ * 11/16/1999 (RJJ) lifted from wine
+ */
+
+int DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse)
+{
+  int colors;
+
+  if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+  {
+    BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
+    colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
+    return sizeof(BITMAPCOREHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
+  }
+  else  /* assume BITMAPINFOHEADER */
+  {
+    colors = info->bmiHeader.biClrUsed;
+    if (!colors && (info->bmiHeader.biBitCount <= 8)) colors = 1 << info->bmiHeader.biBitCount;
+    return sizeof(BITMAPINFOHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
+  }
+}
+
+int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
+                              int *height, WORD *bpp, WORD *compr )
+{
+  if (header->biSize == sizeof(BITMAPINFOHEADER))
+  {
+    *width  = header->biWidth;
+    *height = header->biHeight;
+    *bpp    = header->biBitCount;
+    *compr  = header->biCompression;
+    return 1;
+  }
+  if (header->biSize == sizeof(BITMAPCOREHEADER))
+  {
+    BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
+    *width  = core->bcWidth;
+    *height = core->bcHeight;
+    *bpp    = core->bcBitCount;
+    *compr  = 0;
+    return 0;
+  }
+  DbgPrint("(%ld): wrong size for header\n", header->biSize );
+  return -1;
+}
+
+// Converts a Device Independent Bitmap (DIB) to a Device Dependant Bitmap (DDB)
+// The specified Device Context (DC) defines what the DIB should be converted to
+PBITMAPOBJ DIBtoDDB(HGLOBAL hPackedDIB, HDC hdc) // FIXME: This should be removed. All references to this function should
+                                                // change to W32kSetDIBits
+{
+  HBITMAP hBmp = 0;
+  PBITMAPOBJ pBmp = NULL;
+  DIBSECTION *dib;
+  LPBYTE pbits = NULL;
+
+  // Get a pointer to the packed DIB's data
+  // pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
+  dib = hPackedDIB;
+
+  pbits = (dib + DIB_BitmapInfoSize(&dib->dsBmih, DIB_RGB_COLORS));
+
+  // Create a DDB from the DIB
+  hBmp = W32kCreateDIBitmap(hdc, &dib->dsBmih, CBM_INIT, (LPVOID)pbits, &dib->dsBmih, DIB_RGB_COLORS);
+
+  // GlobalUnlock(hPackedDIB);
+
+  // Retrieve the internal Pixmap from the DDB
+  pBmp = (BITMAPOBJ *)GDIOBJ_HandleToPtr(hBmp, GO_BITMAP_MAGIC);
+
+  return pBmp;
+}
+
+RGBQUAD *DIB_MapPaletteColors(PDC dc, LPBITMAPINFO lpbmi)
+{
+  RGBQUAD *lpRGB;
+  int nNumColors,i;
+  DWORD *lpIndex;
+  PPALOBJ palObj;
+
+  palObj = AccessUserObject(dc->DevInfo.hpalDefault);
+
+  if (palObj == NULL) {
+//      RELEASEDCINFO(hDC);
+    return NULL;
+  }
+
+  nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
+  if (lpbmi->bmiHeader.biClrUsed)
+    nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
+
+  lpRGB = (RGBQUAD *)ExAllocatePool(NonPagedPool, sizeof(RGBQUAD) * nNumColors);
+  lpIndex = (DWORD *)&lpbmi->bmiColors[0];
+
+  for (i=0; i<nNumColors; i++) {
+    pRGB[i].rgbRed = palObj->logpalette.palPalEntry[*lpIndex].peRed;
+    lpRGB[i].rgbGreen = palObj->logpalette.palPalEntry[*lpIndex].peGreen;
+    lpRGB[i].rgbBlue = palObj->logpalette.palPalEntry[*lpIndex].peBlue;
+    lpIndex++;
+  }
+//    RELEASEDCINFO(hDC);
+//    RELEASEPALETTEINFO(hPalette);
+  return lpRGB;
+}
+
+HPALETTE BuildDIBPalette(BITMAPINFO *bmi, PINT paletteType)
+{
+  BYTE bits;
+
+  // Determine Bits Per Pixel
+  bits = bmi->bmiHeader.biBitCount;
+
+  // Determine paletteType from Bits Per Pixel
+  if(bits <= 8)
+  {
+    *paletteType = PAL_INDEXED;
+  } else
+  if(bits < 24)
+  {
+    *paletteType = PAL_BITFIELDS;
+  } else {
+    *paletteType = PAL_RGB; // FIXME: This could be BGR, must still check
+  }
+
+  return EngCreatePalette(*paletteType, bmi->bmiHeader.biClrUsed, bmi->bmiColors, 0, 0, 0);
+}
index 8d5139d..98fd04f 100644 (file)
@@ -77,53 +77,53 @@ W32kRectangle(HDC  hDC,
                     int  RightRect,
                     int  BottomRect)
 {
-   DC          *dc = DC_HandleToPtr(hDC);
-   SURFOBJ     *SurfObj = AccessUserObject(dc->Surface);
-   PBRUSHOBJ   BrushObj;
-   BOOL ret;
-   PRECTL      RectBounds = GDIOBJ_HandleToPtr(dc->w.hGCClipRgn, GO_REGION_MAGIC);
-
-   if(!dc) return FALSE;
-
-   if(PATH_IsPathOpen(dc->w.path)) {
-      ret = PATH_Rectangle(hDC, LeftRect, TopRect, RightRect, BottomRect);
-   } else {
-
-      DbgPrint("W32kRectangle pen: ");
-      DbgPrint("--- %08x\n", GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
-
-      BrushObj = PenToBrushObj(dc, GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
-
-      ret = EngLineTo(SurfObj,
-                      NULL, // ClipObj,
-                      BrushObj,
-                      LeftRect, TopRect, RightRect, TopRect,
-                      RectBounds, // Bounding rectangle
-                      dc->w.ROPmode); // MIX
-
-      ret = EngLineTo(SurfObj,
-                      NULL, // ClipObj,
-                      BrushObj,
-                      RightRect, TopRect, RightRect, BottomRect,
-                      RectBounds, // Bounding rectangle
-                      dc->w.ROPmode); // MIX
-
-      ret = EngLineTo(SurfObj,
-                      NULL, // ClipObj,
-                      BrushObj,
-                      LeftRect, BottomRect, RightRect, BottomRect,
-                      RectBounds, // Bounding rectangle
-                      dc->w.ROPmode); // MIX
-
-      ret = EngLineTo(SurfObj,
-                      NULL, // ClipObj,
-                      BrushObj,
-                      LeftRect, TopRect, LeftRect, BottomRect,
-                      RectBounds, // Bounding rectangle
-                      dc->w.ROPmode); // MIX */
-
-      ExFreePool(BrushObj);
-   }
+  DC           *dc = DC_HandleToPtr(hDC);
+  SURFOBJ      *SurfObj = AccessUserObject(dc->Surface);
+  PBRUSHOBJ    BrushObj;
+  BOOL ret;
+  PRECTL       RectBounds = GDIOBJ_HandleToPtr(dc->w.hGCClipRgn, GO_REGION_MAGIC);
+
+  if(!dc) return FALSE;
+
+  if(PATH_IsPathOpen(dc->w.path)) {
+    ret = PATH_Rectangle(hDC, LeftRect, TopRect, RightRect, BottomRect);
+  } else {
+
+    DbgPrint("W32kRectangle pen: ");
+    DbgPrint("--- %08x\n", GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
+
+    BrushObj = PenToBrushObj(dc, GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
+
+    ret = EngLineTo(SurfObj,
+                    NULL, // ClipObj,
+                    BrushObj,
+                    LeftRect, TopRect, RightRect, TopRect,
+                    RectBounds, // Bounding rectangle
+                    dc->w.ROPmode); // MIX
+
+    ret = EngLineTo(SurfObj,
+                    NULL, // ClipObj,
+                    BrushObj,
+                    RightRect, TopRect, RightRect, BottomRect,
+                    RectBounds, // Bounding rectangle
+                    dc->w.ROPmode); // MIX
+
+    ret = EngLineTo(SurfObj,
+                    NULL, // ClipObj,
+                    BrushObj,
+                    LeftRect, BottomRect, RightRect, BottomRect,
+                    RectBounds, // Bounding rectangle
+                    dc->w.ROPmode); // MIX
+
+    ret = EngLineTo(SurfObj,
+                    NULL, // ClipObj,
+                    BrushObj,
+                    LeftRect, TopRect, LeftRect, BottomRect,
+                    RectBounds, // Bounding rectangle
+                    dc->w.ROPmode); // MIX */
+
+    ExFreePool(BrushObj);
+  }
 
 // FIXME: Move current position in DC?
 
@@ -142,5 +142,3 @@ W32kRoundRect(HDC  hDC,
 {
   UNIMPLEMENTED;
 }
-
-
index b757df5..0301807 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * GDIOBJ.C - GDI object manipulation routines
  *
- * $Id: gdiobj.c,v 1.6 2000/06/16 07:22:39 jfilby Exp $
+ * $Id: gdiobj.c,v 1.7 2001/03/31 15:35:08 jfilby Exp $
  *
  */
 
 #include <windows.h>
 #include <ddk/ntddk.h>
 #include <win32k/gdiobj.h>
+#include <win32k/brush.h>
+#include <win32k/pen.h>
+#include <win32k/text.h>
+
+//  GDI stock objects
+
+static LOGBRUSH WhiteBrush =
+{ BS_SOLID, RGB(255,255,255), 0 };
+
+static LOGBRUSH LtGrayBrush =
+/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
+{ BS_SOLID, RGB(192,192,192), 0 };
+
+static LOGBRUSH GrayBrush =
+/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
+{ BS_SOLID, RGB(128,128,128), 0 };
+
+static LOGBRUSH DkGrayBrush =
+/* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
+/* NB_HATCH_STYLES is an index into HatchBrushes */
+{ BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES };
+
+static LOGBRUSH BlackBrush =
+{ BS_SOLID, RGB(0,0,0), 0 };
+
+static LOGBRUSH NullBrush =
+{ BS_NULL, 0, 0 };
+
+static LOGPEN WhitePen =
+{ PS_SOLID, { 0, 0 }, RGB(255,255,255) };
+
+static LOGPEN BlackPen =
+{ PS_SOLID, { 0, 0 }, RGB(0,0,0) };
+
+static LOGPEN NullPen =
+{ PS_NULL, { 0, 0 }, 0 };
+
+static LOGFONT OEMFixedFont =
+{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
+  0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" };
+
+/* Filler to make the location counter dword aligned again.  This is necessary
+   since (a) LOGFONT is packed, (b) gcc places initialised variables in the code
+   segment, and (c) Solaris assembler is stupid.  */
+static UINT align_OEMFixedFont = 1;
+
+static LOGFONT AnsiFixedFont =
+{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+  0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" };
+
+static UINT align_AnsiFixedFont = 1;
+
+static LOGFONT AnsiVarFont =
+{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+  0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" };
+
+static UINT align_AnsiVarFont = 1;
+
+static LOGFONT SystemFont =
+{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+  0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" };
+
+static UINT align_SystemFont = 1;
+
+static LOGFONT DeviceDefaultFont =
+{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+  0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" };
+
+static UINT align_DeviceDefaultFont = 1;
+
+static LOGFONT SystemFixedFont =
+{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+  0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" };
+
+static UINT align_SystemFixedFont = 1;
+
+/* FIXME: Is this correct? */
+static LOGFONT DefaultGuiFont =
+{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+  0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" };
+
+static UINT align_DefaultGuiFont = 1;
+
+static HGDIOBJ *StockObjects[NB_STOCK_OBJECTS]; // we dont assign these statically as WINE does because we might redesign
+                                                // the way handles work, so it's more dynamic now
+
+HBITMAP hPseudoStockBitmap; /* 1x1 bitmap for memory DCs */
 
 PGDIOBJ  GDIOBJ_AllocObject(WORD Size, WORD Magic)
 {
   PGDIOBJHDR  NewObj;
-  
+
   NewObj = ExAllocatePool(PagedPool, Size + sizeof (GDIOBJHDR)); // FIXME: Allocate with tag of MAGIC?
+
   if (NewObj == NULL)
     {
       return  NULL;
     }
 
   RtlZeroMemory(NewObj, Size + sizeof (GDIOBJHDR));
+
   NewObj->wMagic = Magic;
 #if 0
   KeInitializeSpinlock(&NewObj->Lock);
 #endif
-  
+
   return  (PGDIOBJ)(((PCHAR) NewObj) + sizeof (GDIOBJHDR));
 }
 
@@ -35,9 +124,9 @@ BOOL  GDIOBJ_FreeObject (PGDIOBJ Obj, WORD Magic)
 
   ObjHdr = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR));
   if (ObjHdr->wMagic != Magic)
-    {
-       return FALSE;
-    }
+  {
+    return FALSE;
+  }
   ExFreePool (ObjHdr);
   return TRUE;
 }
@@ -49,9 +138,9 @@ HGDIOBJ  GDIOBJ_PtrToHandle (PGDIOBJ Obj, WORD Magic)
   if (Obj == NULL) return NULL;
   objHeader = (PGDIOBJHDR) (((PCHAR)Obj) - sizeof (GDIOBJHDR));
   if (objHeader->wMagic != Magic)
-    {
-      return  0;
-    }
+  {
+    return  0;
+  }
   
   return  (HGDIOBJ) objHeader;
 }
@@ -67,9 +156,9 @@ PGDIOBJ  GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic)
   /*  FIXME: Lock object for duration  */
 
   if ((objHeader->wMagic != Magic) && (Magic != GO_MAGIC_DONTCARE))
-    {
-      return  0;
-    }
+  {
+    return  0;
+  }
 
   return  (PGDIOBJ) (((PCHAR)Obj) + sizeof (GDIOBJHDR));
 }
@@ -77,7 +166,7 @@ PGDIOBJ  GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic)
 BOOL  GDIOBJ_LockObject (HGDIOBJ Obj)
 {
   /* FIXME: write this  */
-  return  TRUE;
+  // return  TRUE;
 }
 
 BOOL  GDIOBJ_UnlockObject (HGDIOBJ Obj)
@@ -92,9 +181,9 @@ HGDIOBJ  GDIOBJ_GetNextObject (HGDIOBJ Obj, WORD Magic)
   
   objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
   if (objHeader->wMagic != Magic)
-    {
-      return 0;
-    }
+  {
+    return 0;
+  }
 
   return objHeader->hNext;
 }
@@ -107,14 +196,48 @@ HGDIOBJ  GDIOBJ_SetNextObject (HGDIOBJ Obj, WORD Magic, HGDIOBJ NextObj)
   /* FIXME: should we lock/unlock the object here? */
   objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
   if (objHeader->wMagic != Magic)
-    {
-      return  0;
-    }
+  {
+    return  0;
+  }
   oldNext = objHeader->hNext;
   objHeader->hNext = NextObj;
   
   return  oldNext;
 }
 
+VOID CreateStockObjects(void)
+{
+  // Create GDI Stock Objects from the logical structures we've defined
+  StockObjects[WHITE_BRUSH] =  W32kCreateBrushIndirect(&WhiteBrush);
+  StockObjects[LTGRAY_BRUSH] = W32kCreateBrushIndirect(&LtGrayBrush);
+  StockObjects[GRAY_BRUSH] =   W32kCreateBrushIndirect(&GrayBrush);
+  StockObjects[DKGRAY_BRUSH] = W32kCreateBrushIndirect(&DkGrayBrush);
+  StockObjects[BLACK_BRUSH] =  W32kCreateBrushIndirect(&BlackBrush);
+  StockObjects[NULL_BRUSH] =   W32kCreateBrushIndirect(&NullBrush);
+
+  StockObjects[WHITE_PEN] = W32kCreatePenIndirect(&WhitePen);
+  StockObjects[BLACK_PEN] = W32kCreatePenIndirect(&BlackPen);
+  StockObjects[NULL_PEN] =  W32kCreatePenIndirect(&NullPen);
+
+  StockObjects[OEM_FIXED_FONT] =      W32kCreateFontIndirect(&OEMFixedFont);
+  StockObjects[ANSI_FIXED_FONT] =     W32kCreateFontIndirect(&AnsiFixedFont);
+  StockObjects[SYSTEM_FONT] =         W32kCreateFontIndirect(&SystemFont);
+  StockObjects[DEVICE_DEFAULT_FONT] = W32kCreateFontIndirect(&DeviceDefaultFont);
+  StockObjects[SYSTEM_FIXED_FONT] =   W32kCreateFontIndirect(&SystemFixedFont);
+  StockObjects[DEFAULT_GUI_FONT] =    W32kCreateFontIndirect(&DefaultGuiFont);
+
+  StockObjects[DEFAULT_PALETTE] = PALETTE_Init();
+}
+
+HGDIOBJ STDCALL  W32kGetStockObject(INT  Object)
+{
+  HGDIOBJ ret;
+
+/*  if ((Object < 0) || (Object >= NB_STOCK_OBJECTS)) return 0;
+  if (!StockObjects[Object]) return 0;
+  ret = FIRST_STOCK_HANDLE + Object;
 
+  return ret; */
 
+  return StockObjects[Object]; // FIXME........
+}
index e9fe215..4a01c59 100644 (file)
@@ -35,12 +35,12 @@ W32kArc(HDC  hDC,
               int  XEndArc,  
               int  YEndArc)
 {
-   DC *dc = DC_HandleToPtr(hDC);
-   if(!dc) return FALSE;
+  DC *dc = DC_HandleToPtr(hDC);
+  if(!dc) return FALSE;
 
-   if(PATH_IsPathOpen(dc->w.path))
-      return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect,
-                      XStartArc, YStartArc, XEndArc, YEndArc);
+  if(PATH_IsPathOpen(dc->w.path))
+    return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect,
+                    XStartArc, YStartArc, XEndArc, YEndArc);
 
 //   EngArc(dc, LeftRect, TopRect, RightRect, BottomRect, UNIMPLEMENTED
 //          XStartArc, YStartArc, XEndArc, YEndArc);
@@ -58,43 +58,43 @@ W32kArcTo(HDC  hDC,
                 int  XRadial2,
                 int  YRadial2)
 {
-   BOOL result;
-   DC *dc = DC_HandleToPtr(hDC);
-   if(!dc) return FALSE;
+  BOOL result;
+  DC *dc = DC_HandleToPtr(hDC);
+  if(!dc) return FALSE;
 
-   // Line from current position to starting point of arc
-   W32kLineTo(hDC, XRadial1, YRadial1);
+  // Line from current position to starting point of arc
+  W32kLineTo(hDC, XRadial1, YRadial1);
 
-   // Then the arc is drawn.
-   result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect,
-                XRadial1, YRadial1, XRadial2, YRadial2);
+  // Then the arc is drawn.
+  result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect,
+                   XRadial1, YRadial1, XRadial2, YRadial2);
 
-   // If no error occured, the current position is moved to the ending point of the arc.
-   if(result)
-   {
-      W32kMoveToEx(hDC, XRadial2, YRadial2, NULL);
-   }
+  // If no error occured, the current position is moved to the ending point of the arc.
+  if(result)
+  {
+    W32kMoveToEx(hDC, XRadial2, YRadial2, NULL);
+  }
 
-   return result;
+  return result;
 }
 
 INT
 STDCALL
 W32kGetArcDirection(HDC  hDC)
 {
-   PDC dc;
-   int ret;
+  PDC dc;
+  int ret;
   
-   dc = DC_HandleToPtr (hDC);
-   if (!dc)
-   {
-      return 0;
-   }
-
-   ret = dc->w.ArcDirection;
-   DC_UnlockDC (hDC);
+  dc = DC_HandleToPtr (hDC);
+  if (!dc)
+  {
+    return 0;
+  }
+
+  ret = dc->w.ArcDirection;
+  DC_UnlockDC (hDC);
   
-   return ret;
+  return ret;
 }
 
 BOOL
@@ -103,32 +103,28 @@ W32kLineTo(HDC  hDC,
                  int  XEnd,
                  int  YEnd)
 {
-   DC          *dc = DC_HandleToPtr(hDC);
-   SURFOBJ     *SurfObj = AccessUserObject(dc->Surface);
-   BOOL ret;
-
-   if(!dc) return FALSE;
-
-   if(PATH_IsPathOpen(dc->w.path)) {
-      ret = PATH_LineTo(hDC, XEnd, YEnd);
-   } else {
-
-      DbgPrint("W32kLineTo on DC:%08x (h:%08x) with pen handle %08x\n", dc, hDC, dc->w.hPen);
-      DbgPrint("--- %08x\n", GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
-
-      ret = EngLineTo(SurfObj,
-                      NULL, // ClipObj
-                      PenToBrushObj(dc, GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC)),
-                      dc->w.CursPosX, dc->w.CursPosY, XEnd, YEnd,
-                      GDIOBJ_HandleToPtr(dc->w.hGCClipRgn, GO_REGION_MAGIC), // Bounding rectangle
-                      dc->w.ROPmode); // MIX
-   }
-   if(ret) {
-      dc->w.CursPosX = XEnd;
-      dc->w.CursPosY = YEnd;
-   }
-
-   return ret;
+  DC           *dc = DC_HandleToPtr(hDC);
+  SURFOBJ      *SurfObj = AccessUserObject(dc->Surface);
+  BOOL ret;
+
+  if(!dc) return FALSE;
+
+  if(PATH_IsPathOpen(dc->w.path)) {
+    ret = PATH_LineTo(hDC, XEnd, YEnd);
+  } else {
+    ret = EngLineTo(SurfObj,
+                    NULL, // ClipObj
+                    PenToBrushObj(dc, GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC)),
+                    dc->w.CursPosX, dc->w.CursPosY, XEnd, YEnd,
+                    GDIOBJ_HandleToPtr(dc->w.hGCClipRgn, GO_REGION_MAGIC), // Bounding rectangle
+                    dc->w.ROPmode); // MIX
+  }
+  if(ret) {
+    dc->w.CursPosX = XEnd;
+    dc->w.CursPosY = YEnd;
+  }
+
+  return ret;
 }
 
 BOOL
@@ -138,21 +134,21 @@ W32kMoveToEx(HDC  hDC,
                    int  Y,
                    LPPOINT  Point)
 {
-   DC *dc = DC_HandleToPtr( hDC );
+  DC *dc = DC_HandleToPtr( hDC );
 
-   if(!dc) return FALSE;
+  if(!dc) return FALSE;
 
-   if(Point) {
-      Point->x = dc->w.CursPosX;
-      Point->y = dc->w.CursPosY;
-   }
-   dc->w.CursPosX = X;
-   dc->w.CursPosY = Y;
+  if(Point) {
+    Point->x = dc->w.CursPosX;
+    Point->y = dc->w.CursPosY;
+  }
+  dc->w.CursPosX = X;
+  dc->w.CursPosY = Y;
 
-   if(PATH_IsPathOpen(dc->w.path))
-      return PATH_MoveTo(hDC);
+  if(PATH_IsPathOpen(dc->w.path))
+    return PATH_MoveTo(hDC);
 
-   return FALSE;
+  return FALSE;
 }
 
 BOOL
@@ -161,25 +157,25 @@ W32kPolyBezier(HDC  hDC,
                      CONST LPPOINT  pt,
                      DWORD  Count)
 {
-   DC *dc = DC_HandleToPtr(hDC);
-   if(!dc) return FALSE;
-
-   if(PATH_IsPathOpen(dc->w.path))
-      return PATH_PolyBezier(hDC, pt, Count);
-
-   /* We'll convert it into line segments and draw them using Polyline */
-   {
-      POINT *Pts;
-      INT nOut;
-      BOOL ret;
-
-      Pts = GDI_Bezier(pt, Count, &nOut);
-      if(!Pts) return FALSE;
-      DbgPrint("Pts = %p, no = %d\n", Pts, nOut);
-      ret = W32kPolyline(dc->hSelf, Pts, nOut);
-      ExFreePool(Pts);
-      return ret;
-   }
+  DC *dc = DC_HandleToPtr(hDC);
+  if(!dc) return FALSE;
+
+  if(PATH_IsPathOpen(dc->w.path))
+    return PATH_PolyBezier(hDC, pt, Count);
+
+  /* We'll convert it into line segments and draw them using Polyline */
+  {
+    POINT *Pts;
+    INT nOut;
+    BOOL ret;
+
+    Pts = GDI_Bezier(pt, Count, &nOut);
+    if(!Pts) return FALSE;
+    DbgPrint("Pts = %p, no = %d\n", Pts, nOut);
+    ret = W32kPolyline(dc->hSelf, Pts, nOut);
+    ExFreePool(Pts);
+    return ret;
+  }
 }
 
 BOOL
@@ -188,28 +184,28 @@ W32kPolyBezierTo(HDC  hDC,
                        CONST LPPOINT  pt,
                        DWORD  Count)
 {
-   DC *dc = DC_HandleToPtr(hDC);
-   BOOL ret;
-
-   if(!dc) return FALSE;
-
-   if(PATH_IsPathOpen(dc->w.path))
-      ret = PATH_PolyBezierTo(hDC, pt, Count);
-   else { /* We'll do it using PolyBezier */
-      POINT *npt;
-      npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
-      if(!npt) return FALSE;
-      npt[0].x = dc->w.CursPosX;
-      npt[0].y = dc->w.CursPosY;
-      memcpy(npt + 1, pt, sizeof(POINT) * Count);
-      ret = W32kPolyBezier(dc->hSelf, npt, Count+1);
-      ExFreePool(npt);
-   }
-   if(ret) {
-      dc->w.CursPosX = pt[Count-1].x;
-      dc->w.CursPosY = pt[Count-1].y;
-   }
-   return ret;
+  DC *dc = DC_HandleToPtr(hDC);
+  BOOL ret;
+
+  if(!dc) return FALSE;
+
+  if(PATH_IsPathOpen(dc->w.path))
+    ret = PATH_PolyBezierTo(hDC, pt, Count);
+  else { /* We'll do it using PolyBezier */
+    POINT *npt;
+    npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
+    if(!npt) return FALSE;
+    npt[0].x = dc->w.CursPosX;
+    npt[0].y = dc->w.CursPosY;
+    memcpy(npt + 1, pt, sizeof(POINT) * Count);
+    ret = W32kPolyBezier(dc->hSelf, npt, Count+1);
+    ExFreePool(npt);
+  }
+  if(ret) {
+    dc->w.CursPosX = pt[Count-1].x;
+    dc->w.CursPosY = pt[Count-1].y;
+  }
+  return ret;
 }
 
 BOOL
@@ -237,30 +233,30 @@ W32kPolylineTo(HDC  hDC,
                      CONST LPPOINT  pt,
                      DWORD  Count)
 {
-   DC *dc = DC_HandleToPtr(hDC);
-   BOOL ret;
-
-   if(!dc) return FALSE;
-
-   if(PATH_IsPathOpen(dc->w.path))
-   {
-      ret = PATH_PolylineTo(hDC, pt, Count);
-   }
-   else { /* do it using Polyline */
-      POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
-      if(!pts) return FALSE;
-
-      pts[0].x = dc->w.CursPosX;
-      pts[0].y = dc->w.CursPosY;
-      memcpy( pts + 1, pt, sizeof(POINT) * Count);
-      ret = W32kPolyline(hDC, pts, Count + 1);
-      ExFreePool(pts);
-   }
-   if(ret) {
-      dc->w.CursPosX = pt[Count-1].x;
-      dc->w.CursPosY = pt[Count-1].y;
-   }
-   return ret;
+  DC *dc = DC_HandleToPtr(hDC);
+  BOOL ret;
+
+  if(!dc) return FALSE;
+
+  if(PATH_IsPathOpen(dc->w.path))
+  {
+    ret = PATH_PolylineTo(hDC, pt, Count);
+  }
+  else { /* do it using Polyline */
+    POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
+    if(!pts) return FALSE;
+
+    pts[0].x = dc->w.CursPosX;
+    pts[0].y = dc->w.CursPosY;
+    memcpy( pts + 1, pt, sizeof(POINT) * Count);
+    ret = W32kPolyline(hDC, pts, Count + 1);
+    ExFreePool(pts);
+  }
+  if(ret) {
+    dc->w.CursPosX = pt[Count-1].x;
+    dc->w.CursPosY = pt[Count-1].y;
+  }
+  return ret;
 }
 
 BOOL
@@ -278,22 +274,22 @@ STDCALL
 W32kSetArcDirection(HDC  hDC,
                          int  ArcDirection)
 {
-   PDC  dc;
-   INT  nOldDirection;
-
-   dc = DC_HandleToPtr (hDC);
-   if (!dc)
-   {
-      return 0;
-   }
-   if (ArcDirection != AD_COUNTERCLOCKWISE && ArcDirection != AD_CLOCKWISE)
-   {
-//      SetLastError(ERROR_INVALID_PARAMETER);
-      return 0;
-   }
-
-   nOldDirection = dc->w.ArcDirection;
-   dc->w.ArcDirection = ArcDirection;
-
-   return nOldDirection;
+  PDC  dc;
+  INT  nOldDirection;
+
+  dc = DC_HandleToPtr (hDC);
+  if (!dc)
+  {
+    return 0;
+  }
+  if (ArcDirection != AD_COUNTERCLOCKWISE && ArcDirection != AD_CLOCKWISE)
+  {
+//    SetLastError(ERROR_INVALID_PARAMETER);
+    return 0;
+  }
+
+  nOldDirection = dc->w.ArcDirection;
+  dc->w.ArcDirection = ArcDirection;
+
+  return nOldDirection;
 }
index ecdc806..bf1914f 100644 (file)
 
 PBRUSHOBJ PenToBrushObj(PDC dc, PENOBJ *pen)
 {
-   BRUSHOBJ *BrushObj;
-   XLATEOBJ *RGBtoVGA16;
+  BRUSHOBJ *BrushObj;
+  XLATEOBJ *RGBtoVGA16;
 
-// FIXME: move color translation routines to W32kSelectObject
+  BrushObj = ExAllocatePool(NonPagedPool, sizeof(BRUSHOBJ));
+  BrushObj->iSolidColor = pen->logpen.lopnColor;
 
-DbgPrint("PenToBrushObj:%08x ", pen);
-   BrushObj = ExAllocatePool(NonPagedPool, sizeof(BRUSHOBJ));
-
-   RGBtoVGA16 = EngCreateXlate(PAL_INDEXED, PAL_RGB,
-                               dc->DevInfo.hpalDefault, NULL);
-   BrushObj->iSolidColor = XLATEOBJ_iXlate(RGBtoVGA16, pen->logpen.lopnColor);
-
-DbgPrint("BrushObj->iSolidColor:%u\n", BrushObj->iSolidColor);
-   return BrushObj;
-
-//   CreateGDIHandle(BrushGDI, BrushObj);
+  return BrushObj;
 }
 
-VOID BitmapToSurf(PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
+VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
 {
-  SurfObj->dhsurf       = NULL;
-  SurfObj->hsurf        = NULL;
-  SurfObj->dhpdev       = NULL;
-  SurfObj->hdev                 = NULL;
-  SurfObj->sizlBitmap   = Bitmap->size;
-  SurfObj->cjBits       = Bitmap->bitmap.bmHeight * Bitmap->bitmap.bmWidthBytes;
-  SurfObj->pvBits       = Bitmap->bitmap.bmBits;
-  SurfObj->pvScan0      = NULL; // start of bitmap
-  SurfObj->lDelta       = Bitmap->bitmap.bmWidthBytes;
+  if(Bitmap->dib)
+  {
+    SurfGDI->BitsPerPixel = Bitmap->dib->dsBm.bmBitsPixel;
+    SurfObj->lDelta       = Bitmap->dib->dsBm.bmWidthBytes;
+    SurfObj->pvBits       = Bitmap->dib->dsBm.bmBits;
+    SurfObj->cjBits       = Bitmap->dib->dsBm.bmHeight * Bitmap->dib->dsBm.bmWidthBytes;
+  } else {
+    SurfGDI->BitsPerPixel = Bitmap->bitmap.bmBitsPixel;
+    SurfObj->lDelta      = Bitmap->bitmap.bmWidthBytes;
+    SurfObj->pvBits      = Bitmap->bitmap.bmBits;
+    SurfObj->cjBits       = Bitmap->bitmap.bmHeight * Bitmap->bitmap.bmWidthBytes;
+  }
+
+  SurfObj->dhsurf      = NULL;
+  SurfObj->hsurf       = NULL;
+  SurfObj->dhpdev      = NULL;
+  SurfObj->hdev                = NULL;
+  SurfObj->pvScan0     = SurfObj->pvBits; // start of bitmap
+  SurfObj->sizlBitmap  = Bitmap->size; // FIXME: alloc memory for our own struct?
   SurfObj->iUniq        = 0; // not sure..
-  SurfObj->iBitmapFormat = BMF_4BPP; /* FIXME */
+  SurfObj->iBitmapFormat = BitmapFormat(SurfGDI->BitsPerPixel, BI_RGB);
   SurfObj->iType        = STYPE_BITMAP;
   SurfObj->fjBitmap     = BMF_TOPDOWN;
-
-  SurfGDI->BytesPerPixel = bytesPerPixel(SurfObj->iType);
-
-DbgPrint("Bitmap2Surf: cjBits: %u lDelta: %u width: %u height: %u\n",
-  SurfObj->cjBits, SurfObj->lDelta, Bitmap->bitmap.bmWidth, Bitmap->bitmap.bmHeight);
 }
diff --git a/reactos/subsys/win32k/objects/palette.c b/reactos/subsys/win32k/objects/palette.c
new file mode 100644 (file)
index 0000000..95e3a4a
--- /dev/null
@@ -0,0 +1,191 @@
+#undef WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <win32k/debug.h>
+#include <win32k/bitmaps.h>
+#include <win32k/color.h>
+#include <debug.h>
+
+static int           PALETTE_firstFree = 0; 
+static unsigned char PALETTE_freeList[256];
+
+int PALETTE_PaletteFlags     = 0;
+PALETTEENTRY *COLOR_sysPal   = NULL;
+int COLOR_gapStart;
+int COLOR_gapEnd;
+int COLOR_gapFilled;
+int COLOR_max;
+
+PALETTEENTRY *ReturnSystemPalette(void)
+{
+  return COLOR_sysPal;
+}
+
+// Create the system palette
+HPALETTE PALETTE_Init(void)
+{
+  int i;
+  HPALETTE hpalette;
+  PLOGPALETTE palPtr;
+  PPALOBJ palObj;
+  const PALETTEENTRY* __sysPalTemplate = COLOR_GetSystemPaletteTemplate();
+
+  // create default palette (20 system colors)
+  palPtr = ExAllocatePool(NonPagedPool, sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1) * sizeof(PALETTEENTRY));
+  if (!palPtr) return FALSE;
+
+  palPtr->palVersion = 0x300;
+  palPtr->palNumEntries = NB_RESERVED_COLORS;
+  for(i=0; i<NB_RESERVED_COLORS; i++)
+  {
+    palPtr->palPalEntry[i].peRed = __sysPalTemplate[i].peRed;
+    palPtr->palPalEntry[i].peGreen = __sysPalTemplate[i].peGreen;
+    palPtr->palPalEntry[i].peBlue = __sysPalTemplate[i].peBlue;
+    palPtr->palPalEntry[i].peFlags = 0;
+  }
+  hpalette = W32kCreatePalette(palPtr);
+  ExFreePool(palPtr);
+
+  palObj = AccessUserObject(hpalette);
+  if (palObj)
+  {
+    if (!(palObj->mapping = ExAllocatePool(NonPagedPool, sizeof(int) * 20)))
+    {
+      DbgPrint("Win32k: Can not create palette mapping -- out of memory!");
+      return FALSE;
+    }
+//      GDI_ReleaseObj( hpalette );
+  }
+
+  return hpalette;
+}
+
+static void PALETTE_FormatSystemPalette(void)
+{
+  // Build free list so we'd have an easy way to find
+  // out if there are any available colorcells. 
+
+  int i, j = PALETTE_firstFree = NB_RESERVED_COLORS/2;
+
+  COLOR_sysPal[j].peFlags = 0;
+  for(i = NB_RESERVED_COLORS/2 + 1 ; i < 256 - NB_RESERVED_COLORS/2 ; i++)
+  {
+    if( i < COLOR_gapStart || i > COLOR_gapEnd )
+    {
+      COLOR_sysPal[i].peFlags = 0;  // unused tag
+      PALETTE_freeList[j] = i; // next
+      j = i;
+    }
+  }
+  PALETTE_freeList[j] = 0;
+}
+
+void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size)
+{
+  int i = 0;
+  for( ; i<size ; i++ )
+    lpPalE[i].peFlags = PC_SYS_USED | (lpPalE[i].peFlags & 0x07);
+}
+
+// Set the color-mapping table for selected palette. 
+// Return number of entries which mapping has changed.
+int PALETTE_SetMapping(PPALOBJ palPtr, UINT uStart, UINT uNum, BOOL mapOnly)
+{
+  char flag;
+  int  prevMapping = (palPtr->mapping) ? 1 : 0;
+  int  index, iRemapped = 0;
+  int *mapping;
+
+  // reset dynamic system palette entries
+
+  if( !mapOnly && PALETTE_firstFree != -1) PALETTE_FormatSystemPalette();
+
+  // initialize palette mapping table
+  //mapping = HeapReAlloc( GetProcessHeap(), 0, palPtr->mapping,
+  //                       sizeof(int)*palPtr->logpalette.palNumEntries);
+  ExFreePool(palPtr->mapping);
+  mapping = ExAllocatePool(NonPagedPool, sizeof(int)*palPtr->logpalette.palNumEntries);
+
+  palPtr->mapping = mapping;
+
+  for(uNum += uStart; uStart < uNum; uStart++)
+  {
+    index = -1;
+    flag = PC_SYS_USED;
+
+    switch( palPtr->logpalette.palPalEntry[uStart].peFlags & 0x07 )
+    {
+      case PC_EXPLICIT:   // palette entries are indices into system palette
+                          // The PC_EXPLICIT flag is used to copy an entry from the system palette into the logical palette
+        index = *(WORD*)(palPtr->logpalette.palPalEntry + uStart);
+        if(index > 255 || (index >= COLOR_gapStart && index <= COLOR_gapEnd))
+        {
+          DbgPrint("Win32k: PC_EXPLICIT: idx %d out of system palette, assuming black.\n", index); 
+          index = 0;
+        }
+        break;
+
+      case PC_RESERVED:   // forbid future mappings to this entry
+                          // For palette animation, the entries in the logical palette need the PC_RESERVED flag
+        flag |= PC_SYS_RESERVED;
+
+      // fall through
+      default: // try to collapse identical colors
+        index = COLOR_PaletteLookupExactIndex(COLOR_sysPal, 256,  
+                                              *(COLORREF*)(palPtr->logpalette.palPalEntry + uStart));
+            // fall through
+
+      case PC_NOCOLLAPSE:
+        // If an entry in the logical palette is marked with the PC_NOCOLLAPSE flag, the palette
+        // manager allocates a free entry in the system palette if one is available and only uses the
+        // closest colour match if there are no (more) free entries in the system palette
+
+        DbgPrint("Win32k: WARNING: PC_NOCOLLAPSE is not yet working properly\n");
+
+        if( index < 0 )
+        {
+          if(PALETTE_firstFree > 0 /* && !(PALETTE_PaletteFlags & PALETTE_FIXED) FIXME */ )
+          {
+            DgPrint("Win32k: Unimplemented Palette Operation: PC_NOCOLLAPSE [objects/palette.c]\n");
+/*            XColor color;
+            index = PALETTE_firstFree;  // ought to be available
+            PALETTE_firstFree = PALETTE_freeList[index];
+
+            color.pixel = (PALETTE_PaletteToXPixel) ? PALETTE_PaletteToXPixel[index] : index;
+            color.red = palPtr->logpalette.palPalEntry[uStart].peRed << 8;
+            color.green = palPtr->logpalette.palPalEntry[uStart].peGreen << 8;
+            color.blue = palPtr->logpalette.palPalEntry[uStart].peBlue << 8;
+            color.flags = DoRed | DoGreen | DoBlue;
+            TSXStoreColor(display, PALETTE_PaletteXColormap, &color);
+
+            COLOR_sysPal[index] = palPtr->logpalette.palPalEntry[uStart];
+            COLOR_sysPal[index].peFlags = flag;
+            PALETTE_freeList[index] = 0;
+
+            if(PALETTE_PaletteToXPixel) index = PALETTE_PaletteToXPixel[index]; */
+            break;
+          }
+/*          else if (PALETTE_PaletteFlags & PALETTE_VIRTUAL)
+          {
+            index = PALETTE_ToPhysical(NULL, 0x00ffffff &
+                                       *(COLORREF*)(palPtr->logpalette.palPalEntry + uStart));
+             break;     
+           } FIXME */
+
+           // we have to map to existing entry in the system palette
+
+           index = COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL,
+                                            *(COLORREF*)(palPtr->logpalette.palPalEntry + uStart), TRUE);
+           }
+           palPtr->logpalette.palPalEntry[uStart].peFlags |= PC_SYS_USED;
+
+/*         if(PALETTE_PaletteToXPixel) index = PALETTE_PaletteToXPixel[index]; FIXME */
+           break;
+        }
+
+        if( !prevMapping || palPtr->mapping[uStart] != index ) iRemapped++;
+        palPtr->mapping[uStart] = index;
+
+  }
+  return iRemapped;
+}
index 0358584..9145de4 100644 (file)
@@ -142,13 +142,13 @@ W32kWidenPath(HDC  hDC)
  */
 void PATH_InitGdiPath(GdiPath *pPath)
 {
-   assert(pPath!=NULL);
+  assert(pPath!=NULL);
 
-   pPath->state=PATH_Null;
-   pPath->pPoints=NULL;
-   pPath->pFlags=NULL;
-   pPath->numEntriesUsed=0;
-   pPath->numEntriesAllocated=0;
+  pPath->state=PATH_Null;
+  pPath->pPoints=NULL;
+  pPath->pFlags=NULL;
+  pPath->numEntriesUsed=0;
+  pPath->numEntriesAllocated=0;
 }
 
 /* PATH_DestroyGdiPath
@@ -157,10 +157,10 @@ void PATH_InitGdiPath(GdiPath *pPath)
  */
 void PATH_DestroyGdiPath(GdiPath *pPath)
 {
-   assert(pPath!=NULL);
+  assert(pPath!=NULL);
 
-   ExFreePool(pPath->pPoints);
-   ExFreePool(pPath->pFlags);
+  ExFreePool(pPath->pPoints);
+  ExFreePool(pPath->pFlags);
 }
 
 /* PATH_AssignGdiPath
@@ -175,23 +175,23 @@ void PATH_DestroyGdiPath(GdiPath *pPath)
  */
 BOOL PATH_AssignGdiPath(GdiPath *pPathDest, const GdiPath *pPathSrc)
 {
-   assert(pPathDest!=NULL && pPathSrc!=NULL);
+  assert(pPathDest!=NULL && pPathSrc!=NULL);
 
-   /* Make sure destination arrays are big enough */
-   if(!PATH_ReserveEntries(pPathDest, pPathSrc->numEntriesUsed))
-      return FALSE;
+  /* Make sure destination arrays are big enough */
+  if(!PATH_ReserveEntries(pPathDest, pPathSrc->numEntriesUsed))
+    return FALSE;
 
-   /* Perform the copy operation */
-   memcpy(pPathDest->pPoints, pPathSrc->pPoints,
-      sizeof(POINT)*pPathSrc->numEntriesUsed);
-   memcpy(pPathDest->pFlags, pPathSrc->pFlags,
-      sizeof(BYTE)*pPathSrc->numEntriesUsed);
+  /* Perform the copy operation */
+  memcpy(pPathDest->pPoints, pPathSrc->pPoints,
+    sizeof(POINT)*pPathSrc->numEntriesUsed);
+  memcpy(pPathDest->pFlags, pPathSrc->pFlags,
+    sizeof(BYTE)*pPathSrc->numEntriesUsed);
 
-   pPathDest->state=pPathSrc->state;
-   pPathDest->numEntriesUsed=pPathSrc->numEntriesUsed;
-   pPathDest->newStroke=pPathSrc->newStroke;
+  pPathDest->state=pPathSrc->state;
+  pPathDest->numEntriesUsed=pPathSrc->numEntriesUsed;
+  pPathDest->newStroke=pPathSrc->newStroke;
 
-   return TRUE;
+  return TRUE;
 }
 
 /* PATH_MoveTo
@@ -202,21 +202,21 @@ BOOL PATH_AssignGdiPath(GdiPath *pPathDest, const GdiPath *pPathSrc)
  */
 BOOL PATH_MoveTo(HDC hdc)
 {
-   GdiPath *pPath;
+  GdiPath *pPath;
    
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
+  /* Get pointer to path */
+  if(!PATH_GetPathFromHDC(hdc, &pPath))
+    return FALSE;
    
-   /* Check that path is open */
-   if(pPath->state!=PATH_Open)
-      /* FIXME: Do we have to call SetLastError? */
-      return FALSE;
+  /* Check that path is open */
+  if(pPath->state!=PATH_Open)
+    /* FIXME: Do we have to call SetLastError? */
+    return FALSE;
 
-   /* Start a new stroke */
-   pPath->newStroke=TRUE;
+  /* Start a new stroke */
+  pPath->newStroke=TRUE;
 
-   return TRUE;
+  return TRUE;
 }
 
 /* PATH_LineTo
@@ -228,36 +228,36 @@ BOOL PATH_MoveTo(HDC hdc)
  */
 BOOL PATH_LineTo(HDC hdc, INT x, INT y)
 {
-   GdiPath *pPath;
-   POINT point, pointCurPos;
+  GdiPath *pPath;
+  POINT point, pointCurPos;
    
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
+  /* Get pointer to path */
+  if(!PATH_GetPathFromHDC(hdc, &pPath))
+    return FALSE;
    
-   /* Check that path is open */
-   if(pPath->state!=PATH_Open)
+  /* Check that path is open */
+  if(pPath->state!=PATH_Open)
+    return FALSE;
+
+  /* Convert point to device coordinates */
+  point.x=x;
+  point.y=y;
+  if(!W32kLPtoDP(hdc, &point, 1))
+    return FALSE;
+   
+  /* Add a PT_MOVETO if necessary */
+  if(pPath->newStroke)
+  {
+    pPath->newStroke=FALSE;
+    if(!W32kGetCurrentPositionEx(hdc, &pointCurPos) ||
+       !W32kLPtoDP(hdc, &pointCurPos, 1))
       return FALSE;
-
-   /* Convert point to device coordinates */
-   point.x=x;
-   point.y=y;
-   if(!W32kLPtoDP(hdc, &point, 1))
+    if(!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO))
       return FALSE;
+  }
    
-   /* Add a PT_MOVETO if necessary */
-   if(pPath->newStroke)
-   {
-      pPath->newStroke=FALSE;
-      if(!W32kGetCurrentPositionEx(hdc, &pointCurPos) ||
-         !W32kLPtoDP(hdc, &pointCurPos, 1))
-         return FALSE;
-      if(!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO))
-         return FALSE;
-   }
-   
-   /* Add a PT_LINETO entry */
-   return PATH_AddEntry(pPath, &point, PT_LINETO);
+  /* Add a PT_LINETO entry */
+  return PATH_AddEntry(pPath, &point, PT_LINETO);
 }
 
 /* PATH_Rectangle
@@ -267,78 +267,78 @@ BOOL PATH_LineTo(HDC hdc, INT x, INT y)
  */
 BOOL PATH_Rectangle(HDC hdc, INT x1, INT y1, INT x2, INT y2)
 {
-   GdiPath *pPath;
-   POINT corners[2], pointTemp;
-   INT   temp;
+  GdiPath *pPath;
+  POINT corners[2], pointTemp;
+  INT   temp;
 
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
+  /* Get pointer to path */
+  if(!PATH_GetPathFromHDC(hdc, &pPath))
+    return FALSE;
    
-   /* Check that path is open */
-   if(pPath->state!=PATH_Open)
-      return FALSE;
-
-   /* Convert points to device coordinates */
-   corners[0].x=x1;
-   corners[0].y=y1;
-   corners[1].x=x2;
-   corners[1].y=y2;
-   if(!W32kLPtoDP(hdc, corners, 2))
-      return FALSE;
+  /* Check that path is open */
+  if(pPath->state!=PATH_Open)
+    return FALSE;
+
+  /* Convert points to device coordinates */
+  corners[0].x=x1;
+  corners[0].y=y1;
+  corners[1].x=x2;
+  corners[1].y=y2;
+  if(!W32kLPtoDP(hdc, corners, 2))
+    return FALSE;
    
-   /* Make sure first corner is top left and second corner is bottom right */
-   if(corners[0].x>corners[1].x)
-   {
-      temp=corners[0].x;
-      corners[0].x=corners[1].x;
-      corners[1].x=temp;
-   }
-   if(corners[0].y>corners[1].y)
-   {
-      temp=corners[0].y;
-      corners[0].y=corners[1].y;
-      corners[1].y=temp;
-   }
+  /* Make sure first corner is top left and second corner is bottom right */
+  if(corners[0].x>corners[1].x)
+  {
+    temp=corners[0].x;
+    corners[0].x=corners[1].x;
+    corners[1].x=temp;
+  }
+  if(corners[0].y>corners[1].y)
+  {
+    temp=corners[0].y;
+    corners[0].y=corners[1].y;
+    corners[1].y=temp;
+  }
    
-   /* In GM_COMPATIBLE, don't include bottom and right edges */
-   if(W32kGetGraphicsMode(hdc)==GM_COMPATIBLE)
-   {
-      corners[1].x--;
-      corners[1].y--;
-   }
-
-   /* Close any previous figure */
-   if(!W32kCloseFigure(hdc))
-   {
-      /* The W32kCloseFigure call shouldn't have failed */
-      assert(FALSE);
-      return FALSE;
-   }
-
-   /* Add four points to the path */
-   pointTemp.x=corners[1].x;
-   pointTemp.y=corners[0].y;
-   if(!PATH_AddEntry(pPath, &pointTemp, PT_MOVETO))
-      return FALSE;
-   if(!PATH_AddEntry(pPath, corners, PT_LINETO))
-      return FALSE;
-   pointTemp.x=corners[0].x;
-   pointTemp.y=corners[1].y;
-   if(!PATH_AddEntry(pPath, &pointTemp, PT_LINETO))
-      return FALSE;
-   if(!PATH_AddEntry(pPath, corners+1, PT_LINETO))
-      return FALSE;
-
-   /* Close the rectangle figure */
-   if(!W32kCloseFigure(hdc))
-   {
-      /* The W32kCloseFigure call shouldn't have failed */
-      assert(FALSE);
-      return FALSE;
-   }
-
-   return TRUE;
+  /* In GM_COMPATIBLE, don't include bottom and right edges */
+  if(W32kGetGraphicsMode(hdc)==GM_COMPATIBLE)
+  {
+    corners[1].x--;
+    corners[1].y--;
+  }
+
+  /* Close any previous figure */
+  if(!W32kCloseFigure(hdc))
+  {
+    /* The W32kCloseFigure call shouldn't have failed */
+    assert(FALSE);
+    return FALSE;
+  }
+
+  /* Add four points to the path */
+  pointTemp.x=corners[1].x;
+  pointTemp.y=corners[0].y;
+  if(!PATH_AddEntry(pPath, &pointTemp, PT_MOVETO))
+    return FALSE;
+  if(!PATH_AddEntry(pPath, corners, PT_LINETO))
+    return FALSE;
+  pointTemp.x=corners[0].x;
+  pointTemp.y=corners[1].y;
+  if(!PATH_AddEntry(pPath, &pointTemp, PT_LINETO))
+    return FALSE;
+  if(!PATH_AddEntry(pPath, corners+1, PT_LINETO))
+    return FALSE;
+
+  /* Close the rectangle figure */
+  if(!W32kCloseFigure(hdc))
+  {
+    /* The W32kCloseFigure call shouldn't have failed */
+    assert(FALSE);
+    return FALSE;
+  }
+
+  return TRUE;
 }
 
 /* PATH_Ellipse
@@ -349,9 +349,9 @@ BOOL PATH_Rectangle(HDC hdc, INT x1, INT y1, INT x2, INT y2)
  */
 BOOL PATH_Ellipse(HDC hdc, INT x1, INT y1, INT x2, INT y2)
 {
-   /* TODO: This should probably be revised to call PATH_AngleArc */
-   /* (once it exists) */
-   return PATH_Arc(hdc, x1, y1, x2, y2, x1, (y1+y2)/2, x1, (y1+y2)/2);
+  /* TODO: This should probably be revised to call PATH_AngleArc */
+  /* (once it exists) */
+  return PATH_Arc(hdc, x1, y1, x2, y2, x1, (y1+y2)/2, x1, (y1+y2)/2);
 }
 
 /* PATH_Arc
@@ -363,328 +363,327 @@ BOOL PATH_Ellipse(HDC hdc, INT x1, INT y1, INT x2, INT y2)
 BOOL PATH_Arc(HDC hdc, INT x1, INT y1, INT x2, INT y2,
    INT xStart, INT yStart, INT xEnd, INT yEnd)
 {
-   GdiPath     *pPath;
-   DC          *pDC;
-   double      angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0;
-               /* Initialize angleEndQuadrant to silence gcc's warning */
-   double      x, y;
-   FLOAT_POINT corners[2], pointStart, pointEnd;
-   BOOL      start, end;
-   INT       temp;
-
-   /* FIXME: This function should check for all possible error returns */
-   /* FIXME: Do we have to respect newStroke? */
+  GdiPath *pPath;
+  DC      *pDC;
+  double  angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0;
+          /* Initialize angleEndQuadrant to silence gcc's warning */
+  double  x, y;
+  FLOAT_POINT corners[2], pointStart, pointEnd;
+  BOOL    start, end;
+  INT     temp;
+
+  /* FIXME: This function should check for all possible error returns */
+  /* FIXME: Do we have to respect newStroke? */
    
-   /* Get pointer to DC */
-   pDC=DC_HandleToPtr(hdc);
-   if(pDC==NULL)
-      return FALSE;
-
-   /* Get pointer to path */
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
+  /* Get pointer to DC */
+  pDC=DC_HandleToPtr(hdc);
+  if(pDC==NULL)
+    return FALSE;
+
+  /* Get pointer to path */
+  if(!PATH_GetPathFromHDC(hdc, &pPath))
+    return FALSE;
    
-   /* Check that path is open */
-   if(pPath->state!=PATH_Open)
-      return FALSE;
+  /* Check that path is open */
+  if(pPath->state!=PATH_Open)
+    return FALSE;
 
-   /* FIXME: Do we have to close the current figure? */
+  /* FIXME: Do we have to close the current figure? */
    
-   /* Check for zero height / width */
-   /* FIXME: Only in GM_COMPATIBLE? */
-   if(x1==x2 || y1==y2)
-      return TRUE;
+  /* Check for zero height / width */
+  /* FIXME: Only in GM_COMPATIBLE? */
+  if(x1==x2 || y1==y2)
+    return TRUE;
    
-   /* Convert points to device coordinates */
-   corners[0].x=(FLOAT)x1;
-   corners[0].y=(FLOAT)y1;
-   corners[1].x=(FLOAT)x2;
-   corners[1].y=(FLOAT)y2;
-   pointStart.x=(FLOAT)xStart;
-   pointStart.y=(FLOAT)yStart;
-   pointEnd.x=(FLOAT)xEnd;
-   pointEnd.y=(FLOAT)yEnd;
-   INTERNAL_LPTODP_FLOAT(pDC, corners);
-   INTERNAL_LPTODP_FLOAT(pDC, corners+1);
-   INTERNAL_LPTODP_FLOAT(pDC, &pointStart);
-   INTERNAL_LPTODP_FLOAT(pDC, &pointEnd);
-
-   /* Make sure first corner is top left and second corner is bottom right */
-   if(corners[0].x>corners[1].x)
-   {
-      temp=corners[0].x;
-      corners[0].x=corners[1].x;
-      corners[1].x=temp;
-   }
-   if(corners[0].y>corners[1].y)
-   {
-      temp=corners[0].y;
-      corners[0].y=corners[1].y;
-      corners[1].y=temp;
-   }
-
-   /* Compute start and end angle */
-   PATH_NormalizePoint(corners, &pointStart, &x, &y);
-   angleStart=atan2(y, x);
-   PATH_NormalizePoint(corners, &pointEnd, &x, &y);
-   angleEnd=atan2(y, x);
-
-   /* Make sure the end angle is "on the right side" of the start angle */
-   if(W32kGetArcDirection(hdc)==AD_CLOCKWISE)
-   {
-      if(angleEnd<=angleStart)
-      {
-         angleEnd+=2*M_PI;
-        assert(angleEnd>=angleStart);
-      }
-   }
-   else
-   {
-      if(angleEnd>=angleStart)
-      {
-         angleEnd-=2*M_PI;
-        assert(angleEnd<=angleStart);
-      }
-   }
-
-   /* In GM_COMPATIBLE, don't include bottom and right edges */
-   if(W32kGetGraphicsMode(hdc)==GM_COMPATIBLE)
-   {
-      corners[1].x--;
-      corners[1].y--;
-   }
+  /* Convert points to device coordinates */
+  corners[0].x=(FLOAT)x1;
+  corners[0].y=(FLOAT)y1;
+  corners[1].x=(FLOAT)x2;
+  corners[1].y=(FLOAT)y2;
+  pointStart.x=(FLOAT)xStart;
+  pointStart.y=(FLOAT)yStart;
+  pointEnd.x=(FLOAT)xEnd;
+  pointEnd.y=(FLOAT)yEnd;
+  INTERNAL_LPTODP_FLOAT(pDC, corners);
+  INTERNAL_LPTODP_FLOAT(pDC, corners+1);
+  INTERNAL_LPTODP_FLOAT(pDC, &pointStart);
+  INTERNAL_LPTODP_FLOAT(pDC, &pointEnd);
+
+  /* Make sure first corner is top left and second corner is bottom right */
+  if(corners[0].x>corners[1].x)
+  {
+    temp=corners[0].x;
+    corners[0].x=corners[1].x;
+    corners[1].x=temp;
+  }
+  if(corners[0].y>corners[1].y)
+  {
+    temp=corners[0].y;
+    corners[0].y=corners[1].y;
+    corners[1].y=temp;
+  }
+
+  /* Compute start and end angle */
+  PATH_NormalizePoint(corners, &pointStart, &x, &y);
+  angleStart=atan2(y, x);
+  PATH_NormalizePoint(corners, &pointEnd, &x, &y);
+  angleEnd=atan2(y, x);
+
+  /* Make sure the end angle is "on the right side" of the start angle */
+  if(W32kGetArcDirection(hdc)==AD_CLOCKWISE)
+  {
+    if(angleEnd<=angleStart)
+    {
+      angleEnd+=2*M_PI;
+      assert(angleEnd>=angleStart);
+    }
+  }
+  else
+  {
+    if(angleEnd>=angleStart)
+    {
+      angleEnd-=2*M_PI;
+      assert(angleEnd<=angleStart);
+    }
+  }
+
+  /* In GM_COMPATIBLE, don't include bottom and right edges */
+  if(W32kGetGraphicsMode(hdc)==GM_COMPATIBLE)
+  {
+    corners[1].x--;
+    corners[1].y--;
+  }
    
-   /* Add the arc to the path with one Bezier spline per quadrant that the
-    * arc spans */
-   start=TRUE;
-   end=FALSE;
-   do
-   {
-      /* Determine the start and end angles for this quadrant */
-      if(start)
-      {
-         angleStartQuadrant=angleStart;
-        if(W32kGetArcDirection(hdc)==AD_CLOCKWISE)
-           angleEndQuadrant=(floor(angleStart/M_PI_2)+1.0)*M_PI_2;
-        else
-           angleEndQuadrant=(ceil(angleStart/M_PI_2)-1.0)*M_PI_2;
-      }
+  /* Add the arc to the path with one Bezier spline per quadrant that the
+   * arc spans */
+  start=TRUE;
+  end=FALSE;
+  do
+  {
+    /* Determine the start and end angles for this quadrant */
+    if(start)
+    {
+      angleStartQuadrant=angleStart;
+      if(W32kGetArcDirection(hdc)==AD_CLOCKWISE)
+        angleEndQuadrant=(floor(angleStart/M_PI_2)+1.0)*M_PI_2;
       else
-      {
-        angleStartQuadrant=angleEndQuadrant;
-        if(W32kGetArcDirection(hdc)==AD_CLOCKWISE)
-           angleEndQuadrant+=M_PI_2;
-        else
-           angleEndQuadrant-=M_PI_2;
-      }
-
-      /* Have we reached the last part of the arc? */
-      if((W32kGetArcDirection(hdc)==AD_CLOCKWISE &&
-         angleEnd<angleEndQuadrant) ||
-        (W32kGetArcDirection(hdc)==AD_COUNTERCLOCKWISE &&
-        angleEnd>angleEndQuadrant))
-      {
-        /* Adjust the end angle for this quadrant */
-         angleEndQuadrant=angleEnd;
-        end=TRUE;
-      }
-
-      /* Add the Bezier spline to the path */
-      PATH_DoArcPart(pPath, corners, angleStartQuadrant, angleEndQuadrant,
-         start);
-      start=FALSE;
-   }  while(!end);
-
-   return TRUE;
+        angleEndQuadrant=(ceil(angleStart/M_PI_2)-1.0)*M_PI_2;
+    }
+    else
+    {
+      angleStartQuadrant=angleEndQuadrant;
+      if(W32kGetArcDirection(hdc)==AD_CLOCKWISE)
+        angleEndQuadrant+=M_PI_2;
+      else
+        angleEndQuadrant-=M_PI_2;
+    }
+
+    /* Have we reached the last part of the arc? */
+    if((W32kGetArcDirection(hdc)==AD_CLOCKWISE &&
+        angleEnd<angleEndQuadrant) ||
+        (W32kGetArcDirection(hdc)==AD_COUNTERCLOCKWISE &&
+        angleEnd>angleEndQuadrant))
+    {
+      /* Adjust the end angle for this quadrant */
+     angleEndQuadrant=angleEnd;
+     end=TRUE;
+    }
+
+    /* Add the Bezier spline to the path */
+    PATH_DoArcPart(pPath, corners, angleStartQuadrant, angleEndQuadrant, start);
+    start=FALSE;
+  }  while(!end);
+
+  return TRUE;
 }
 
 BOOL PATH_PolyBezierTo(HDC hdc, const POINT *pts, DWORD cbPoints)
 {
-   GdiPath     *pPath;
-   POINT       pt;
-   INT         i;
+  GdiPath *pPath;
+  POINT pt;
+  INT i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
+  if(!PATH_GetPathFromHDC(hdc, &pPath))
+    return FALSE;
    
-   /* Check that path is open */
-   if(pPath->state!=PATH_Open)
-      return FALSE;
-
-   /* Add a PT_MOVETO if necessary */
-   if(pPath->newStroke)
-   {
-      pPath->newStroke=FALSE;
-      if(!W32kGetCurrentPositionEx(hdc, &pt) ||
-         !W32kLPtoDP(hdc, &pt, 1))
-         return FALSE;
-      if(!PATH_AddEntry(pPath, &pt, PT_MOVETO))
-         return FALSE;
-   }
-
-   for(i = 0; i < cbPoints; i++) {
-       pt = pts[i];
-       if(!W32kLPtoDP(hdc, &pt, 1))
-          return FALSE;
-       PATH_AddEntry(pPath, &pt, PT_BEZIERTO);
-   }
-   return TRUE;
+  /* Check that path is open */
+  if(pPath->state!=PATH_Open)
+    return FALSE;
+
+  /* Add a PT_MOVETO if necessary */
+  if(pPath->newStroke)
+  {
+    pPath->newStroke=FALSE;
+    if(!W32kGetCurrentPositionEx(hdc, &pt) ||
+       !W32kLPtoDP(hdc, &pt, 1))
+        return FALSE;
+    if(!PATH_AddEntry(pPath, &pt, PT_MOVETO))
+        return FALSE;
+  }
+
+  for(i = 0; i < cbPoints; i++) {
+    pt = pts[i];
+    if(!W32kLPtoDP(hdc, &pt, 1))
+      return FALSE;
+    PATH_AddEntry(pPath, &pt, PT_BEZIERTO);
+  }
+  return TRUE;
 }
    
 BOOL PATH_PolyBezier(HDC hdc, const POINT *pts, DWORD cbPoints)
 {
-   GdiPath     *pPath;
-   POINT       pt;
-   INT         i;
+  GdiPath *pPath;
+  POINT   pt;
+  INT     i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
+  if(!PATH_GetPathFromHDC(hdc, &pPath))
+    return FALSE;
    
    /* Check that path is open */
-   if(pPath->state!=PATH_Open)
-      return FALSE;
+  if(pPath->state!=PATH_Open)
+    return FALSE;
 
-   for(i = 0; i < cbPoints; i++) {
-       pt = pts[i];
-       if(!W32kLPtoDP(hdc, &pt, 1))
-          return FALSE;
-       PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO);
-   }
-   return TRUE;
+  for(i = 0; i < cbPoints; i++) {
+    pt = pts[i];
+    if(!W32kLPtoDP(hdc, &pt, 1))
+      return FALSE;
+    PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO);
+  }
+  return TRUE;
 }
 
 BOOL PATH_Polyline(HDC hdc, const POINT *pts, DWORD cbPoints)
 {
-   GdiPath     *pPath;
-   POINT       pt;
-   INT         i;
+  GdiPath *pPath;
+  POINT   pt;
+  INT     i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
+  if(!PATH_GetPathFromHDC(hdc, &pPath))
+    return FALSE;
    
-   /* Check that path is open */
-   if(pPath->state!=PATH_Open)
-      return FALSE;
+  /* Check that path is open */
+  if(pPath->state!=PATH_Open)
+    return FALSE;
 
-   for(i = 0; i < cbPoints; i++) {
-       pt = pts[i];
-       if(!W32kLPtoDP(hdc, &pt, 1))
-          return FALSE;
-       PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_LINETO);
-   }
-   return TRUE;
+  for(i = 0; i < cbPoints; i++) {
+    pt = pts[i];
+    if(!W32kLPtoDP(hdc, &pt, 1))
+      return FALSE;
+    PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_LINETO);
+  }
+  return TRUE;
 }
    
 BOOL PATH_PolylineTo(HDC hdc, const POINT *pts, DWORD cbPoints)
 {
-   GdiPath     *pPath;
-   POINT       pt;
-   INT         i;
+  GdiPath *pPath;
+  POINT   pt;
+  INT     i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
+  if(!PATH_GetPathFromHDC(hdc, &pPath))
+    return FALSE;
    
-   /* Check that path is open */
-   if(pPath->state!=PATH_Open)
-      return FALSE;
+  /* Check that path is open */
+  if(pPath->state!=PATH_Open)
+    return FALSE;
 
-   /* Add a PT_MOVETO if necessary */
-   if(pPath->newStroke)
-   {
-      pPath->newStroke=FALSE;
-      if(!W32kGetCurrentPositionEx(hdc, &pt) ||
-         !W32kLPtoDP(hdc, &pt, 1))
-         return FALSE;
-      if(!PATH_AddEntry(pPath, &pt, PT_MOVETO))
-         return FALSE;
-   }
+  /* Add a PT_MOVETO if necessary */
+  if(pPath->newStroke)
+  {
+    pPath->newStroke=FALSE;
+    if(!W32kGetCurrentPositionEx(hdc, &pt) ||
+       !W32kLPtoDP(hdc, &pt, 1))
+      return FALSE;
+    if(!PATH_AddEntry(pPath, &pt, PT_MOVETO))
+      return FALSE;
+  }
 
-   for(i = 0; i < cbPoints; i++) {
-       pt = pts[i];
-       if(!W32kLPtoDP(hdc, &pt, 1))
-          return FALSE;
-       PATH_AddEntry(pPath, &pt, PT_LINETO);
-   }
+  for(i = 0; i < cbPoints; i++) {
+    pt = pts[i];
+    if(!W32kLPtoDP(hdc, &pt, 1))
+      return FALSE;
+    PATH_AddEntry(pPath, &pt, PT_LINETO);
+  }
 
-   return TRUE;
+  return TRUE;
 }
 
 
 BOOL PATH_Polygon(HDC hdc, const POINT *pts, DWORD cbPoints)
 {
-   GdiPath     *pPath;
-   POINT       pt;
-   INT         i;
+  GdiPath *pPath;
+  POINT   pt;
+  INT     i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
+  if(!PATH_GetPathFromHDC(hdc, &pPath))
+    return FALSE;
    
-   /* Check that path is open */
-   if(pPath->state!=PATH_Open)
-      return FALSE;
+  /* Check that path is open */
+  if(pPath->state!=PATH_Open)
+    return FALSE;
 
-   for(i = 0; i < cbPoints; i++) {
-       pt = pts[i];
-       if(!W32kLPtoDP(hdc, &pt, 1))
-          return FALSE;
-       PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO :
-                    ((i == cbPoints-1) ? PT_LINETO | PT_CLOSEFIGURE :
-                     PT_LINETO));
-   }
-   return TRUE;
+  for(i = 0; i < cbPoints; i++) {
+    pt = pts[i];
+    if(!W32kLPtoDP(hdc, &pt, 1))
+      return FALSE;
+    PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO :
+      ((i == cbPoints-1) ? PT_LINETO | PT_CLOSEFIGURE :
+      PT_LINETO));
+  }
+  return TRUE;
 }
 
 BOOL PATH_PolyPolygon( HDC hdc, const POINT* pts, const INT* counts,
                       UINT polygons )
 {
-   GdiPath     *pPath;
-   POINT       pt, startpt;
-   INT         poly, point, i;
+  GdiPath *pPath;
+  POINT   pt, startpt;
+  INT     poly, point, i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
+  if(!PATH_GetPathFromHDC(hdc, &pPath))
+    return FALSE;
    
-   /* Check that path is open */
-   if(pPath->state!=PATH_Open)
-      return FALSE;
-
-   for(i = 0, poly = 0; poly < polygons; poly++) {
-       for(point = 0; point < counts[poly]; point++, i++) {
-          pt = pts[i];
-          if(!W32kLPtoDP(hdc, &pt, 1))
-              return FALSE;
-          if(point == 0) startpt = pt;
-          PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO);
-       }
-       /* win98 adds an extra line to close the figure for some reason */
-       PATH_AddEntry(pPath, &startpt, PT_LINETO | PT_CLOSEFIGURE);
-   }
-   return TRUE;
+  /* Check that path is open */
+  if(pPath->state!=PATH_Open)
+    return FALSE;
+
+  for(i = 0, poly = 0; poly < polygons; poly++) {
+    for(point = 0; point < counts[poly]; point++, i++) {
+      pt = pts[i];
+      if(!W32kLPtoDP(hdc, &pt, 1))
+         return FALSE;
+      if(point == 0) startpt = pt;
+        PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO);
+    }
+    /* win98 adds an extra line to close the figure for some reason */
+    PATH_AddEntry(pPath, &startpt, PT_LINETO | PT_CLOSEFIGURE);
+  }
+  return TRUE;
 }
 
 BOOL PATH_PolyPolyline( HDC hdc, const POINT* pts, const DWORD* counts,
                        DWORD polylines )
 {
-   GdiPath     *pPath;
-   POINT       pt;
-   INT         poly, point, i;
+  GdiPath *pPath;
+  POINT   pt;
+  INT     poly, point, i;
 
-   if(!PATH_GetPathFromHDC(hdc, &pPath))
-      return FALSE;
+  if(!PATH_GetPathFromHDC(hdc, &pPath))
+    return FALSE;
    
-   /* Check that path is open */
-   if(pPath->state!=PATH_Open)
-      return FALSE;
-
-   for(i = 0, poly = 0; poly < polylines; poly++) {
-       for(point = 0; point < counts[poly]; point++, i++) {
-          pt = pts[i];
-          if(!W32kLPtoDP(hdc, &pt, 1))
-              return FALSE;
-          PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO);
-       }
-   }
-   return TRUE;
+  /* Check that path is open */
+  if(pPath->state!=PATH_Open)
+    return FALSE;
+
+  for(i = 0, poly = 0; poly < polylines; poly++) {
+    for(point = 0; point < counts[poly]; point++, i++) {
+      pt = pts[i];
+      if(!W32kLPtoDP(hdc, &pt, 1))
+        return FALSE;
+      PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO);
+    }
+  }
+  return TRUE;
 }
    
 /***********************************************************************
@@ -697,17 +696,17 @@ BOOL PATH_PolyPolyline( HDC hdc, const POINT* pts, const DWORD* counts,
  */
 static BOOL PATH_AddFlatBezier(GdiPath *pPath, POINT *pt, BOOL closed)
 {
-    POINT *pts;
-    INT no, i;
+  POINT *pts;
+  INT no, i;
 
-    pts = GDI_Bezier( pt, 4, &no );
-    if(!pts) return FALSE;
+  pts = GDI_Bezier( pt, 4, &no );
+  if(!pts) return FALSE;
 
-    for(i = 1; i < no; i++)
-        PATH_AddEntry(pPath, &pts[i], 
-           (i == no-1 && closed) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO);
-    ExFreePool(pts);
-    return TRUE;
+  for(i = 1; i < no; i++)
+    PATH_AddEntry(pPath, &pts[i],  (i == no-1 && closed) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO);
+
+  ExFreePool(pts);
+  return TRUE;
 }
 
 /* PATH_FlattenPath
@@ -717,29 +716,27 @@ static BOOL PATH_AddFlatBezier(GdiPath *pPath, POINT *pt, BOOL closed)
  */
 static BOOL PATH_FlattenPath(GdiPath *pPath)
 {
-    GdiPath newPath;
-    INT srcpt;
-
-    memset(&newPath, 0, sizeof(newPath));
-    newPath.state = PATH_Open;
-    for(srcpt = 0; srcpt < pPath->numEntriesUsed; srcpt++) {
-        switch(pPath->pFlags[srcpt] & ~PT_CLOSEFIGURE) {
-       case PT_MOVETO:
-       case PT_LINETO:
-           PATH_AddEntry(&newPath, &pPath->pPoints[srcpt],
-                         pPath->pFlags[srcpt]);
-           break;
-       case PT_BEZIERTO:
-         PATH_AddFlatBezier(&newPath, &pPath->pPoints[srcpt-1],
-                            pPath->pFlags[srcpt+2] & PT_CLOSEFIGURE);
-           srcpt += 2;
-           break;
-       }
+  GdiPath newPath;
+  INT srcpt;
+
+  memset(&newPath, 0, sizeof(newPath));
+  newPath.state = PATH_Open;
+  for(srcpt = 0; srcpt < pPath->numEntriesUsed; srcpt++) {
+    switch(pPath->pFlags[srcpt] & ~PT_CLOSEFIGURE) {
+      case PT_MOVETO:
+      case PT_LINETO:
+        PATH_AddEntry(&newPath, &pPath->pPoints[srcpt], pPath->pFlags[srcpt]);
+        break;
+      case PT_BEZIERTO:
+        PATH_AddFlatBezier(&newPath, &pPath->pPoints[srcpt-1], pPath->pFlags[srcpt+2] & PT_CLOSEFIGURE);
+        srcpt += 2;
+        break;
     }
-    newPath.state = PATH_Closed;
-    PATH_AssignGdiPath(pPath, &newPath);
-    PATH_EmptyPath(&newPath);
-    return TRUE;
+  }
+  newPath.state = PATH_Closed;
+  PATH_AssignGdiPath(pPath, &newPath);
+  PATH_EmptyPath(&newPath);
+  return TRUE;
 }
          
 /* PATH_PathToRegion
@@ -753,61 +750,61 @@ static BOOL PATH_FlattenPath(GdiPath *pPath)
 static BOOL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode,
    HRGN *pHrgn)
 {
-   int    numStrokes, iStroke, i;
-   INT  *pNumPointsInStroke;
-   HRGN hrgn;
+  int    numStrokes, iStroke, i;
+  INT  *pNumPointsInStroke;
+  HRGN hrgn;
 
-   assert(pPath!=NULL);
-   assert(pHrgn!=NULL);
+  assert(pPath!=NULL);
+  assert(pHrgn!=NULL);
 
-      PATH_FlattenPath(pPath);
+  PATH_FlattenPath(pPath);
 
-   /* FIXME: What happens when number of points is zero? */
+  /* FIXME: What happens when number of points is zero? */
    
-   /* First pass: Find out how many strokes there are in the path */
-   /* FIXME: We could eliminate this with some bookkeeping in GdiPath */
-   numStrokes=0;
-   for(i=0; i<pPath->numEntriesUsed; i++)
-      if((pPath->pFlags[i] & ~PT_CLOSEFIGURE) == PT_MOVETO)
-         numStrokes++;
-
-   /* Allocate memory for number-of-points-in-stroke array */
-   pNumPointsInStroke=(int *)ExAllocatePool(NonPagedPool, sizeof(int) * numStrokes);
-   if(!pNumPointsInStroke)
-   {
-//      SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-      return FALSE;
-   }
+  /* First pass: Find out how many strokes there are in the path */
+  /* FIXME: We could eliminate this with some bookkeeping in GdiPath */
+  numStrokes=0;
+  for(i=0; i<pPath->numEntriesUsed; i++)
+    if((pPath->pFlags[i] & ~PT_CLOSEFIGURE) == PT_MOVETO)
+      numStrokes++;
+
+  /* Allocate memory for number-of-points-in-stroke array */
+  pNumPointsInStroke=(int *)ExAllocatePool(NonPagedPool, sizeof(int) * numStrokes);
+  if(!pNumPointsInStroke)
+  {
+//    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    return FALSE;
+  }
    
-   /* Second pass: remember number of points in each polygon */
-   iStroke=-1;  /* Will get incremented to 0 at beginning of first stroke */
-   for(i=0; i<pPath->numEntriesUsed; i++)
-   {
-      /* Is this the beginning of a new stroke? */
-      if((pPath->pFlags[i] & ~PT_CLOSEFIGURE) == PT_MOVETO)
-      {
-         iStroke++;
-        pNumPointsInStroke[iStroke]=0;
-      }
-
-      pNumPointsInStroke[iStroke]++;
-   }
-
-   /* Create a region from the strokes */
-/*   hrgn=CreatePolyPolygonRgn(pPath->pPoints, pNumPointsInStroke,
-      numStrokes, nPolyFillMode); FIXME: reinclude when region code implemented */
-   if(hrgn==(HRGN)0)
-   {
-//      SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-      return FALSE;
-   }
+  /* Second pass: remember number of points in each polygon */
+  iStroke=-1;  /* Will get incremented to 0 at beginning of first stroke */
+  for(i=0; i<pPath->numEntriesUsed; i++)
+  {
+    /* Is this the beginning of a new stroke? */
+    if((pPath->pFlags[i] & ~PT_CLOSEFIGURE) == PT_MOVETO)
+    {
+      iStroke++;
+      pNumPointsInStroke[iStroke]=0;
+    }
 
-   /* Free memory for number-of-points-in-stroke array */
-   ExFreePool(pNumPointsInStroke);
+    pNumPointsInStroke[iStroke]++;
+  }
 
-   /* Success! */
-   *pHrgn=hrgn;
-   return TRUE;
+  /* Create a region from the strokes */
+/*  hrgn=CreatePolyPolygonRgn(pPath->pPoints, pNumPointsInStroke,
+    numStrokes, nPolyFillMode); FIXME: reinclude when region code implemented */
+  if(hrgn==(HRGN)0)
+  {
+//    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    return FALSE;
+  }
+
+  /* Free memory for number-of-points-in-stroke array */
+  ExFreePool(pNumPointsInStroke);
+
+  /* Success! */
+  *pHrgn=hrgn;
+  return TRUE;
 }
 
 /* PATH_EmptyPath
@@ -816,10 +813,10 @@ static BOOL PATH_PathToRegion(const GdiPath *pPath, INT nPolyFillMode,
  */
 static void PATH_EmptyPath(GdiPath *pPath)
 {
-   assert(pPath!=NULL);
+  assert(pPath!=NULL);
 
-   pPath->state=PATH_Null;
-   pPath->numEntriesUsed=0;
+  pPath->state=PATH_Null;
+  pPath->numEntriesUsed=0;
 }
 
 /* PATH_AddEntry
@@ -830,32 +827,32 @@ static void PATH_EmptyPath(GdiPath *pPath)
  */
 BOOL PATH_AddEntry(GdiPath *pPath, const POINT *pPoint, BYTE flags)
 {
-   assert(pPath!=NULL);
+  assert(pPath!=NULL);
    
-   /* FIXME: If newStroke is true, perhaps we want to check that we're
-    * getting a PT_MOVETO
-    */
+  /* FIXME: If newStroke is true, perhaps we want to check that we're
+   * getting a PT_MOVETO
+   */
 
-   /* Check that path is open */
-   if(pPath->state!=PATH_Open)
-      return FALSE;
+  /* Check that path is open */
+  if(pPath->state!=PATH_Open)
+    return FALSE;
    
-   /* Reserve enough memory for an extra path entry */
-   if(!PATH_ReserveEntries(pPath, pPath->numEntriesUsed+1))
-      return FALSE;
+  /* Reserve enough memory for an extra path entry */
+  if(!PATH_ReserveEntries(pPath, pPath->numEntriesUsed+1))
+    return FALSE;
 
-   /* Store information in path entry */
-   pPath->pPoints[pPath->numEntriesUsed]=*pPoint;
-   pPath->pFlags[pPath->numEntriesUsed]=flags;
+  /* Store information in path entry */
+  pPath->pPoints[pPath->numEntriesUsed]=*pPoint;
+  pPath->pFlags[pPath->numEntriesUsed]=flags;
 
-   /* If this is PT_CLOSEFIGURE, we have to start a new stroke next time */
-   if((flags & PT_CLOSEFIGURE) == PT_CLOSEFIGURE)
-      pPath->newStroke=TRUE;
+  /* If this is PT_CLOSEFIGURE, we have to start a new stroke next time */
+  if((flags & PT_CLOSEFIGURE) == PT_CLOSEFIGURE)
+    pPath->newStroke=TRUE;
 
-   /* Increment entry count */
-   pPath->numEntriesUsed++;
+  /* Increment entry count */
+  pPath->numEntriesUsed++;
 
-   return TRUE;
+  return TRUE;
 }
 
 /* PATH_ReserveEntries
@@ -866,59 +863,55 @@ BOOL PATH_AddEntry(GdiPath *pPath, const POINT *pPoint, BYTE flags)
  */
 static BOOL PATH_ReserveEntries(GdiPath *pPath, INT numEntries)
 {
-   INT   numEntriesToAllocate;
-   POINT *pPointsNew;
-   BYTE    *pFlagsNew;
+  INT   numEntriesToAllocate;
+  POINT *pPointsNew;
+  BYTE    *pFlagsNew;
    
-   assert(pPath!=NULL);
-   assert(numEntries>=0);
-
-   /* Do we have to allocate more memory? */
-   if(numEntries > pPath->numEntriesAllocated)
-   {
-      /* Find number of entries to allocate. We let the size of the array
-       * grow exponentially, since that will guarantee linear time
-       * complexity. */
-      if(pPath->numEntriesAllocated)
-      {
-        numEntriesToAllocate=pPath->numEntriesAllocated;
-        while(numEntriesToAllocate<numEntries)
-           numEntriesToAllocate=numEntriesToAllocate*GROW_FACTOR_NUMER/
-              GROW_FACTOR_DENOM;
-      }
-      else
-         numEntriesToAllocate=numEntries;
+  assert(pPath!=NULL);
+  assert(numEntries>=0);
+
+  /* Do we have to allocate more memory? */
+  if(numEntries > pPath->numEntriesAllocated)
+  {
+    /* Find number of entries to allocate. We let the size of the array
+     * grow exponentially, since that will guarantee linear time
+     * complexity. */
+    if(pPath->numEntriesAllocated)
+    {
+      numEntriesToAllocate=pPath->numEntriesAllocated;
+      while(numEntriesToAllocate<numEntries)
+        numEntriesToAllocate=numEntriesToAllocate*GROW_FACTOR_NUMER/GROW_FACTOR_DENOM;
+    } else
+       numEntriesToAllocate=numEntries;
+
+    /* Allocate new arrays */
+    pPointsNew=(POINT *)ExAllocatePool(NonPagedPool, numEntriesToAllocate * sizeof(POINT));
+    if(!pPointsNew)
+      return FALSE;
+    pFlagsNew=(BYTE *)ExAllocatePool(NonPagedPool, numEntriesToAllocate * sizeof(BYTE));
+    if(!pFlagsNew)
+    {
+      ExFreePool(pPointsNew);
+      return FALSE;
+    }
 
-      /* Allocate new arrays */
-      pPointsNew=(POINT *)ExAllocatePool(NonPagedPool, numEntriesToAllocate * sizeof(POINT));
-      if(!pPointsNew)
-         return FALSE;
-      pFlagsNew=(BYTE *)ExAllocatePool(NonPagedPool, numEntriesToAllocate * sizeof(BYTE));
-      if(!pFlagsNew)
-      {
-         ExFreePool(pPointsNew);
-        return FALSE;
-      }
-
-      /* Copy old arrays to new arrays and discard old arrays */
-      if(pPath->pPoints)
-      {
-         assert(pPath->pFlags);
-
-        memcpy(pPointsNew, pPath->pPoints,
-            sizeof(POINT)*pPath->numEntriesUsed);
-        memcpy(pFlagsNew, pPath->pFlags,
-            sizeof(BYTE)*pPath->numEntriesUsed);
-
-        ExFreePool(pPath->pPoints);
-        ExFreePool(pPath->pFlags);
-      }
-      pPath->pPoints=pPointsNew;
-      pPath->pFlags=pFlagsNew;
-      pPath->numEntriesAllocated=numEntriesToAllocate;
-   }
-
-   return TRUE;
+    /* Copy old arrays to new arrays and discard old arrays */
+    if(pPath->pPoints)
+    {
+      assert(pPath->pFlags);
+
+      memcpy(pPointsNew, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed);
+      memcpy(pFlagsNew, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed);
+
+      ExFreePool(pPath->pPoints);
+      ExFreePool(pPath->pFlags);
+    }
+    pPath->pPoints=pPointsNew;
+    pPath->pFlags=pFlagsNew;
+    pPath->numEntriesAllocated=numEntriesToAllocate;
+  }
+
+  return TRUE;
 }
 
 /* PATH_GetPathFromHDC
@@ -928,16 +921,15 @@ static BOOL PATH_ReserveEntries(GdiPath *pPath, INT numEntries)
  */
 static BOOL PATH_GetPathFromHDC(HDC hdc, GdiPath **ppPath)
 {
-   DC *pDC;
-
-   pDC=DC_HandleToPtr(hdc);
-   if(pDC)
-   {
-      *ppPath=&pDC->w.path;
-      return TRUE;
-   }
-   else
-      return FALSE;
+  DC *pDC;
+
+  pDC=DC_HandleToPtr(hdc);
+  if(pDC)
+  {
+    *ppPath=&pDC->w.path;
+    return TRUE;
+  } else
+    return FALSE;
 }
 
 /* PATH_DoArcPart
@@ -952,53 +944,52 @@ static BOOL PATH_GetPathFromHDC(HDC hdc, GdiPath **ppPath)
 static BOOL PATH_DoArcPart(GdiPath *pPath, FLOAT_POINT corners[],
    double angleStart, double angleEnd, BOOL addMoveTo)
 {
-   double  halfAngle, a;
-   double  xNorm[4], yNorm[4];
-   POINT point;
-   int     i;
-
-   assert(fabs(angleEnd-angleStart)<=M_PI_2);
-
-   /* FIXME: Is there an easier way of computing this? */
-
-   /* Compute control points */
-   halfAngle=(angleEnd-angleStart)/2.0;
-   if(fabs(halfAngle)>1e-8)
-   {
-      a=4.0/3.0*(1-cos(halfAngle))/sin(halfAngle);
-      xNorm[0]=cos(angleStart);
-      yNorm[0]=sin(angleStart);
-      xNorm[1]=xNorm[0] - a*yNorm[0];
-      yNorm[1]=yNorm[0] + a*xNorm[0];
-      xNorm[3]=cos(angleEnd);
-      yNorm[3]=sin(angleEnd);
-      xNorm[2]=xNorm[3] + a*yNorm[3];
-      yNorm[2]=yNorm[3] - a*xNorm[3];
-   }
-   else
-      for(i=0; i<4; i++)
-      {
-        xNorm[i]=cos(angleStart);
-        yNorm[i]=sin(angleStart);
-      }
+  double  halfAngle, a;
+  double  xNorm[4], yNorm[4];
+  POINT point;
+  int i;
+
+  assert(fabs(angleEnd-angleStart)<=M_PI_2);
+
+  /* FIXME: Is there an easier way of computing this? */
+
+  /* Compute control points */
+  halfAngle=(angleEnd-angleStart)/2.0;
+  if(fabs(halfAngle)>1e-8)
+  {
+    a=4.0/3.0*(1-cos(halfAngle))/sin(halfAngle);
+    xNorm[0]=cos(angleStart);
+    yNorm[0]=sin(angleStart);
+    xNorm[1]=xNorm[0] - a*yNorm[0];
+    yNorm[1]=yNorm[0] + a*xNorm[0];
+    xNorm[3]=cos(angleEnd);
+    yNorm[3]=sin(angleEnd);
+    xNorm[2]=xNorm[3] + a*yNorm[3];
+    yNorm[2]=yNorm[3] - a*xNorm[3];
+  } else
+    for(i=0; i<4; i++)
+    {
+      xNorm[i]=cos(angleStart);
+      yNorm[i]=sin(angleStart);
+    }
    
-   /* Add starting point to path if desired */
-   if(addMoveTo)
-   {
-      PATH_ScaleNormalizedPoint(corners, xNorm[0], yNorm[0], &point);
-      if(!PATH_AddEntry(pPath, &point, PT_MOVETO))
-         return FALSE;
-   }
+  /* Add starting point to path if desired */
+  if(addMoveTo)
+  {
+    PATH_ScaleNormalizedPoint(corners, xNorm[0], yNorm[0], &point);
+    if(!PATH_AddEntry(pPath, &point, PT_MOVETO))
+      return FALSE;
+  }
 
-   /* Add remaining control points */
-   for(i=1; i<4; i++)
-   {
-      PATH_ScaleNormalizedPoint(corners, xNorm[i], yNorm[i], &point);
-      if(!PATH_AddEntry(pPath, &point, PT_BEZIERTO))
-         return FALSE;
-   }
+  /* Add remaining control points */
+  for(i=1; i<4; i++)
+  {
+    PATH_ScaleNormalizedPoint(corners, xNorm[i], yNorm[i], &point);
+    if(!PATH_AddEntry(pPath, &point, PT_BEZIERTO))
+      return FALSE;
+  }
 
-   return TRUE;
+  return TRUE;
 }
 
 /* PATH_ScaleNormalizedPoint
@@ -1011,10 +1002,8 @@ static BOOL PATH_DoArcPart(GdiPath *pPath, FLOAT_POINT corners[],
 static void PATH_ScaleNormalizedPoint(FLOAT_POINT corners[], double x,
    double y, POINT *pPoint)
 {
-   pPoint->x=GDI_ROUND( (double)corners[0].x +
-      (double)(corners[1].x-corners[0].x)*0.5*(x+1.0) );
-   pPoint->y=GDI_ROUND( (double)corners[0].y +
-      (double)(corners[1].y-corners[0].y)*0.5*(y+1.0) );
+  pPoint->x=GDI_ROUND( (double)corners[0].x + (double)(corners[1].x-corners[0].x)*0.5*(x+1.0) );
+  pPoint->y=GDI_ROUND( (double)corners[0].y + (double)(corners[1].y-corners[0].y)*0.5*(y+1.0) );
 }
 
 /* PATH_NormalizePoint
@@ -1026,8 +1015,6 @@ static void PATH_NormalizePoint(FLOAT_POINT corners[],
    const FLOAT_POINT *pPoint,
    double *pX, double *pY)
 {
-   *pX=(double)(pPoint->x-corners[0].x)/(double)(corners[1].x-corners[0].x) *
-      2.0 - 1.0;
-   *pY=(double)(pPoint->y-corners[0].y)/(double)(corners[1].y-corners[0].y) *
-      2.0 - 1.0;
+  *pX=(double)(pPoint->x-corners[0].x)/(double)(corners[1].x-corners[0].x) * 2.0 - 1.0;
+  *pY=(double)(pPoint->y-corners[0].y)/(double)(corners[1].y-corners[0].y) * 2.0 - 1.0;
 }
index 5bac552..d90c029 100644 (file)
@@ -1,5 +1,3 @@
-
-
 #undef WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <ddk/ntddk.h>
@@ -12,37 +10,37 @@ HPEN
 STDCALL
 W32kCreatePen(INT PenStyle, INT Width, COLORREF Color)
 {
-   LOGPEN logpen;
+  LOGPEN logpen;
 
-   logpen.lopnStyle = PenStyle; 
-   logpen.lopnWidth.x = Width;
-   logpen.lopnWidth.y = 0;
-   logpen.lopnColor = Color;
+  logpen.lopnStyle = PenStyle; 
+  logpen.lopnWidth.x = Width;
+  logpen.lopnWidth.y = 0;
+  logpen.lopnColor = Color;
 
-   return W32kCreatePenIndirect(&logpen);
+  return W32kCreatePenIndirect(&logpen);
 }
 
 HPEN
 STDCALL
 W32kCreatePenIndirect(CONST PLOGPEN lgpn)
 {
-   PPENOBJ penPtr;
-   HPEN    hpen;
+  PPENOBJ penPtr;
+  HPEN    hpen;
 
-   if (lgpn->lopnStyle > PS_INSIDEFRAME) return 0;
+  if (lgpn->lopnStyle > PS_INSIDEFRAME) return 0;
 
-   penPtr = PENOBJ_AllocPen();
-   hpen   = PENOBJ_PtrToHandle(penPtr);
-   if (!hpen) return 0;
-   PENOBJ_LockPen(hpen);
+  penPtr = PENOBJ_AllocPen();
+  hpen   = PENOBJ_PtrToHandle(penPtr);
+  if (!hpen) return 0;
+  PENOBJ_LockPen(hpen);
 
-   penPtr->logpen.lopnStyle = lgpn->lopnStyle;
-   penPtr->logpen.lopnWidth = lgpn->lopnWidth;
-   penPtr->logpen.lopnColor = lgpn->lopnColor;
+  penPtr->logpen.lopnStyle = lgpn->lopnStyle;
+  penPtr->logpen.lopnWidth = lgpn->lopnWidth;
+  penPtr->logpen.lopnColor = lgpn->lopnColor;
 
-   PENOBJ_UnlockPen(hpen);
+  PENOBJ_UnlockPen(hpen);
 
-   return hpen;
+  return hpen;
 }
 
 HPEN
index c03d1da..b8b4528 100644 (file)
@@ -1,5 +1,3 @@
-
-
 #undef WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <ddk/ntddk.h>
index c84cfec..2628109 100644 (file)
@@ -1,5 +1,3 @@
-
-
 #undef WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <ddk/ntddk.h>
index 54c5a7b..80bea0f 100644 (file)
@@ -6,10 +6,24 @@
 #include <win32k/dc.h>
 #include <win32k/text.h>
 #include <win32k/kapi.h>
+#include <freetype/freetype.h>
 
 // #define NDEBUG
 #include <win32k/debug1.h>
 
+FT_Library  library;
+
+BOOL InitFontSupport()
+{
+  ULONG error;
+
+  error = FT_Init_FreeType(&library);
+  if(error)
+  {
+    return FALSE;
+  } else return TRUE;
+}
+
 int
 STDCALL
 W32kAddFontResource(LPCWSTR  Filename)
@@ -41,7 +55,7 @@ HFONT
 STDCALL
 W32kCreateFontIndirect(CONST LPLOGFONT  lf)
 {
-  UNIMPLEMENTED;
+  DbgPrint("WARNING: W32kCreateFontIndirect is current unimplemented\n");
 }
 
 BOOL
@@ -336,9 +350,9 @@ W32kSetTextColor(HDC hDC,
   PDC  dc = DC_HandleToPtr(hDC);
   
   if (!dc) 
-    {
-      return 0x80000000;
-    }
+  {
+    return 0x80000000;
+  }
 
   oldColor = dc->w.textColor;
   dc->w.textColor = color;
@@ -364,19 +378,176 @@ W32kTextOut(HDC  hDC,
                   LPCWSTR  String,
                   int  Count)
 {
-    DC                 *dc      = DC_HandleToPtr(hDC);
-    SURFOBJ            *SurfObj = AccessUserObject(dc->Surface);
-    UNICODE_STRING     UString;
-    ANSI_STRING        AString;
+  // Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
+
+  DC *dc = DC_HandleToPtr(hDC);
+  SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
+  UNICODE_STRING FileName;
+  int error, glyph_index, n, load_flags = FT_LOAD_RENDER, i, j;
+  FT_Face face;
+  FT_GlyphSlot glyph;
+  NTSTATUS Status;
+  HANDLE FileHandle;
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  FILE_STANDARD_INFORMATION FileStdInfo;
+  PVOID buffer;
+  ULONG size, TextLeft = XStart, TextTop = YStart, SpaceBetweenChars = 5, StringLength;
+  FT_Vector origin;
+  FT_Bitmap bit, bit2, bit3;
+  POINTL SourcePoint;
+  RECTL DestRect;
+  HBITMAP HSourceGlyph;
+  PSURFOBJ SourceGlyphSurf;
+  SIZEL bitSize;
+  FT_CharMap found = 0;
+  FT_CharMap charmap;
+  PCHAR bitbuf;
+
+  // For now we're just going to use an internal font
+//  grWriteCellString(SurfObj, XStart, YStart, AString->Buffer, 0xffffff);
+
+  //  Prepare the Unicode FileName
+  RtlCreateUnicodeString(&FileName, L"\\SystemRoot\\fonts\\arial.ttf");
+
+  //  Open the Module
+  InitializeObjectAttributes(&ObjectAttributes, &FileName, 0, NULL, NULL);
+
+  Status = NtOpenFile(&FileHandle, FILE_ALL_ACCESS, &ObjectAttributes, NULL, 0, 0);
+
+  if (!NT_SUCCESS(Status))
+  {
+    DbgPrint("Could not open module file: %wZ\n", L"c:/reactos/fonts/arial.ttf");
+    return  0;
+  }
+
+  //  Get the size of the file
+  Status = NtQueryInformationFile(FileHandle, NULL, &FileStdInfo, sizeof(FileStdInfo), FileStandardInformation);
+  if (!NT_SUCCESS(Status))
+  {
+    DbgPrint("Could not get file size\n");
+    return  0;
+  }
+
+  //  Allocate nonpageable memory for driver
+  size = FileStdInfo.EndOfFile.u.LowPart;
+  buffer = ExAllocatePool(NonPagedPool, size);
+
+  if (buffer == NULL)
+  {
+    DbgPrint("could not allocate memory for module");
+    return  0;
+  }
+   
+  //  Load driver into memory chunk
+  Status = NtReadFile(FileHandle, 0, 0, 0, 0, buffer, FileStdInfo.EndOfFile.u.LowPart, 0, 0);
+  if (!NT_SUCCESS(Status))
+  {
+    DbgPrint("could not read module file into memory");
+    ExFreePool(buffer);
+
+    return  0;
+  }
+
+  NtClose(FileHandle);
+
+  error = FT_New_Memory_Face(library,
+                             buffer,    // first byte in memory
+                             size,      // size in bytes
+                             0,         // face_index
+                             &face );
+  if ( error == FT_Err_Unknown_File_Format )
+  {
+    DbgPrint("Unknown font file format\n");
+  }
+  else if ( error )
+  {
+    DbgPrint("Error reading font file\n");
+  }
+
+  DbgPrint("Family name: %s\n", face->family_name);
+  DbgPrint("Style name: %s\n", face->style_name);
+  DbgPrint("Num glyphs: %u\n", face->num_glyphs);
+  DbgPrint("Height: %d\n", face->height);
+
+  if (face->charmap == NULL)
+  {
+    DbgPrint("WARNING: No charmap selected!\n");
+    DbgPrint("This font face has %d charmaps\n", face->num_charmaps);
+
+    for ( n = 0; n < face->num_charmaps; n++ )
+    {
+      charmap = face->charmaps[n];
+      DbgPrint("found charmap encoding: %u\n", charmap->encoding);
+      if (charmap->encoding != 0)
+      {
+        found = charmap;
+        break;
+      }
+    }
+  }
+  if (!found) DbgPrint("WARNING: Could not find desired charmap!\n");
+                 
+  error = FT_Set_Charmap(face, found);
+  if (error) DbgPrint("WARNING: Could not set the charmap!\n");
+
+  error = FT_Set_Char_Size(
+              face,    // handle to face object
+              16*64,   // char_width in 1/64th of points
+              16*64,   // char_height in 1/64th of points
+              300,     // horizontal device resolution
+              300 );   // vertical device resolution
+
+  StringLength = wcslen(String);
+  DbgPrint("StringLength: %u\n", StringLength);
+
+  for(i=0; i<StringLength; i++)
+  {
+    glyph_index = FT_Get_Char_Index(face, *String);
+
+    error = FT_Load_Glyph( 
+              face,                    // handle to face object
+              glyph_index,             // glyph index
+              FT_LOAD_DEFAULT );       // load flags (erase previous glyph)
+    if(error) DbgPrint("WARNING: Failed to load and render glyph!\n");
+
+    glyph = face->glyph;
+
+    if ( glyph->format == ft_glyph_format_outline )
+    {
+      DbgPrint("Outline Format Font\n");
+      error = FT_Render_Glyph( glyph, ft_render_mode_normal );
+      if(error) DbgPrint("WARNING: Failed to render glyph!\n");
+    } else {
+      DbgPrint("Bitmap Format Font\n");
+      bit3.rows   = glyph->bitmap.rows;
+      bit3.width  = glyph->bitmap.width;
+      bit3.pitch  = glyph->bitmap.pitch;
+      bit3.buffer = glyph->bitmap.buffer;
+    }
 
-    RtlCreateUnicodeString(&UString, (PWSTR)String);
-    RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
+    SourcePoint.x      = 0;
+    SourcePoint.y      = 0;
+    DestRect.left      = TextLeft;
+    DestRect.top       = TextTop;
+    DestRect.right     = TextLeft + glyph->bitmap.width-1;
+    DestRect.bottom    = TextTop  + glyph->bitmap.rows-1;
+    bitSize.cx         = glyph->bitmap.width-1;
+    bitSize.cy         = glyph->bitmap.rows-1;
 
-    // For now we're just going to use an internal font
-    grWriteCellString(SurfObj, XStart, YStart, AString.Buffer, 0xffffff);
+    HSourceGlyph = EngCreateBitmap(bitSize, glyph->bitmap.pitch /* -1 */ , BMF_8BPP, 0, glyph->bitmap.buffer);
+    SourceGlyphSurf = AccessUserObject(HSourceGlyph);
 
-    RtlFreeAnsiString(&AString);
-    RtlFreeUnicodeString(&UString);
+    EngBitBlt(SurfObj, SourceGlyphSurf,
+              NULL, NULL, NULL, &DestRect, &SourcePoint, NULL, NULL, NULL, NULL);
+
+    TextLeft += glyph->bitmap.width + SpaceBetweenChars;
+    String++;
+  }
+
+DbgPrint("BREAK\n"); for (;;) ;
+
+/*  RtlFreeAnsiString(AString);
+    RtlFreeUnicodeString(UString); */
 }
 
 UINT
@@ -387,4 +558,3 @@ W32kTranslateCharsetInfo(PDWORD  Src,
 {
   UNIMPLEMENTED;
 }
-