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

View file

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

View file

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

View file

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

View file

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

View file

@ -11,40 +11,33 @@
#include <ddk/ntddk.h>
DWORD STDCALL EngDeviceIoControl(
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
DWORD *lpBytesReturned)
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
DWORD *lpBytesReturned)
{
PIRP Irp;
NTSTATUS Status;
KEVENT Event;
IO_STATUS_BLOCK Iosb;
PDRIVER_OBJECT DriverObject;
PIRP Irp;
NTSTATUS Status;
KEVENT Event;
IO_STATUS_BLOCK Iosb;
PDRIVER_OBJECT DriverObject;
DriverObject = hDevice;
DriverObject = hDevice;
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
Irp = IoBuildDeviceIoControlRequest(dwIoControlCode,
DriverObject->DeviceObject,
lpInBuffer,
nInBufferSize,
lpOutBuffer,
nOutBufferSize,
FALSE,
&Event,
&Iosb);
Irp = IoBuildDeviceIoControlRequest(dwIoControlCode, DriverObject->DeviceObject, lpInBuffer, nInBufferSize,
lpOutBuffer, nOutBufferSize, FALSE, &Event, &Iosb);
Status = IoCallDriver(DriverObject->DeviceObject, Irp);
Status = IoCallDriver(DriverObject->DeviceObject, Irp);
if (Status == STATUS_PENDING)
{
(void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
}
if (Status == STATUS_PENDING)
{
(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 MaxRects)
{
// Sets the parameters for enumerating rectables in the given clip region
// Sets the parameters for enumerating rectables in the given clip region
ULONG enumCount = 0;
ENUMRECTS enumRects;
ULONG enumCount = 0;
ENUMRECTS enumRects;
// MUCH WORK TO DO HERE
// MUCH WORK TO DO HERE
// Return the number of rectangles enumerated
if(enumCount>MaxRects)
{
enumCount = 0xFFFFFFFF;
}
return enumCount;
// Return the number of rectangles enumerated
if(enumCount>MaxRects)
{
enumCount = 0xFFFFFFFF;
}
return enumCount;
}
BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj,

View file

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

View file

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

View file

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

View file

@ -1,111 +1,118 @@
#include <ddk/winddi.h>
#include "objects.h"
#include "../dib/dib.h"
// POSSIBLE FIXME: Switch X and Y's so that drawing a line doesn't try to draw from 150 to 50 (negative dx)
VOID LinePoint(SURFOBJ *Surface, SURFGDI *SurfGDI,
LONG x, LONG y, ULONG iColor)
{
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,
LONG x1, LONG y1, LONG x2, LONG y2,
RECTL *RectBounds, MIX mix)
{
SURFGDI *SurfGDI;
LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error;
SURFGDI *SurfGDI;
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)
{
// Call the driver's DrvLineTo
return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2,
RectBounds, mix);
}
SurfGDI = AccessInternalObjectFromUserObject(Surface);
// 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;
y=y1;
deltax=x2-x1;
deltay=y2-y1;
case 24:
DIB_PutPixel = DIB_24BPP_PutPixel;
DIB_HLine = DIB_24BPP_HLine;
DIB_VLine = DIB_24BPP_VLine;
break;
if(deltax<0)
{
xchange=-1;
deltax=-deltax;
} else
{
xchange=1;
}
default:
DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
BitsPerFormat(Surface->iBitmapFormat));
return FALSE;
}
if(deltay<0)
{
ychange=-1;
deltay=-deltay;
} else
{
ychange=1;
};
// FIXME: Implement clipping
x=x1;
y=y1;
deltax=x2-x1;
deltay=y2-y1;
if(deltax<0)
{
xchange=-1;
deltax=-deltax;
hx = x2;
} else
{
xchange=1;
hx = x1;
}
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;
i=0;
if(deltax<deltay)
{
length=deltay+1;
while(i<length)
{
LinePoint(Surface, SurfGDI, x, y, Brush->iSolidColor);
y=y+ychange;
error=error+deltax;
length=deltay+1;
while(i<length)
{
DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
y=y+ychange;
error=error+deltax;
if(error>deltay)
{
x=x+xchange;
error=error-deltay;
}
i=i+1;
}
if(error>deltay)
{
x=x+xchange;
error=error-deltay;
}
i=i+1;
}
} else
{
length=deltax+1;
while(i<length)
{
LinePoint(Surface, SurfGDI, x, y, Brush->iSolidColor);
x=x+xchange;
error=error+deltay;
if(error>deltax)
{
y=y+ychange;
error=error-deltax;
}
i=i+1;
DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
x=x+xchange;
error=error+deltay;
if(error>deltax)
{
y=y+ychange;
error=error-deltax;
}
}
i=i+1;
}
}
return TRUE;
return TRUE;
}

View file

@ -13,35 +13,34 @@
PVOID STDCALL EngAllocMem(ULONG Flags, ULONG MemSize, ULONG Tag)
{
PVOID newMem;
PVOID newMem;
newMem = ExAllocatePoolWithTag(NonPagedPool, MemSize, Tag); // FIXME: Use PagedPool when it is implemented
newMem = ExAllocatePoolWithTag(NonPagedPool, MemSize, Tag); // FIXME: Use PagedPool when it is implemented
if(Flags == FL_ZERO_MEMORY)
{
RtlZeroMemory(newMem, MemSize);
}
if(Flags == FL_ZERO_MEMORY)
{
RtlZeroMemory(newMem, MemSize);
}
return newMem;
return newMem;
}
VOID STDCALL EngFreeMem(PVOID Mem)
{
ExFreePool(Mem);
ExFreePool(Mem);
}
PVOID STDCALL EngAllocUserMem(ULONG cj, ULONG tag)
{
/* PVOID newMem;
/* PVOID newMem;
return ZwAllocateVirtualMemory(mycurrentprocess, newMem, 0, cj,
MEM_COMMIT, PAGE_READWRITE); */
return ZwAllocateVirtualMemory(mycurrentprocess, newMem, 0, cj,
MEM_COMMIT, PAGE_READWRITE); */
return NULL;
return NULL;
}
VOID STDCALL EngFreeUserMem(PVOID pv)
{
/* ZwFreeVirtualMemory (mycurrentprocess, pv, 0, MEM_DECOMMIT); */
/* ZwFreeVirtualMemory (mycurrentprocess, pv, 0, MEM_DECOMMIT); */
}

View file

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

View file

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

View file

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

View file

@ -6,64 +6,72 @@
* PROGRAMER: Jason Filby
* REVISION HISTORY:
* 3/7/1999: Created
* 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
* TESTING TO BE DONE:
* - Create a GDI bitmap with all formats, perform all drawing operations on them, render to VGA surface
* refer to \test\microwin\src\engine\devdraw.c for info on correct pixel plotting for various formats
*/
#include <ddk/winddi.h>
#include <win32k/dc.h>
#include "objects.h"
BYTE bytesPerPixel(ULONG Format)
INT BitsPerFormat(ULONG Format)
{
// FIXME: GDI bitmaps are supposed to be pixel-packed. Right now if the
// pixel size if < 1 byte we expand it to 1 byte
switch(Format)
{
case BMF_1BPP: return 1;
case BMF_4BPP:
case BMF_4RLE: return 4;
case BMF_8BPP:
case BMF_8RLE: return 8;
case BMF_16BPP: return 16;
case BMF_24BPP: return 24;
case BMF_32BPP: return 32;
default: return 0;
}
}
if(Format==BMF_1BPP)
{
return 1;
} else
if((Format==BMF_4BPP) || (Format==BMF_4RLE))
{
return 1;
} else
if((Format==BMF_8BPP) || (Format==BMF_8RLE))
{
return 1;
} else
if(Format==BMF_16BPP)
{
return 2;
} else
if(Format==BMF_24BPP)
{
return 3;
} else
if(Format==BMF_32BPP)
{
return 4;
}
ULONG BitmapFormat(WORD Bits, DWORD Compression)
{
switch(Compression)
{
case BI_RGB:
switch(Bits)
{
case 1: return BMF_1BPP;
case 4: return BMF_4BPP;
case 8: return BMF_8BPP;
case 16: return BMF_16BPP;
case 24: return BMF_24BPP;
case 32: return BMF_32BPP;
}
return 0;
case BI_RLE4: return BMF_4RLE;
case BI_RLE8: return BMF_8RLE;
default: return 0;
}
}
VOID InitializeHooks(SURFGDI *SurfGDI)
{
SurfGDI->BitBlt = NULL;
SurfGDI->CopyBits = NULL;
SurfGDI->CreateDeviceBitmap = NULL;
SurfGDI->BitBlt = NULL;
SurfGDI->CopyBits = NULL;
SurfGDI->CreateDeviceBitmap = NULL;
SurfGDI->SetPalette = NULL;
}
HBITMAP EngCreateDeviceBitmap(DHSURF dhsurf, SIZEL Size, ULONG Format)
{
HBITMAP NewBitmap;
SURFOBJ *SurfObj;
HBITMAP NewBitmap;
SURFOBJ *SurfObj;
NewBitmap = EngCreateBitmap(Size, bytesPerPixel(Format) * Size.cx, Format, 0, NULL);
SurfObj = AccessUserObject(NewBitmap);
SurfObj->dhpdev = dhsurf;
NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
SurfObj = (PVOID)AccessUserObject(NewBitmap);
SurfObj->dhpdev = dhsurf;
return NewBitmap;
return 0;
return NewBitmap;
}
HBITMAP EngCreateBitmap(IN SIZEL Size,
@ -72,141 +80,134 @@ HBITMAP EngCreateBitmap(IN SIZEL Size,
IN ULONG Flags,
IN PVOID Bits)
{
HBITMAP NewBitmap;
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
HBITMAP NewBitmap;
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), 0);
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), 0);
NewBitmap = CreateGDIHandle(SurfGDI, SurfObj);
NewBitmap = (PVOID)CreateGDIHandle(SurfGDI, SurfObj);
InitializeHooks(SurfGDI);
SurfGDI->BytesPerPixel = bytesPerPixel(Format);
InitializeHooks(SurfGDI);
SurfGDI->BitsPerPixel = BitsPerFormat(Format);
SurfObj->lDelta = Width;
SurfObj->cjBits = SurfObj->lDelta * Size.cy;
SurfObj->lDelta = ((bytesPerPixel(Format) * Width) + 31) & ~31; // round up 4 bytes
SurfObj->cjBits = SurfObj->lDelta * Size.cy;
if(Bits!=NULL)
{
SurfObj->pvBits = Bits;
} else
{
if(Flags & BMF_USERMEM)
if(Bits!=NULL)
{
SurfObj->pvBits = Bits;
} else
{
if(Flags & BMF_USERMEM)
{
SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
} else {
if(Flags & BMF_NOZEROINIT)
{
SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
} else {
if(Flags & BMF_NOZEROINIT)
{
SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
} else {
SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
}
SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
}
}
}
}
SurfObj->dhsurf = 0; // device managed surface
SurfObj->hsurf = 0;
SurfObj->sizlBitmap = Size;
SurfObj->iBitmapFormat = Format;
SurfObj->iType = STYPE_BITMAP;
SurfObj->dhsurf = 0; // device managed surface
SurfObj->hsurf = 0;
SurfObj->sizlBitmap = Size;
SurfObj->iBitmapFormat = Format;
SurfObj->iType = STYPE_BITMAP;
// Use flags to determine bitmap type -- TOP_DOWN or whatever
// Use flags to determine bitmap type -- TOP_DOWN or whatever
return NewBitmap;
return NewBitmap;
}
HSURF EngCreateDeviceSurface(DHSURF dhsurf, SIZEL Size, ULONG Format)
{
HSURF NewSurface;
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
HSURF NewSurface;
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), 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;
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;
return NewSurface;
}
PFN DriverFunction(DRVENABLEDATA *DED, ULONG DriverFunc)
{
ULONG i;
ULONG i;
for(i=0; i<DED->c; i++)
{
if(DED->pdrvfn[i].iFunc == DriverFunc)
return DED->pdrvfn[i].pfn;
}
return NULL;
for(i=0; i<DED->c; i++)
{
if(DED->pdrvfn[i].iFunc == DriverFunc)
return DED->pdrvfn[i].pfn;
}
return NULL;
}
BOOL EngAssociateSurface(HSURF Surface, HDEV Dev, ULONG Hooks)
{
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
// it looks like this Dev is actually a pointer to the DC!
PDC Dc = (PDC)Dev;
DbgPrint("Associate 1\n");
// DRVENABLEDATA *DED;
PDC Dc = (PDC)Dev;
SurfGDI = AccessInternalObject(Surface);
SurfObj = AccessUserObject(Surface);
SurfGDI = (PVOID)AccessInternalObject(Surface);
SurfObj = (PVOID)AccessUserObject(Surface);
// DED = AccessInternalObject(Dev);
// Associate the hdev
SurfObj->hdev = Dev;
// Associate the hdev
SurfObj->hdev = Dev;
// Hook up specified functions
if(Hooks & HOOK_BITBLT) SurfGDI->BitBlt = Dc->DriverFunctions.BitBlt;
if(Hooks & HOOK_STRETCHBLT) SurfGDI->StretchBlt = Dc->DriverFunctions.StretchBlt;
if(Hooks & HOOK_TEXTOUT) SurfGDI->TextOut = Dc->DriverFunctions.TextOut;
if(Hooks & HOOK_PAINT) SurfGDI->Paint = Dc->DriverFunctions.Paint;
if(Hooks & HOOK_STROKEPATH) SurfGDI->StrokePath = Dc->DriverFunctions.StrokePath;
if(Hooks & HOOK_FILLPATH) SurfGDI->FillPath = Dc->DriverFunctions.FillPath;
if(Hooks & HOOK_STROKEANDFILLPATH) SurfGDI->StrokeAndFillPath = Dc->DriverFunctions.StrokeAndFillPath;
if(Hooks & HOOK_LINETO) SurfGDI->LineTo = Dc->DriverFunctions.LineTo;
if(Hooks & HOOK_COPYBITS) SurfGDI->CopyBits = Dc->DriverFunctions.CopyBits;
if(Hooks & HOOK_SYNCHRONIZE) SurfGDI->Synchronize = Dc->DriverFunctions.Synchronize;
if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE;
// Hook up specified functions
if(Hooks & HOOK_BITBLT) SurfGDI->BitBlt = Dc->DriverFunctions.BitBlt;
if(Hooks & HOOK_STRETCHBLT) SurfGDI->StretchBlt = Dc->DriverFunctions.StretchBlt;
if(Hooks & HOOK_TEXTOUT) SurfGDI->TextOut = Dc->DriverFunctions.TextOut;
if(Hooks & HOOK_PAINT) SurfGDI->Paint = Dc->DriverFunctions.Paint;
if(Hooks & HOOK_STROKEPATH) SurfGDI->StrokePath = Dc->DriverFunctions.StrokePath;
if(Hooks & HOOK_FILLPATH) SurfGDI->FillPath = Dc->DriverFunctions.FillPath;
if(Hooks & HOOK_STROKEANDFILLPATH) SurfGDI->StrokeAndFillPath = Dc->DriverFunctions.StrokeAndFillPath;
if(Hooks & HOOK_LINETO) SurfGDI->LineTo = Dc->DriverFunctions.LineTo;
if(Hooks & HOOK_COPYBITS) SurfGDI->CopyBits = Dc->DriverFunctions.CopyBits;
if(Hooks & HOOK_SYNCHRONIZE) SurfGDI->Synchronize = Dc->DriverFunctions.Synchronize;
if(Hooks & HOOK_SYNCHRONIZEACCESS) SurfGDI->SynchronizeAccess = TRUE;
SurfGDI->CreateDeviceBitmap = Dc->DriverFunctions.CreateDeviceBitmap;
SurfGDI->SetPalette = Dc->DriverFunctions.SetPalette;
SurfGDI->CreateDeviceBitmap = Dc->DriverFunctions.CreateDeviceBitmap;
return TRUE;
return TRUE;
}
BOOL EngDeleteSurface(HSURF Surface)
{
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
SurfGDI = AccessInternalObject(Surface);
SurfObj = AccessUserObject(Surface);
SurfGDI = AccessInternalObject(Surface);
SurfObj = AccessUserObject(Surface);
EngFreeMem(SurfGDI);
EngFreeMem(SurfObj);
FreeGDIHandle(Surface);
EngFreeMem(SurfGDI);
EngFreeMem(SurfObj);
FreeGDIHandle(Surface);
return TRUE;
return TRUE;
}
SURFOBJ *EngLockSurface(HSURF Surface)
{
// FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
return AccessUserObject(Surface);
// FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
return AccessUserObject(Surface);
}

View file

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

View file

@ -285,9 +285,11 @@ void CreateCellCharSurface()
surfgdi = ExAllocatePool(NonPagedPool, sizeof(SURFGDI));
hCharCellBitmap = W32kCreateBitmap(8, 8, 1, 8, NULL); // 8x8, 1 plane, 8 bits per pel
pbo = BITMAPOBJ_HandleToPtr(hCharCellBitmap);
BitmapToSurf(surfgdi, CharCellSurfObj, pbo); // Make the bitmap a surface
// VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
BitmapToSurf(0, surfgdi, CharCellSurfObj, pbo); // Make the bitmap a surface
}
void grWriteCellChar(PSURFOBJ target,

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

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

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
#
@ -6,8 +6,13 @@ PATH_TO_TOP = ../..
TARGET=win32k
# from atheos appserver makefile
COPTS = -pipe -O3 -I./freetype2-beta8/include -c -Wall
CFLAGS = -I.
#define FT_FLAT_COMPILE
ENG_OBJECTS= eng/debug.o eng/mem.o eng/brush.o eng/bitblt.o eng/clip.o eng/copybits.o \
eng/device.o eng/handle.o eng/lineto.o eng/paint.o eng/palette.o \
eng/surface.o eng/xlate.o
@ -20,14 +25,19 @@ OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \
objects/line.o objects/metafile.o objects/paint.o \
objects/path.o objects/pen.o objects/print.o \
objects/region.o objects/text.o objects/wingl.o \
objects/bezier.o objects/objconv.o
FREETYPE_OBJECTS = freetype/grfont.o
objects/bezier.o objects/objconv.o objects/dib.o objects/palette.o
DIB_OBJECTS = dib/dib4bpp.o dib/dib24bpp.o
FREETYPE_OBJECTS = freetype/grfont.o freetype/ctype.o \
freetype/ftsystem.o freetype/ftdebug.o freetype/ftinit.o freetype/ftbase.o \
freetype/ftglyph.o freetype/ftmm.o freetype/autohint.o freetype/cff.o \
freetype/type1cid.o freetype/psnames.o freetype/raster1.o freetype/sfnt.o \
freetype/smooth.o freetype/truetype.o freetype/winfnt.o freetype/type1z.o
RESOURCE_OBJECT = $(TARGET).coff
STUBS_OBJECTS = stubs/stubs.o
OBJECTS = $(ENG_OBJECTS) $(MAIN_OBJECTS) $(MISC_OBJECTS) $(LDR_OBJECTS) $(OBJECTS_OBJECTS) \
$(RESOURCE_OBJECT) $(STUBS_OBJECTS) $(MATH_OBJECTS) $(FLOAT_OBJECTS) $(FREETYPE_OBJECTS)
$(RESOURCE_OBJECT) $(STUBS_OBJECTS) $(MATH_OBJECTS) $(FLOAT_OBJECTS) $(FREETYPE_OBJECTS) \
$(DIB_OBJECTS)
all: $(TARGET).sys
@ -116,4 +126,3 @@ $(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
#WIN32_LEAN_AND_MEAN = yes
#WARNINGS_ARE_ERRORS = yes
include ../../rules.mak

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

View file

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

View file

@ -1,10 +1,9 @@
#undef WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#include <win32k/bitmaps.h>
//#include <win32k/debug.h>
#include "../eng/objects.h"
#define NDEBUG
#include <debug.h>
@ -19,15 +18,19 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest,
INT YSrc,
DWORD ROP)
{
PDC DCDest = DC_HandleToPtr(hDCDest);
PDC DCSrc = DC_HandleToPtr(hDCSrc);
PSURFOBJ SurfDest;
PSURFOBJ SurfSrc;
RECTL DestRect;
POINTL SourcePoint;
PBITMAPOBJ DestBitmapObj;
PBITMAPOBJ SrcBitmapObj;
BOOL Status, SurfDestAlloc, SurfSrcAlloc;
PDC DCDest = DC_HandleToPtr(hDCDest);
PDC DCSrc = DC_HandleToPtr(hDCSrc);
PSURFOBJ SurfDest, SurfSrc;
PSURFGDI SurfGDIDest, SurfGDISrc;
RECTL DestRect;
POINTL SourcePoint;
PBITMAPOBJ DestBitmapObj;
PBITMAPOBJ SrcBitmapObj;
BOOL Status, SurfDestAlloc, SurfSrcAlloc;
PPALOBJ DCLogPal;
PPALGDI PalDestGDI, PalSourceGDI;
PXLATEOBJ XlateObj = NULL;
HPALETTE SourcePalette, DestPalette;
DestRect.left = XDest;
DestRect.top = YDest;
@ -40,32 +43,44 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest,
SurfDestAlloc = FALSE;
SurfSrcAlloc = FALSE;
DPRINT("Get surfdest.. ");
// Determine surfaces to be used in the bitblt
SurfDest = AccessUserObject(DCDest->Surface);
SurfSrc = AccessUserObject(DCSrc->Surface);
// Get the SurfDest
if(DCDest->Surface != NULL)
SurfGDIDest = AccessInternalObjectFromUserObject(SurfDest);
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
SurfDest = AccessUserObject(DCDest->Surface);
} else
return FALSE;
if(DCDest->w.hPalette != 0)
{
DestPalette = DCDest->w.hPalette;
} 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
if(DCSrc->Surface != NULL)
{
DPRINT("from DC's surface\n");
PalDestGDI = AccessInternalObject(DestPalette);
PalSourceGDI = AccessInternalObject(SourcePalette);
// Use the DC's surface if it has one
SurfSrc = AccessUserObject(DCSrc->Surface);
} else
return FALSE;
XlateObj = EngCreateXlate(PalDestGDI->Mode, PalSourceGDI->Mode, DestPalette, SourcePalette);
}
// Perform the bitblt operation
DPRINT("Go to EngBitBlt\n");
Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, NULL,
&DestRect, &SourcePoint, NULL, NULL, NULL, NULL); // FIXME: Color translation (xlateobj)
Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, NULL);
if(SurfDestAlloc == TRUE) ExFreePool(SurfDest);
if(SurfSrcAlloc == TRUE) ExFreePool(SurfSrc);
@ -87,35 +102,35 @@ HBITMAP STDCALL W32kCreateBitmap(INT Width,
/* Check parameters */
if (!Height || !Width)
{
return 0;
}
{
return 0;
}
if (Planes != 1)
{
UNIMPLEMENTED;
return 0;
}
{
UNIMPLEMENTED;
return 0;
}
if (Height < 0)
{
Height = -Height;
}
{
Height = -Height;
}
if (Width < 0)
{
Width = -Width;
}
{
Width = -Width;
}
/* Create the BITMAPOBJ */
bmp = BITMAPOBJ_AllocBitmap ();
if (!bmp)
{
return 0;
}
{
return 0;
}
DPRINT("W32kCreateBitmap:%dx%d, %d (%d BPP) colors returning %08x\n", Width, Height,
1 << (Planes * BitsPerPel), BitsPerPel, bmp);
bmp->size.cx = 0;
bmp->size.cy = 0;
bmp->size.cx = Width;
bmp->size.cy = Height;
bmp->bitmap.bmType = 0;
bmp->bitmap.bmWidth = Width;
bmp->bitmap.bmHeight = Height;
@ -131,12 +146,9 @@ HBITMAP STDCALL W32kCreateBitmap(INT Width,
bmp->bitmap.bmBits = ExAllocatePool(PagedPool, bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight);
if (Bits) /* Set bitmap bits */
{
W32kSetBitmapBits(hBitmap,
Height * bmp->bitmap.bmWidthBytes,
Bits);
}
{
W32kSetBitmapBits(hBitmap, Height * bmp->bitmap.bmWidthBytes, Bits);
}
return hBitmap;
}
@ -151,36 +163,31 @@ HBITMAP STDCALL W32kCreateCompatibleBitmap(HDC hDC,
hbmpRet = 0;
dc = DC_HandleToPtr (hDC);
DPRINT("W32kCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC, Width, Height, dc->w.bitsPerPixel);
DbgPrint("W32kCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC, Width, Height, dc->w.bitsPerPixel);
if (!dc)
{
return 0;
}
{
return 0;
}
if ((Width >= 0x10000) || (Height >= 0x10000))
{
DPRINT("got bad width %d or height %d, please look for reason\n",
Width, Height);
}
{
DPRINT("got bad width %d or height %d, please look for reason\n", Width, Height);
}
else
{
/* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
if (!Width || !Height)
{
/* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
if (!Width || !Height)
{
hbmpRet = W32kCreateBitmap (1, 1, 1, 1, NULL);
}
else
{
hbmpRet = W32kCreateBitmap (Width,
Height,
1,
dc->w.bitsPerPixel,
NULL);
}
hbmpRet = W32kCreateBitmap (1, 1, 1, 1, NULL);
}
else
{
hbmpRet = W32kCreateBitmap(Width, Height, 1, dc->w.bitsPerPixel, NULL);
}
}
DPRINT ("\t\t%04x\n", hbmpRet);
DC_UnlockDC (hDC);
return hbmpRet;
}
@ -193,26 +200,6 @@ HBITMAP STDCALL W32kCreateBitmapIndirect(CONST BITMAP *BM)
BM->bmBits);
}
HBITMAP STDCALL W32kCreateDIBitmap(HDC hDC,
CONST BITMAPINFOHEADER *bmih,
DWORD Init,
CONST VOID *bInit,
CONST BITMAPINFO *bmi,
UINT Usage)
{
UNIMPLEMENTED;
}
HBITMAP STDCALL W32kCreateDIBSection(HDC hDC,
CONST BITMAPINFO *bmi,
UINT Usage,
VOID *Bits,
HANDLE hSection,
DWORD dwOffset)
{
UNIMPLEMENTED;
}
HBITMAP STDCALL W32kCreateDiscardableBitmap(HDC hDC,
INT Width,
INT Height)
@ -238,83 +225,6 @@ BOOL STDCALL W32kFloodFill(HDC hDC,
UNIMPLEMENTED;
}
LONG STDCALL W32kGetBitmapBits(HBITMAP hBitmap,
LONG Count,
LPVOID Bits)
{
PBITMAPOBJ bmp;
LONG height, ret;
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
if (!bmp)
{
return 0;
}
/* If the bits vector is null, the function should return the read size */
if (Bits == NULL)
{
return bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight;
}
if (Count < 0)
{
DPRINT ("(%ld): Negative number of bytes passed???\n", Count);
Count = -Count;
}
/* Only get entire lines */
height = Count / bmp->bitmap.bmWidthBytes;
if (height > bmp->bitmap.bmHeight)
{
height = bmp->bitmap.bmHeight;
}
Count = height * bmp->bitmap.bmWidthBytes;
if (Count == 0)
{
DPRINT("Less then one entire line requested\n");
BITMAPOBJ_UnlockBitmap (hBitmap);
return 0;
}
DPRINT("(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
hBitmap, Count, Bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
1 << bmp->bitmap.bmBitsPixel, height );
#if 0
/* FIXME: Call DDI CopyBits here if available */
if(bmp->DDBitmap)
{
DPRINT("Calling device specific BitmapBits\n");
if(bmp->DDBitmap->funcs->pBitmapBits)
{
ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, bits, count,
DDB_GET);
}
else
{
ERR_(bitmap)("BitmapBits == NULL??\n");
ret = 0;
}
}
else
#endif
{
if(!bmp->bitmap.bmBits)
{
DPRINT ("Bitmap is empty\n");
ret = 0;
}
else
{
memcpy(Bits, bmp->bitmap.bmBits, Count);
ret = Count;
}
}
BITMAPOBJ_UnlockBitmap (hBitmap);
return ret;
}
BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
LPSIZE Dimension)
{
@ -322,9 +232,9 @@ BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
if (bmp == NULL)
{
return FALSE;
}
{
return FALSE;
}
*Dimension = bmp->size;
BITMAPOBJ_UnlockBitmap (hBitmap);
@ -332,25 +242,6 @@ BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
return TRUE;
}
UINT STDCALL W32kGetDIBColorTable(HDC hDC,
UINT StartIndex,
UINT Entries,
RGBQUAD *Colors)
{
UNIMPLEMENTED;
}
INT STDCALL W32kGetDIBits(HDC hDC,
HBITMAP hBitmap,
UINT StartScan,
UINT ScanLines,
LPVOID Bits,
LPBITMAPINFO bi,
UINT Usage)
{
UNIMPLEMENTED;
}
COLORREF STDCALL W32kGetPixel(HDC hDC,
INT XPos,
INT YPos)
@ -397,22 +288,22 @@ LONG STDCALL W32kSetBitmapBits(HBITMAP hBitmap,
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
if (bmp == NULL || Bits == NULL)
{
return 0;
}
{
return 0;
}
if (Bytes < 0)
{
DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes );
Bytes = -Bytes;
}
{
DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes );
Bytes = -Bytes;
}
/* Only get entire lines */
height = Bytes / bmp->bitmap.bmWidthBytes;
if (height > bmp->bitmap.bmHeight)
{
height = bmp->bitmap.bmHeight;
}
{
height = bmp->bitmap.bmHeight;
}
Bytes = height * bmp->bitmap.bmWidthBytes;
DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
hBitmap,
@ -426,39 +317,36 @@ LONG STDCALL W32kSetBitmapBits(HBITMAP hBitmap,
#if 0
/* FIXME: call DDI specific function here if available */
if(bmp->DDBitmap)
{
DPRINT ("Calling device specific BitmapBits\n");
if (bmp->DDBitmap->funcs->pBitmapBits)
{
DPRINT ("Calling device specific BitmapBits\n");
if (bmp->DDBitmap->funcs->pBitmapBits)
{
ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap,
(void *) Bits,
Bytes,
DDB_SET);
}
else
{
DPRINT ("BitmapBits == NULL??\n");
ret = 0;
}
ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap, (void *) Bits, Bytes, DDB_SET);
}
else
{
DPRINT ("BitmapBits == NULL??\n");
ret = 0;
}
}
else
#endif
{
/* FIXME: Alloc enough for entire bitmap */
if (bmp->bitmap.bmBits == NULL)
{
bmp->bitmap.bmBits = ExAllocatePool (PagedPool, Bytes);
}
{
bmp->bitmap.bmBits = ExAllocatePool (PagedPool, Bytes);
}
if(!bmp->bitmap.bmBits)
{
DPRINT ("Unable to allocate bit buffer\n");
ret = 0;
}
{
DPRINT ("Unable to allocate bit buffer\n");
ret = 0;
}
else
{
memcpy(bmp->bitmap.bmBits, Bits, Bytes);
ret = Bytes;
}
{
memcpy(bmp->bitmap.bmBits, Bits, Bytes);
ret = Bytes;
}
}
BITMAPOBJ_UnlockBitmap (hBitmap);
@ -474,14 +362,14 @@ BOOL STDCALL W32kSetBitmapDimensionEx(HBITMAP hBitmap,
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
if (bmp == NULL)
{
return FALSE;
}
{
return FALSE;
}
if (Size)
{
*Size = bmp->size;
}
{
*Size = bmp->size;
}
bmp->size.cx = Width;
bmp->size.cy = Height;
BITMAPOBJ_UnlockBitmap (hBitmap);
@ -489,41 +377,6 @@ BOOL STDCALL W32kSetBitmapDimensionEx(HBITMAP hBitmap,
return TRUE;
}
UINT STDCALL W32kSetDIBColorTable(HDC hDC,
UINT StartIndex,
UINT Entries,
CONST RGBQUAD *Colors)
{
UNIMPLEMENTED;
}
INT STDCALL W32kSetDIBits(HDC hDC,
HBITMAP hBitmap,
UINT StartScan,
UINT ScanLines,
CONST VOID *Bits,
CONST BITMAPINFO *bmi,
UINT ColorUse)
{
UNIMPLEMENTED;
}
INT STDCALL W32kSetDIBitsToDevice(HDC hDC,
INT XDest,
INT YDest,
DWORD Width,
DWORD Height,
INT XSrc,
INT YSrc,
UINT StartScan,
UINT ScanLines,
CONST VOID *Bits,
CONST BITMAPINFO *bmi,
UINT ColorUse)
{
UNIMPLEMENTED;
}
COLORREF STDCALL W32kSetPixel(HDC hDC,
INT X,
INT Y,
@ -555,30 +408,13 @@ BOOL STDCALL W32kStretchBlt(HDC hDCDest,
UNIMPLEMENTED;
}
INT STDCALL W32kStretchDIBits(HDC hDC,
INT XDest,
INT YDest,
INT DestWidth,
INT DestHeight,
INT XSrc,
INT YSrc,
INT SrcWidth,
INT SrcHeight,
CONST VOID *Bits,
CONST BITMAPINFO *BitsInfo,
UINT Usage,
DWORD ROP)
{
UNIMPLEMENTED;
}
/* Internal Functions */
INT
BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
{
switch(bpp)
{
{
case 1:
return 2 * ((bmWidth+15) >> 4);
@ -599,7 +435,7 @@ BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
default:
DPRINT ("stub");
}
}
return -1;
}
@ -612,94 +448,47 @@ HBITMAP BITMAPOBJ_CopyBitmap(HBITMAP hBitmap)
bmp = BITMAPOBJ_HandleToPtr (hBitmap);
if (bmp == NULL)
{
return 0;
}
{
return 0;
}
res = 0;
bm = bmp->bitmap;
bm.bmBits = NULL;
res = W32kCreateBitmapIndirect(&bm);
if(res)
{
char *buf;
{
char *buf;
buf = ExAllocatePool (NonPagedPool, bm.bmWidthBytes * bm.bmHeight);
W32kGetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
W32kSetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
ExFreePool (buf);
}
buf = ExAllocatePool (NonPagedPool, bm.bmWidthBytes * bm.bmHeight);
W32kGetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
W32kSetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
ExFreePool (buf);
}
BITMAPOBJ_UnlockBitmap (hBitmap);
return res;
}
/***********************************************************************
* DIB_GetDIBWidthBytes
*
* Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
* http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
* 11/16/1999 (RJJ) lifted from wine
*/
int DIB_GetDIBWidthBytes(int width, int depth)
INT BITMAP_GetObject(BITMAPOBJ * bmp, INT count, LPVOID buffer)
{
int words;
switch(depth)
if(bmp->dib)
{
if(count < sizeof(DIBSECTION))
{
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;
if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
}
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))
else
{
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));
if (count > sizeof(DIBSECTION)) count = sizeof(DIBSECTION);
}
memcpy(buffer, bmp->dib, count);
return count;
}
else
{
if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
memcpy(buffer, &bmp->bitmap, count);
return count;
}
}

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

View file

@ -1,28 +1,135 @@
// FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping
#undef WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <ddk/ntddk.h>
#include <ddk/winddi.h>
#include <win32k/dc.h>
#include <win32k/color.h>
#include "../eng/objects.h"
// #define NDEBUG
#include <win32k/debug1.h>
int COLOR_gapStart = 256;
int COLOR_gapEnd = -1;
int COLOR_gapFilled = 0;
int COLOR_max = 256;
static HPALETTE hPrimaryPalette = 0; // used for WM_PALETTECHANGED
static HPALETTE hLastRealizedPalette = 0; // UnrealizeObject() needs it
const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] =
{
// first 10 entries in the system palette
// red green blue flags
{ 0x00, 0x00, 0x00, PC_SYS_USED },
{ 0x80, 0x00, 0x00, PC_SYS_USED },
{ 0x00, 0x80, 0x00, PC_SYS_USED },
{ 0x80, 0x80, 0x00, PC_SYS_USED },
{ 0x00, 0x00, 0x80, PC_SYS_USED },
{ 0x80, 0x00, 0x80, PC_SYS_USED },
{ 0x00, 0x80, 0x80, PC_SYS_USED },
{ 0xc0, 0xc0, 0xc0, PC_SYS_USED },
{ 0xc0, 0xdc, 0xc0, PC_SYS_USED },
{ 0xa6, 0xca, 0xf0, PC_SYS_USED },
// ... c_min/2 dynamic colorcells
// ... gap (for sparse palettes)
// ... c_min/2 dynamic colorcells
{ 0xff, 0xfb, 0xf0, PC_SYS_USED },
{ 0xa0, 0xa0, 0xa4, PC_SYS_USED },
{ 0x80, 0x80, 0x80, PC_SYS_USED },
{ 0xff, 0x00, 0x00, PC_SYS_USED },
{ 0x00, 0xff, 0x00, PC_SYS_USED },
{ 0xff, 0xff, 0x00, PC_SYS_USED },
{ 0x00, 0x00, 0xff, PC_SYS_USED },
{ 0xff, 0x00, 0xff, PC_SYS_USED },
{ 0x00, 0xff, 0xff, PC_SYS_USED },
{ 0xff, 0xff, 0xff, PC_SYS_USED } // last 10
};
const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void)
{
return COLOR_sysPalTemplate;
}
BOOL STDCALL W32kAnimatePalette(HPALETTE hpal,
UINT StartIndex,
UINT Entries,
CONST PPALETTEENTRY ppe)
{
/*
if( hPal != W32kGetStockObject(DEFAULT_PALETTE) )
{
PALETTEOBJ* palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPal, PALETTE_MAGIC);
if (!palPtr) return FALSE;
if( (StartIndex + NumEntries) <= palPtr->logpalette.palNumEntries )
{
UINT u;
for( u = 0; u < NumEntries; u++ )
palPtr->logpalette.palPalEntry[u + StartIndex] = PaletteColors[u];
PALETTE_Driver->pSetMapping(palPtr, StartIndex, NumEntries, hPal != hPrimaryPalette );
GDI_ReleaseObj(hPal);
return TRUE;
}
GDI_ReleaseObj(hPal);
}
return FALSE;
*/
UNIMPLEMENTED;
}
HPALETTE STDCALL W32kCreateHalftonePalette(HDC hDC)
{
UNIMPLEMENTED;
int i, r, g, b;
struct {
WORD Version;
WORD NumberOfEntries;
PALETTEENTRY aEntries[256];
} Palette;
Palette.Version = 0x300;
Palette.NumberOfEntries = 256;
W32kGetSystemPaletteEntries(hDC, 0, 256, Palette.aEntries);
for (r = 0; r < 6; r++) {
for (g = 0; g < 6; g++) {
for (b = 0; b < 6; b++) {
i = r + g*6 + b*36 + 10;
Palette.aEntries[i].peRed = r * 51;
Palette.aEntries[i].peGreen = g * 51;
Palette.aEntries[i].peBlue = b * 51;
}
}
}
for (i = 216; i < 246; i++) {
int v = (i - 216) * 8;
Palette.aEntries[i].peRed = v;
Palette.aEntries[i].peGreen = v;
Palette.aEntries[i].peBlue = v;
}
return W32kCreatePalette((LOGPALETTE *)&Palette);
}
HPALETTE STDCALL W32kCreatePalette(CONST PLOGPALETTE lgpl)
HPALETTE STDCALL W32kCreatePalette(CONST PLOGPALETTE palette)
{
UNIMPLEMENTED;
PPALOBJ PalObj;
HPALETTE NewPalette = EngCreatePalette(PAL_INDEXED, palette->palNumEntries, palette->palPalEntry, 0, 0, 0);
ULONG size;
PalObj = AccessUserObject(NewPalette);
size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
memcpy(&PalObj->logpalette, palette, size);
PALETTE_ValidateFlags(PalObj->logpalette.palPalEntry, PalObj->logpalette.palNumEntries);
PalObj->logicalToSystem = NULL;
return NewPalette;
}
BOOL STDCALL W32kGetColorAdjustment(HDC hDC,
@ -34,13 +141,43 @@ BOOL STDCALL W32kGetColorAdjustment(HDC hDC,
COLORREF STDCALL W32kGetNearestColor(HDC hDC,
COLORREF Color)
{
UNIMPLEMENTED;
COLORREF nearest = CLR_INVALID;
PDC dc;
PPALOBJ palObj;
if(DC_HandleToPtr(hDC))
{
HPALETTE hpal = (dc->w.hPalette)? dc->w.hPalette : W32kGetStockObject(DEFAULT_PALETTE);
palObj = AccessUserObject(hpal);
if (!palObj) {
// GDI_ReleaseObj(hdc);
return nearest;
}
nearest = COLOR_LookupNearestColor(palObj->logpalette.palPalEntry,
palObj->logpalette.palNumEntries, Color);
// GDI_ReleaseObj( hpal );
// GDI_ReleaseObj( hdc );
}
return nearest;
}
UINT STDCALL W32kGetNearestPaletteIndex(HPALETTE hpal,
COLORREF Color)
{
UNIMPLEMENTED;
PPALOBJ palObj = AccessUserObject(hpal);
UINT index = 0;
if( palObj )
{
// Return closest match for the given RGB color
index = COLOR_PaletteLookupPixel(palObj->logpalette.palPalEntry, palObj->logpalette.palNumEntries, NULL, Color, FALSE);
// GDI_ReleaseObj( hpalette );
}
return index;
}
UINT STDCALL W32kGetPaletteEntries(HPALETTE hpal,
@ -48,7 +185,29 @@ UINT STDCALL W32kGetPaletteEntries(HPALETTE hpal,
UINT Entries,
LPPALETTEENTRY pe)
{
UNIMPLEMENTED;
PPALOBJ palPtr;
UINT numEntries;
palPtr = AccessUserObject(hpal);
if (!palPtr) return 0;
numEntries = palPtr->logpalette.palNumEntries;
if (StartIndex + Entries > numEntries) Entries = numEntries - StartIndex;
if (pe)
{
if (StartIndex >= numEntries)
{
// GDI_ReleaseObj( hpalette );
return 0;
}
memcpy(pe, &palPtr->logpalette.palPalEntry[StartIndex], Entries * sizeof(PALETTEENTRY));
for(numEntries = 0; numEntries < Entries ; numEntries++)
if (pe[numEntries].peFlags & 0xF0)
pe[numEntries].peFlags = 0;
}
// GDI_ReleaseObj( hpalette );
return Entries;
}
UINT STDCALL W32kGetSystemPaletteEntries(HDC hDC,
@ -56,7 +215,33 @@ UINT STDCALL W32kGetSystemPaletteEntries(HDC hDC,
UINT Entries,
LPPALETTEENTRY pe)
{
UNIMPLEMENTED;
UINT i;
PDC dc;
/*
if (!(dc = AccessUserObject(hdc))) return 0;
if (!pe)
{
Entries = dc->devCaps->sizePalette;
goto done;
}
if (StartIndex >= dc->devCaps->sizePalette)
{
Entries = 0;
goto done;
}
if (StartIndex + Entries >= dc->devCaps->sizePalette) Entries = dc->devCaps->sizePalette - StartIndex;
for (i = 0; i < Entries; i++)
{
*(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry(StartIndex + i);
}
done:
// GDI_ReleaseObj(hdc);
return count; */
}
UINT STDCALL W32kGetSystemPaletteUse(HDC hDC)
@ -65,13 +250,112 @@ UINT STDCALL W32kGetSystemPaletteUse(HDC hDC)
}
UINT STDCALL W32kRealizePalette(HDC hDC)
/*
The RealizePalette function modifies the palette for the device associated with the specified device context. If the device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device context is a display DC, the physical palette for that device is modified.
A logical palette is a buffer between color-intensive applications and the system, allowing these applications to use as many colors as needed without interfering with colors displayed by other windows.
1= IF DRAWING TO A DEVICE
-- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
the system palette.
-- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the system palette.
2= IF DRAWING TO A MEMORY DC\BITMAP
-- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
the dc palette.
-- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the dc palette.
*/
{
UNIMPLEMENTED;
PPALOBJ palPtr, sysPtr;
PPALGDI palGDI, sysGDI;
int realized = 0;
PDC dc = AccessUserObject(hDC);
HPALETTE systemPalette;
PSURFGDI SurfGDI;
BOOLEAN success;
if (!dc) return 0;
palPtr = AccessUserObject(dc->w.hPalette);
SurfGDI = AccessInternalObjectFromUserObject(dc->Surface);
systemPalette = W32kGetStockObject(STOCK_DEFAULT_PALETTE);
sysPtr = AccessInternalObject(systemPalette);
palGDI = AccessInternalObject(dc->w.hPalette);
sysGDI = AccessInternalObject(systemPalette);
// Step 1: Create mapping of system palette\DC palette
realized = PALETTE_SetMapping(palPtr, 0, palPtr->logpalette.palNumEntries,
(dc->w.hPalette != hPrimaryPalette) ||
(dc->w.hPalette == W32kGetStockObject(DEFAULT_PALETTE)));
// Step 2:
// The RealizePalette function modifies the palette for the device associated with the specified device context. If the
// device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device
// context is a display DC, the physical palette for that device is modified.
if(dc->w.flags == DC_MEMORY)
{
// Memory managed DC
DbgPrint("win32k: realizepalette unimplemented step 2 for DC_MEMORY");
} else {
if(SurfGDI->SetPalette)
{
success = SurfGDI->SetPalette(dc->PDev, sysPtr, 0, 0, sysPtr->logpalette.palNumEntries);
}
}
// Step 3: Create the XLATEOBJ for device managed DCs
if(dc->w.flags != DC_MEMORY)
{
// Device managed DC
palPtr->logicalToSystem = EngCreateXlate(sysGDI->Mode, palGDI->Mode, systemPalette, dc->w.hPalette);
}
// GDI_ReleaseObj(dc->w.hPalette);
// GDI_ReleaseObj(hdc);
return realized;
}
BOOL STDCALL W32kResizePalette(HPALETTE hpal,
UINT Entries)
{
/* PPALOBJ palPtr = (PPALOBJ)AccessUserObject(hPal);
UINT cPrevEnt, prevVer;
INT prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
PXLATEOBJ XlateObj = NULL;
if(!palPtr) return FALSE;
cPrevEnt = palPtr->logpalette.palNumEntries;
prevVer = palPtr->logpalette.palVersion;
prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) + sizeof(int*) + sizeof(GDIOBJHDR);
size += sizeof(int*) + sizeof(GDIOBJHDR);
XlateObj = palPtr->logicalToSystem;
if (!(palPtr = GDI_ReallocObject(size, hPal, palPtr))) return FALSE;
if(XlateObj)
{
PXLATEOBJ NewXlateObj = (int*) HeapReAlloc(GetProcessHeap(), 0, XlateObj, cEntries * sizeof(int));
if(NewXlateObj == NULL)
{
ERR("Can not resize logicalToSystem -- out of memory!");
GDI_ReleaseObj( hPal );
return FALSE;
}
palPtr->logicalToSystem = NewXlateObj;
}
if(cEntries > cPrevEnt)
{
if(XlateObj) memset(palPtr->logicalToSystem + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), cEntries - cPrevEnt );
}
palPtr->logpalette.palNumEntries = cEntries;
palPtr->logpalette.palVersion = prevVer;
// GDI_ReleaseObj( hPal );
return TRUE; */
UNIMPLEMENTED;
}
@ -79,7 +363,15 @@ HPALETTE STDCALL W32kSelectPalette(HDC hDC,
HPALETTE hpal,
BOOL ForceBackground)
{
UNIMPLEMENTED;
PDC dc = AccessUserObject(hDC);
HPALETTE oldPal;
oldPal = dc->w.hPalette;
dc->w.hPalette = hpal;
// FIXME: mark the palette as a [fore\back]ground pal
return oldPal;
}
BOOL STDCALL W32kSetColorAdjustment(HDC hDC,
@ -93,7 +385,25 @@ UINT STDCALL W32kSetPaletteEntries(HPALETTE hpal,
UINT Entries,
CONST LPPALETTEENTRY pe)
{
UNIMPLEMENTED;
PPALOBJ palPtr;
INT numEntries;
palPtr = AccessUserObject(hpal);
if (!palPtr) return 0;
numEntries = palPtr->logpalette.palNumEntries;
if (Start >= numEntries)
{
// GDI_ReleaseObj( hpalette );
return 0;
}
if (Start + Entries > numEntries) Entries = numEntries - Start;
memcpy(&palPtr->logpalette.palPalEntry[Start], pe, Entries * sizeof(PALETTEENTRY));
PALETTE_ValidateFlags(palPtr->logpalette.palPalEntry, palPtr->logpalette.palNumEntries);
ExFreePool(palPtr->logicalToSystem);
palPtr->logicalToSystem = NULL;
// GDI_ReleaseObj( hpalette );
return Entries;
}
UINT STDCALL W32kSetSystemPaletteUse(HDC hDC,
@ -109,6 +419,81 @@ BOOL STDCALL W32kUnrealizeObject(HGDIOBJ hgdiobj)
BOOL STDCALL W32kUpdateColors(HDC hDC)
{
UNIMPLEMENTED;
PDC dc;
HWND hWnd;
int size;
/*
if (!(dc = AccessUserObject(hDC))) return 0;
size = dc->devCaps->sizePalette;
// GDI_ReleaseObj( hDC );
if (Callout.WindowFromDC)
{
hWnd = Callout.WindowFromDC( hDC );
// Docs say that we have to remap current drawable pixel by pixel
// but it would take forever given the speed of XGet/PutPixel.
if (hWnd && size) Callout.RedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
} */
return 0x666;
}
int COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, int size,
PXLATEOBJ XlateObj, COLORREF col, BOOL skipReserved)
{
int i, best = 0, diff = 0x7fffffff;
int r, g, b;
for( i = 0; i < size && diff ; i++ )
{
if(!(palPalEntry[i].peFlags & PC_SYS_USED) || (skipReserved && palPalEntry[i].peFlags & PC_SYS_RESERVED))
continue;
r = palPalEntry[i].peRed - GetRValue(col);
g = palPalEntry[i].peGreen - GetGValue(col);
b = palPalEntry[i].peBlue - GetBValue(col);
r = r*r + g*g + b*b;
if( r < diff ) { best = i; diff = r; }
}
return (XlateObj->pulXlate) ? XlateObj->pulXlate[best] : best;
}
COLORREF COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
{
unsigned char spec_type = color >> 24;
int i;
PALETTEENTRY *COLOR_sysPal = ReturnSystemPalette();
// we need logical palette for PALETTERGB and PALETTEINDEX colorrefs
if( spec_type == 2 ) /* PALETTERGB */
color = *(COLORREF*)(palPalEntry + COLOR_PaletteLookupPixel(palPalEntry,size,NULL,color,FALSE));
else if( spec_type == 1 ) /* PALETTEINDEX */
{
if( (i = color & 0x0000ffff) >= size )
{
DbgPrint("RGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
color = *(COLORREF*)palPalEntry;
}
else color = *(COLORREF*)(palPalEntry + i);
}
color &= 0x00ffffff;
return (0x00ffffff & *(COLORREF*)(COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
}
int COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
COLORREF col )
{
int i;
BYTE r = GetRValue(col), g = GetGValue(col), b = GetBValue(col);
for( i = 0; i < size; i++ )
{
if( palPalEntry[i].peFlags & PC_SYS_USED ) /* skips gap */
if(palPalEntry[i].peRed == r && palPalEntry[i].peGreen == g && palPalEntry[i].peBlue == b) return i;
}
return -1;
}

View file

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

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

View file

@ -1,7 +1,7 @@
/*
* GDIOBJ.C - GDI object manipulation routines
*
* $Id: gdiobj.c,v 1.6 2000/06/16 07:22:39 jfilby Exp $
* $Id: gdiobj.c,v 1.7 2001/03/31 15:35:08 jfilby Exp $
*
*/
@ -9,23 +9,112 @@
#include <windows.h>
#include <ddk/ntddk.h>
#include <win32k/gdiobj.h>
#include <win32k/brush.h>
#include <win32k/pen.h>
#include <win32k/text.h>
// GDI stock objects
static LOGBRUSH WhiteBrush =
{ BS_SOLID, RGB(255,255,255), 0 };
static LOGBRUSH LtGrayBrush =
/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
{ BS_SOLID, RGB(192,192,192), 0 };
static LOGBRUSH GrayBrush =
/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
{ BS_SOLID, RGB(128,128,128), 0 };
static LOGBRUSH DkGrayBrush =
/* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
/* NB_HATCH_STYLES is an index into HatchBrushes */
{ BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES };
static LOGBRUSH BlackBrush =
{ BS_SOLID, RGB(0,0,0), 0 };
static LOGBRUSH NullBrush =
{ BS_NULL, 0, 0 };
static LOGPEN WhitePen =
{ PS_SOLID, { 0, 0 }, RGB(255,255,255) };
static LOGPEN BlackPen =
{ PS_SOLID, { 0, 0 }, RGB(0,0,0) };
static LOGPEN NullPen =
{ PS_NULL, { 0, 0 }, 0 };
static LOGFONT OEMFixedFont =
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" };
/* Filler to make the location counter dword aligned again. This is necessary
since (a) LOGFONT is packed, (b) gcc places initialised variables in the code
segment, and (c) Solaris assembler is stupid. */
static UINT align_OEMFixedFont = 1;
static LOGFONT AnsiFixedFont =
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" };
static UINT align_AnsiFixedFont = 1;
static LOGFONT AnsiVarFont =
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" };
static UINT align_AnsiVarFont = 1;
static LOGFONT SystemFont =
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" };
static UINT align_SystemFont = 1;
static LOGFONT DeviceDefaultFont =
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" };
static UINT align_DeviceDefaultFont = 1;
static LOGFONT SystemFixedFont =
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" };
static UINT align_SystemFixedFont = 1;
/* FIXME: Is this correct? */
static LOGFONT DefaultGuiFont =
{ 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" };
static UINT align_DefaultGuiFont = 1;
static HGDIOBJ *StockObjects[NB_STOCK_OBJECTS]; // we dont assign these statically as WINE does because we might redesign
// the way handles work, so it's more dynamic now
HBITMAP hPseudoStockBitmap; /* 1x1 bitmap for memory DCs */
PGDIOBJ GDIOBJ_AllocObject(WORD Size, WORD Magic)
{
PGDIOBJHDR NewObj;
NewObj = ExAllocatePool(PagedPool, Size + sizeof (GDIOBJHDR)); // FIXME: Allocate with tag of MAGIC?
if (NewObj == NULL)
{
return NULL;
}
RtlZeroMemory(NewObj, Size + sizeof (GDIOBJHDR));
NewObj->wMagic = Magic;
#if 0
KeInitializeSpinlock(&NewObj->Lock);
#endif
return (PGDIOBJ)(((PCHAR) NewObj) + sizeof (GDIOBJHDR));
}
@ -35,9 +124,9 @@ BOOL GDIOBJ_FreeObject (PGDIOBJ Obj, WORD Magic)
ObjHdr = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR));
if (ObjHdr->wMagic != Magic)
{
return FALSE;
}
{
return FALSE;
}
ExFreePool (ObjHdr);
return TRUE;
}
@ -49,9 +138,9 @@ HGDIOBJ GDIOBJ_PtrToHandle (PGDIOBJ Obj, WORD Magic)
if (Obj == NULL) return NULL;
objHeader = (PGDIOBJHDR) (((PCHAR)Obj) - sizeof (GDIOBJHDR));
if (objHeader->wMagic != Magic)
{
return 0;
}
{
return 0;
}
return (HGDIOBJ) objHeader;
}
@ -67,9 +156,9 @@ PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic)
/* FIXME: Lock object for duration */
if ((objHeader->wMagic != Magic) && (Magic != GO_MAGIC_DONTCARE))
{
return 0;
}
{
return 0;
}
return (PGDIOBJ) (((PCHAR)Obj) + sizeof (GDIOBJHDR));
}
@ -77,7 +166,7 @@ PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic)
BOOL GDIOBJ_LockObject (HGDIOBJ Obj)
{
/* FIXME: write this */
return TRUE;
// return TRUE;
}
BOOL GDIOBJ_UnlockObject (HGDIOBJ Obj)
@ -92,9 +181,9 @@ HGDIOBJ GDIOBJ_GetNextObject (HGDIOBJ Obj, WORD Magic)
objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
if (objHeader->wMagic != Magic)
{
return 0;
}
{
return 0;
}
return objHeader->hNext;
}
@ -107,14 +196,48 @@ HGDIOBJ GDIOBJ_SetNextObject (HGDIOBJ Obj, WORD Magic, HGDIOBJ NextObj)
/* FIXME: should we lock/unlock the object here? */
objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
if (objHeader->wMagic != Magic)
{
return 0;
}
{
return 0;
}
oldNext = objHeader->hNext;
objHeader->hNext = NextObj;
return oldNext;
}
VOID CreateStockObjects(void)
{
// Create GDI Stock Objects from the logical structures we've defined
StockObjects[WHITE_BRUSH] = W32kCreateBrushIndirect(&WhiteBrush);
StockObjects[LTGRAY_BRUSH] = W32kCreateBrushIndirect(&LtGrayBrush);
StockObjects[GRAY_BRUSH] = W32kCreateBrushIndirect(&GrayBrush);
StockObjects[DKGRAY_BRUSH] = W32kCreateBrushIndirect(&DkGrayBrush);
StockObjects[BLACK_BRUSH] = W32kCreateBrushIndirect(&BlackBrush);
StockObjects[NULL_BRUSH] = W32kCreateBrushIndirect(&NullBrush);
StockObjects[WHITE_PEN] = W32kCreatePenIndirect(&WhitePen);
StockObjects[BLACK_PEN] = W32kCreatePenIndirect(&BlackPen);
StockObjects[NULL_PEN] = W32kCreatePenIndirect(&NullPen);
StockObjects[OEM_FIXED_FONT] = W32kCreateFontIndirect(&OEMFixedFont);
StockObjects[ANSI_FIXED_FONT] = W32kCreateFontIndirect(&AnsiFixedFont);
StockObjects[SYSTEM_FONT] = W32kCreateFontIndirect(&SystemFont);
StockObjects[DEVICE_DEFAULT_FONT] = W32kCreateFontIndirect(&DeviceDefaultFont);
StockObjects[SYSTEM_FIXED_FONT] = W32kCreateFontIndirect(&SystemFixedFont);
StockObjects[DEFAULT_GUI_FONT] = W32kCreateFontIndirect(&DefaultGuiFont);
StockObjects[DEFAULT_PALETTE] = PALETTE_Init();
}
HGDIOBJ STDCALL W32kGetStockObject(INT Object)
{
HGDIOBJ ret;
/* if ((Object < 0) || (Object >= NB_STOCK_OBJECTS)) return 0;
if (!StockObjects[Object]) return 0;
ret = FIRST_STOCK_HANDLE + Object;
return ret; */
return StockObjects[Object]; // FIXME........
}

View file

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

View file

@ -15,42 +15,38 @@
PBRUSHOBJ PenToBrushObj(PDC dc, PENOBJ *pen)
{
BRUSHOBJ *BrushObj;
XLATEOBJ *RGBtoVGA16;
BRUSHOBJ *BrushObj;
XLATEOBJ *RGBtoVGA16;
// FIXME: move color translation routines to W32kSelectObject
BrushObj = ExAllocatePool(NonPagedPool, sizeof(BRUSHOBJ));
BrushObj->iSolidColor = pen->logpen.lopnColor;
DbgPrint("PenToBrushObj:%08x ", pen);
BrushObj = ExAllocatePool(NonPagedPool, sizeof(BRUSHOBJ));
RGBtoVGA16 = EngCreateXlate(PAL_INDEXED, PAL_RGB,
dc->DevInfo.hpalDefault, NULL);
BrushObj->iSolidColor = XLATEOBJ_iXlate(RGBtoVGA16, pen->logpen.lopnColor);
DbgPrint("BrushObj->iSolidColor:%u\n", BrushObj->iSolidColor);
return BrushObj;
// CreateGDIHandle(BrushGDI, BrushObj);
return BrushObj;
}
VOID BitmapToSurf(PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap)
{
SurfObj->dhsurf = NULL;
SurfObj->hsurf = NULL;
SurfObj->dhpdev = NULL;
SurfObj->hdev = NULL;
SurfObj->sizlBitmap = Bitmap->size;
SurfObj->cjBits = Bitmap->bitmap.bmHeight * Bitmap->bitmap.bmWidthBytes;
SurfObj->pvBits = Bitmap->bitmap.bmBits;
SurfObj->pvScan0 = NULL; // start of bitmap
SurfObj->lDelta = Bitmap->bitmap.bmWidthBytes;
if(Bitmap->dib)
{
SurfGDI->BitsPerPixel = Bitmap->dib->dsBm.bmBitsPixel;
SurfObj->lDelta = Bitmap->dib->dsBm.bmWidthBytes;
SurfObj->pvBits = Bitmap->dib->dsBm.bmBits;
SurfObj->cjBits = Bitmap->dib->dsBm.bmHeight * Bitmap->dib->dsBm.bmWidthBytes;
} else {
SurfGDI->BitsPerPixel = Bitmap->bitmap.bmBitsPixel;
SurfObj->lDelta = Bitmap->bitmap.bmWidthBytes;
SurfObj->pvBits = Bitmap->bitmap.bmBits;
SurfObj->cjBits = Bitmap->bitmap.bmHeight * Bitmap->bitmap.bmWidthBytes;
}
SurfObj->dhsurf = NULL;
SurfObj->hsurf = NULL;
SurfObj->dhpdev = NULL;
SurfObj->hdev = NULL;
SurfObj->pvScan0 = SurfObj->pvBits; // start of bitmap
SurfObj->sizlBitmap = Bitmap->size; // FIXME: alloc memory for our own struct?
SurfObj->iUniq = 0; // not sure..
SurfObj->iBitmapFormat = BMF_4BPP; /* FIXME */
SurfObj->iBitmapFormat = BitmapFormat(SurfGDI->BitsPerPixel, BI_RGB);
SurfObj->iType = STYPE_BITMAP;
SurfObj->fjBitmap = BMF_TOPDOWN;
SurfGDI->BytesPerPixel = bytesPerPixel(SurfObj->iType);
DbgPrint("Bitmap2Surf: cjBits: %u lDelta: %u width: %u height: %u\n",
SurfObj->cjBits, SurfObj->lDelta, Bitmap->bitmap.bmWidth, Bitmap->bitmap.bmHeight);
}

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

View file

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

View file

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

View file

@ -6,10 +6,24 @@
#include <win32k/dc.h>
#include <win32k/text.h>
#include <win32k/kapi.h>
#include <freetype/freetype.h>
// #define NDEBUG
#include <win32k/debug1.h>
FT_Library library;
BOOL InitFontSupport()
{
ULONG error;
error = FT_Init_FreeType(&library);
if(error)
{
return FALSE;
} else return TRUE;
}
int
STDCALL
W32kAddFontResource(LPCWSTR Filename)
@ -41,7 +55,7 @@ HFONT
STDCALL
W32kCreateFontIndirect(CONST LPLOGFONT lf)
{
UNIMPLEMENTED;
DbgPrint("WARNING: W32kCreateFontIndirect is current unimplemented\n");
}
BOOL
@ -336,9 +350,9 @@ W32kSetTextColor(HDC hDC,
PDC dc = DC_HandleToPtr(hDC);
if (!dc)
{
return 0x80000000;
}
{
return 0x80000000;
}
oldColor = dc->w.textColor;
dc->w.textColor = color;
@ -364,19 +378,176 @@ W32kTextOut(HDC hDC,
LPCWSTR String,
int Count)
{
DC *dc = DC_HandleToPtr(hDC);
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
UNICODE_STRING UString;
ANSI_STRING AString;
// Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
RtlCreateUnicodeString(&UString, (PWSTR)String);
RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
DC *dc = DC_HandleToPtr(hDC);
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
UNICODE_STRING FileName;
int error, glyph_index, n, load_flags = FT_LOAD_RENDER, i, j;
FT_Face face;
FT_GlyphSlot glyph;
NTSTATUS Status;
HANDLE FileHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
FILE_STANDARD_INFORMATION FileStdInfo;
PVOID buffer;
ULONG size, TextLeft = XStart, TextTop = YStart, SpaceBetweenChars = 5, StringLength;
FT_Vector origin;
FT_Bitmap bit, bit2, bit3;
POINTL SourcePoint;
RECTL DestRect;
HBITMAP HSourceGlyph;
PSURFOBJ SourceGlyphSurf;
SIZEL bitSize;
FT_CharMap found = 0;
FT_CharMap charmap;
PCHAR bitbuf;
// For now we're just going to use an internal font
grWriteCellString(SurfObj, XStart, YStart, AString.Buffer, 0xffffff);
// For now we're just going to use an internal font
// grWriteCellString(SurfObj, XStart, YStart, AString->Buffer, 0xffffff);
RtlFreeAnsiString(&AString);
RtlFreeUnicodeString(&UString);
// Prepare the Unicode FileName
RtlCreateUnicodeString(&FileName, L"\\SystemRoot\\fonts\\arial.ttf");
// Open the Module
InitializeObjectAttributes(&ObjectAttributes, &FileName, 0, NULL, NULL);
Status = NtOpenFile(&FileHandle, FILE_ALL_ACCESS, &ObjectAttributes, NULL, 0, 0);
if (!NT_SUCCESS(Status))
{
DbgPrint("Could not open module file: %wZ\n", L"c:/reactos/fonts/arial.ttf");
return 0;
}
// Get the size of the file
Status = NtQueryInformationFile(FileHandle, NULL, &FileStdInfo, sizeof(FileStdInfo), FileStandardInformation);
if (!NT_SUCCESS(Status))
{
DbgPrint("Could not get file size\n");
return 0;
}
// Allocate nonpageable memory for driver
size = FileStdInfo.EndOfFile.u.LowPart;
buffer = ExAllocatePool(NonPagedPool, size);
if (buffer == NULL)
{
DbgPrint("could not allocate memory for module");
return 0;
}
// Load driver into memory chunk
Status = NtReadFile(FileHandle, 0, 0, 0, 0, buffer, FileStdInfo.EndOfFile.u.LowPart, 0, 0);
if (!NT_SUCCESS(Status))
{
DbgPrint("could not read module file into memory");
ExFreePool(buffer);
return 0;
}
NtClose(FileHandle);
error = FT_New_Memory_Face(library,
buffer, // first byte in memory
size, // size in bytes
0, // face_index
&face );
if ( error == FT_Err_Unknown_File_Format )
{
DbgPrint("Unknown font file format\n");
}
else if ( error )
{
DbgPrint("Error reading font file\n");
}
DbgPrint("Family name: %s\n", face->family_name);
DbgPrint("Style name: %s\n", face->style_name);
DbgPrint("Num glyphs: %u\n", face->num_glyphs);
DbgPrint("Height: %d\n", face->height);
if (face->charmap == NULL)
{
DbgPrint("WARNING: No charmap selected!\n");
DbgPrint("This font face has %d charmaps\n", face->num_charmaps);
for ( n = 0; n < face->num_charmaps; n++ )
{
charmap = face->charmaps[n];
DbgPrint("found charmap encoding: %u\n", charmap->encoding);
if (charmap->encoding != 0)
{
found = charmap;
break;
}
}
}
if (!found) DbgPrint("WARNING: Could not find desired charmap!\n");
error = FT_Set_Charmap(face, found);
if (error) DbgPrint("WARNING: Could not set the charmap!\n");
error = FT_Set_Char_Size(
face, // handle to face object
16*64, // char_width in 1/64th of points
16*64, // char_height in 1/64th of points
300, // horizontal device resolution
300 ); // vertical device resolution
StringLength = wcslen(String);
DbgPrint("StringLength: %u\n", StringLength);
for(i=0; i<StringLength; i++)
{
glyph_index = FT_Get_Char_Index(face, *String);
error = FT_Load_Glyph(
face, // handle to face object
glyph_index, // glyph index
FT_LOAD_DEFAULT ); // load flags (erase previous glyph)
if(error) DbgPrint("WARNING: Failed to load and render glyph!\n");
glyph = face->glyph;
if ( glyph->format == ft_glyph_format_outline )
{
DbgPrint("Outline Format Font\n");
error = FT_Render_Glyph( glyph, ft_render_mode_normal );
if(error) DbgPrint("WARNING: Failed to render glyph!\n");
} else {
DbgPrint("Bitmap Format Font\n");
bit3.rows = glyph->bitmap.rows;
bit3.width = glyph->bitmap.width;
bit3.pitch = glyph->bitmap.pitch;
bit3.buffer = glyph->bitmap.buffer;
}
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
@ -387,4 +558,3 @@ W32kTranslateCharsetInfo(PDWORD Src,
{
UNIMPLEMENTED;
}