Added eng files

svn path=/trunk/; revision=1068
This commit is contained in:
Jason Filby 2000-03-17 21:44:02 +00:00
parent e1d6086025
commit 690a781452
9 changed files with 1306 additions and 39 deletions

View file

@ -0,0 +1,226 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI BitBlt Functions
* FILE: subsys/win32k/eng/bitblt.c
* PROGRAMER: Jason Filby
* REVISION HISTORY:
* 2/10/1999: Created
*/
#include <ddk/winddi.h>
#include <ddk/ntddk.h>
#include "brush.h"
#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 };
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->top < prcDst->bottom)
return(TRUE);
}
*prcDst = rclEmpty;
return(FALSE);
}
BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
SURFOBJ *Mask, CLIPOBJ *ClipRegion,
XLATEOBJ *ColorTranslation, RECTL *DestRect,
POINTL *SourcePoint, POINTL *MaskRect,
BRUSHOBJ *Brush, POINTL *BrushOrigin, ROP4 rop4)
{
BYTE clippingType;
RECTL rclTmp;
POINTL ptlTmp;
RECT_ENUM RectEnum;
BOOL EnumMore;
SURFGDI *DestGDI, *SourceGDI;
BOOLEAN canCopyBits;
// If we don't have to do anything special, we can punt to DrvCopyBits
// if it exists
if( (Mask == NULL) && (MaskRect == NULL) && (Brush == NULL) &&
(BrushOrigin == NULL) && (rop4 == NULL) )
{
canCopyBits = TRUE;
} else
canCopyBits = FALSE;
// FIXME: Use XLATEOBJ to translate source bitmap into destination bitmap's
// format. Call DrvDitherColor function where necessary and if available
// FIXME: If canCopyBits == TRUE AND the driver has a DrvCopyBits then
// punt to EngCopyBits and not the driver's DrvCopyBits just yet so
// that the EngCopyBits can take care of the clipping drivers
// DrvCopyBits
// FIXME: Don't punt to DrvBitBlt straight away. Instead, mark a typedef'd
// function to go there instead of the Engine's bltting function
// so as to do the clipping for the driver
// Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
{
// Destination surface is device managed
if(Dest->iType!=STYPE_BITMAP)
{
DestGDI = AccessInternalObjectFromUserObject(Dest);
if ((DestGDI->CopyBits!=NULL) && (canCopyBits == TRUE))
{
return DestGDI->CopyBits(Dest, Source, ClipRegion,
ColorTranslation, DestRect, SourcePoint);
}
if (DestGDI->BitBlt!=NULL)
{
return DestGDI->BitBlt(Dest, Source, Mask, ClipRegion,
ColorTranslation, DestRect, SourcePoint,
MaskRect, Brush, BrushOrigin, rop4);
}
}
// Source surface is device managed
if(Source->iType!=STYPE_BITMAP)
{
SourceGDI = AccessInternalObjectFromUserObject(Source);
if ((SourceGDI->CopyBits!=NULL) && (canCopyBits == TRUE))
{
return SourceGDI->CopyBits(Dest, Source, ClipRegion,
ColorTranslation, DestRect, SourcePoint);
}
if (SourceGDI->BitBlt!=NULL)
{
return SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion,
ColorTranslation, DestRect, SourcePoint,
MaskRect, Brush, BrushOrigin, rop4);
}
// Should never get here, if it's not GDI managed then the device
// should take care of it
// FIXME: Error message here
}
}
DestGDI = AccessInternalObjectFromUserObject(Dest);
SourceGDI = AccessInternalObjectFromUserObject(Source);
// Determine clipping type
if (ClipRegion == (CLIPOBJ *) NULL)
{
clippingType = DC_TRIVIAL;
} else {
clippingType = ClipRegion->iDComplexity;
}
// We don't handle color translation just yet
if ((rop4 == 0x0000CCCC) &&
((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL)))
{
switch(clippingType)
{
case DC_TRIVIAL:
BitBltCopy(Dest, Source,
DestGDI, SourceGDI,
DestRect, SourcePoint, Source->lDelta);
return(TRUE);
case DC_RECT:
// Clip the blt to the clip rectangle
EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds);
ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
BitBltCopy(Dest, Source,
DestGDI, SourceGDI,
&rclTmp, &ptlTmp, Source->lDelta);
return(TRUE);
case DC_COMPLEX:
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES,
CD_ANY, ENUM_RECT_LIMIT);
do {
EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
(PVOID) &RectEnum);
if (RectEnum.c > 0)
{
RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
RECTL* prcl = &RectEnum.arcl[0];
do {
EngIntersectRect(prcl, prcl, DestRect);
ptlTmp.x = SourcePoint->x + prcl->left
- DestRect->left;
ptlTmp.y = SourcePoint->y + prcl->top
- DestRect->top;
BitBltCopy(Dest, Source,
DestGDI, SourceGDI,
prcl, &ptlTmp, Source->lDelta);
prcl++;
} while (prcl < prclEnd);
}
} while(EnumMore);
return(TRUE);
}
}
return(FALSE);
}

View file

@ -0,0 +1,124 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI Clipping Functions
* FILE: subsys/win32k/eng/clip.c
* PROGRAMER: Jason Filby
* REVISION HISTORY:
* 21/8/1999: Created
*/
#include <ddk/winddi.h>
#include <ddk/ntddk.h>
#include "objects.h"
#include "clip.h"
// FIXME: Complex clipping doesn't work
CLIPOBJ *EngCreateClipRegion(ULONG NumRects, RECTL Rects[],
ULONG Mode, ULONG Options)
{
HCLIP NewClip;
CLIPOBJ *ClipObj;
CLIPGDI *ClipGDI;
ClipObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
ClipGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPGDI), NULL);
NewClip = CreateGDIHandle(ClipGDI, ClipObj);
ClipGDI->NumRegionRects = NumRects;
ClipGDI->RegionRects = Rects;
ClipObj->iMode = Mode;
ClipObj->fjOptions = Options;
ClipObj->iDComplexity = DC_TRIVIAL;
if(NumRects == 1)
{
ClipObj->iFComplexity = FC_RECT;
ClipObj->iDComplexity = DC_RECT;
// FIXME: Is this correct??
ClipObj->rclBounds = Rects[0];
} else
{
ClipObj->iDComplexity = DC_COMPLEX;
if(NumRects <= 4)
{
ClipObj->iFComplexity = FC_RECT4;
} else
{
ClipObj->iFComplexity = FC_COMPLEX;
}
}
}
VOID EngDeleteClipRegion(CLIPOBJ *ClipObj)
{
HCLIP HClip = AccessHandleFromUserObject(ClipObj);
CLIPGDI *ClipGDI = AccessInternalObject(HClip);
EngFreeMem(ClipGDI);
EngFreeMem(ClipObj);
FreeGDIHandle(HClip);
}
VOID EngIntersectClipRegion(CLIPOBJ *ClipObj, ULONG NumRects, RECTL *IntersectRects)
{
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
ClipGDI->NumIntersectRects = NumRects;
ClipGDI->IntersectRects = IntersectRects;
if(NumRects == 1)
{
ClipObj->iDComplexity = DC_RECT;
ClipObj->rclBounds = IntersectRects[0];
} else
{
ClipObj->iDComplexity = DC_COMPLEX;
ClipGDI->IntersectRects = IntersectRects;
}
}
CLIPOBJ *EngCreateClip(VOID)
{
return EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPOBJ), NULL);
}
VOID EngDeleteClip(CLIPOBJ *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->EnumPos = 0;
ClipGDI->EnumRects.c = MaxRects;
// Return the number of rectangles enumerated
if(ClipGDI->EnumRects.c>MaxRects)
{
ClipGDI->EnumRects.c = 0xFFFFFFFF;
}
return ClipGDI->EnumRects.c;
}
BOOL CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj, IN ULONG ObjSize,
OUT ULONG *EnumRects)
{
CLIPGDI *ClipGDI = AccessInternalObjectFromUserObject(ClipObj);
ClipGDI->EnumPos++;
if(ClipGDI->EnumPos > ClipGDI->EnumRects.c)
{
return FALSE;
} else
return TRUE;
}

View file

@ -0,0 +1,162 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI EngCopyBits Function
* FILE: subsys/win32k/eng/copybits.c
* PROGRAMER: Jason Filby
* REVISION HISTORY:
* 8/18/1999: Created
*/
#include <ddk/winddi.h>
#include "objects.h"
#include "enum.h"
VOID CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFGDI *DestGDI, SURFGDI *SourceGDI,
PRECTL DestRect, POINTL *SourcePoint,
ULONG Delta)
{
ULONG dy, leftOfSource, leftOfDest, Width;
// 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;
for(dy=DestRect->top; dy<DestRect->bottom; dy++)
{
memcpy(DestSurf->pvBits+Delta*dy+leftOfDest,
SourceSurf->pvBits+Delta*dy+leftOfSource,
Width);
}
}
BOOL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source,
CLIPOBJ *Clip, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
SURFGDI *DestGDI, *SourceGDI;
BYTE clippingType;
RECTL rclTmp;
POINTL ptlTmp;
RECT_ENUM RectEnum;
BOOL EnumMore;
// FIXME: Do color translation -- refer to eng\bitblt.c
// FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
// mark the copy block function to be DrvCopyBits instead of the
// GDI's copy bit function so as to remove clipping from the
// driver's responsibility
// If one of the surfaces isn't managed by the GDI
if((Dest->iType!=STYPE_BITMAP) || (Source->iType!=STYPE_BITMAP))
{
// Destination surface is device managed
if(Dest->iType!=STYPE_BITMAP)
{
DestGDI = AccessInternalObjectFromUserObject(Dest);
if (DestGDI->CopyBits!=NULL)
{
return DestGDI->CopyBits(Dest, Source, Clip,
ColorTranslation, DestRect, SourcePoint);
}
}
// Source surface is device managed
if(Source->iType!=STYPE_BITMAP)
{
SourceGDI = AccessInternalObjectFromUserObject(Dest);
if (SourceGDI->CopyBits!=NULL)
{
return SourceGDI->CopyBits(Dest, Source, Clip,
ColorTranslation, DestRect, SourcePoint);
}
}
// If CopyBits wasn't hooked, BitBlt must be
return EngBitBlt(Dest, Source,
NULL, Clip, ColorTranslation, DestRect, SourcePoint,
NULL, NULL, NULL, NULL);
}
// Determine clipping type
if (Clip == (CLIPOBJ *) NULL)
{
clippingType = DC_TRIVIAL;
} else {
clippingType = Clip->iDComplexity;
}
// We don't handle color translation just yet
if ((ColorTranslation == NULL) || (ColorTranslation->flXlate & XO_TRIVIAL))
{
switch(clippingType)
{
case DC_TRIVIAL:
CopyBitsCopy(Dest, Source,
DestGDI, SourceGDI,
DestRect, SourcePoint, Source->lDelta);
return(TRUE);
case DC_RECT:
// Clip the blt to the clip rectangle
EngIntersectRect(&rclTmp, DestRect, &Clip->rclBounds);
ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left;
ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top;
CopyBitsCopy(Dest, Source,
DestGDI, SourceGDI,
&rclTmp, &ptlTmp, Source->lDelta);
return(TRUE);
case DC_COMPLEX:
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES,
CD_ANY, ENUM_RECT_LIMIT);
do {
EnumMore = CLIPOBJ_bEnum(Clip,(ULONG) sizeof(RectEnum),
(PVOID) &RectEnum);
if (RectEnum.c > 0)
{
RECTL* prclEnd = &RectEnum.arcl[RectEnum.c];
RECTL* prcl = &RectEnum.arcl[0];
do {
EngIntersectRect(prcl, prcl, DestRect);
ptlTmp.x = SourcePoint->x + prcl->left
- DestRect->left;
ptlTmp.y = SourcePoint->y + prcl->top
- DestRect->top;
CopyBitsCopy(Dest, Source,
DestGDI, SourceGDI,
prcl, &ptlTmp, Source->lDelta);
prcl++;
} while (prcl < prclEnd);
}
} while(EnumMore);
return(TRUE);
}
}
return FALSE;
}

View file

@ -0,0 +1,66 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Manage GDI Handles
* FILE: subsys/win32k/eng/handle.c
* PROGRAMER: Jason Filby
* REVISION HISTORY:
* 29/8/1999: Created
*/
#include <ddk/winddi.h>
#include "handle.h"
// FIXME: Total rewrite..
ULONG CreateGDIHandle(PVOID InternalObject, PVOID UserObject)
{
ULONG NewHandle = HandleCounter++;
GDIHandles[NewHandle].InternalObject = InternalObject;
GDIHandles[NewHandle].UserObject = UserObject;
return NewHandle;
}
VOID FreeGDIHandle(ULONG Handle)
{
GDIHandles[Handle].InternalObject = NULL;
GDIHandles[Handle].UserObject = NULL;
}
PVOID AccessInternalObject(ULONG Handle)
{
return GDIHandles[Handle].InternalObject;
}
PVOID AccessUserObject(ULONG Handle)
{
return GDIHandles[Handle].UserObject;
}
PVOID AccessInternalObjectFromUserObject(PVOID UserObject)
{
ULONG i;
for(i=0; i<MAX_GDI_HANDLES; i++)
{
if(GDIHandles[i].UserObject == UserObject)
return GDIHandles[i].InternalObject;
}
return NULL;
}
ULONG AccessHandleFromUserObject(PVOID UserObject)
{
ULONG i;
for(i=0; i<MAX_GDI_HANDLES; i++)
{
if(GDIHandles[i].UserObject == UserObject)
return i;
}
return INVALID_HANDLE;
}

View file

@ -0,0 +1,109 @@
#include <ddk/winddi.h>
#include "objects.h"
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 = AccessInternalObjectFromUserObject(Surface);
if(Surface->iType!=STYPE_BITMAP)
{
// Call the driver's DrvLineTo
return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2,
RectBounds, mix);
}
// FIXME: Implement clipping
if(y1==y2) return EngHLine(Surface, SurfGDI, x1, y1, (x2-x1), Brush->iSolidColor);
x=x1;
y=y1;
deltax=x2-x1;
deltay=y2-y1;
if(deltax<0)
{
xchange=-1;
deltax=-deltax;
} else
{
xchange=1;
}
if(deltay<0)
{
ychange=-1;
deltay=-deltay;
} else
{
ychange=1;
};
error=0;
i=0;
if(deltax<deltay)
{
length=deltay+1;
while(i<length)
{
LinePoint(Surface, SurfGDI, x, y, Brush->iSolidColor);
y=y+ychange;
error=error+deltax;
if(error>deltay)
{
x=x+xchange;
error=error-deltay;
}
i=i+1;
}
} 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;
}
}
return TRUE;
}

View file

@ -0,0 +1,94 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI Driver Paint Functions
* FILE: subsys/win32k/eng/paint.c
* PROGRAMER: Jason Filby
* REVISION HISTORY:
* 3/7/1999: Created
*/
#include <ddk/winddi.h>
#include "objects.h"
#include "brush.h"
#include "enum.h"
BOOL FillSolid(SURFOBJ *Surface, PRECTL Dimensions, ULONG iColor)
{
ULONG x, y, LineWidth, leftOfBitmap;
SURFGDI *SurfaceGDI;
SurfaceGDI = AccessInternalObjectFromUserObject(Surface);
LineWidth = Dimensions->right - Dimensions->left;
for (y = Dimensions->top; y < Dimensions->bottom; y++)
{
EngHLine(Surface, SurfaceGDI, Dimensions->left, y, LineWidth, iColor);
}
return TRUE;
}
BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
BRUSHINST *BrushInst, POINTL *BrushPoint)
{
RECT_ENUM RectEnum;
BOOL EnumMore;
switch(ClipRegion->iMode) {
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 */
if (ClipRegion->iDComplexity == DC_RECT)
{
FillSolid(Surface, &ClipRegion->rclBounds, iColor);
} else {
/* Enumerate all the rectangles and draw them */
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);
}
return(TRUE);
default:
return(FALSE);
}
}
BOOL EngPaint(IN SURFOBJ *Surface, IN CLIPOBJ *ClipRegion,
IN BRUSHOBJ *Brush, IN POINTL *BrushOrigin,
IN MIX Mix)
{
SURFGDI *SurfGDI;
// 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);
}
// 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);
}

View file

@ -1,7 +1,7 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI Driver Bitmap Functions
* PURPOSE: GDI Palette Functions
* FILE: subsys/win32k/eng/palette.c
* PROGRAMER: Jason Filby
* REVISION HISTORY:
@ -9,33 +9,68 @@
*/
#include <ddk/winddi.h>
#include "objects.h"
HPALETTE EngCreatePalette(IN ULONG Mode,
IN ULONG NumColors,
IN PULONG *Colors,
IN ULONG Red,
IN ULONG Green,
IN ULONG Blue)
HPALETTE EngCreatePalette(ULONG Mode,
ULONG NumColors,
PULONG *Colors, // FIXME: This was implemented with ULONG *Colors!!
ULONG Red,
ULONG Green,
ULONG Blue)
{
/* We need to take the colors given to us and generate a nice default color
model */
HPALETTE NewPalette;
PALOBJ *PalObj;
PALGDI *PalGDI;
PalObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALOBJ), NULL);
PalGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALGDI), NULL);
NewPalette = CreateGDIHandle(PalGDI, PalObj);
PalGDI->Mode = Mode;
if(Mode==PAL_INDEXED)
{
/* For now the ultimate color model is just colors.. */
PalGDI->NumColors = NumColors;
PalGDI->IndexedColors = Colors;
} else
if(Mode==PAL_BITFIELDS)
{
PalGDI->RedMask = Red;
PalGDI->GreenMask = Green;
PalGDI->BlueMask = Blue;
}
/* FIXME: Add support for other given palette types */
return NewPalette;
}
/* FIXME: Generate a handle for Colors */
BOOL EngDeletePalette(IN HPALETTE Palette)
{
PALOBJ *PalObj;
PALGDI *PalGDI;
PalGDI = AccessInternalObject(Palette);
PalObj = AccessInternalObject(Palette);
EngFreeMem(PalGDI);
EngFreeMem(PalObj);
FreeGDIHandle(Palette);
return TRUE;
}
ULONG PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors,
ULONG *PaletteEntry)
{
ULONG i, entry;
PALGDI *PalGDI;
PalGDI = AccessInternalObjectFromUserObject(PalObj);
for(i=Start; i<Colors; i++)
{
PaletteEntry[i] = PalGDI->IndexedColors[i];
}
return Colors;
}
BOOL EngDeletePalette(IN HPALETTE hpal)
{
/* Should actually get the pointer from this handle.. which for now IS
the pointer */
EngFreeMem(hpal);
}

View file

@ -9,36 +9,219 @@
*/
#include <ddk/winddi.h>
#include "objects.h"
BOOL EngAssociateSurface(IN HSURF Surface,
IN HDEV Dev,
IN ULONG Hooks)
BYTE bytesPerPixel(ULONG Format)
{
SURFOBJ *Surfobj;
// FIXME: GDI bitmaps are supposed to be pixel-packed. Right now if the
// pixel size if < 1 byte we expand it to 1 byte
// Point our new Surfobj to hsurf (assumes hsurf is value returned by
// ExAllocatePool)
Surfobj = Surface;
if(Format==BMF_1BPP)
{
return 1;
} else
if((Format==BMF_4BPP) || (Format==BMF_4RLE))
{
return 1;
} else
if((Format==BMF_8BPP) || (Format==BMF_8RLE))
{
return 1;
} else
if(Format==BMF_16BPP)
{
return 2;
} else
if(Format==BMF_24BPP)
{
return 3;
} else
if(Format==BMF_32BPP)
{
return 4;
}
return 0;
}
VOID InitializeHooks(SURFGDI *SurfGDI)
{
SurfGDI->BitBlt = NULL;
SurfGDI->CopyBits = NULL;
}
HBITMAP EngCreateDeviceBitmap(DHSURF dhsurf, SIZEL Size, ULONG Format)
{
HBITMAP NewBitmap;
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
NewBitmap = CreateGDIHandle(SurfGDI, SurfObj);
InitializeHooks(SurfGDI);
SurfGDI->BytesPerPixel = bytesPerPixel(Format);
SurfObj->dhsurf = dhsurf;
SurfObj->hsurf = dhsurf; // FIXME: Is this correct??
SurfObj->sizlBitmap = Size;
SurfObj->iBitmapFormat = Format;
SurfObj->lDelta = SurfGDI->BytesPerPixel * Size.cx;
SurfObj->iType = STYPE_DEVBITMAP;
return NewBitmap;
}
HBITMAP EngCreateBitmap(IN SIZEL Size,
IN LONG Width,
IN ULONG Format,
IN ULONG Flags,
IN PVOID Bits)
{
HBITMAP NewBitmap;
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
NewBitmap = CreateGDIHandle(SurfGDI, SurfObj);
InitializeHooks(SurfGDI);
SurfGDI->BytesPerPixel = bytesPerPixel(Format);
SurfObj->cjBits = Width * Size.cy;
if(Bits!=NULL)
{
SurfObj->pvBits = Bits;
} else
{
if(Flags & BMF_USERMEM)
{
SurfObj->pvBits = EngAllocUserMem(SurfObj->cjBits, 0);
} else {
if(Flags & BMF_NOZEROINIT)
{
SurfObj->pvBits = EngAllocMem(0, SurfObj->cjBits, 0);
} else {
SurfObj->pvBits = EngAllocMem(FL_ZERO_MEMORY, SurfObj->cjBits, 0);
}
}
}
SurfObj->dhsurf = 0;
SurfObj->hsurf = 0;
SurfObj->sizlBitmap = Size;
SurfObj->iBitmapFormat = Format;
SurfObj->lDelta = Width;
SurfObj->iType = STYPE_BITMAP;
// Use flags to determine bitmap type -- TOP_DOWN or whatever
return NewBitmap;
}
HSURF EngCreateDeviceSurface(DHSURF dhsurf, SIZEL Size, ULONG Format)
{
HSURF NewSurface;
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
// DrvCreateDeviceSurface???
SurfObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFOBJ), NULL);
SurfGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(SURFGDI), NULL);
NewSurface = CreateGDIHandle(SurfGDI, SurfObj);
InitializeHooks(SurfGDI);
SurfGDI->BytesPerPixel = bytesPerPixel(Format);
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;
}
PFN DriverFunction(DRVENABLEDATA *DED, ULONG DriverFunc)
{
ULONG i;
for(i=0; i<DED->c; i++)
{
if(DED->pdrvfn[i].iFunc == DriverFunc)
return DED->pdrvfn[i].pfn;
}
return NULL;
}
BOOL EngAssociateSurface(HSURF Surface, HDEV Dev, ULONG Hooks)
{
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
DRVENABLEDATA *DED;
SurfGDI = AccessInternalObject(Surface);
SurfObj = AccessUserObject(Surface);
DED = AccessInternalObject(Dev);
// Associate the hdev
Surfobj->hdev = Dev;
SurfObj->hdev = Dev;
// FIXME: Hook up the specified functions
// Hook up specified functions
if(Hooks & HOOK_BITBLT)
SurfGDI->BitBlt = DriverFunction(DED, INDEX_DrvBitBlt);
if(Hooks & HOOK_STRETCHBLT)
SurfGDI->StretchBlt = DriverFunction(DED, INDEX_DrvStretchBlt);
if(Hooks & HOOK_TEXTOUT)
SurfGDI->TextOut = DriverFunction(DED, INDEX_DrvTextOut);
if(Hooks & HOOK_PAINT)
SurfGDI->Paint = DriverFunction(DED, INDEX_DrvPaint);
if(Hooks & HOOK_STROKEPATH)
SurfGDI->StrokePath = DriverFunction(DED, INDEX_DrvStrokePath);
if(Hooks & HOOK_FILLPATH)
SurfGDI->FillPath = DriverFunction(DED, INDEX_DrvFillPath);
if(Hooks & HOOK_STROKEANDFILLPATH)
SurfGDI->StrokeAndFillPath = DriverFunction(DED, INDEX_DrvStrokeAndFillPath);
if(Hooks & HOOK_LINETO)
SurfGDI->LineTo = DriverFunction(DED, INDEX_DrvLineTo);
if(Hooks & HOOK_COPYBITS)
SurfGDI->CopyBits = DriverFunction(DED, INDEX_DrvCopyBits);
if(Hooks & HOOK_SYNCHRONIZE)
SurfGDI->Synchronize = DriverFunction(DED, INDEX_DrvSynchronize);
if(Hooks & HOOK_SYNCHRONIZEACCESS)
SurfGDI->SynchronizeAccess = TRUE;
return TRUE;
}
BOOL APIENTRY EngDeleteSurface(HSURF hsurf)
BOOL EngDeleteSurface(HSURF Surface)
{
// Assume the hsurf was the value returned by ExAllocatePool
ExFreePool(hsurf);
SURFOBJ *SurfObj;
SURFGDI *SurfGDI;
SurfGDI = AccessInternalObject(Surface);
SurfObj = AccessUserObject(Surface);
EngFreeMem(SurfGDI);
EngFreeMem(SurfObj);
FreeGDIHandle(Surface);
return TRUE;
}
SURFOBJ *EngLockSurface(IN HSURF hsurf)
SURFOBJ *EngLockSurface(HSURF Surface)
{
/* We assume that hsurf is the value returned from ExAllocatePool */
return EngAllocUserMem(NULL, sizeof(SURFOBJ), "");
}
// FIXME: Do we need to allocate new memory for this user object??
VOID EngUnlockSurface(IN SURFOBJ *pso)
{
EngFreeUserMem(sizeof(pso));
return AccessUserObject(Surface);
}

View file

@ -0,0 +1,268 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI Color Translation Functions
* FILE: subsys/win32k/eng/xlate.c
* PROGRAMER: Jason Filby
* REVISION HISTORY:
* 8/20/1999: Created
*/
#include <ddk/ntddk.h>
#include <ddk/winddi.h>
#include <ddk/ntddvid.h>
#include "objects.h"
ULONG CCMLastSourceColor = 0, CCMLastColorMatch = 0;
ULONG RGBtoULONG(BYTE Red, BYTE Green, BYTE Blue)
{
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);
}
INT abs(INT 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.
ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors,
ULONG NumColors)
{
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
if(SourceColor == CCMLastSourceColor)
{
return CCMLastColorMatch;
}
cSourceColor = &SourceColor;
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;
if(rt<=bestMatch)
{
idx = i;
bestMatch = rt;
}
}
CCMLastSourceColor = SourceColor;
CCMLastColorMatch = idx;
return idx;
}
VOID IndexedToIndexedTranslationTable(ULONG *TranslationTable,
PALGDI *PalDest, PALGDI *PalSource)
{
ULONG i;
for(i=0; i<PalSource->NumColors; i++)
{
TranslationTable[i] = ClosestColorMatch(PalSource->IndexedColors[i],
PalDest->IndexedColors, PalDest->NumColors);
}
}
XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
HPALETTE PaletteDest, HPALETTE PaletteSource)
{
// FIXME: Add support for BGR conversions
HPALETTE NewXlate;
XLATEOBJ *XlateObj;
XLATEGDI *XlateGDI;
PALGDI *SourcePalGDI, *DestPalGDI;
ULONG IndexedColors;
XlateObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEOBJ), NULL);
XlateGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEGDI), NULL);
NewXlate = CreateGDIHandle(XlateGDI, XlateObj);
if(SourcePalType == PAL_INDEXED)
{
SourcePalGDI = AccessInternalObject(PaletteSource);
} else
if(DestPalType == PAL_INDEXED)
{
DestPalGDI = AccessInternalObject(PaletteDest);
}
XlateObj->iSrcType = SourcePalType;
XlateObj->iDstType = DestPalType;
// Store handles of palettes in internal Xlate GDI object (or NULLs)
XlateGDI->DestPal = PaletteDest;
XlateGDI->SourcePal = PaletteSource;
XlateObj->flXlate = 0;
// If source and destination palettes are the same or if they're RGB/BGR
if( (PaletteDest == PaletteSource) ||
((DestPalType == PAL_RGB) && (SourcePalType == PAL_RGB)) ||
((DestPalType == PAL_BGR) && (SourcePalType == PAL_BGR)) )
{
XlateObj->flXlate |= XO_TRIVIAL;
}
// Prepare the translation table
if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
{
XlateObj->flXlate |= XO_TABLE;
if (SourcePalType == PAL_INDEXED) IndexedColors = SourcePalGDI->NumColors;
if (DestPalType == PAL_INDEXED) IndexedColors = DestPalGDI->NumColors;
XlateGDI->translationTable = EngAllocMem(
FL_ZERO_MEMORY, sizeof(ULONG)*IndexedColors, NULL);
}
// Source palette is indexed
if(XlateObj->iSrcType == PAL_INDEXED)
{
if(XlateObj->iDstType == PAL_INDEXED)
{
// Converting from indexed to indexed
IndexedToIndexedTranslationTable(XlateGDI->translationTable,
DestPalGDI, SourcePalGDI);
} else
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
// Converting from indexed to RGB
XLATEOBJ_cGetPalette(XlateObj, XO_SRCPALETTE,
SourcePalGDI->NumColors,
XlateGDI->translationTable);
}
XlateObj->pulXlate = XlateGDI->translationTable;
}
// Source palette is RGB
if(XlateObj->iSrcType == PAL_RGB)
{
if(XlateObj->iDstType == PAL_INDEXED)
{
// FIXME: Is this necessary? I think the driver has to call this
// function anyways if pulXlate is NULL and Dest is PAL_INDEXED
// Converting from RGB to indexed
XLATEOBJ_cGetPalette(XlateObj, XO_DESTPALETTE,
DestPalGDI->NumColors,
XlateGDI->translationTable);
}
}
// FIXME: Add support for XO_TO_MONO
return XlateObj;
}
EngDeleteXlate(XLATEOBJ *XlateObj)
{
HPALETTE HXlate = AccessHandleFromUserObject(XlateObj);
XLATEGDI *XlateGDI = AccessInternalObject(HXlate);
if(XlateGDI->translationTable!=NULL)
{
EngFreeMem(XlateGDI->translationTable);
}
EngFreeMem(XlateGDI);
EngFreeMem(XlateObj);
FreeGDIHandle(HXlate);
}
ULONG *XLATEOBJ_piVector(XLATEOBJ *XlateObj)
{
XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
if(XlateObj->iSrcType == PAL_INDEXED)
{
return XlateGDI->translationTable;
}
return NULL;
}
ULONG XLATEOBJ_iXlate(XLATEOBJ *XlateObj, ULONG Color)
{
PALGDI *PalGDI;
XLATEGDI *XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
if(XlateObj->iSrcType == PAL_RGB)
{
// FIXME: should we cache colors used often?
// FIXME: won't work if destination isn't indexed
// Extract the destination palette
PalGDI = AccessInternalObject(XlateGDI->DestPal);
// Return closest match for the given RGB color
return ClosestColorMatch(Color, PalGDI->IndexedColors, PalGDI->NumColors);
} else
if(XlateObj->iSrcType == PAL_INDEXED)
{
return XlateGDI->translationTable[Color];
}
return 0;
}
ULONG XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj,
ULONG PalOutType, ULONG cPal, ULONG *OutPal)
{
ULONG i;
HPALETTE HPal;
XLATEGDI *XlateGDI;
PALGDI *PalGDI;
XlateGDI = AccessInternalObjectFromUserObject(XlateObj);
if(PalOutType == XO_SRCPALETTE)
{
HPal = XlateGDI->SourcePal;
} else
if(PalOutType == XO_DESTPALETTE)
{
HPal = XlateGDI->DestPal;
}
PalGDI = AccessInternalObject(HPal);
RtlCopyMemory(OutPal, PalGDI->IndexedColors, sizeof(ULONG)*cPal);
return i;
}