Identation corrected, many fixes and minor improvements, initial DIB support

svn path=/trunk/; revision=1753
This commit is contained in:
Jason Filby 2001-03-31 15:35:08 +00:00
parent a934fd1c24
commit 14c634ca97
42 changed files with 4532 additions and 2967 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -15,212 +15,159 @@
#include "enum.h" #include "enum.h"
#include "objects.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) 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->left = max(prcSrc1->left, prcSrc2->left);
prcDst->right = min(prcSrc1->right, prcSrc2->right); prcDst->right = min(prcSrc1->right, prcSrc2->right);
if (prcDst->left < prcDst->right) if (prcDst->left < prcDst->right)
{ {
prcDst->top = max(prcSrc1->top, prcSrc2->top); prcDst->top = max(prcSrc1->top, prcSrc2->top);
prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom); prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
if (prcDst->top < prcDst->bottom) if (prcDst->top < prcDst->bottom) return(TRUE);
return(TRUE); }
}
*prcDst = rclEmpty; *prcDst = rclEmpty;
return(FALSE); return(FALSE);
} }
BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source, BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
SURFOBJ *Mask, CLIPOBJ *ClipRegion, SURFOBJ *Mask, CLIPOBJ *ClipRegion,
XLATEOBJ *ColorTranslation, RECTL *DestRect, XLATEOBJ *ColorTranslation, RECTL *DestRect,
POINTL *SourcePoint, POINTL *MaskRect, POINTL *SourcePoint, POINTL *MaskRect,
BRUSHOBJ *Brush, POINTL *BrushOrigin, ROP4 rop4) BRUSHOBJ *Brush, POINTL *BrushOrigin, ROP4 rop4)
{ {
BYTE clippingType; BYTE clippingType;
RECTL rclTmp; RECTL rclTmp;
POINTL ptlTmp; POINTL ptlTmp;
RECT_ENUM RectEnum; RECT_ENUM RectEnum;
BOOL EnumMore; BOOL EnumMore;
SURFGDI *DestGDI, *SourceGDI; PSURFGDI DestGDI, SourceGDI;
BOOLEAN canCopyBits; HSURF hTemp;
PSURFOBJ TempSurf;
BOOLEAN canCopyBits;
POINTL TempPoint;
RECTL TempRect;
SIZEL TempSize;
// If we don't have to do anything special, we can punt to DrvCopyBits SourceGDI = AccessInternalObjectFromUserObject(Source);
// 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 // If we don't have to do anything special, we can punt to DrvCopyBits
// format. Call DrvDitherColor function where necessary and if available // if it exists
if( (Mask == NULL) && (MaskRect == NULL) && (Brush == NULL) &&
(BrushOrigin == NULL) && (rop4 == 0) )
{
canCopyBits = TRUE;
} else
canCopyBits = FALSE;
// FIXME: If canCopyBits == TRUE AND the driver has a DrvCopyBits then // Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap, IF:
// punt to EngCopyBits and not the driver's DrvCopyBits just yet so // * The destination bitmap is not managed by the GDI OR
// that the EngCopyBits can take care of the clipping drivers if(Dest->iType != STYPE_BITMAP)
// DrvCopyBits {
// Destination surface is device managed
DestGDI = AccessInternalObjectFromUserObject(Dest);
// FIXME: Don't punt to DrvBitBlt straight away. Instead, mark a typedef'd if (DestGDI->BitBlt!=NULL)
// function to go there instead of the Engine's bltting function {
// so as to do the clipping for the driver // 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;
// Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap hTemp = EngCreateBitmap(TempSize,
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP)) DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)),
{ Dest->iBitmapFormat, 0, NULL);
// Destination surface is device managed TempSurf = AccessUserObject(hTemp);
if(Dest->iType!=STYPE_BITMAP)
{
DestGDI = AccessInternalObjectFromUserObject(Dest);
if ((DestGDI->CopyBits!=NULL) && (canCopyBits == TRUE)) // 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->CopyBits(Dest, Source, ClipRegion,
ColorTranslation, DestRect, SourcePoint);
}
if (DestGDI->BitBlt!=NULL) return DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion,
{ NULL, DestRect, &TempPoint,
return DestGDI->BitBlt(Dest, Source, Mask, ClipRegion, MaskRect, Brush, BrushOrigin, rop4);
ColorTranslation, DestRect, SourcePoint, }
MaskRect, Brush, BrushOrigin, rop4); }
}
}
// Source surface is device managed // * 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) if(Source->iType != STYPE_BITMAP && SourceGDI->CopyBits == NULL)
{ {
SourceGDI = AccessInternalObjectFromUserObject(Source); 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);
if ((SourceGDI->CopyBits!=NULL) && (canCopyBits == TRUE)) // Convert the surface from the driver into the required destination surface
{ }
return SourceGDI->CopyBits(Dest, Source, ClipRegion, }
ColorTranslation, DestRect, SourcePoint);
}
if (SourceGDI->BitBlt!=NULL) DestGDI = AccessInternalObjectFromUserObject(Dest);
{ SourceGDI = AccessInternalObjectFromUserObject(Source);
return SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion,
ColorTranslation, DestRect, SourcePoint,
MaskRect, Brush, BrushOrigin, rop4);
}
// Determine clipping type
if (ClipRegion == (CLIPOBJ *) NULL)
{
clippingType = DC_TRIVIAL;
} else {
clippingType = ClipRegion->iDComplexity;
}
// Should never get here, if it's not GDI managed then the device // We don't handle color translation just yet [we dont have to.. REMOVE REMOVE REMOVE]
// should take care of it switch(clippingType)
{
case DC_TRIVIAL:
CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation);
return(TRUE);
// FIXME: Error message here case DC_RECT:
}
} // Clip the blt to the clip rectangle
EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds);
DestGDI = AccessInternalObjectFromUserObject(Dest); ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
SourceGDI = AccessInternalObjectFromUserObject(Source); ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
// Determine clipping type return(TRUE);
if (ClipRegion == (CLIPOBJ *) NULL)
{
clippingType = DC_TRIVIAL;
} else {
clippingType = ClipRegion->iDComplexity;
}
// We don't handle color translation just yet case DC_COMPLEX:
if ((rop4 == 0x0000CCCC) && CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL)))
{
switch(clippingType)
{
case DC_TRIVIAL:
BitBltCopy(Dest, Source,
DestGDI, SourceGDI,
DestRect, SourcePoint, Source->lDelta);
return(TRUE); do {
EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
case DC_RECT: if (RectEnum.c > 0)
{
RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
RECTL* prcl = &RectEnum.arcl[0];
// Clip the blt to the clip rectangle do {
EngIntersectRect(prcl, prcl, DestRect);
EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds); ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left; prcl++;
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
BitBltCopy(Dest, Source, } while (prcl < prclEnd);
DestGDI, SourceGDI, }
&rclTmp, &ptlTmp, Source->lDelta);
return(TRUE); } while(EnumMore);
case DC_COMPLEX: return(TRUE);
}
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, return(FALSE);
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);
} }

View file

@ -13,11 +13,11 @@
PVOID BRUSHOBJ_pvAllocRbrush(IN PBRUSHOBJ BrushObj, PVOID BRUSHOBJ_pvAllocRbrush(IN PBRUSHOBJ BrushObj,
IN ULONG ObjSize) IN ULONG ObjSize)
{ {
BrushObj->pvRbrush=EngAllocMem(0, ObjSize, 0); BrushObj->pvRbrush=EngAllocMem(0, ObjSize, 0);
return BrushObj->pvRbrush; return BrushObj->pvRbrush;
} }
PVOID BRUSHOBJ_pvGetRbrush(IN PBRUSHOBJ BrushObj) PVOID BRUSHOBJ_pvGetRbrush(IN PBRUSHOBJ BrushObj)
{ {
return BrushObj->pvRbrush; return BrushObj->pvRbrush;
} }

View file

@ -1,23 +1,23 @@
typedef struct _BRUSHINST typedef struct _BRUSHINST
{ {
// We need to removed ajC0-3 when color pattern code is complete!!! // We need to removed ajC0-3 when color pattern code is complete!!!
// //
BYTE ajC0[8]; // Color bits for plane 0 BYTE ajC0[8]; // Color bits for plane 0
BYTE ajC1[8]; // Color bits for plane 1 BYTE ajC1[8]; // Color bits for plane 1
BYTE ajC2[8]; // Color bits for plane 2 BYTE ajC2[8]; // Color bits for plane 2
BYTE ajC3[8]; // Color bits for plane 3 BYTE ajC3[8]; // Color bits for plane 3
BYTE ajPattern[32]; // Color bits for the mask BYTE ajPattern[32]; // Color bits for the mask
USHORT usStyle; // Brush style USHORT usStyle; // Brush style
BYTE fjAccel; // Accelerator flags BYTE fjAccel; // Accelerator flags
BYTE jFgColor; // Current foreground color BYTE jFgColor; // Current foreground color
BYTE jBkColor; // Current background color BYTE jBkColor; // Current background color
BYTE RealWidth;// BYTE RealWidth;//
BYTE YShiftValue; // BYTE YShiftValue; //
BYTE jOldBrushRealized; // BYTE jOldBrushRealized; //
DWORD Width; // Width of brush DWORD Width; // Width of brush
DWORD Height; DWORD Height;
BYTE *pPattern; //Pointer to realized mono pattern BYTE *pPattern; //Pointer to realized mono pattern
} BRUSHINST; } BRUSHINST;
#define BRI_SOLID 0 #define BRI_SOLID 0

View file

@ -18,109 +18,109 @@
CLIPOBJ *EngCreateClipRegion(ULONG NumRects, RECTL Rects[], CLIPOBJ *EngCreateClipRegion(ULONG NumRects, RECTL Rects[],
ULONG Mode, ULONG Options) ULONG Mode, ULONG Options)
{ {
HCLIP NewClip; HCLIP NewClip;
CLIPOBJ *ClipObj; CLIPOBJ *ClipObj;
CLIPGDI *ClipGDI; CLIPGDI *ClipGDI;
ClipObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL); ClipObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
ClipGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPGDI), NULL); ClipGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPGDI), NULL);
NewClip = CreateGDIHandle(ClipGDI, ClipObj); NewClip = CreateGDIHandle(ClipGDI, ClipObj);
ClipGDI->NumRegionRects = NumRects; ClipGDI->NumRegionRects = NumRects;
ClipGDI->RegionRects = Rects; ClipGDI->RegionRects = Rects;
ClipObj->iMode = Mode; ClipObj->iMode = Mode;
ClipObj->fjOptions = Options; ClipObj->fjOptions = Options;
ClipObj->iDComplexity = DC_TRIVIAL; ClipObj->iDComplexity = DC_TRIVIAL;
if(NumRects == 1) if(NumRects == 1)
{ {
ClipObj->iFComplexity = FC_RECT; ClipObj->iFComplexity = FC_RECT;
ClipObj->iDComplexity = DC_RECT; ClipObj->iDComplexity = DC_RECT;
// FIXME: Is this correct?? // FIXME: Is this correct??
ClipObj->rclBounds = Rects[0]; ClipObj->rclBounds = Rects[0];
} else } else
{ {
ClipObj->iDComplexity = DC_COMPLEX; ClipObj->iDComplexity = DC_COMPLEX;
if(NumRects <= 4) if(NumRects <= 4)
{ {
ClipObj->iFComplexity = FC_RECT4; ClipObj->iFComplexity = FC_RECT4;
} else } else
{ {
ClipObj->iFComplexity = FC_COMPLEX; ClipObj->iFComplexity = FC_COMPLEX;
} }
} }
return ClipObj; return ClipObj;
} }
VOID EngDeleteClipRegion(CLIPOBJ *ClipObj) VOID EngDeleteClipRegion(CLIPOBJ *ClipObj)
{ {
HCLIP HClip = AccessHandleFromUserObject(ClipObj); HCLIP HClip = AccessHandleFromUserObject(ClipObj);
CLIPGDI *ClipGDI = AccessInternalObject(HClip); CLIPGDI *ClipGDI = AccessInternalObject(HClip);
EngFreeMem(ClipGDI); EngFreeMem(ClipGDI);
EngFreeMem(ClipObj); EngFreeMem(ClipObj);
FreeGDIHandle(HClip); FreeGDIHandle(HClip);
} }
VOID EngIntersectClipRegion(CLIPOBJ *ClipObj, ULONG NumRects, RECTL *IntersectRects) VOID EngIntersectClipRegion(CLIPOBJ *ClipObj, ULONG NumRects, RECTL *IntersectRects)
{ {
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj); CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
ClipGDI->NumIntersectRects = NumRects; ClipGDI->NumIntersectRects = NumRects;
ClipGDI->IntersectRects = IntersectRects; ClipGDI->IntersectRects = IntersectRects;
if(NumRects == 1) if(NumRects == 1)
{ {
ClipObj->iDComplexity = DC_RECT; ClipObj->iDComplexity = DC_RECT;
ClipObj->rclBounds = IntersectRects[0]; ClipObj->rclBounds = IntersectRects[0];
} else } else
{ {
ClipObj->iDComplexity = DC_COMPLEX; ClipObj->iDComplexity = DC_COMPLEX;
ClipGDI->IntersectRects = IntersectRects; ClipGDI->IntersectRects = IntersectRects;
} }
} }
CLIPOBJ *EngCreateClip(VOID) CLIPOBJ *EngCreateClip(VOID)
{ {
return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL); return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
} }
VOID EngDeleteClip(CLIPOBJ *ClipRegion) VOID EngDeleteClip(CLIPOBJ *ClipRegion)
{ {
EngFreeMem(ClipRegion); EngFreeMem(ClipRegion);
} }
ULONG CLIPOBJ_cEnumStart(IN PCLIPOBJ ClipObj, IN BOOL ShouldDoAll, ULONG CLIPOBJ_cEnumStart(IN PCLIPOBJ ClipObj, IN BOOL ShouldDoAll,
IN ULONG ClipType, IN ULONG BuildOrder, IN ULONG ClipType, IN ULONG BuildOrder,
IN ULONG MaxRects) IN ULONG MaxRects)
{ {
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj); CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
ClipGDI->EnumPos = 0; ClipGDI->EnumPos = 0;
ClipGDI->EnumRects.c = MaxRects; ClipGDI->EnumRects.c = MaxRects;
// Return the number of rectangles enumerated // Return the number of rectangles enumerated
if(ClipGDI->EnumRects.c>MaxRects) if(ClipGDI->EnumRects.c>MaxRects)
{ {
ClipGDI->EnumRects.c = 0xFFFFFFFF; ClipGDI->EnumRects.c = 0xFFFFFFFF;
} }
return ClipGDI->EnumRects.c; return ClipGDI->EnumRects.c;
} }
BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj, IN ULONG ObjSize, BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj, IN ULONG ObjSize,
OUT ULONG *EnumRects) OUT ULONG *EnumRects)
{ {
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj); CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
ClipGDI->EnumPos++; ClipGDI->EnumPos++;
if(ClipGDI->EnumPos > ClipGDI->EnumRects.c) if(ClipGDI->EnumPos > ClipGDI->EnumRects.c)
{ {
return FALSE; return FALSE;
} else } else
return TRUE; return TRUE;
} }

View file

@ -11,192 +11,153 @@
#include <ddk/winddi.h> #include <ddk/winddi.h>
#include "objects.h" #include "objects.h"
#include "enum.h" #include "enum.h"
#include "../dib/dib.h"
VOID CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, BOOLEAN CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI, SURFGDI *DestGDI, SURFGDI *SourceGDI,
PRECTL DestRect, POINTL *SourcePoint, PRECTL DestRect, POINTL *SourcePoint,
ULONG Delta, XLATEOBJ *ColorTranslation) ULONG Delta, XLATEOBJ *ColorTranslation)
{ {
ULONG dy, leftOfSource, leftOfDest, Width, SourceBPP, DestBPP, RGBulong = 0, idxColor, i, TrivialCopy = 0; ULONG DestWidth, DestHeight, CurrentDestLine, CurrentSourceLine, CurrentDestCol, CurrentSourceCol, i, TranslationPixel;
BYTE *SourcePos, *SourceInitial, *DestPos, *DestInitial;
// FIXME: Get ColorTranslation passed here and do something with it PFN_DIB_GetPixel Source_DIB_GetPixel;
PFN_DIB_PutPixel Dest_DIB_PutPixel;
if(ColorTranslation == NULL) DestWidth = DestRect->right - DestRect->left;
{ DestHeight = DestRect->bottom - DestRect->top;
TrivialCopy = 1; CurrentSourceCol = SourcePoint->x;
} else if(ColorTranslation->flXlate & XO_TRIVIAL) CurrentSourceLine = SourcePoint->y;
{
TrivialCopy = 1;
}
leftOfSource = SourcePoint->x * SourceGDI->BytesPerPixel; // Assign GetPixel DIB function according to bytes per pixel
leftOfDest = DestRect->left * DestGDI->BytesPerPixel; switch(DestGDI->BitsPerPixel)
Width = (DestRect->right - DestRect->left) * DestGDI->BytesPerPixel; {
case 4:
return DIB_To_4BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
DestRect, SourcePoint, Delta, ColorTranslation);
break;
if(TrivialCopy == 1) case 24:
{ return DIB_To_24BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
for(dy=DestRect->top; dy<DestRect->bottom; dy++) DestRect, SourcePoint, Delta, ColorTranslation);
{ break;
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 + default:
(SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x * SourceBPP); return FALSE;
SourceInitial = SourcePos; }
DestPos = DestSurf->pvBits + return TRUE;
((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;
}
} }
BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
CLIPOBJ *Clip, XLATEOBJ *ColorTranslation, CLIPOBJ *Clip, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint) RECTL *DestRect, POINTL *SourcePoint)
{ {
SURFGDI *DestGDI, *SourceGDI; SURFGDI *DestGDI, *SourceGDI;
BYTE clippingType; BYTE clippingType;
RECTL rclTmp; RECTL rclTmp;
POINTL ptlTmp; POINTL ptlTmp;
RECT_ENUM RectEnum; RECT_ENUM RectEnum;
BOOL EnumMore; 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
// FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead, // If one of the surfaces isn't managed by the GDI
// mark the copy block function to be DrvCopyBits instead of the if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
// GDI's copy bit function so as to remove clipping from the {
// driver's responsibility // Destination surface is device managed
if(Dest->iType!=STYPE_BITMAP)
{
DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
// If one of the surfaces isn't managed by the GDI if (DestGDI->CopyBits!=NULL)
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
{
// Destination surface is device managed
if(Dest->iType!=STYPE_BITMAP)
{ {
DestGDI = AccessInternalObjectFromUserObject(Dest); return DestGDI->CopyBits(Dest, Source, Clip, ColorTranslation, DestRect, SourcePoint);
if (DestGDI->CopyBits!=NULL)
{
return DestGDI->CopyBits(Dest, Source, Clip,
ColorTranslation, DestRect, SourcePoint);
}
} }
}
// Source surface is device managed // Source surface is device managed
if(Source->iType!=STYPE_BITMAP) if(Source->iType!=STYPE_BITMAP)
{
SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
if (SourceGDI->CopyBits!=NULL)
{ {
SourceGDI = AccessInternalObjectFromUserObject(Source); 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 // If CopyBits wasn't hooked, BitBlt must be
return EngBitBlt(Dest, Source, return EngBitBlt(Dest, Source,
NULL, Clip, ColorTranslation, DestRect, SourcePoint, NULL, Clip, ColorTranslation, DestRect, SourcePoint,
NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL);
} }
// Determine clipping type // Determine clipping type
if (Clip == (CLIPOBJ *) NULL) if (Clip == (CLIPOBJ *) NULL)
{ {
clippingType = DC_TRIVIAL; clippingType = DC_TRIVIAL;
} else { } else {
clippingType = Clip->iDComplexity; clippingType = Clip->iDComplexity;
} }
// We only handle XO_TABLE translations at the momement // We only handle XO_TABLE translations at the momement
if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL) || if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL) ||
(ColorTranslation->flXlate & XO_TABLE)) (ColorTranslation->flXlate & XO_TABLE))
{ {
SourceGDI = AccessInternalObjectFromUserObject(Source); SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
DestGDI = AccessInternalObjectFromUserObject(Dest); DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
switch(clippingType) switch(clippingType)
{ {
case DC_TRIVIAL: case DC_TRIVIAL:
CopyBitsCopy(Dest, Source, CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation);
DestGDI, SourceGDI, return(TRUE);
DestRect, SourcePoint, Source->lDelta, ColorTranslation);
return(TRUE); case DC_RECT:
// Clip the blt to the clip rectangle
EngIntersectRect(&rclTmp, DestRect, &Clip->rclBounds);
case DC_RECT: ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
// Clip the blt to the clip rectangle CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, &rclTmp, &ptlTmp, Source->lDelta, ColorTranslation);
EngIntersectRect(&rclTmp, DestRect, &Clip->rclBounds); return(TRUE);
ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left; case DC_COMPLEX:
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
CopyBitsCopy(Dest, Source, CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT);
DestGDI, SourceGDI,
&rclTmp, &ptlTmp, Source->lDelta, ColorTranslation);
return(TRUE); do {
EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
case DC_COMPLEX: if (RectEnum.c > 0)
{
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
CD_ANY, ENUM_RECT_LIMIT); RECTL* prcl = &RectEnum.arcl[0];
do { do {
EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum), EngIntersectRect(prcl, prcl, DestRect);
(PVOID) &RectEnum);
if (RectEnum.c > 0) ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left;
{ ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top;
RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
RECTL* prcl = &RectEnum.arcl[0];
do { if(!CopyBitsCopy(Dest, Source, DestGDI, SourceGDI,
EngIntersectRect(prcl, prcl, DestRect); prcl, &ptlTmp, Source->lDelta, ColorTranslation)) return FALSE;
ptlTmp.x = SourcePoint->x + prcl->left prcl++;
- DestRect->left;
ptlTmp.y = SourcePoint->y + prcl->top
- DestRect->top;
CopyBitsCopy(Dest, Source, } while (prcl < prclEnd);
DestGDI, SourceGDI, }
prcl, &ptlTmp, Source->lDelta, ColorTranslation);
prcl++; } while(EnumMore);
} while (prcl < prclEnd); return(TRUE);
} }
}
} while(EnumMore); return FALSE;
return(TRUE);
}
}
return FALSE;
} }

View file

@ -11,40 +11,33 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
DWORD STDCALL EngDeviceIoControl( DWORD STDCALL EngDeviceIoControl(
HANDLE hDevice, HANDLE hDevice,
DWORD dwIoControlCode, DWORD dwIoControlCode,
LPVOID lpInBuffer, LPVOID lpInBuffer,
DWORD nInBufferSize, DWORD nInBufferSize,
LPVOID lpOutBuffer, LPVOID lpOutBuffer,
DWORD nOutBufferSize, DWORD nOutBufferSize,
DWORD *lpBytesReturned) DWORD *lpBytesReturned)
{ {
PIRP Irp; PIRP Irp;
NTSTATUS Status; NTSTATUS Status;
KEVENT Event; KEVENT Event;
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
PDRIVER_OBJECT DriverObject; PDRIVER_OBJECT DriverObject;
DriverObject = hDevice; DriverObject = hDevice;
KeInitializeEvent(&Event, SynchronizationEvent, FALSE); KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
Irp = IoBuildDeviceIoControlRequest(dwIoControlCode, Irp = IoBuildDeviceIoControlRequest(dwIoControlCode, DriverObject->DeviceObject, lpInBuffer, nInBufferSize,
DriverObject->DeviceObject, lpOutBuffer, nOutBufferSize, FALSE, &Event, &Iosb);
lpInBuffer,
nInBufferSize,
lpOutBuffer,
nOutBufferSize,
FALSE,
&Event,
&Iosb);
Status = IoCallDriver(DriverObject->DeviceObject, Irp); Status = IoCallDriver(DriverObject->DeviceObject, Irp);
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
(void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0); (void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
} }
return (Status); return (Status);
} }

View file

@ -16,19 +16,19 @@ ULONG CLIPOBJ_cEnumStart(IN PCLIPOBJ ClipObj,
IN ULONG BuildOrder, IN ULONG BuildOrder,
IN ULONG MaxRects) 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; ULONG enumCount = 0;
ENUMRECTS enumRects; ENUMRECTS enumRects;
// MUCH WORK TO DO HERE // MUCH WORK TO DO HERE
// Return the number of rectangles enumerated // Return the number of rectangles enumerated
if(enumCount>MaxRects) if(enumCount>MaxRects)
{ {
enumCount = 0xFFFFFFFF; enumCount = 0xFFFFFFFF;
} }
return enumCount; return enumCount;
} }
BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj, BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj,

View file

@ -2,6 +2,6 @@
typedef struct _RECT_ENUM typedef struct _RECT_ENUM
{ {
ULONG c; ULONG c;
RECTL arcl[ENUM_RECT_LIMIT]; RECTL arcl[ENUM_RECT_LIMIT];
} RECT_ENUM; } RECT_ENUM;

View file

@ -18,52 +18,50 @@
ULONG CreateGDIHandle(PVOID InternalObject, PVOID UserObject) ULONG CreateGDIHandle(PVOID InternalObject, PVOID UserObject)
{ {
ULONG NewHandle = HandleCounter++; ULONG NewHandle = HandleCounter++;
GDIHandles[NewHandle].InternalObject = InternalObject; GDIHandles[NewHandle].InternalObject = InternalObject;
GDIHandles[NewHandle].UserObject = UserObject; GDIHandles[NewHandle].UserObject = UserObject;
return NewHandle; return NewHandle;
} }
VOID FreeGDIHandle(ULONG Handle) VOID FreeGDIHandle(ULONG Handle)
{ {
GDIHandles[Handle].InternalObject = NULL; GDIHandles[Handle].InternalObject = NULL;
GDIHandles[Handle].UserObject = NULL; GDIHandles[Handle].UserObject = NULL;
} }
PVOID AccessInternalObject(ULONG Handle) PVOID AccessInternalObject(ULONG Handle)
{ {
return GDIHandles[Handle].InternalObject; return GDIHandles[Handle].InternalObject;
} }
PVOID AccessUserObject(ULONG Handle) PVOID AccessUserObject(ULONG Handle)
{ {
return GDIHandles[Handle].UserObject; return GDIHandles[Handle].UserObject;
} }
PVOID AccessInternalObjectFromUserObject(PVOID UserObject) PVOID AccessInternalObjectFromUserObject(PVOID UserObject)
{ {
ULONG i; ULONG i;
for(i=0; i<MAX_GDI_HANDLES; i++) for(i=0; i<MAX_GDI_HANDLES; i++)
{ {
if(GDIHandles[i].UserObject == UserObject) if(GDIHandles[i].UserObject == UserObject) return GDIHandles[i].InternalObject;
return GDIHandles[i].InternalObject; }
}
return NULL; return NULL;
} }
ULONG AccessHandleFromUserObject(PVOID UserObject) ULONG AccessHandleFromUserObject(PVOID UserObject)
{ {
ULONG i; ULONG i;
for(i=0; i<MAX_GDI_HANDLES; i++) for(i=0; i<MAX_GDI_HANDLES; i++)
{ {
if(GDIHandles[i].UserObject == UserObject) if(GDIHandles[i].UserObject == UserObject) return i;
return i; }
}
return INVALID_HANDLE; return INVALID_HANDLE;
} }

View file

@ -9,9 +9,9 @@
*/ */
typedef struct _GDI_HANDLE { typedef struct _GDI_HANDLE {
ULONG Handle; ULONG Handle;
PVOID InternalObject; PVOID InternalObject;
PVOID UserObject; PVOID UserObject;
} GDI_HANDLE, *PGDI_HANDLE; } GDI_HANDLE, *PGDI_HANDLE;
#define INVALID_HANDLE 0 #define INVALID_HANDLE 0

View file

@ -1,111 +1,118 @@
#include <ddk/winddi.h> #include <ddk/winddi.h>
#include "objects.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) // 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)
{
ULONG offset;
offset = (Surface->lDelta*y)+(x*SurfGDI->BytesPerPixel);
memcpy(Surface->pvBits+offset,
&iColor, SurfGDI->BytesPerPixel);
}
BOOL EngHLine(SURFOBJ *Surface, SURFGDI *SurfGDI,
LONG x, LONG y, LONG len, ULONG iColor)
{
ULONG offset, ix;
offset = (Surface->lDelta*y)+(x*SurfGDI->BytesPerPixel);
for(ix=0; ix<len*SurfGDI->BytesPerPixel; ix+=SurfGDI->BytesPerPixel)
memcpy(Surface->pvBits+offset+ix,
&iColor, SurfGDI->BytesPerPixel);
return TRUE;
}
BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush, BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush,
LONG x1, LONG y1, LONG x2, LONG y2, LONG x1, LONG y1, LONG x2, LONG y2,
RECTL *RectBounds, MIX mix) RECTL *RectBounds, MIX mix)
{ {
SURFGDI *SurfGDI; SURFGDI *SurfGDI;
LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error; LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error, hx, vy;
SurfGDI = AccessInternalObjectFromUserObject(Surface); // 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;
if(Surface->iType!=STYPE_BITMAP) SurfGDI = AccessInternalObjectFromUserObject(Surface);
{
// Call the driver's DrvLineTo
return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2,
RectBounds, mix);
}
// FIXME: Implement clipping if(Surface->iType!=STYPE_BITMAP)
{
// Call the driver's DrvLineTo
return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
}
if(y1==y2) return EngHLine(Surface, SurfGDI, x1, y1, (x2-x1), Brush->iSolidColor); // 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;
x=x1; case 24:
y=y1; DIB_PutPixel = DIB_24BPP_PutPixel;
deltax=x2-x1; DIB_HLine = DIB_24BPP_HLine;
deltay=y2-y1; DIB_VLine = DIB_24BPP_VLine;
break;
if(deltax<0) default:
{ DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
xchange=-1; BitsPerFormat(Surface->iBitmapFormat));
deltax=-deltax; return FALSE;
} else }
{
xchange=1;
}
if(deltay<0) // FIXME: Implement clipping
{
ychange=-1; x=x1;
deltay=-deltay; y=y1;
} else deltax=x2-x1;
{ deltay=y2-y1;
ychange=1;
}; if(deltax<0)
{
xchange=-1;
deltax=-deltax;
hx = x2;
} else
{
xchange=1;
hx = x1;
}
if(deltay<0)
{
ychange=-1;
deltay=-deltay;
vy = y2;
} else
{
ychange=1;
vy = y1;
}
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; error=0;
i=0; i=0;
if(deltax<deltay) if(deltax<deltay)
{ {
length=deltay+1; length=deltay+1;
while(i<length) while(i<length)
{ {
LinePoint(Surface, SurfGDI, x, y, Brush->iSolidColor); DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
y=y+ychange; y=y+ychange;
error=error+deltax; error=error+deltax;
if(error>deltay) if(error>deltay)
{ {
x=x+xchange; x=x+xchange;
error=error-deltay; error=error-deltay;
} }
i=i+1; i=i+1;
} }
} else } else
{ {
length=deltax+1; length=deltax+1;
while(i<length) while(i<length)
{ {
LinePoint(Surface, SurfGDI, x, y, Brush->iSolidColor); DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
x=x+xchange; x=x+xchange;
error=error+deltay; error=error+deltay;
if(error>deltax) if(error>deltax)
{ {
y=y+ychange; y=y+ychange;
error=error-deltax; error=error-deltax;
}
i=i+1;
} }
} i=i+1;
}
}
return TRUE; return TRUE;
} }

View file

@ -13,35 +13,34 @@
PVOID STDCALL EngAllocMem(ULONG Flags, ULONG MemSize, ULONG Tag) 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) if(Flags == FL_ZERO_MEMORY)
{ {
RtlZeroMemory(newMem, MemSize); RtlZeroMemory(newMem, MemSize);
} }
return newMem; return newMem;
} }
VOID STDCALL EngFreeMem(PVOID Mem) VOID STDCALL EngFreeMem(PVOID Mem)
{ {
ExFreePool(Mem); ExFreePool(Mem);
} }
PVOID STDCALL EngAllocUserMem(ULONG cj, ULONG tag) PVOID STDCALL EngAllocUserMem(ULONG cj, ULONG tag)
{ {
/* PVOID newMem; /* PVOID newMem;
return ZwAllocateVirtualMemory(mycurrentprocess, newMem, 0, cj, return ZwAllocateVirtualMemory(mycurrentprocess, newMem, 0, cj,
MEM_COMMIT, PAGE_READWRITE); */ MEM_COMMIT, PAGE_READWRITE); */
return NULL; return NULL;
} }
VOID STDCALL EngFreeUserMem(PVOID pv) VOID STDCALL EngFreeUserMem(PVOID pv)
{ {
/* ZwFreeVirtualMemory (mycurrentprocess, pv, 0, MEM_DECOMMIT); */ /* ZwFreeVirtualMemory (mycurrentprocess, pv, 0, MEM_DECOMMIT); */
} }

View file

@ -13,18 +13,18 @@ typedef struct _BRUSHGDI {
} BRUSHGDI; } BRUSHGDI;
typedef struct _CLIPGDI { typedef struct _CLIPGDI {
ULONG NumRegionRects; ULONG NumRegionRects;
ULONG NumIntersectRects; ULONG NumIntersectRects;
RECTL *RegionRects; RECTL *RegionRects;
RECTL *IntersectRects; RECTL *IntersectRects;
ULONG EnumPos; ULONG EnumPos;
ENUMRECTS EnumRects; ENUMRECTS EnumRects;
} CLIPGDI, *PCLIPGDI; } CLIPGDI, *PCLIPGDI;
typedef struct _DRVFUNCTIONSGDI { typedef struct _DRVFUNCTIONSGDI {
HDEV hdev; HDEV hdev;
DRVFN Functions[INDEX_LAST]; DRVFN Functions[INDEX_LAST];
} DRVFUNCTIONSGDI; } DRVFUNCTIONSGDI;
typedef struct _FLOATGDI { typedef struct _FLOATGDI {
@ -36,12 +36,12 @@ typedef struct _FONTGDI {
} FONTGDI; } FONTGDI;
typedef struct _PALGDI { typedef struct _PALGDI {
ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
ULONG NumColors; ULONG NumColors;
ULONG *IndexedColors; ULONG *IndexedColors;
ULONG RedMask; ULONG RedMask;
ULONG GreenMask; ULONG GreenMask;
ULONG BlueMask; ULONG BlueMask;
} PALGDI, *PPALGDI; } PALGDI, *PPALGDI;
typedef struct _PATHGDI { typedef struct _PATHGDI {
@ -88,21 +88,24 @@ typedef VOID (*PFN_MovePointer)(PSURFOBJ, LONG, LONG, PRECTL);
typedef HBITMAP (*PFN_CreateDeviceBitmap)(DHPDEV, SIZEL, ULONG); typedef HBITMAP (*PFN_CreateDeviceBitmap)(DHPDEV, SIZEL, ULONG);
typedef struct _SURFGDI { typedef BOOL (*PFN_SetPalette)(DHPDEV, PALOBJ*, ULONG, ULONG, ULONG);
BYTE BytesPerPixel;
PFN_BitBlt BitBlt; typedef struct _SURFGDI {
PFN_StretchBlt StretchBlt; INT BitsPerPixel;
PFN_TextOut TextOut;
PFN_Paint Paint; PFN_BitBlt BitBlt;
PFN_StrokePath StrokePath; PFN_StretchBlt StretchBlt;
PFN_FillPath FillPath; PFN_TextOut TextOut;
PFN_StrokeAndFillPath StrokeAndFillPath; PFN_Paint Paint;
PFN_LineTo LineTo; PFN_StrokePath StrokePath;
PFN_CopyBits CopyBits; PFN_FillPath FillPath;
PFN_Synchronize Synchronize; PFN_StrokeAndFillPath StrokeAndFillPath;
BOOL SynchronizeAccess; PFN_LineTo LineTo;
PFN_CreateDeviceBitmap CreateDeviceBitmap; PFN_CopyBits CopyBits;
PFN_Synchronize Synchronize;
BOOL SynchronizeAccess;
PFN_CreateDeviceBitmap CreateDeviceBitmap;
PFN_SetPalette SetPalette;
} SURFGDI, *PSURFGDI; } SURFGDI, *PSURFGDI;
typedef struct _XFORMGDI { typedef struct _XFORMGDI {
@ -110,10 +113,10 @@ typedef struct _XFORMGDI {
} XFORMGDI; } XFORMGDI;
typedef struct _XLATEGDI { typedef struct _XLATEGDI {
HPALETTE DestPal; HPALETTE DestPal;
HPALETTE SourcePal; HPALETTE SourcePal;
ULONG *translationTable; ULONG *translationTable;
} XLATEGDI; } XLATEGDI;
// List of GDI objects // List of GDI objects

View file

@ -15,80 +15,75 @@
BOOL FillSolid(SURFOBJ *Surface, PRECTL Dimensions, ULONG iColor) BOOL FillSolid(SURFOBJ *Surface, PRECTL Dimensions, ULONG iColor)
{ {
ULONG x, y, LineWidth, leftOfBitmap; ULONG x, y, LineWidth, leftOfBitmap;
SURFGDI *SurfaceGDI; SURFGDI *SurfaceGDI;
SurfaceGDI = AccessInternalObjectFromUserObject(Surface); SurfaceGDI = AccessInternalObjectFromUserObject(Surface);
LineWidth = Dimensions->right - Dimensions->left; LineWidth = Dimensions->right - Dimensions->left;
for (y = Dimensions->top; y < Dimensions->bottom; y++) for (y = Dimensions->top; y < Dimensions->bottom; y++)
{ {
EngHLine(Surface, SurfaceGDI, Dimensions->left, y, LineWidth, iColor); // EngHLine(Surface, SurfaceGDI, Dimensions->left, y, LineWidth, iColor);
} }
return TRUE; return TRUE;
} }
BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix, BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
BRUSHINST *BrushInst, POINTL *BrushPoint) BRUSHINST *BrushInst, POINTL *BrushPoint)
{ {
RECT_ENUM RectEnum; RECT_ENUM RectEnum;
BOOL EnumMore; BOOL EnumMore;
switch(ClipRegion->iMode) { switch(ClipRegion->iMode) {
case TC_RECTANGLES: case TC_RECTANGLES:
/* Rectangular clipping can be handled without enumeration. /* Rectangular clipping can be handled without enumeration.
Note that trivial clipping is not possible, since the clipping Note that trivial clipping is not possible, since the clipping
region defines the area to fill */ region defines the area to fill */
if (ClipRegion->iDComplexity == DC_RECT) if (ClipRegion->iDComplexity == DC_RECT)
{ {
FillSolid(Surface, &ClipRegion->rclBounds, iColor); FillSolid(Surface, &ClipRegion->rclBounds, iColor);
} else { } 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, do {
ENUM_RECT_LIMIT); EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
FillSolid(Surface, &RectEnum.arcl[0], iColor);
} while (EnumMore);
}
do { return(TRUE);
EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
FillSolid(Surface, &RectEnum.arcl[0], iColor); default:
return(FALSE);
} while (EnumMore); }
}
return(TRUE);
default:
return(FALSE);
}
} }
BOOL EngPaint(IN SURFOBJ *Surface, IN CLIPOBJ *ClipRegion, BOOL EngPaint(IN SURFOBJ *Surface, IN CLIPOBJ *ClipRegion,
IN BRUSHOBJ *Brush, IN POINTL *BrushOrigin, IN BRUSHOBJ *Brush, IN POINTL *BrushOrigin,
IN MIX Mix) IN MIX Mix)
{ {
SURFGDI *SurfGDI; SURFGDI *SurfGDI;
// Is the surface's Paint function hooked? // Is the surface's Paint function hooked?
SurfGDI = AccessInternalObjectFromUserObject(Surface); SurfGDI = AccessInternalObjectFromUserObject(Surface);
if((Surface->iType!=STYPE_BITMAP) && (SurfGDI->Paint!=NULL)) if((Surface->iType!=STYPE_BITMAP) && (SurfGDI->Paint!=NULL))
{ {
// Call the driver's DrvPaint // Call the driver's DrvPaint
return SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix); return SurfGDI->Paint(Surface, ClipRegion, Brush, BrushOrigin, Mix);
} }
// FIXME: We only support a brush's solid color attribute // FIXME: We only support a brush's solid color attribute
return(EngPaintRgn(Surface, ClipRegion, Brush->iSolidColor, Mix, NULL, return(EngPaintRgn(Surface, ClipRegion, Brush->iSolidColor, Mix, NULL, BrushOrigin));
BrushOrigin));
} }
BOOL EngEraseSurface(SURFOBJ *Surface, RECTL *Rect, ULONG iColor) BOOL EngEraseSurface(SURFOBJ *Surface, RECTL *Rect, ULONG iColor)
{ {
return FillSolid(Surface, Rect, iColor); return FillSolid(Surface, Rect, iColor);
} }

View file

@ -18,59 +18,65 @@ HPALETTE EngCreatePalette(ULONG Mode,
ULONG Green, ULONG Green,
ULONG Blue) ULONG Blue)
{ {
HPALETTE NewPalette; HPALETTE NewPalette;
PALOBJ *PalObj; PALOBJ *PalObj;
PALGDI *PalGDI; PALGDI *PalGDI;
PalObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALOBJ), NULL); PalObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALOBJ), NULL);
PalGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALGDI), NULL); PalGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALGDI), NULL);
NewPalette = CreateGDIHandle(PalGDI, PalObj); NewPalette = CreateGDIHandle(PalGDI, PalObj);
PalGDI->Mode = Mode; PalGDI->Mode = Mode;
if(Mode==PAL_INDEXED) if(Colors != NULL)
{ {
PalGDI->NumColors = NumColors; PalGDI->IndexedColors = ExAllocatePool(NonPagedPool, sizeof(ULONG)*NumColors);
PalGDI->IndexedColors = Colors; RtlCopyMemory(PalGDI->IndexedColors, Colors, sizeof(ULONG)*NumColors);
} else }
if(Mode==PAL_BITFIELDS)
{
PalGDI->RedMask = Red;
PalGDI->GreenMask = Green;
PalGDI->BlueMask = Blue;
}
return NewPalette; 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) BOOL EngDeletePalette(IN HPALETTE Palette)
{ {
PALOBJ *PalObj; PALOBJ *PalObj;
PALGDI *PalGDI; PALGDI *PalGDI;
PalGDI = AccessInternalObject(Palette); PalGDI = AccessInternalObject(Palette);
PalObj = AccessInternalObject(Palette); PalObj = AccessInternalObject(Palette);
EngFreeMem(PalGDI); EngFreeMem(PalGDI);
EngFreeMem(PalObj); EngFreeMem(PalObj);
FreeGDIHandle(Palette); FreeGDIHandle(Palette);
return TRUE; return TRUE;
} }
ULONG PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors, ULONG PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors,
ULONG *PaletteEntry) ULONG *PaletteEntry)
{ {
ULONG i, entry; ULONG i, entry;
PALGDI *PalGDI; PALGDI *PalGDI;
PalGDI = AccessInternalObjectFromUserObject(PalObj); PalGDI = AccessInternalObjectFromUserObject(PalObj);
for(i=Start; i<Colors; i++) for(i=Start; i<Colors; i++)
{ {
PaletteEntry[i] = PalGDI->IndexedColors[i]; PaletteEntry[i] = PalGDI->IndexedColors[i];
} }
return Colors; return Colors;
} }

View file

@ -6,64 +6,72 @@
* PROGRAMER: Jason Filby * PROGRAMER: Jason Filby
* REVISION HISTORY: * REVISION HISTORY:
* 3/7/1999: Created * 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 <ddk/winddi.h>
#include <win32k/dc.h> #include <win32k/dc.h>
#include "objects.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 switch(Format)
// pixel size if < 1 byte we expand it to 1 byte {
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;
}
}
if(Format==BMF_1BPP) ULONG BitmapFormat(WORD Bits, DWORD Compression)
{ {
return 1; switch(Compression)
} else {
if((Format==BMF_4BPP) || (Format==BMF_4RLE)) case BI_RGB:
{ switch(Bits)
return 1; {
} else case 1: return BMF_1BPP;
if((Format==BMF_8BPP) || (Format==BMF_8RLE)) case 4: return BMF_4BPP;
{ case 8: return BMF_8BPP;
return 1; case 16: return BMF_16BPP;
} else case 24: return BMF_24BPP;
if(Format==BMF_16BPP) case 32: return BMF_32BPP;
{ }
return 2;
} else
if(Format==BMF_24BPP)
{
return 3;
} else
if(Format==BMF_32BPP)
{
return 4;
}
return 0; case BI_RLE4: return BMF_4RLE;
case BI_RLE8: return BMF_8RLE;
default: return 0;
}
} }
VOID InitializeHooks(SURFGDI *SurfGDI) VOID InitializeHooks(SURFGDI *SurfGDI)
{ {
SurfGDI->BitBlt = NULL; SurfGDI->BitBlt = NULL;
SurfGDI->CopyBits = NULL; SurfGDI->CopyBits = NULL;
SurfGDI->CreateDeviceBitmap = NULL; SurfGDI->CreateDeviceBitmap = NULL;
SurfGDI->SetPalette = NULL;
} }
HBITMAP EngCreateDeviceBitmap(DHSURF dhsurf, SIZEL Size, ULONG Format) HBITMAP EngCreateDeviceBitmap(DHSURF dhsurf, SIZEL Size, ULONG Format)
{ {
HBITMAP NewBitmap; HBITMAP NewBitmap;
SURFOBJ *SurfObj; SURFOBJ *SurfObj;
NewBitmap = EngCreateBitmap(Size, bytesPerPixel(Format) * Size.cx, Format, 0, NULL); NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
SurfObj = AccessUserObject(NewBitmap); SurfObj = (PVOID)AccessUserObject(NewBitmap);
SurfObj->dhpdev = dhsurf; SurfObj->dhpdev = dhsurf;
return NewBitmap; return NewBitmap;
return 0;
} }
HBITMAP EngCreateBitmap(IN SIZEL Size, HBITMAP EngCreateBitmap(IN SIZEL Size,
@ -72,141 +80,134 @@ HBITMAP EngCreateBitmap(IN SIZEL Size,
IN ULONG Flags, IN ULONG Flags,
IN PVOID Bits) IN PVOID Bits)
{ {
HBITMAP NewBitmap; HBITMAP NewBitmap;
SURFOBJ *SurfObj; SURFOBJ *SurfObj;
SURFGDI *SurfGDI; SURFGDI *SurfGDI;
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL); SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), 0);
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL); SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), 0);
NewBitmap = CreateGDIHandle(SurfGDI, SurfObj); NewBitmap = (PVOID)CreateGDIHandle(SurfGDI, SurfObj);
InitializeHooks(SurfGDI); InitializeHooks(SurfGDI);
SurfGDI->BytesPerPixel = bytesPerPixel(Format); SurfGDI->BitsPerPixel = BitsPerFormat(Format);
SurfObj->lDelta = Width;
SurfObj->cjBits = SurfObj->lDelta * Size.cy;
SurfObj->lDelta = ((bytesPerPixel(Format) * Width) + 31) & ~31; // round up 4 bytes if(Bits!=NULL)
SurfObj->cjBits = SurfObj->lDelta * Size.cy; {
SurfObj->pvBits = Bits;
if(Bits!=NULL) } else
{ {
SurfObj->pvBits = Bits; if(Flags & BMF_USERMEM)
} else {
{ SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
if(Flags & BMF_USERMEM) } else {
if(Flags & BMF_NOZEROINIT)
{ {
SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0); SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
} else { } else {
if(Flags & BMF_NOZEROINIT) SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
{
SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
} else {
SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
}
} }
} }
}
SurfObj->dhsurf = 0; // device managed surface SurfObj->dhsurf = 0; // device managed surface
SurfObj->hsurf = 0; SurfObj->hsurf = 0;
SurfObj->sizlBitmap = Size; SurfObj->sizlBitmap = Size;
SurfObj->iBitmapFormat = Format; SurfObj->iBitmapFormat = Format;
SurfObj->iType = STYPE_BITMAP; 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 EngCreateDeviceSurface(DHSURF dhsurf, SIZEL Size, ULONG Format)
{ {
HSURF NewSurface; HSURF NewSurface;
SURFOBJ *SurfObj; SURFOBJ *SurfObj;
SURFGDI *SurfGDI; SURFGDI *SurfGDI;
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL); SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL); SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
NewSurface = CreateGDIHandle(SurfGDI, SurfObj); NewSurface = CreateGDIHandle(SurfGDI, SurfObj);
InitializeHooks(SurfGDI); InitializeHooks(SurfGDI);
SurfGDI->BytesPerPixel = bytesPerPixel(Format); 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;
SurfObj->dhsurf = dhsurf; return NewSurface;
SurfObj->hsurf = dhsurf; // FIXME: Is this correct??
SurfObj->sizlBitmap = Size;
SurfObj->iBitmapFormat = Format;
SurfObj->lDelta = SurfGDI->BytesPerPixel * Size.cx;
SurfObj->iType = STYPE_DEVICE;
return NewSurface;
} }
PFN DriverFunction(DRVENABLEDATA *DED, ULONG DriverFunc) PFN DriverFunction(DRVENABLEDATA *DED, ULONG DriverFunc)
{ {
ULONG i; ULONG i;
for(i=0; i<DED->c; i++) for(i=0; i<DED->c; i++)
{ {
if(DED->pdrvfn[i].iFunc == DriverFunc) if(DED->pdrvfn[i].iFunc == DriverFunc)
return DED->pdrvfn[i].pfn; return DED->pdrvfn[i].pfn;
} }
return NULL; return NULL;
} }
BOOL EngAssociateSurface(HSURF Surface, HDEV Dev, ULONG Hooks) BOOL EngAssociateSurface(HSURF Surface, HDEV Dev, ULONG Hooks)
{ {
SURFOBJ *SurfObj; SURFOBJ *SurfObj;
SURFGDI *SurfGDI; SURFGDI *SurfGDI;
// it looks like this Dev is actually a pointer to the DC! PDC Dc = (PDC)Dev;
PDC Dc = (PDC)Dev;
DbgPrint("Associate 1\n");
// DRVENABLEDATA *DED;
SurfGDI = AccessInternalObject(Surface); SurfGDI = (PVOID)AccessInternalObject(Surface);
SurfObj = AccessUserObject(Surface); SurfObj = (PVOID)AccessUserObject(Surface);
// DED = AccessInternalObject(Dev); // Associate the hdev
SurfObj->hdev = Dev;
// Associate the hdev // Hook up specified functions
SurfObj->hdev = Dev; 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;
// Hook up specified functions SurfGDI->CreateDeviceBitmap = Dc->DriverFunctions.CreateDeviceBitmap;
if(Hooks & HOOK_BITBLT) SurfGDI->BitBlt = Dc->DriverFunctions.BitBlt; SurfGDI->SetPalette = Dc->DriverFunctions.SetPalette;
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;
return TRUE;
} }
BOOL EngDeleteSurface(HSURF Surface) BOOL EngDeleteSurface(HSURF Surface)
{ {
SURFOBJ *SurfObj; SURFOBJ *SurfObj;
SURFGDI *SurfGDI; SURFGDI *SurfGDI;
SurfGDI = AccessInternalObject(Surface); SurfGDI = AccessInternalObject(Surface);
SurfObj = AccessUserObject(Surface); SurfObj = AccessUserObject(Surface);
EngFreeMem(SurfGDI); EngFreeMem(SurfGDI);
EngFreeMem(SurfObj); EngFreeMem(SurfObj);
FreeGDIHandle(Surface); FreeGDIHandle(Surface);
return TRUE; return TRUE;
} }
SURFOBJ *EngLockSurface(HSURF Surface) SURFOBJ *EngLockSurface(HSURF Surface)
{ {
// FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c) // FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
return AccessUserObject(Surface);
return AccessUserObject(Surface);
} }

View file

@ -18,251 +18,249 @@ ULONG CCMLastSourceColor = 0, CCMLastColorMatch = 0;
ULONG RGBtoULONG(BYTE Red, BYTE Green, BYTE Blue) 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) 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) INT abs(INT nm)
{ {
if(nm<0) if(nm<0)
{ {
return nm * -1; return nm * -1;
} else } else
{ {
return nm; return nm;
} }
} }
// FIXME: If the caller knows that the destinations are indexed and not RGB // 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. // then we should cache more than one value. Same with the source.
// Takes indexed palette and a
ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors, ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors,
ULONG NumColors) ULONG NumColors)
{ {
PVIDEO_CLUTDATA cSourceColor; PVIDEO_CLUTDATA cSourceColor;
PVIDEO_CLUTDATA cDestColors; PVIDEO_CLUTDATA cDestColors;
ULONG bestMatch = 256, idx = 0, i; ULONG bestMatch = 256, idx = 0, i;
ULONG rt; ULONG rt;
// Simple cache -- only one value because we don't want to waste time // Simple cache -- only one value because we don't want to waste time
// if the colors aren't very sequential // if the colors aren't very sequential
if(SourceColor == CCMLastSourceColor) if(SourceColor == CCMLastSourceColor)
{ {
return CCMLastColorMatch; return CCMLastColorMatch;
} }
cSourceColor = &SourceColor; cSourceColor = &SourceColor;
for (i=0; i<NumColors; i++) for (i=0; i<NumColors; i++)
{ {
cDestColors = &DestColors[i]; cDestColors = &DestColors[i];
rt = ( abs(cSourceColor->Red - cDestColors->Red) + rt = ( abs(cSourceColor->Red - cDestColors->Red) +
abs(cSourceColor->Green - cDestColors->Green) + abs(cSourceColor->Green - cDestColors->Green) +
abs(cSourceColor->Blue - cDestColors->Blue) ) / 3; abs(cSourceColor->Blue - cDestColors->Blue) ) / 3;
if(rt<=bestMatch) if(rt<=bestMatch)
{ {
idx = i; idx = i;
bestMatch = rt; bestMatch = rt;
} }
} }
CCMLastSourceColor = SourceColor; CCMLastSourceColor = SourceColor;
CCMLastColorMatch = idx; CCMLastColorMatch = idx;
return idx; return idx;
} }
VOID IndexedToIndexedTranslationTable(ULONG *TranslationTable, VOID IndexedToIndexedTranslationTable(ULONG *TranslationTable,
PALGDI *PalDest, PALGDI *PalSource) PALGDI *PalDest, PALGDI *PalSource)
{ {
ULONG i; ULONG i;
for(i=0; i<PalSource->NumColors; i++) for(i=0; i<PalSource->NumColors; i++)
{ {
TranslationTable[i] = ClosestColorMatch(PalSource->IndexedColors[i], TranslationTable[i] = ClosestColorMatch(PalSource->IndexedColors[i], PalDest->IndexedColors, PalDest->NumColors);
PalDest->IndexedColors, PalDest->NumColors); }
}
} }
XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType, XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
HPALETTE PaletteDest, HPALETTE PaletteSource) HPALETTE PaletteDest, HPALETTE PaletteSource)
{ {
// FIXME: Add support for BGR conversions // FIXME: Add support for BGR conversions
HPALETTE NewXlate; HPALETTE NewXlate;
XLATEOBJ *XlateObj; XLATEOBJ *XlateObj;
XLATEGDI *XlateGDI; XLATEGDI *XlateGDI;
PALGDI *SourcePalGDI, *DestPalGDI; PALGDI *SourcePalGDI, *DestPalGDI;
ULONG IndexedColors; ULONG IndexedColors;
XlateObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEOBJ), NULL); XlateObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEOBJ), NULL);
XlateGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEGDI), NULL); XlateGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEGDI), NULL);
NewXlate = CreateGDIHandle(XlateGDI, XlateObj); NewXlate = CreateGDIHandle(XlateGDI, XlateObj);
if(SourcePalType == PAL_INDEXED) if(SourcePalType == PAL_INDEXED)
{ {
SourcePalGDI = AccessInternalObject(PaletteSource); SourcePalGDI = AccessInternalObject(PaletteSource);
} else } else
if(DestPalType == PAL_INDEXED) if(DestPalType == PAL_INDEXED)
{ {
DestPalGDI = AccessInternalObject(PaletteDest); DestPalGDI = AccessInternalObject(PaletteDest);
} }
XlateObj->iSrcType = SourcePalType; XlateObj->iSrcType = SourcePalType;
XlateObj->iDstType = DestPalType; XlateObj->iDstType = DestPalType;
// Store handles of palettes in internal Xlate GDI object (or NULLs) // Store handles of palettes in internal Xlate GDI object (or NULLs)
XlateGDI->DestPal = PaletteDest; XlateGDI->DestPal = PaletteDest;
XlateGDI->SourcePal = PaletteSource; XlateGDI->SourcePal = PaletteSource;
XlateObj->flXlate = 0; XlateObj->flXlate = 0;
// If source and destination palettes are the same or if they're RGB/BGR // If source and destination palettes are the same or if they're RGB/BGR
if( (PaletteDest == PaletteSource) || if( (PaletteDest == PaletteSource) ||
((DestPalType == PAL_RGB) && (SourcePalType == PAL_RGB)) || ((DestPalType == PAL_RGB) && (SourcePalType == PAL_RGB)) ||
((DestPalType == PAL_BGR) && (SourcePalType == PAL_BGR)) ) ((DestPalType == PAL_BGR) && (SourcePalType == PAL_BGR)) )
{ {
XlateObj->flXlate |= XO_TRIVIAL; XlateObj->flXlate |= XO_TRIVIAL;
} return XlateObj;
}
// Prepare the translation table // Prepare the translation table
if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) ) if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
{ {
XlateObj->flXlate |= XO_TABLE; XlateObj->flXlate |= XO_TABLE;
if (SourcePalType == PAL_INDEXED) IndexedColors = SourcePalGDI->NumColors; if (SourcePalType == PAL_INDEXED) IndexedColors = SourcePalGDI->NumColors;
if (DestPalType == PAL_INDEXED) IndexedColors = DestPalGDI->NumColors; if (DestPalType == PAL_INDEXED) IndexedColors = DestPalGDI->NumColors;
XlateGDI->translationTable = EngAllocMem( XlateGDI->translationTable = EngAllocMem(FL_ZERO_MEMORY, sizeof(ULONG)*IndexedColors, NULL);
FL_ZERO_MEMORY, sizeof(ULONG)*IndexedColors, NULL); }
}
// Source palette is indexed // Source palette is indexed
if(XlateObj->iSrcType == PAL_INDEXED) if(XlateObj->iSrcType == PAL_INDEXED)
{ {
if(XlateObj->iDstType == PAL_INDEXED) if(XlateObj->iDstType == PAL_INDEXED)
{ {
// Converting from indexed to indexed // Converting from indexed to indexed
IndexedToIndexedTranslationTable(XlateGDI->translationTable, IndexedToIndexedTranslationTable(XlateGDI->translationTable, DestPalGDI, SourcePalGDI);
DestPalGDI, SourcePalGDI); } else
} else
if(XlateObj->iDstType == PAL_RGB) if(XlateObj->iDstType == PAL_RGB)
{ {
// FIXME: Is this necessary? I think the driver has to call this // FIXME: Is this necessary? I think the driver has to call this
// function anyways if pulXlate is NULL and Source is PAL_INDEXED // 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, XLATEOBJ_cGetPalette(XlateObj, XO_SRCPALETTE,
SourcePalGDI->NumColors, SourcePalGDI->NumColors,
XlateGDI->translationTable); XlateGDI->translationTable);
} }
XlateObj->pulXlate = XlateGDI->translationTable; XlateObj->pulXlate = XlateGDI->translationTable;
} }
// Source palette is RGB // Source palette is RGB
if(XlateObj->iSrcType == PAL_RGB) if(XlateObj->iSrcType == PAL_RGB)
{ {
if(XlateObj->iDstType == PAL_INDEXED) if(XlateObj->iDstType == PAL_INDEXED)
{ {
// FIXME: Is this necessary? I think the driver has to call this // FIXME: Is this necessary? I think the driver has to call this
// function anyways if pulXlate is NULL and Dest is PAL_INDEXED // function anyways if pulXlate is NULL and Dest is PAL_INDEXED
// Converting from RGB to indexed // Converting from RGB to indexed
XLATEOBJ_cGetPalette(XlateObj, XO_DESTPALETTE, XLATEOBJ_cGetPalette(XlateObj, XO_DESTPALETTE, DestPalGDI->NumColors, XlateGDI->translationTable);
DestPalGDI->NumColors, }
XlateGDI->translationTable); }
}
}
// FIXME: Add support for XO_TO_MONO // FIXME: Add support for XO_TO_MONO
return XlateObj;
return XlateObj;
} }
EngDeleteXlate(XLATEOBJ *XlateObj) EngDeleteXlate(XLATEOBJ *XlateObj)
{ {
HPALETTE HXlate = AccessHandleFromUserObject(XlateObj); HPALETTE HXlate = AccessHandleFromUserObject(XlateObj);
XLATEGDI *XlateGDI = AccessInternalObject(HXlate); XLATEGDI *XlateGDI = AccessInternalObject(HXlate);
if(XlateGDI->translationTable!=NULL) if(XlateGDI->translationTable!=NULL)
{ {
EngFreeMem(XlateGDI->translationTable); EngFreeMem(XlateGDI->translationTable);
} }
EngFreeMem(XlateGDI); EngFreeMem(XlateGDI);
EngFreeMem(XlateObj); EngFreeMem(XlateObj);
FreeGDIHandle(HXlate); FreeGDIHandle(HXlate);
} }
ULONG *XLATEOBJ_piVector(XLATEOBJ *XlateObj) 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 NULL;
{
return XlateGDI->translationTable;
}
return NULL;
} }
ULONG XLATEOBJ_iXlate(XLATEOBJ *XlateObj, ULONG Color) ULONG XLATEOBJ_iXlate(XLATEOBJ *XlateObj, ULONG Color)
{ {
PALGDI *PalGDI; PALGDI *PalGDI;
XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj); XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
if(XlateObj->iSrcType == PAL_RGB) if(XlateObj->flXlate & XO_TRIVIAL)
{ {
// FIXME: should we cache colors used often? return Color;
// FIXME: won't work if destination isn't indexed } 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 // Extract the destination palette
PalGDI = AccessInternalObject(XlateGDI->DestPal); PalGDI = AccessInternalObject(XlateGDI->DestPal);
// Return closest match for the given RGB color // Return closest match for the given RGB color
return ClosestColorMatch(Color, PalGDI->IndexedColors, PalGDI->NumColors); return ClosestColorMatch(Color, PalGDI->IndexedColors, PalGDI->NumColors);
} else } else
if(XlateObj->iSrcType == PAL_INDEXED)
{
return XlateGDI->translationTable[Color];
}
if(XlateObj->iSrcType == PAL_INDEXED) return 0;
{
return XlateGDI->translationTable[Color];
}
return 0;
} }
ULONG XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj, ULONG XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj,
ULONG PalOutType, ULONG cPal, ULONG *OutPal) ULONG PalOutType, ULONG cPal, ULONG *OutPal)
{ {
ULONG i; ULONG i;
HPALETTE HPal; HPALETTE HPal;
XLATEGDI *XlateGDI; XLATEGDI *XlateGDI;
PALGDI *PalGDI; PALGDI *PalGDI;
XlateGDI = AccessInternalObjectFromUserObject(XlateObj); XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
if(PalOutType == XO_SRCPALETTE) if(PalOutType == XO_SRCPALETTE)
{ {
HPal = XlateGDI->SourcePal; HPal = XlateGDI->SourcePal;
} else } else
if(PalOutType == XO_DESTPALETTE) if(PalOutType == XO_DESTPALETTE)
{ {
HPal = XlateGDI->DestPal; HPal = XlateGDI->DestPal;
} }
PalGDI = AccessInternalObject(HPal); PalGDI = AccessInternalObject(HPal);
RtlCopyMemory(OutPal, PalGDI->IndexedColors, sizeof(ULONG)*cPal); RtlCopyMemory(OutPal, PalGDI->IndexedColors, sizeof(ULONG)*cPal);
return i; return i;
} }

View file

@ -285,9 +285,11 @@ void CreateCellCharSurface()
surfgdi = ExAllocatePool(NonPagedPool, sizeof(SURFGDI)); surfgdi = ExAllocatePool(NonPagedPool, sizeof(SURFGDI));
hCharCellBitmap = W32kCreateBitmap(8, 8, 1, 8, NULL); // 8x8, 1 plane, 8 bits per pel hCharCellBitmap = W32kCreateBitmap(8, 8, 1, 8, NULL); // 8x8, 1 plane, 8 bits per pel
pbo = BITMAPOBJ_HandleToPtr(hCharCellBitmap); 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, void grWriteCellChar(PSURFOBJ target,

View 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/ntddk.h>
#include <ddk/winddi.h> #include <ddk/winddi.h>
HANDLE HANDLE
STDCALL STDCALL
EngLoadImage (LPWSTR DriverName) EngLoadImage (LPWSTR DriverName)
{ {
SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo; SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
NTSTATUS Status; NTSTATUS Status;
RtlInitUnicodeString (&GdiDriverInfo.DriverName, RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName);
DriverName); Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, if (!NT_SUCCESS(Status)) return NULL;
&GdiDriverInfo,
sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
if (!NT_SUCCESS(Status))
return NULL;
return (HANDLE)GdiDriverInfo.ImageAddress; return (HANDLE)GdiDriverInfo.ImageAddress;
} }
@ -29,20 +24,16 @@ HANDLE
STDCALL STDCALL
EngLoadModule(LPWSTR ModuleName) EngLoadModule(LPWSTR ModuleName)
{ {
SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo; SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
NTSTATUS Status; NTSTATUS Status;
// FIXME: should load as readonly // FIXME: should load as readonly
RtlInitUnicodeString (&GdiDriverInfo.DriverName, RtlInitUnicodeString (&GdiDriverInfo.DriverName, ModuleName);
ModuleName); Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, if (!NT_SUCCESS(Status)) return NULL;
&GdiDriverInfo,
sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
if (!NT_SUCCESS(Status))
return NULL;
return (HANDLE)GdiDriverInfo.ImageAddress; return (HANDLE)GdiDriverInfo.ImageAddress;
} }
/* EOF */ /* EOF */

View 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 * Entry Point for win32k.sys
*/ */
@ -25,31 +25,26 @@
NTSTATUS NTSTATUS
STDCALL STDCALL
DllMain ( DllMain (
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath 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 * Register user mode call interface
* (system service table index = 1) * (system service table index = 1)
*/ */
Result = KeAddSystemServiceTable (Win32kSSDT, Result = KeAddSystemServiceTable (Win32kSSDT, NULL, NUMBER_OF_SYSCALLS, Win32kSSPT, 1);
NULL, if (Result == FALSE)
NUMBER_OF_SYSCALLS, {
Win32kSSPT, DbgPrint("Adding system services failed!\n");
1); return STATUS_UNSUCCESSFUL;
if (Result == FALSE) }
{
DbgPrint("Adding system services failed!\n");
return STATUS_UNSUCCESSFUL;
}
DbgPrint("System services added successfully!\n"); DbgPrint("System services added successfully!\n");
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -57,14 +52,19 @@ BOOLEAN
STDCALL STDCALL
W32kInitialize (VOID) W32kInitialize (VOID)
{ {
// FIXME: Retrieve name from registry
EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys");
// FIXME: Retrieve name from registry // Create surface used to draw the internal font onto
EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys"); CreateCellCharSurface();
// Create surface used to draw the internal font onto // Create stock objects, ie. precreated objects commonly used by win32 applications
CreateCellCharSurface(); CreateStockObjects();
return TRUE; // Initialize FreeType library
if(!InitFontSupport()) return FALSE;
return TRUE;
} }
/* EOF */ /* EOF */

View 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 # WIN32K.SYS build spec
# #
@ -6,8 +6,13 @@ PATH_TO_TOP = ../..
TARGET=win32k TARGET=win32k
# from atheos appserver makefile
COPTS = -pipe -O3 -I./freetype2-beta8/include -c -Wall
CFLAGS = -I. 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_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/device.o eng/handle.o eng/lineto.o eng/paint.o eng/palette.o \
eng/surface.o eng/xlate.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/line.o objects/metafile.o objects/paint.o \
objects/path.o objects/pen.o objects/print.o \ objects/path.o objects/pen.o objects/print.o \
objects/region.o objects/text.o objects/wingl.o \ objects/region.o objects/text.o objects/wingl.o \
objects/bezier.o objects/objconv.o objects/bezier.o objects/objconv.o objects/dib.o objects/palette.o
FREETYPE_OBJECTS = freetype/grfont.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 RESOURCE_OBJECT = $(TARGET).coff
STUBS_OBJECTS = stubs/stubs.o STUBS_OBJECTS = stubs/stubs.o
OBJECTS = $(ENG_OBJECTS) $(MAIN_OBJECTS) $(MISC_OBJECTS) $(LDR_OBJECTS) $(OBJECTS_OBJECTS) \ 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 all: $(TARGET).sys
@ -116,4 +126,3 @@ $(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
#WIN32_LEAN_AND_MEAN = yes #WIN32_LEAN_AND_MEAN = yes
#WARNINGS_ARE_ERRORS = yes #WARNINGS_ARE_ERRORS = yes
include ../../rules.mak include ../../rules.mak

View 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 * GDI Driver support routines
* (mostly swiped from Wine) * (mostly swiped from Wine)
@ -34,28 +34,23 @@ BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver)
{ {
PGRAPHICS_DRIVER Driver = ExAllocatePool(NonPagedPool, sizeof(*Driver)); PGRAPHICS_DRIVER Driver = ExAllocatePool(NonPagedPool, sizeof(*Driver));
DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name ); DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
if (!Driver) if (!Driver) return FALSE;
{
return FALSE;
}
Driver->ReferenceCount = 0; Driver->ReferenceCount = 0;
Driver->EnableDriver = EnableDriver; Driver->EnableDriver = EnableDriver;
if (Name) if (Name)
{ {
Driver->Name = ExAllocatePool(PagedPool, Driver->Name = ExAllocatePool(PagedPool, (wcslen(Name) + 1) * sizeof(WCHAR));
(wcslen(Name) + 1) * sizeof(WCHAR)); wcscpy(Driver->Name, Name);
wcscpy(Driver->Name, Name); Driver->Next = DriverList;
Driver->Next = DriverList; DriverList = Driver;
DriverList = Driver; return TRUE;
return TRUE; }
}
if (GenericDriver != NULL) if (GenericDriver != NULL)
{ {
ExFreePool(Driver); ExFreePool(Driver);
return FALSE;
return FALSE; }
}
GenericDriver = Driver; GenericDriver = Driver;
return TRUE; return TRUE;
@ -69,22 +64,18 @@ PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name)
/* First see if the driver hasn't already been loaded */ /* First see if the driver hasn't already been loaded */
while (Driver && Name) while (Driver && Name)
{
if (!_wcsicmp( Driver->Name, Name))
{ {
if (!_wcsicmp( Driver->Name, Name)) return Driver->EnableDriver;
{
return Driver->EnableDriver;
}
Driver = Driver->Next;
} }
Driver = Driver->Next;
}
/* If not, then load it */ /* If not, then load it */
RtlInitUnicodeString (&GdiDriverInfo.DriverName, RtlInitUnicodeString (&GdiDriverInfo.DriverName, (LPWSTR)Name);
(LPWSTR)Name); Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, if (!NT_SUCCESS(Status)) return NULL;
&GdiDriverInfo,
sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
if (!NT_SUCCESS(Status))
return NULL;
DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint); DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
return (PGD_ENABLEDRIVER)GdiDriverInfo.EntryPoint; return (PGD_ENABLEDRIVER)GdiDriverInfo.EntryPoint;
@ -182,35 +173,31 @@ HANDLE DRIVER_FindMPDriver(LPCWSTR Name)
PMP_DRIVERENTRY PMP_DriverEntry; PMP_DRIVERENTRY PMP_DriverEntry;
/* Phase 1 */ /* Phase 1 */
RtlInitUnicodeString (&GdiDriverInfo.DriverName, RtlInitUnicodeString (&GdiDriverInfo.DriverName, L"\\SystemRoot\\system32\\drivers\\vgamp.sys");
L"\\SystemRoot\\system32\\drivers\\vgamp.sys"); Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation,
&GdiDriverInfo,
sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return NULL; return NULL;
/* Phase 2 */ /* Phase 2 */
if (Name[0] != '\\') 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) + /* FIXME: Read this information from the registry ??? */
10 * sizeof(WCHAR)); wcscat(lName, L"DISPLAY1");
wcscpy(lName, L"\\??\\");
if (!wcscmp (Name, L"DISPLAY"))
{
/* FIXME: Read this information from the registry ??? */
wcscat(lName, L"DISPLAY1");
}
else
{
wcscat(lName, Name);
}
} }
else
{
wcscat(lName, Name);
}
}
else else
{ {
lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR)); lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR));
wcscpy(lName, Name); wcscpy(lName, Name);
} }
/* Phase 3 */ /* Phase 3 */
DriverObject = ExAllocatePool(NonPagedPool,sizeof(DRIVER_OBJECT)); DriverObject = ExAllocatePool(NonPagedPool,sizeof(DRIVER_OBJECT));
@ -234,44 +221,44 @@ BOOL DRIVER_UnregisterDriver(LPCWSTR Name)
PGRAPHICS_DRIVER Driver = NULL; PGRAPHICS_DRIVER Driver = NULL;
if (Name) 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 = Driver->Next;
{
Driver = DriverList;
DriverList = DriverList->Next;
}
else
{
Driver = DriverList;
while (Driver->Next && _wcsicmp(Driver->Name, Name))
{
Driver = Driver->Next;
}
}
} }
}
} }
}
else else
{
if (GenericDriver != NULL)
{ {
if (GenericDriver != NULL) Driver = GenericDriver;
{ GenericDriver = NULL;
Driver = GenericDriver;
GenericDriver = NULL;
}
} }
}
if (Driver != NULL) if (Driver != NULL)
{ {
ExFreePool(Driver->Name); ExFreePool(Driver->Name);
ExFreePool(Driver); ExFreePool(Driver);
return TRUE; return TRUE;
} }
else else
{ {
return FALSE; return FALSE;
} }
} }
INT DRIVER_ReferenceDriver (LPCWSTR Name) INT DRIVER_ReferenceDriver (LPCWSTR Name)
@ -279,14 +266,14 @@ INT DRIVER_ReferenceDriver (LPCWSTR Name)
GRAPHICS_DRIVER *Driver = DriverList; GRAPHICS_DRIVER *Driver = DriverList;
while (Driver && Name) 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 ); return ++Driver->ReferenceCount;
if (!_wcsicmp( Driver->Name, Name))
{
return ++Driver->ReferenceCount;
}
Driver = Driver->Next;
} }
Driver = Driver->Next;
}
DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount ); DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
assert( GenericDriver != 0 ); assert( GenericDriver != 0 );
return ++GenericDriver->ReferenceCount; return ++GenericDriver->ReferenceCount;
@ -297,14 +284,14 @@ INT DRIVER_UnreferenceDriver (LPCWSTR Name)
GRAPHICS_DRIVER *Driver = DriverList; GRAPHICS_DRIVER *Driver = DriverList;
while (Driver && Name) 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 ); return --Driver->ReferenceCount;
if (!_wcsicmp( Driver->Name, Name))
{
return --Driver->ReferenceCount;
}
Driver = Driver->Next;
} }
Driver = Driver->Next;
}
DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount ); DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
assert( GenericDriver != 0 ); assert( GenericDriver != 0 );
return --GenericDriver->ReferenceCount; return --GenericDriver->ReferenceCount;

View file

@ -41,8 +41,8 @@
* */ * */
#define BEZIERMIDDLE(Mid, P1, P2) \ #define BEZIERMIDDLE(Mid, P1, P2) \
(Mid).x=((P1).x+(P2).x + 1)/2;\ (Mid).x=((P1).x+(P2).x + 1)/2;\
(Mid).y=((P1).y+(P2).y + 1)/2; (Mid).y=((P1).y+(P2).y + 1)/2;
/********************************************************** /**********************************************************
* BezierCheck helper function to check * BezierCheck helper function to check
@ -54,55 +54,46 @@
*/ */
static BOOL BezierCheck( int level, POINT *Points) static BOOL BezierCheck( int level, POINT *Points)
{ {
INT dx, dy; INT dx, dy;
dx=Points[3].x-Points[0].x;
dy=Points[3].y-Points[0].y; dx=Points[3].x-Points[0].x;
if(abs(dy)<=abs(dx)){/* shallow line */ dy=Points[3].y-Points[0].y;
/* check that control points are between begin and end */ if(abs(dy)<=abs(dx)) {/* shallow line */
if(Points[1].x < Points[0].x){ /* check that control points are between begin and end */
if(Points[1].x < Points[3].x) if(Points[1].x < Points[0].x){
return FALSE; if(Points[1].x < Points[3].x) return FALSE;
}else }else
if(Points[1].x > Points[3].x) if(Points[1].x > Points[3].x) return FALSE;
return FALSE; if(Points[2].x < Points[0].x) {
if(Points[2].x < Points[0].x){ if(Points[2].x < Points[3].x) return FALSE;
if(Points[2].x < Points[3].x) } else
return FALSE; if(Points[2].x > Points[3].x) return FALSE;
}else dx=BEZIERSHIFTDOWN(dx);
if(Points[2].x > Points[3].x) if(!dx) return TRUE;
return FALSE; if(abs(Points[1].y-Points[0].y-(dy/dx)*
dx=BEZIERSHIFTDOWN(dx); BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL ||
if(!dx) return TRUE; abs(Points[2].y-Points[0].y-(dy/dx)*
if(abs(Points[1].y-Points[0].y-(dy/dx)* BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL) return FALSE;
BEZIERSHIFTDOWN(Points[1].x-Points[0].x)) > BEZIERPIXEL || else
abs(Points[2].y-Points[0].y-(dy/dx)* return TRUE;
BEZIERSHIFTDOWN(Points[2].x-Points[0].x)) > BEZIERPIXEL ) } else{ /* steep line */
return FALSE; /* check that control points are between begin and end */
else if(Points[1].y < Points[0].y){
return TRUE; if(Points[1].y < Points[3].y) return FALSE;
}else{ /* steep line */ } else
/* check that control points are between begin and end */ if(Points[1].y > Points[3].y) return FALSE;
if(Points[1].y < Points[0].y){ if(Points[2].y < Points[0].y){
if(Points[1].y < Points[3].y) if(Points[2].y < Points[3].y) return FALSE;
return FALSE; } else
}else if(Points[2].y > Points[3].y) return FALSE;
if(Points[1].y > Points[3].y) dy=BEZIERSHIFTDOWN(dy);
return FALSE; if(!dy) return TRUE;
if(Points[2].y < Points[0].y){ if(abs(Points[1].x-Points[0].x-(dx/dy)*
if(Points[2].y < Points[3].y) BEZIERSHIFTDOWN(Points[1].y-Points[0].y)) > BEZIERPIXEL ||
return FALSE; abs(Points[2].x-Points[0].x-(dx/dy)*
}else BEZIERSHIFTDOWN(Points[2].y-Points[0].y)) > BEZIERPIXEL ) return FALSE;
if(Points[2].y > Points[3].y) else
return FALSE; return TRUE;
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, static void GDI_InternalBezier( POINT *Points, POINT **PtsOut, INT *dwOut,
INT *nPtsOut, INT level ) INT *nPtsOut, INT level )
{ {
if(*nPtsOut == *dwOut) { if(*nPtsOut == *dwOut) {
*dwOut *= 2; *dwOut *= 2;
*PtsOut = ExAllocatePool(NonPagedPool, *dwOut * sizeof(POINT)); *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)) { BEZIERMIDDLE(Points[1], Points[0], Points[1]);
if(*nPtsOut == 0) { BEZIERMIDDLE(Points[2], Points[1], Points2[0]);
(*PtsOut)[0].x = BEZIERSHIFTDOWN(Points[0].x); BEZIERMIDDLE(Points[3], Points[2], Points2[1]);
(*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]); Points2[0]=Points[3];
BEZIERMIDDLE(Points[2], Points[1], Points2[0]);
BEZIERMIDDLE(Points[3], Points[2], Points2[1]);
Points2[0]=Points[3]; /* do the two halves */
GDI_InternalBezier(Points, PtsOut, dwOut, nPtsOut, level-1);
/* do the two halves */ GDI_InternalBezier(Points2, PtsOut, dwOut, nPtsOut, level-1);
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 *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut )
{ {
POINT *out; POINT *out;
INT Bezier, dwOut = BEZIER_INITBUFSIZE, i; INT Bezier, dwOut = BEZIER_INITBUFSIZE, i;
if((count - 1) % 3 != 0) { if((count - 1) % 3 != 0) {
return NULL; return NULL;
} }
*nPtsOut = 0; *nPtsOut = 0;
out = ExAllocatePool(NonPagedPool, dwOut * sizeof(POINT)); out = ExAllocatePool(NonPagedPool, dwOut * sizeof(POINT));
for(Bezier = 0; Bezier < (count-1)/3; Bezier++) { for(Bezier = 0; Bezier < (count-1)/3; Bezier++) {
POINT ptBuf[4]; POINT ptBuf[4];
memcpy(ptBuf, Points + Bezier * 3, sizeof(POINT) * 4); memcpy(ptBuf, Points + Bezier * 3, sizeof(POINT) * 4);
for(i = 0; i < 4; i++) { for(i = 0; i < 4; i++) {
ptBuf[i].x = BEZIERSHIFTUP(ptBuf[i].x); ptBuf[i].x = BEZIERSHIFTUP(ptBuf[i].x);
ptBuf[i].y = BEZIERSHIFTUP(ptBuf[i].y); ptBuf[i].y = BEZIERSHIFTUP(ptBuf[i].y);
}
GDI_InternalBezier( ptBuf, &out, &dwOut, nPtsOut, BEZIERMAXDEPTH );
} }
GDI_InternalBezier( ptBuf, &out, &dwOut, nPtsOut, BEZIERMAXDEPTH );
}
return out; return out;
} }

View file

@ -1,10 +1,9 @@
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <stdlib.h> #include <stdlib.h>
#include <win32k/bitmaps.h> #include <win32k/bitmaps.h>
//#include <win32k/debug.h> //#include <win32k/debug.h>
#include "../eng/objects.h"
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
@ -19,15 +18,19 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest,
INT YSrc, INT YSrc,
DWORD ROP) DWORD ROP)
{ {
PDC DCDest = DC_HandleToPtr(hDCDest); PDC DCDest = DC_HandleToPtr(hDCDest);
PDC DCSrc = DC_HandleToPtr(hDCSrc); PDC DCSrc = DC_HandleToPtr(hDCSrc);
PSURFOBJ SurfDest; PSURFOBJ SurfDest, SurfSrc;
PSURFOBJ SurfSrc; PSURFGDI SurfGDIDest, SurfGDISrc;
RECTL DestRect; RECTL DestRect;
POINTL SourcePoint; POINTL SourcePoint;
PBITMAPOBJ DestBitmapObj; PBITMAPOBJ DestBitmapObj;
PBITMAPOBJ SrcBitmapObj; PBITMAPOBJ SrcBitmapObj;
BOOL Status, SurfDestAlloc, SurfSrcAlloc; BOOL Status, SurfDestAlloc, SurfSrcAlloc;
PPALOBJ DCLogPal;
PPALGDI PalDestGDI, PalSourceGDI;
PXLATEOBJ XlateObj = NULL;
HPALETTE SourcePalette, DestPalette;
DestRect.left = XDest; DestRect.left = XDest;
DestRect.top = YDest; DestRect.top = YDest;
@ -40,32 +43,44 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest,
SurfDestAlloc = FALSE; SurfDestAlloc = FALSE;
SurfSrcAlloc = 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 SurfGDIDest = AccessInternalObjectFromUserObject(SurfDest);
if(DCDest->Surface != NULL) SurfGDISrc = AccessInternalObjectFromUserObject(SurfSrc);
// Retrieve the logical palette of the destination DC
DCLogPal = AccessUserObject(DCDest->w.hPalette);
if(DCLogPal)
if(DCLogPal->logicalToSystem)
XlateObj = DCLogPal->logicalToSystem;
// 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))
{ {
// Use the DC's surface if it has one if(DCDest->w.hPalette != 0)
SurfDest = AccessUserObject(DCDest->Surface); {
} else DestPalette = DCDest->w.hPalette;
return FALSE; } else
DestPalette = W32kGetStockObject(DEFAULT_PALETTE);
DPRINT("Get surfsrc.. "); if(DCSrc->w.hPalette != 0)
{
SourcePalette = DCSrc->w.hPalette;
} else
SourcePalette = W32kGetStockObject(DEFAULT_PALETTE);
// Get the SurfSrc PalDestGDI = AccessInternalObject(DestPalette);
if(DCSrc->Surface != NULL) PalSourceGDI = AccessInternalObject(SourcePalette);
{
DPRINT("from DC's surface\n");
// Use the DC's surface if it has one XlateObj = EngCreateXlate(PalDestGDI->Mode, PalSourceGDI->Mode, DestPalette, SourcePalette);
SurfSrc = AccessUserObject(DCSrc->Surface); }
} else
return FALSE;
// Perform the bitblt operation
DPRINT("Go to EngBitBlt\n"); Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, NULL);
Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, NULL,
&DestRect, &SourcePoint, NULL, NULL, NULL, NULL); // FIXME: Color translation (xlateobj)
if(SurfDestAlloc == TRUE) ExFreePool(SurfDest); if(SurfDestAlloc == TRUE) ExFreePool(SurfDest);
if(SurfSrcAlloc == TRUE) ExFreePool(SurfSrc); if(SurfSrcAlloc == TRUE) ExFreePool(SurfSrc);
@ -87,35 +102,35 @@ HBITMAP STDCALL W32kCreateBitmap(INT Width,
/* Check parameters */ /* Check parameters */
if (!Height || !Width) if (!Height || !Width)
{ {
return 0; return 0;
} }
if (Planes != 1) if (Planes != 1)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
return 0; return 0;
} }
if (Height < 0) if (Height < 0)
{ {
Height = -Height; Height = -Height;
} }
if (Width < 0) if (Width < 0)
{ {
Width = -Width; Width = -Width;
} }
/* Create the BITMAPOBJ */ /* Create the BITMAPOBJ */
bmp = BITMAPOBJ_AllocBitmap (); bmp = BITMAPOBJ_AllocBitmap ();
if (!bmp) if (!bmp)
{ {
return 0; return 0;
} }
DPRINT("W32kCreateBitmap:%dx%d, %d (%d BPP) colors returning %08x\n", Width, Height, DPRINT("W32kCreateBitmap:%dx%d, %d (%d BPP) colors returning %08x\n", Width, Height,
1 << (Planes * BitsPerPel), BitsPerPel, bmp); 1 << (Planes * BitsPerPel), BitsPerPel, bmp);
bmp->size.cx = 0; bmp->size.cx = Width;
bmp->size.cy = 0; bmp->size.cy = Height;
bmp->bitmap.bmType = 0; bmp->bitmap.bmType = 0;
bmp->bitmap.bmWidth = Width; bmp->bitmap.bmWidth = Width;
bmp->bitmap.bmHeight = Height; bmp->bitmap.bmHeight = Height;
@ -131,12 +146,9 @@ HBITMAP STDCALL W32kCreateBitmap(INT Width,
bmp->bitmap.bmBits = ExAllocatePool(PagedPool, bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight); bmp->bitmap.bmBits = ExAllocatePool(PagedPool, bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight);
if (Bits) /* Set bitmap bits */ if (Bits) /* Set bitmap bits */
{ {
W32kSetBitmapBits(hBitmap, W32kSetBitmapBits(hBitmap, Height * bmp->bitmap.bmWidthBytes, Bits);
Height * bmp->bitmap.bmWidthBytes, }
Bits);
}
return hBitmap; return hBitmap;
} }
@ -151,33 +163,28 @@ HBITMAP STDCALL W32kCreateCompatibleBitmap(HDC hDC,
hbmpRet = 0; hbmpRet = 0;
dc = DC_HandleToPtr (hDC); 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) if (!dc)
{ {
return 0; return 0;
} }
if ((Width >= 0x10000) || (Height >= 0x10000)) if ((Width >= 0x10000) || (Height >= 0x10000))
{ {
DPRINT("got bad width %d or height %d, please look for reason\n", DPRINT("got bad width %d or height %d, please look for reason\n", Width, Height);
Width, Height); }
}
else 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 */ hbmpRet = W32kCreateBitmap (1, 1, 1, 1, NULL);
if (!Width || !Height)
{
hbmpRet = W32kCreateBitmap (1, 1, 1, 1, NULL);
}
else
{
hbmpRet = W32kCreateBitmap (Width,
Height,
1,
dc->w.bitsPerPixel,
NULL);
}
} }
else
{
hbmpRet = W32kCreateBitmap(Width, Height, 1, dc->w.bitsPerPixel, NULL);
}
}
DPRINT ("\t\t%04x\n", hbmpRet); DPRINT ("\t\t%04x\n", hbmpRet);
DC_UnlockDC (hDC); DC_UnlockDC (hDC);
@ -193,26 +200,6 @@ HBITMAP STDCALL W32kCreateBitmapIndirect(CONST BITMAP *BM)
BM->bmBits); 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, HBITMAP STDCALL W32kCreateDiscardableBitmap(HDC hDC,
INT Width, INT Width,
INT Height) INT Height)
@ -238,83 +225,6 @@ BOOL STDCALL W32kFloodFill(HDC hDC,
UNIMPLEMENTED; 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, BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
LPSIZE Dimension) LPSIZE Dimension)
{ {
@ -322,9 +232,9 @@ BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
bmp = BITMAPOBJ_HandleToPtr (hBitmap); bmp = BITMAPOBJ_HandleToPtr (hBitmap);
if (bmp == NULL) if (bmp == NULL)
{ {
return FALSE; return FALSE;
} }
*Dimension = bmp->size; *Dimension = bmp->size;
BITMAPOBJ_UnlockBitmap (hBitmap); BITMAPOBJ_UnlockBitmap (hBitmap);
@ -332,25 +242,6 @@ BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
return TRUE; 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, COLORREF STDCALL W32kGetPixel(HDC hDC,
INT XPos, INT XPos,
INT YPos) INT YPos)
@ -397,22 +288,22 @@ LONG STDCALL W32kSetBitmapBits(HBITMAP hBitmap,
bmp = BITMAPOBJ_HandleToPtr (hBitmap); bmp = BITMAPOBJ_HandleToPtr (hBitmap);
if (bmp == NULL || Bits == NULL) if (bmp == NULL || Bits == NULL)
{ {
return 0; return 0;
} }
if (Bytes < 0) if (Bytes < 0)
{ {
DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes ); DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes );
Bytes = -Bytes; Bytes = -Bytes;
} }
/* Only get entire lines */ /* Only get entire lines */
height = Bytes / bmp->bitmap.bmWidthBytes; height = Bytes / bmp->bitmap.bmWidthBytes;
if (height > bmp->bitmap.bmHeight) if (height > bmp->bitmap.bmHeight)
{ {
height = bmp->bitmap.bmHeight; height = bmp->bitmap.bmHeight;
} }
Bytes = height * bmp->bitmap.bmWidthBytes; Bytes = height * bmp->bitmap.bmWidthBytes;
DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n", DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
hBitmap, hBitmap,
@ -426,39 +317,36 @@ LONG STDCALL W32kSetBitmapBits(HBITMAP hBitmap,
#if 0 #if 0
/* FIXME: call DDI specific function here if available */ /* FIXME: call DDI specific function here if available */
if(bmp->DDBitmap) if(bmp->DDBitmap)
{
DPRINT ("Calling device specific BitmapBits\n");
if (bmp->DDBitmap->funcs->pBitmapBits)
{ {
DPRINT ("Calling device specific BitmapBits\n"); ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap, (void *) Bits, Bytes, DDB_SET);
if (bmp->DDBitmap->funcs->pBitmapBits)
{
ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap,
(void *) Bits,
Bytes,
DDB_SET);
}
else
{
DPRINT ("BitmapBits == NULL??\n");
ret = 0;
}
} }
else
{
DPRINT ("BitmapBits == NULL??\n");
ret = 0;
}
}
else else
#endif #endif
{ {
/* FIXME: Alloc enough for entire bitmap */ /* FIXME: Alloc enough for entire bitmap */
if (bmp->bitmap.bmBits == NULL) if (bmp->bitmap.bmBits == NULL)
{ {
bmp->bitmap.bmBits = ExAllocatePool (PagedPool, Bytes); bmp->bitmap.bmBits = ExAllocatePool (PagedPool, Bytes);
} }
if(!bmp->bitmap.bmBits) if(!bmp->bitmap.bmBits)
{ {
DPRINT ("Unable to allocate bit buffer\n"); DPRINT ("Unable to allocate bit buffer\n");
ret = 0; ret = 0;
} }
else else
{ {
memcpy(bmp->bitmap.bmBits, Bits, Bytes); memcpy(bmp->bitmap.bmBits, Bits, Bytes);
ret = Bytes; ret = Bytes;
} }
} }
BITMAPOBJ_UnlockBitmap (hBitmap); BITMAPOBJ_UnlockBitmap (hBitmap);
@ -474,14 +362,14 @@ BOOL STDCALL W32kSetBitmapDimensionEx(HBITMAP hBitmap,
bmp = BITMAPOBJ_HandleToPtr (hBitmap); bmp = BITMAPOBJ_HandleToPtr (hBitmap);
if (bmp == NULL) if (bmp == NULL)
{ {
return FALSE; return FALSE;
} }
if (Size) if (Size)
{ {
*Size = bmp->size; *Size = bmp->size;
} }
bmp->size.cx = Width; bmp->size.cx = Width;
bmp->size.cy = Height; bmp->size.cy = Height;
BITMAPOBJ_UnlockBitmap (hBitmap); BITMAPOBJ_UnlockBitmap (hBitmap);
@ -489,41 +377,6 @@ BOOL STDCALL W32kSetBitmapDimensionEx(HBITMAP hBitmap,
return TRUE; 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, COLORREF STDCALL W32kSetPixel(HDC hDC,
INT X, INT X,
INT Y, INT Y,
@ -555,30 +408,13 @@ BOOL STDCALL W32kStretchBlt(HDC hDCDest,
UNIMPLEMENTED; 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 */ /* Internal Functions */
INT INT
BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp) BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
{ {
switch(bpp) switch(bpp)
{ {
case 1: case 1:
return 2 * ((bmWidth+15) >> 4); return 2 * ((bmWidth+15) >> 4);
@ -599,7 +435,7 @@ BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
default: default:
DPRINT ("stub"); DPRINT ("stub");
} }
return -1; return -1;
} }
@ -612,94 +448,47 @@ HBITMAP BITMAPOBJ_CopyBitmap(HBITMAP hBitmap)
bmp = BITMAPOBJ_HandleToPtr (hBitmap); bmp = BITMAPOBJ_HandleToPtr (hBitmap);
if (bmp == NULL) if (bmp == NULL)
{ {
return 0; return 0;
} }
res = 0; res = 0;
bm = bmp->bitmap; bm = bmp->bitmap;
bm.bmBits = NULL; bm.bmBits = NULL;
res = W32kCreateBitmapIndirect(&bm); res = W32kCreateBitmapIndirect(&bm);
if(res) if(res)
{ {
char *buf; char *buf;
buf = ExAllocatePool (NonPagedPool, bm.bmWidthBytes * bm.bmHeight); buf = ExAllocatePool (NonPagedPool, bm.bmWidthBytes * bm.bmHeight);
W32kGetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf); W32kGetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
W32kSetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf); W32kSetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
ExFreePool (buf); ExFreePool (buf);
} }
BITMAPOBJ_UnlockBitmap (hBitmap); BITMAPOBJ_UnlockBitmap (hBitmap);
return res; return res;
} }
/*********************************************************************** INT BITMAP_GetObject(BITMAPOBJ * bmp, INT count, LPVOID buffer)
* 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; if(bmp->dib)
{
switch(depth) if(count < sizeof(DIBSECTION))
{ {
case 1: words = (width + 31) / 32; break; if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
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; else
}
/***********************************************************************
* 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; if (count > sizeof(DIBSECTION)) count = sizeof(DIBSECTION);
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));
} }
memcpy(buffer, bmp->dib, count);
return count;
}
else
{
if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
memcpy(buffer, &bmp->bitmap, count);
return count;
}
} }

View 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; PBRUSHOBJ brushPtr;
HBRUSH hBrush; HBRUSH hBrush;
hBrush = BRUSHOBJ_AllocBrush (); brushPtr = BRUSHOBJ_AllocBrush();
hBrush = BRUSHOBJ_PtrToHandle (brushPtr);
if (hBrush == NULL) if (hBrush == NULL)
{ {
return 0; return 0;
} }
brushPtr = BRUSHOBJ_HandleToPtr (hBrush);
brushPtr->logbrush.lbStyle = lb->lbStyle; brushPtr->logbrush.lbStyle = lb->lbStyle;
brushPtr->logbrush.lbColor = lb->lbColor; brushPtr->logbrush.lbColor = lb->lbColor;
brushPtr->logbrush.lbHatch = lb->lbHatch; brushPtr->logbrush.lbHatch = lb->lbHatch;
BRUSHOBJ_UnlockBrush (hBrush); BRUSHOBJ_UnlockBrush (hBrush);
DPRINT("%08x\n", hBrush); DPRINT("%08x\n", hBrush);
@ -50,29 +51,26 @@ HBRUSH STDCALL W32kCreateDIBPatternBrush(HGLOBAL hDIBPacked,
/* Make a copy of the bitmap */ /* Make a copy of the bitmap */
if (!(info = (BITMAPINFO *)GlobalLock( hbitmap ))) if (!(info = (BITMAPINFO *)GlobalLock( hbitmap )))
{ {
return 0; return 0;
} }
if (info->bmiHeader.biCompression) if (info->bmiHeader.biCompression) size = info->bmiHeader.biSizeImage;
size = info->bmiHeader.biSizeImage; else
else size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth, size += DIB_BitmapInfoSize(info, coloruse);
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount);
size += DIB_BitmapInfoSize( info, coloruse );
if (!(logbrush.lbHatch = (INT)GlobalAlloc16( GMEM_MOVEABLE, size ))) if (!(logbrush.lbHatch = (INT)GlobalAlloc16( GMEM_MOVEABLE, size )))
{ {
GlobalUnlock16( hbitmap ); GlobalUnlock16( hbitmap );
return 0; return 0;
} }
newInfo = (BITMAPINFO *) GlobalLock16( (HGLOBAL16)logbrush.lbHatch ); newInfo = (BITMAPINFO *) GlobalLock16((HGLOBAL16)logbrush.lbHatch);
memcpy( newInfo, info, size ); memcpy(newInfo, info, size);
GlobalUnlock16( (HGLOBAL16)logbrush.lbHatch ); GlobalUnlock16((HGLOBAL16)logbrush.lbHatch);
GlobalUnlock( hbitmap ); GlobalUnlock(hbitmap);
return W32kCreateBrushIndirect( &logbrush ); return W32kCreateBrushIndirect(&logbrush);
#endif #endif
} }
@ -86,9 +84,9 @@ HBRUSH STDCALL W32kCreateDIBPatternBrushPt(CONST VOID *PackedDIB,
info = (BITMAPINFO *) PackedDIB; info = (BITMAPINFO *) PackedDIB;
if (info == NULL) if (info == NULL)
{ {
return 0; return 0;
} }
DPRINT ("%p %ldx%ld %dbpp\n", DPRINT ("%p %ldx%ld %dbpp\n",
info, info,
info->bmiHeader.biWidth, info->bmiHeader.biWidth,
@ -102,28 +100,23 @@ HBRUSH STDCALL W32kCreateDIBPatternBrushPt(CONST VOID *PackedDIB,
/* Make a copy of the bitmap */ /* Make a copy of the bitmap */
if (info->bmiHeader.biCompression) if (info->bmiHeader.biCompression)
{ {
size = info->bmiHeader.biSizeImage; size = info->bmiHeader.biSizeImage;
} }
else else
{ {
size = DIB_GetDIBImageBytes (info->bmiHeader.biWidth, size = DIB_GetDIBImageBytes (info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
info->bmiHeader.biHeight, }
info->bmiHeader.biBitCount);
}
size += DIB_BitmapInfoSize (info, Usage); size += DIB_BitmapInfoSize (info, Usage);
logbrush.lbHatch = (INT) logbrush.lbHatch = (INT)GDIOBJ_PtrToHandle (GDIOBJ_AllocObject (size, GO_MAGIC_DONTCARE), GO_MAGIC_DONTCARE);
GDIOBJ_PtrToHandle (GDIOBJ_AllocObject (size, GO_MAGIC_DONTCARE),
GO_MAGIC_DONTCARE);
if (logbrush.lbHatch == 0) if (logbrush.lbHatch == 0)
{ {
return 0; return 0;
} }
newInfo = (PBITMAPINFO) GDIOBJ_HandleToPtr ((HGDIOBJ) logbrush.lbHatch, newInfo = (PBITMAPINFO) GDIOBJ_HandleToPtr ((HGDIOBJ) logbrush.lbHatch, GO_MAGIC_DONTCARE);
GO_MAGIC_DONTCARE); memcpy(newInfo, info, size);
memcpy (newInfo, info, size); GDIOBJ_UnlockObject((HGDIOBJ)logbrush.lbHatch);
GDIOBJ_UnlockObject ((HGDIOBJ) logbrush.lbHatch);
return W32kCreateBrushIndirect (&logbrush); return W32kCreateBrushIndirect (&logbrush);
} }
@ -136,9 +129,9 @@ HBRUSH STDCALL W32kCreateHatchBrush(INT Style,
DPRINT("%d %06lx\n", Style, Color); DPRINT("%d %06lx\n", Style, Color);
if (Style < 0 || Style >= NB_HATCH_STYLES) if (Style < 0 || Style >= NB_HATCH_STYLES)
{ {
return 0; return 0;
} }
logbrush.lbStyle = BS_HATCHED; logbrush.lbStyle = BS_HATCHED;
logbrush.lbColor = Color; logbrush.lbColor = Color;
logbrush.lbHatch = Style; logbrush.lbHatch = Style;
@ -153,24 +146,24 @@ HBRUSH STDCALL W32kCreatePatternBrush(HBITMAP hBitmap)
DPRINT ("%04x\n", hBitmap); DPRINT ("%04x\n", hBitmap);
logbrush.lbHatch = (INT) BITMAPOBJ_CopyBitmap (hBitmap); logbrush.lbHatch = (INT) BITMAPOBJ_CopyBitmap (hBitmap);
if(!logbrush.lbHatch) if(!logbrush.lbHatch)
{ {
return 0; return 0;
} }
else else
{ {
return W32kCreateBrushIndirect( &logbrush ); return W32kCreateBrushIndirect( &logbrush );
} }
} }
HBRUSH STDCALL W32kCreateSolidBrush(COLORREF Color) HBRUSH STDCALL W32kCreateSolidBrush(COLORREF Color)
{ {
LOGBRUSH logbrush; LOGBRUSH logbrush;
logbrush.lbStyle = BS_SOLID; logbrush.lbStyle = BS_SOLID;
logbrush.lbColor = Color; logbrush.lbColor = Color;
logbrush.lbHatch = 0; logbrush.lbHatch = 0;
return W32kCreateBrushIndirect(&logbrush); return W32kCreateBrushIndirect(&logbrush);
} }
BOOL STDCALL W32kFixBrushOrgEx(VOID) BOOL STDCALL W32kFixBrushOrgEx(VOID)

View file

@ -1,28 +1,135 @@
// FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <ddk/winddi.h>
#include <win32k/dc.h>
#include <win32k/color.h> #include <win32k/color.h>
#include "../eng/objects.h"
// #define NDEBUG // #define NDEBUG
#include <win32k/debug1.h> #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, BOOL STDCALL W32kAnimatePalette(HPALETTE hpal,
UINT StartIndex, UINT StartIndex,
UINT Entries, UINT Entries,
CONST PPALETTEENTRY ppe) 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; UNIMPLEMENTED;
} }
HPALETTE STDCALL W32kCreateHalftonePalette(HDC hDC) 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, BOOL STDCALL W32kGetColorAdjustment(HDC hDC,
@ -34,13 +141,43 @@ BOOL STDCALL W32kGetColorAdjustment(HDC hDC,
COLORREF STDCALL W32kGetNearestColor(HDC hDC, COLORREF STDCALL W32kGetNearestColor(HDC hDC,
COLORREF Color) 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, UINT STDCALL W32kGetNearestPaletteIndex(HPALETTE hpal,
COLORREF Color) 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, UINT STDCALL W32kGetPaletteEntries(HPALETTE hpal,
@ -48,7 +185,29 @@ UINT STDCALL W32kGetPaletteEntries(HPALETTE hpal,
UINT Entries, UINT Entries,
LPPALETTEENTRY pe) 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, UINT STDCALL W32kGetSystemPaletteEntries(HDC hDC,
@ -56,7 +215,33 @@ UINT STDCALL W32kGetSystemPaletteEntries(HDC hDC,
UINT Entries, UINT Entries,
LPPALETTEENTRY pe) 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) UINT STDCALL W32kGetSystemPaletteUse(HDC hDC)
@ -65,13 +250,112 @@ UINT STDCALL W32kGetSystemPaletteUse(HDC hDC)
} }
UINT STDCALL W32kRealizePalette(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, BOOL STDCALL W32kResizePalette(HPALETTE hpal,
UINT Entries) 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; UNIMPLEMENTED;
} }
@ -79,7 +363,15 @@ HPALETTE STDCALL W32kSelectPalette(HDC hDC,
HPALETTE hpal, HPALETTE hpal,
BOOL ForceBackground) 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, BOOL STDCALL W32kSetColorAdjustment(HDC hDC,
@ -93,7 +385,25 @@ UINT STDCALL W32kSetPaletteEntries(HPALETTE hpal,
UINT Entries, UINT Entries,
CONST LPPALETTEENTRY pe) 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, UINT STDCALL W32kSetSystemPaletteUse(HDC hDC,
@ -109,6 +419,81 @@ BOOL STDCALL W32kUnrealizeObject(HGDIOBJ hgdiobj)
BOOL STDCALL W32kUpdateColors(HDC hDC) 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;
}

View file

@ -17,23 +17,17 @@ BOOL STDCALL W32kCombineTransform(LPXFORM XFormResult,
/* Check for illegal parameters */ /* Check for illegal parameters */
if (!XFormResult || !xform1 || !xform2) if (!XFormResult || !xform1 || !xform2)
{ {
return FALSE; return FALSE;
} }
/* Create the result in a temporary XFORM, since xformResult may be /* Create the result in a temporary XFORM, since xformResult may be
* equal to xform1 or xform2 */ * equal to xform1 or xform2 */
xformTemp.eM11 = xform1->eM11 * xform2->eM11 + xformTemp.eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21;
xform1->eM12 * xform2->eM21; xformTemp.eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22;
xformTemp.eM12 = xform1->eM11 * xform2->eM12 + xformTemp.eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21;
xform1->eM12 * xform2->eM22; xformTemp.eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22;
xformTemp.eM21 = xform1->eM21 * xform2->eM11 + xformTemp.eDx = xform1->eDx * xform2->eM11 + xform1->eDy * xform2->eM21 + xform2->eDx;
xform1->eM22 * xform2->eM21; xformTemp.eDy = xform1->eDx * xform2->eM12 + xform1->eDy * xform2->eM22 + xform2->eDy;
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 */ /* Copy the result to xformResult */
*XFormResult = xformTemp; *XFormResult = xformTemp;
@ -57,9 +51,9 @@ W32kGetGraphicsMode(HDC hDC)
dc = DC_HandleToPtr (hDC); dc = DC_HandleToPtr (hDC);
if (!dc) if (!dc)
{ {
return 0; return 0;
} }
GraphicsMode = dc->w.GraphicsMode; GraphicsMode = dc->w.GraphicsMode;
DC_UnlockDC (hDC); DC_UnlockDC (hDC);
@ -76,13 +70,13 @@ W32kGetWorldTransform(HDC hDC,
dc = DC_HandleToPtr (hDC); dc = DC_HandleToPtr (hDC);
if (!dc) if (!dc)
{ {
return FALSE; return FALSE;
} }
if (!XForm) if (!XForm)
{ {
return FALSE; return FALSE;
} }
*XForm = dc->w.xformWorld2Wnd; *XForm = dc->w.xformWorld2Wnd;
DC_UnlockDC (hDC); DC_UnlockDC (hDC);
@ -108,22 +102,22 @@ W32kModifyWorldTransform(HDC hDC,
dc = DC_HandleToPtr (hDC); dc = DC_HandleToPtr (hDC);
if (!dc) if (!dc)
{ {
// SetLastError( ERROR_INVALID_HANDLE ); // SetLastError( ERROR_INVALID_HANDLE );
return FALSE; return FALSE;
} }
if (!XForm) if (!XForm)
{ {
return FALSE; return FALSE;
} }
/* Check that graphics mode is GM_ADVANCED */ /* Check that graphics mode is GM_ADVANCED */
if (dc->w.GraphicsMode!=GM_ADVANCED) if (dc->w.GraphicsMode!=GM_ADVANCED)
{ {
return FALSE; return FALSE;
} }
switch (Mode) switch (Mode)
{ {
case MWT_IDENTITY: case MWT_IDENTITY:
dc->w.xformWorld2Wnd.eM11 = 1.0f; dc->w.xformWorld2Wnd.eM11 = 1.0f;
dc->w.xformWorld2Wnd.eM12 = 0.0f; dc->w.xformWorld2Wnd.eM12 = 0.0f;
@ -134,20 +128,16 @@ W32kModifyWorldTransform(HDC hDC,
break; break;
case MWT_LEFTMULTIPLY: case MWT_LEFTMULTIPLY:
W32kCombineTransform(&dc->w.xformWorld2Wnd, W32kCombineTransform(&dc->w.xformWorld2Wnd, XForm, &dc->w.xformWorld2Wnd );
XForm,
&dc->w.xformWorld2Wnd );
break; break;
case MWT_RIGHTMULTIPLY: case MWT_RIGHTMULTIPLY:
W32kCombineTransform(&dc->w.xformWorld2Wnd, W32kCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, XForm);
&dc->w.xformWorld2Wnd,
XForm);
break; break;
default: default:
return FALSE; return FALSE;
} }
DC_UpdateXforms (dc); DC_UpdateXforms (dc);
DC_UnlockDC (hDC); DC_UnlockDC (hDC);
@ -208,9 +198,9 @@ W32kSetGraphicsMode(HDC hDC,
dc = DC_HandleToPtr (hDC); dc = DC_HandleToPtr (hDC);
if (!dc) if (!dc)
{ {
return 0; return 0;
} }
/* One would think that setting the graphics mode to GM_COMPATIBLE /* One would think that setting the graphics mode to GM_COMPATIBLE
* would also reset the world transformation matrix to the unity * would also reset the world transformation matrix to the unity
@ -219,9 +209,9 @@ W32kSetGraphicsMode(HDC hDC,
*/ */
if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED)) if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
{ {
return 0; return 0;
} }
ret = dc->w.GraphicsMode; ret = dc->w.GraphicsMode;
dc->w.GraphicsMode = Mode; dc->w.GraphicsMode = Mode;
DC_UnlockDC (hDC); DC_UnlockDC (hDC);
@ -286,20 +276,20 @@ W32kSetWorldTransform(HDC hDC,
dc = DC_HandleToPtr (hDC); dc = DC_HandleToPtr (hDC);
if (!dc) if (!dc)
{ {
// SetLastError( ERROR_INVALID_HANDLE ); // SetLastError( ERROR_INVALID_HANDLE );
return FALSE; return FALSE;
} }
if (!XForm) if (!XForm)
{ {
return FALSE; return FALSE;
} }
/* Check that graphics mode is GM_ADVANCED */ /* Check that graphics mode is GM_ADVANCED */
if (dc->w.GraphicsMode != GM_ADVANCED) if (dc->w.GraphicsMode != GM_ADVANCED)
{ {
return FALSE; return FALSE;
} }
dc->w.xformWorld2Wnd = *XForm; dc->w.xformWorld2Wnd = *XForm;
DC_UpdateXforms (dc); DC_UpdateXforms (dc);
DC_UnlockDC (hDC); DC_UnlockDC (hDC);

File diff suppressed because it is too large Load diff

View file

@ -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);
}

View file

@ -77,53 +77,53 @@ W32kRectangle(HDC hDC,
int RightRect, int RightRect,
int BottomRect) int BottomRect)
{ {
DC *dc = DC_HandleToPtr(hDC); DC *dc = DC_HandleToPtr(hDC);
SURFOBJ *SurfObj = AccessUserObject(dc->Surface); SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
PBRUSHOBJ BrushObj; PBRUSHOBJ BrushObj;
BOOL ret; BOOL ret;
PRECTL RectBounds = GDIOBJ_HandleToPtr(dc->w.hGCClipRgn, GO_REGION_MAGIC); PRECTL RectBounds = GDIOBJ_HandleToPtr(dc->w.hGCClipRgn, GO_REGION_MAGIC);
if(!dc) return FALSE; if(!dc) return FALSE;
if(PATH_IsPathOpen(dc->w.path)) { if(PATH_IsPathOpen(dc->w.path)) {
ret = PATH_Rectangle(hDC, LeftRect, TopRect, RightRect, BottomRect); ret = PATH_Rectangle(hDC, LeftRect, TopRect, RightRect, BottomRect);
} else { } else {
DbgPrint("W32kRectangle pen: "); DbgPrint("W32kRectangle pen: ");
DbgPrint("--- %08x\n", GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC)); DbgPrint("--- %08x\n", GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
BrushObj = PenToBrushObj(dc, GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC)); BrushObj = PenToBrushObj(dc, GDIOBJ_HandleToPtr(dc->w.hPen, GO_PEN_MAGIC));
ret = EngLineTo(SurfObj, ret = EngLineTo(SurfObj,
NULL, // ClipObj, NULL, // ClipObj,
BrushObj, BrushObj,
LeftRect, TopRect, RightRect, TopRect, LeftRect, TopRect, RightRect, TopRect,
RectBounds, // Bounding rectangle RectBounds, // Bounding rectangle
dc->w.ROPmode); // MIX dc->w.ROPmode); // MIX
ret = EngLineTo(SurfObj, ret = EngLineTo(SurfObj,
NULL, // ClipObj, NULL, // ClipObj,
BrushObj, BrushObj,
RightRect, TopRect, RightRect, BottomRect, RightRect, TopRect, RightRect, BottomRect,
RectBounds, // Bounding rectangle RectBounds, // Bounding rectangle
dc->w.ROPmode); // MIX dc->w.ROPmode); // MIX
ret = EngLineTo(SurfObj, ret = EngLineTo(SurfObj,
NULL, // ClipObj, NULL, // ClipObj,
BrushObj, BrushObj,
LeftRect, BottomRect, RightRect, BottomRect, LeftRect, BottomRect, RightRect, BottomRect,
RectBounds, // Bounding rectangle RectBounds, // Bounding rectangle
dc->w.ROPmode); // MIX dc->w.ROPmode); // MIX
ret = EngLineTo(SurfObj, ret = EngLineTo(SurfObj,
NULL, // ClipObj, NULL, // ClipObj,
BrushObj, BrushObj,
LeftRect, TopRect, LeftRect, BottomRect, LeftRect, TopRect, LeftRect, BottomRect,
RectBounds, // Bounding rectangle RectBounds, // Bounding rectangle
dc->w.ROPmode); // MIX */ dc->w.ROPmode); // MIX */
ExFreePool(BrushObj); ExFreePool(BrushObj);
} }
// FIXME: Move current position in DC? // FIXME: Move current position in DC?
@ -142,5 +142,3 @@ W32kRoundRect(HDC hDC,
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }

View file

@ -1,7 +1,7 @@
/* /*
* GDIOBJ.C - GDI object manipulation routines * 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 $
* *
*/ */
@ -9,18 +9,107 @@
#include <windows.h> #include <windows.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <win32k/gdiobj.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) PGDIOBJ GDIOBJ_AllocObject(WORD Size, WORD Magic)
{ {
PGDIOBJHDR NewObj; PGDIOBJHDR NewObj;
NewObj = ExAllocatePool(PagedPool, Size + sizeof (GDIOBJHDR)); // FIXME: Allocate with tag of MAGIC? NewObj = ExAllocatePool(PagedPool, Size + sizeof (GDIOBJHDR)); // FIXME: Allocate with tag of MAGIC?
if (NewObj == NULL) if (NewObj == NULL)
{ {
return NULL; return NULL;
} }
RtlZeroMemory(NewObj, Size + sizeof (GDIOBJHDR)); RtlZeroMemory(NewObj, Size + sizeof (GDIOBJHDR));
NewObj->wMagic = Magic; NewObj->wMagic = Magic;
#if 0 #if 0
KeInitializeSpinlock(&NewObj->Lock); KeInitializeSpinlock(&NewObj->Lock);
@ -35,9 +124,9 @@ BOOL GDIOBJ_FreeObject (PGDIOBJ Obj, WORD Magic)
ObjHdr = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR)); ObjHdr = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR));
if (ObjHdr->wMagic != Magic) if (ObjHdr->wMagic != Magic)
{ {
return FALSE; return FALSE;
} }
ExFreePool (ObjHdr); ExFreePool (ObjHdr);
return TRUE; return TRUE;
} }
@ -49,9 +138,9 @@ HGDIOBJ GDIOBJ_PtrToHandle (PGDIOBJ Obj, WORD Magic)
if (Obj == NULL) return NULL; if (Obj == NULL) return NULL;
objHeader = (PGDIOBJHDR) (((PCHAR)Obj) - sizeof (GDIOBJHDR)); objHeader = (PGDIOBJHDR) (((PCHAR)Obj) - sizeof (GDIOBJHDR));
if (objHeader->wMagic != Magic) if (objHeader->wMagic != Magic)
{ {
return 0; return 0;
} }
return (HGDIOBJ) objHeader; return (HGDIOBJ) objHeader;
} }
@ -67,9 +156,9 @@ PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic)
/* FIXME: Lock object for duration */ /* FIXME: Lock object for duration */
if ((objHeader->wMagic != Magic) && (Magic != GO_MAGIC_DONTCARE)) if ((objHeader->wMagic != Magic) && (Magic != GO_MAGIC_DONTCARE))
{ {
return 0; return 0;
} }
return (PGDIOBJ) (((PCHAR)Obj) + sizeof (GDIOBJHDR)); return (PGDIOBJ) (((PCHAR)Obj) + sizeof (GDIOBJHDR));
} }
@ -77,7 +166,7 @@ PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic)
BOOL GDIOBJ_LockObject (HGDIOBJ Obj) BOOL GDIOBJ_LockObject (HGDIOBJ Obj)
{ {
/* FIXME: write this */ /* FIXME: write this */
return TRUE; // return TRUE;
} }
BOOL GDIOBJ_UnlockObject (HGDIOBJ Obj) BOOL GDIOBJ_UnlockObject (HGDIOBJ Obj)
@ -92,9 +181,9 @@ HGDIOBJ GDIOBJ_GetNextObject (HGDIOBJ Obj, WORD Magic)
objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR)); objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
if (objHeader->wMagic != Magic) if (objHeader->wMagic != Magic)
{ {
return 0; return 0;
} }
return objHeader->hNext; return objHeader->hNext;
} }
@ -107,14 +196,48 @@ HGDIOBJ GDIOBJ_SetNextObject (HGDIOBJ Obj, WORD Magic, HGDIOBJ NextObj)
/* FIXME: should we lock/unlock the object here? */ /* FIXME: should we lock/unlock the object here? */
objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR)); objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
if (objHeader->wMagic != Magic) if (objHeader->wMagic != Magic)
{ {
return 0; return 0;
} }
oldNext = objHeader->hNext; oldNext = objHeader->hNext;
objHeader->hNext = NextObj; objHeader->hNext = NextObj;
return oldNext; 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........
}

View file

@ -35,12 +35,12 @@ W32kArc(HDC hDC,
int XEndArc, int XEndArc,
int YEndArc) int YEndArc)
{ {
DC *dc = DC_HandleToPtr(hDC); DC *dc = DC_HandleToPtr(hDC);
if(!dc) return FALSE; if(!dc) return FALSE;
if(PATH_IsPathOpen(dc->w.path)) if(PATH_IsPathOpen(dc->w.path))
return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect, return PATH_Arc(hDC, LeftRect, TopRect, RightRect, BottomRect,
XStartArc, YStartArc, XEndArc, YEndArc); XStartArc, YStartArc, XEndArc, YEndArc);
// EngArc(dc, LeftRect, TopRect, RightRect, BottomRect, UNIMPLEMENTED // EngArc(dc, LeftRect, TopRect, RightRect, BottomRect, UNIMPLEMENTED
// XStartArc, YStartArc, XEndArc, YEndArc); // XStartArc, YStartArc, XEndArc, YEndArc);
@ -58,43 +58,43 @@ W32kArcTo(HDC hDC,
int XRadial2, int XRadial2,
int YRadial2) int YRadial2)
{ {
BOOL result; BOOL result;
DC *dc = DC_HandleToPtr(hDC); DC *dc = DC_HandleToPtr(hDC);
if(!dc) return FALSE; if(!dc) return FALSE;
// Line from current position to starting point of arc // Line from current position to starting point of arc
W32kLineTo(hDC, XRadial1, YRadial1); W32kLineTo(hDC, XRadial1, YRadial1);
// Then the arc is drawn. // Then the arc is drawn.
result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect, result = W32kArc(hDC, LeftRect, TopRect, RightRect, BottomRect,
XRadial1, YRadial1, XRadial2, YRadial2); XRadial1, YRadial1, XRadial2, YRadial2);
// If no error occured, the current position is moved to the ending point of the arc. // If no error occured, the current position is moved to the ending point of the arc.
if(result) if(result)
{ {
W32kMoveToEx(hDC, XRadial2, YRadial2, NULL); W32kMoveToEx(hDC, XRadial2, YRadial2, NULL);
} }
return result; return result;
} }
INT INT
STDCALL STDCALL
W32kGetArcDirection(HDC hDC) W32kGetArcDirection(HDC hDC)
{ {
PDC dc; PDC dc;
int ret; int ret;
dc = DC_HandleToPtr (hDC); dc = DC_HandleToPtr (hDC);
if (!dc) if (!dc)
{ {
return 0; return 0;
} }
ret = dc->w.ArcDirection; ret = dc->w.ArcDirection;
DC_UnlockDC (hDC); DC_UnlockDC (hDC);
return ret; return ret;
} }
BOOL BOOL
@ -103,32 +103,28 @@ W32kLineTo(HDC hDC,
int XEnd, int XEnd,
int YEnd) int YEnd)
{ {
DC *dc = DC_HandleToPtr(hDC); DC *dc = DC_HandleToPtr(hDC);
SURFOBJ *SurfObj = AccessUserObject(dc->Surface); SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
BOOL ret; BOOL ret;
if(!dc) return FALSE; if(!dc) return FALSE;
if(PATH_IsPathOpen(dc->w.path)) { if(PATH_IsPathOpen(dc->w.path)) {
ret = PATH_LineTo(hDC, XEnd, YEnd); ret = PATH_LineTo(hDC, XEnd, YEnd);
} else { } 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;
}
DbgPrint("W32kLineTo on DC:%08x (h:%08x) with pen handle %08x\n", dc, hDC, dc->w.hPen); return ret;
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;
} }
BOOL BOOL
@ -138,21 +134,21 @@ W32kMoveToEx(HDC hDC,
int Y, int Y,
LPPOINT Point) LPPOINT Point)
{ {
DC *dc = DC_HandleToPtr( hDC ); DC *dc = DC_HandleToPtr( hDC );
if(!dc) return FALSE; if(!dc) return FALSE;
if(Point) { if(Point) {
Point->x = dc->w.CursPosX; Point->x = dc->w.CursPosX;
Point->y = dc->w.CursPosY; Point->y = dc->w.CursPosY;
} }
dc->w.CursPosX = X; dc->w.CursPosX = X;
dc->w.CursPosY = Y; dc->w.CursPosY = Y;
if(PATH_IsPathOpen(dc->w.path)) if(PATH_IsPathOpen(dc->w.path))
return PATH_MoveTo(hDC); return PATH_MoveTo(hDC);
return FALSE; return FALSE;
} }
BOOL BOOL
@ -161,25 +157,25 @@ W32kPolyBezier(HDC hDC,
CONST LPPOINT pt, CONST LPPOINT pt,
DWORD Count) DWORD Count)
{ {
DC *dc = DC_HandleToPtr(hDC); DC *dc = DC_HandleToPtr(hDC);
if(!dc) return FALSE; if(!dc) return FALSE;
if(PATH_IsPathOpen(dc->w.path)) if(PATH_IsPathOpen(dc->w.path))
return PATH_PolyBezier(hDC, pt, Count); return PATH_PolyBezier(hDC, pt, Count);
/* We'll convert it into line segments and draw them using Polyline */ /* We'll convert it into line segments and draw them using Polyline */
{ {
POINT *Pts; POINT *Pts;
INT nOut; INT nOut;
BOOL ret; BOOL ret;
Pts = GDI_Bezier(pt, Count, &nOut); Pts = GDI_Bezier(pt, Count, &nOut);
if(!Pts) return FALSE; if(!Pts) return FALSE;
DbgPrint("Pts = %p, no = %d\n", Pts, nOut); DbgPrint("Pts = %p, no = %d\n", Pts, nOut);
ret = W32kPolyline(dc->hSelf, Pts, nOut); ret = W32kPolyline(dc->hSelf, Pts, nOut);
ExFreePool(Pts); ExFreePool(Pts);
return ret; return ret;
} }
} }
BOOL BOOL
@ -188,28 +184,28 @@ W32kPolyBezierTo(HDC hDC,
CONST LPPOINT pt, CONST LPPOINT pt,
DWORD Count) DWORD Count)
{ {
DC *dc = DC_HandleToPtr(hDC); DC *dc = DC_HandleToPtr(hDC);
BOOL ret; BOOL ret;
if(!dc) return FALSE; if(!dc) return FALSE;
if(PATH_IsPathOpen(dc->w.path)) if(PATH_IsPathOpen(dc->w.path))
ret = PATH_PolyBezierTo(hDC, pt, Count); ret = PATH_PolyBezierTo(hDC, pt, Count);
else { /* We'll do it using PolyBezier */ else { /* We'll do it using PolyBezier */
POINT *npt; POINT *npt;
npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1)); npt = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
if(!npt) return FALSE; if(!npt) return FALSE;
npt[0].x = dc->w.CursPosX; npt[0].x = dc->w.CursPosX;
npt[0].y = dc->w.CursPosY; npt[0].y = dc->w.CursPosY;
memcpy(npt + 1, pt, sizeof(POINT) * Count); memcpy(npt + 1, pt, sizeof(POINT) * Count);
ret = W32kPolyBezier(dc->hSelf, npt, Count+1); ret = W32kPolyBezier(dc->hSelf, npt, Count+1);
ExFreePool(npt); ExFreePool(npt);
} }
if(ret) { if(ret) {
dc->w.CursPosX = pt[Count-1].x; dc->w.CursPosX = pt[Count-1].x;
dc->w.CursPosY = pt[Count-1].y; dc->w.CursPosY = pt[Count-1].y;
} }
return ret; return ret;
} }
BOOL BOOL
@ -237,30 +233,30 @@ W32kPolylineTo(HDC hDC,
CONST LPPOINT pt, CONST LPPOINT pt,
DWORD Count) DWORD Count)
{ {
DC *dc = DC_HandleToPtr(hDC); DC *dc = DC_HandleToPtr(hDC);
BOOL ret; BOOL ret;
if(!dc) return FALSE; if(!dc) return FALSE;
if(PATH_IsPathOpen(dc->w.path)) if(PATH_IsPathOpen(dc->w.path))
{ {
ret = PATH_PolylineTo(hDC, pt, Count); ret = PATH_PolylineTo(hDC, pt, Count);
} }
else { /* do it using Polyline */ else { /* do it using Polyline */
POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1)); POINT *pts = ExAllocatePool(NonPagedPool, sizeof(POINT) * (Count + 1));
if(!pts) return FALSE; if(!pts) return FALSE;
pts[0].x = dc->w.CursPosX; pts[0].x = dc->w.CursPosX;
pts[0].y = dc->w.CursPosY; pts[0].y = dc->w.CursPosY;
memcpy( pts + 1, pt, sizeof(POINT) * Count); memcpy( pts + 1, pt, sizeof(POINT) * Count);
ret = W32kPolyline(hDC, pts, Count + 1); ret = W32kPolyline(hDC, pts, Count + 1);
ExFreePool(pts); ExFreePool(pts);
} }
if(ret) { if(ret) {
dc->w.CursPosX = pt[Count-1].x; dc->w.CursPosX = pt[Count-1].x;
dc->w.CursPosY = pt[Count-1].y; dc->w.CursPosY = pt[Count-1].y;
} }
return ret; return ret;
} }
BOOL BOOL
@ -278,22 +274,22 @@ STDCALL
W32kSetArcDirection(HDC hDC, W32kSetArcDirection(HDC hDC,
int ArcDirection) int ArcDirection)
{ {
PDC dc; PDC dc;
INT nOldDirection; INT nOldDirection;
dc = DC_HandleToPtr (hDC); dc = DC_HandleToPtr (hDC);
if (!dc) if (!dc)
{ {
return 0; return 0;
} }
if (ArcDirection != AD_COUNTERCLOCKWISE && ArcDirection != AD_CLOCKWISE) if (ArcDirection != AD_COUNTERCLOCKWISE && ArcDirection != AD_CLOCKWISE)
{ {
// SetLastError(ERROR_INVALID_PARAMETER); // SetLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
nOldDirection = dc->w.ArcDirection; nOldDirection = dc->w.ArcDirection;
dc->w.ArcDirection = ArcDirection; dc->w.ArcDirection = ArcDirection;
return nOldDirection; return nOldDirection;
} }

View file

@ -15,42 +15,38 @@
PBRUSHOBJ PenToBrushObj(PDC dc, PENOBJ *pen) PBRUSHOBJ PenToBrushObj(PDC dc, PENOBJ *pen)
{ {
BRUSHOBJ *BrushObj; BRUSHOBJ *BrushObj;
XLATEOBJ *RGBtoVGA16; XLATEOBJ *RGBtoVGA16;
// FIXME: move color translation routines to W32kSelectObject BrushObj = ExAllocatePool(NonPagedPool, sizeof(BRUSHOBJ));
BrushObj->iSolidColor = pen->logpen.lopnColor;
DbgPrint("PenToBrushObj:%08x ", pen); return BrushObj;
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);
} }
VOID BitmapToSurf(PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap) VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
{ {
SurfObj->dhsurf = NULL; if(Bitmap->dib)
SurfObj->hsurf = NULL; {
SurfObj->dhpdev = NULL; SurfGDI->BitsPerPixel = Bitmap->dib->dsBm.bmBitsPixel;
SurfObj->hdev = NULL; SurfObj->lDelta = Bitmap->dib->dsBm.bmWidthBytes;
SurfObj->sizlBitmap = Bitmap->size; SurfObj->pvBits = Bitmap->dib->dsBm.bmBits;
SurfObj->cjBits = Bitmap->bitmap.bmHeight * Bitmap->bitmap.bmWidthBytes; SurfObj->cjBits = Bitmap->dib->dsBm.bmHeight * Bitmap->dib->dsBm.bmWidthBytes;
SurfObj->pvBits = Bitmap->bitmap.bmBits; } else {
SurfObj->pvScan0 = NULL; // start of bitmap SurfGDI->BitsPerPixel = Bitmap->bitmap.bmBitsPixel;
SurfObj->lDelta = Bitmap->bitmap.bmWidthBytes; 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->iUniq = 0; // not sure..
SurfObj->iBitmapFormat = BMF_4BPP; /* FIXME */ SurfObj->iBitmapFormat = BitmapFormat(SurfGDI->BitsPerPixel, BI_RGB);
SurfObj->iType = STYPE_BITMAP; SurfObj->iType = STYPE_BITMAP;
SurfObj->fjBitmap = BMF_TOPDOWN; 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);
} }

View file

@ -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;
}

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,3 @@
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
@ -12,37 +10,37 @@ HPEN
STDCALL STDCALL
W32kCreatePen(INT PenStyle, INT Width, COLORREF Color) W32kCreatePen(INT PenStyle, INT Width, COLORREF Color)
{ {
LOGPEN logpen; LOGPEN logpen;
logpen.lopnStyle = PenStyle; logpen.lopnStyle = PenStyle;
logpen.lopnWidth.x = Width; logpen.lopnWidth.x = Width;
logpen.lopnWidth.y = 0; logpen.lopnWidth.y = 0;
logpen.lopnColor = Color; logpen.lopnColor = Color;
return W32kCreatePenIndirect(&logpen); return W32kCreatePenIndirect(&logpen);
} }
HPEN HPEN
STDCALL STDCALL
W32kCreatePenIndirect(CONST PLOGPEN lgpn) W32kCreatePenIndirect(CONST PLOGPEN lgpn)
{ {
PPENOBJ penPtr; PPENOBJ penPtr;
HPEN hpen; HPEN hpen;
if (lgpn->lopnStyle > PS_INSIDEFRAME) return 0; if (lgpn->lopnStyle > PS_INSIDEFRAME) return 0;
penPtr = PENOBJ_AllocPen(); penPtr = PENOBJ_AllocPen();
hpen = PENOBJ_PtrToHandle(penPtr); hpen = PENOBJ_PtrToHandle(penPtr);
if (!hpen) return 0; if (!hpen) return 0;
PENOBJ_LockPen(hpen); PENOBJ_LockPen(hpen);
penPtr->logpen.lopnStyle = lgpn->lopnStyle; penPtr->logpen.lopnStyle = lgpn->lopnStyle;
penPtr->logpen.lopnWidth = lgpn->lopnWidth; penPtr->logpen.lopnWidth = lgpn->lopnWidth;
penPtr->logpen.lopnColor = lgpn->lopnColor; penPtr->logpen.lopnColor = lgpn->lopnColor;
PENOBJ_UnlockPen(hpen); PENOBJ_UnlockPen(hpen);
return hpen; return hpen;
} }
HPEN HPEN

View file

@ -1,5 +1,3 @@
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>

View file

@ -1,5 +1,3 @@
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>

View file

@ -6,10 +6,24 @@
#include <win32k/dc.h> #include <win32k/dc.h>
#include <win32k/text.h> #include <win32k/text.h>
#include <win32k/kapi.h> #include <win32k/kapi.h>
#include <freetype/freetype.h>
// #define NDEBUG // #define NDEBUG
#include <win32k/debug1.h> #include <win32k/debug1.h>
FT_Library library;
BOOL InitFontSupport()
{
ULONG error;
error = FT_Init_FreeType(&library);
if(error)
{
return FALSE;
} else return TRUE;
}
int int
STDCALL STDCALL
W32kAddFontResource(LPCWSTR Filename) W32kAddFontResource(LPCWSTR Filename)
@ -41,7 +55,7 @@ HFONT
STDCALL STDCALL
W32kCreateFontIndirect(CONST LPLOGFONT lf) W32kCreateFontIndirect(CONST LPLOGFONT lf)
{ {
UNIMPLEMENTED; DbgPrint("WARNING: W32kCreateFontIndirect is current unimplemented\n");
} }
BOOL BOOL
@ -336,9 +350,9 @@ W32kSetTextColor(HDC hDC,
PDC dc = DC_HandleToPtr(hDC); PDC dc = DC_HandleToPtr(hDC);
if (!dc) if (!dc)
{ {
return 0x80000000; return 0x80000000;
} }
oldColor = dc->w.textColor; oldColor = dc->w.textColor;
dc->w.textColor = color; dc->w.textColor = color;
@ -364,19 +378,176 @@ W32kTextOut(HDC hDC,
LPCWSTR String, LPCWSTR String,
int Count) int Count)
{ {
DC *dc = DC_HandleToPtr(hDC); // Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
UNICODE_STRING UString;
ANSI_STRING AString;
RtlCreateUnicodeString(&UString, (PWSTR)String); DC *dc = DC_HandleToPtr(hDC);
RtlUnicodeStringToAnsiString(&AString, &UString, TRUE); 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 // For now we're just going to use an internal font
grWriteCellString(SurfObj, XStart, YStart, AString.Buffer, 0xffffff); // grWriteCellString(SurfObj, XStart, YStart, AString->Buffer, 0xffffff);
RtlFreeAnsiString(&AString); // Prepare the Unicode FileName
RtlFreeUnicodeString(&UString); 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;
}
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;
HSourceGlyph = EngCreateBitmap(bitSize, glyph->bitmap.pitch /* -1 */ , BMF_8BPP, 0, glyph->bitmap.buffer);
SourceGlyphSurf = AccessUserObject(HSourceGlyph);
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 UINT
@ -387,4 +558,3 @@ W32kTranslateCharsetInfo(PDWORD Src,
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }