diff --git a/reactos/include/win32k/bitmaps.h b/reactos/include/win32k/bitmaps.h index 49eb62aa1d3..cdf6c380d09 100644 --- a/reactos/include/win32k/bitmaps.h +++ b/reactos/include/win32k/bitmaps.h @@ -3,7 +3,43 @@ #define __WIN32K_BITMAPS_H #include +#include +typedef struct _DDBITMAP +{ + const PDRIVER_FUNCTIONS pDriverFunctions; +// DHPDEV PDev; +// HSURF Surface; +} DDBITMAP; + +/* GDI logical bitmap object */ +typedef struct _BITMAPOBJ +{ + GDIOBJHDR header; + BITMAP bitmap; + SIZE size; /* For SetBitmapDimension() */ + + DDBITMAP *DDBitmap; + + /* For device-independent bitmaps: */ + DIBSECTION *dib; +} BITMAPOBJ, *PBITMAPOBJ; + +/* Internal interface */ + +#define BITMAPOBJ_AllocBitmap() \ + ((PBITMAPOBJ) GDIOBJ_AllocObject(sizeof(BITMAPOBJ), GO_BITMAP_MAGIC)) +#define BITMAPOBJ_FreeBitmap(hBMObj) GDIOBJ_FreeObject((HGDIOBJ)hBMObj) +#define BITMAPOBJ_HandleToPtr(hBMObj) \ + ((PBITMAPOBJ) GDIOBJ_HandleToPtr((HGDIOBJ)hBMObj, GO_BITMAP_MAGIC)) +#define BITMAPOBJ_PtrToHandle(hBMObj) \ + ((HBITMAP) GDIOBJ_HandleToPtr((PGDIOBJ)hBMObj, GO_BITMAP_MAGIC)) +#define BITMAPOBJ_LockBitmap(hBMObj) GDIOBJ_LockObject((HGDIOBJ)hBMObj) +#define BITMAPOBJ_UnlockBitmap(hBMObj) GDIOBJ_UnlockObject((HGDIOBJ)hBMObj) + +INT BITMAP_GetWidthBytes (INT bmWidth, INT bpp); + +/* User Entry Points */ BOOL W32kBitBlt(HDC hDCDest, INT XDest, INT YDest, diff --git a/reactos/include/win32k/dc.h b/reactos/include/win32k/dc.h index 5fcb6c45076..9af8e5e338d 100644 --- a/reactos/include/win32k/dc.h +++ b/reactos/include/win32k/dc.h @@ -145,14 +145,16 @@ typedef struct _DC /* Internal functions */ +#define DC_PtrToHandle(pDC) \ + ((HDC) GDIOBJ_PtrToHandle((PGDIOBJ)pDC, GO_DC_MAGIC)) +#define DC_HandleToPtr(hDC) \ + ((PDC) GDIOBJ_HandleToPtr((HGDIOBJ)hDC, GO_DC_MAGIC)) +#define DC_LockDC(hDC) GDIOBJ_LockObject((HGDIOBJ)hDC) +#define DC_UnlockDC(hDC) GDIOBJ_UnlockObject((HGDIOBJ)hDC) PDC DC_AllocDC(LPCWSTR Driver); void DC_InitDC(PDC DCToInit); PDC DC_FindOpenDC(LPCWSTR Driver); void DC_FreeDC(PDC DCToFree); -HDC DC_PtrToHandle(PDC pDC); -PDC DC_HandleToPtr(HDC hDC); -BOOL DC_LockDC(HDC hDC); -BOOL DC_UnlockDC(HDC hDC); void DC_UpdateXforms(PDC dc); BOOL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest); diff --git a/reactos/include/win32k/gdiobj.h b/reactos/include/win32k/gdiobj.h index dc98b016d47..5088984a3d0 100644 --- a/reactos/include/win32k/gdiobj.h +++ b/reactos/include/win32k/gdiobj.h @@ -36,6 +36,10 @@ typedef struct _GDIOBJHDR typedef PVOID PGDIOBJ; PGDIOBJ GDIOBJ_AllocObject(WORD Size, WORD Magic); +HGDIOBJ GDIOBJ_PtrToHandle (PGDIOBJ Obj, WORD Magic); +PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic); +BOOL GDIOBJ_LockObject (HGDIOBJ Obj); +BOOL GDIOBJ_UnlockObject (HGDIOBJ Obj); #endif diff --git a/reactos/subsys/win32k/objects/bitmaps.c b/reactos/subsys/win32k/objects/bitmaps.c index c42052af6a8..ce4ec6951d9 100644 --- a/reactos/subsys/win32k/objects/bitmaps.c +++ b/reactos/subsys/win32k/objects/bitmaps.c @@ -26,19 +26,112 @@ HBITMAP W32kCreateBitmap(INT Width, UINT BitsPerPel, CONST VOID *Bits) { - UNIMPLEMENTED; + PBITMAPOBJ bmp; + HBITMAP hBitmap; + + Planes = (BYTE) Planes; + BitsPerPel = (BYTE) BitsPerPel; + + /* Check parameters */ + if (!Height || !Width) + { + return 0; + } + if (Planes != 1) + { + UNIMPLEMENTED; + return 0; + } + if (Height < 0) + { + Height = -Height; + } + if (Width < 0) + { + Width = -Width; + } + + /* Create the BITMAPOBJ */ + bmp = BITMAPOBJ_AllocBitmap (); + if (!bmp) + { + return 0; + } + + DPRINT("%dx%d, %d colors returning %08x\n", Width, Height, + 1 << (Planes * BitsPerPel), bmp); + + bmp->size.cx = 0; + bmp->size.cy = 0; + bmp->bitmap.bmType = 0; + bmp->bitmap.bmWidth = Width; + bmp->bitmap.bmHeight = Height; + bmp->bitmap.bmPlanes = Planes; + bmp->bitmap.bmBitsPixel = BitsPerPel; + bmp->bitmap.bmWidthBytes = BITMAP_GetWidthBytes (Width, BitsPerPel); + bmp->bitmap.bmBits = NULL; + bmp->DDBitmap = NULL; + bmp->dib = NULL; + hBitmap = BITMAPOBJ_PtrToHandle (bmp); + if (Bits) /* Set bitmap bits */ + { + W32kSetBitmapBits(hBitmap, + Height * bmp->bitmap.bmWidthBytes, + Bits); + } + BITMAPOBJ_UnlockBitmap (hBitmap); + + return hBitmap; } HBITMAP W32kCreateCompatibleBitmap(HDC hDC, INT Width, INT Height) { - UNIMPLEMENTED; + HBITMAP hbmpRet; + PDC dc; + + hbmpRet = 0; + DPRINT("(%04x,%d,%d) = \n", hDC, Width, Height); + dc = DC_PtrToHandle (hDC); + if (!dc) + { + return 0; + } + if ((Width >= 0x10000) || (Height >= 0x10000)) + { + 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) + { + 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; } HBITMAP W32kCreateBitmapIndirect(CONST BITMAP *BM) { - UNIMPLEMENTED; + return W32kCreateBitmap (BM->bmWidth, + BM->bmHeight, + BM->bmPlanes, + BM->bmBitsPixel, + BM->bmBits); } HBITMAP W32kCreateDIBitmap(HDC hDC, @@ -86,10 +179,80 @@ BOOL W32kFloodFill(HDC hDC, } LONG W32kGetBitmapBits(HBITMAP hBitmap, - LONG Buffer, + LONG Count, LPVOID Bits) { - UNIMPLEMENTED; + 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 W32kGetBitmapDimensionEx(HBITMAP hBitmap, @@ -252,3 +415,35 @@ INT W32kStretchDIBits(HDC hDC, UNIMPLEMENTED; } +/* Internal Functions */ + +INT +BITMAP_GetWidthBytes (INT bmWidth, INT bpp) +{ + switch(bpp) + { + case 1: + return 2 * ((bmWidth+15) >> 4); + + case 24: + bmWidth *= 3; /* fall through */ + case 8: + return bmWidth + (bmWidth & 1); + + case 32: + return bmWidth * 4; + + case 16: + case 15: + return bmWidth * 2; + + case 4: + return 2 * ((bmWidth+3) >> 2); + + default: + UNIMPLEMENTED; + } + + return -1; +} + diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index aed682ffd5d..ee1f41b0257 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.c @@ -841,36 +841,6 @@ void DC_FreeDC(PDC DCToFree) ExFreePool(DCToFree); } -HDC DC_PtrToHandle(PDC pDC) -{ - /* FIXME: this should actually return a handle obtained from the pointer */ - return (HDC) pDC; -} - - -PDC DC_HandleToPtr(HDC hDC) -{ - /* FIXME: this should actually return a pointer obtained from the handle */ - if (((PDC)hDC)->header.wMagic != GO_DC_MAGIC) - { - return 0; - } - - return (PDC) hDC; -} - -BOOL DC_LockDC(HDC hDC) -{ - /* FIXME */ - return TRUE; -} - -BOOL DC_UnlockDC(HDC hDC) -{ - /* FIXME */ - return TRUE; -} - void DC_UpdateXforms(PDC dc) { diff --git a/reactos/subsys/win32k/objects/gdiobj.c b/reactos/subsys/win32k/objects/gdiobj.c index baab1847d85..3612d3b00cd 100644 --- a/reactos/subsys/win32k/objects/gdiobj.c +++ b/reactos/subsys/win32k/objects/gdiobj.c @@ -1,7 +1,7 @@ /* * GDIOBJ.C - GDI object manipulation routines * - * $Id: gdiobj.c,v 1.2 1999/09/10 21:17:07 rex Exp $ + * $Id: gdiobj.c,v 1.3 1999/10/29 01:58:20 rex Exp $ * */ @@ -29,3 +29,36 @@ PGDIOBJ GDIOBJ_AllocObject(WORD Size, WORD Magic) return NewObj; } +HGDIOBJ GDIOBJ_PtrToHandle (PGDIOBJ Obj, WORD Magic) +{ + if (((PGDIOBJHDR)Obj)->wMagic != Magic) + { + return 0; + } + + return (HGDIOBJ) Obj; +} + +PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic) +{ + /* FIXME: Lock object for duration */ + if (((PGDIOBJHDR)Obj)->wMagic != Magic) + { + return 0; + } + + return (PGDIOBJ) Obj; +} + +BOOL GDIOBJ_LockObject (HGDIOBJ Obj) +{ + /* FIXME: write this */ + return TRUE; +} + +BOOL GDIOBJ_UnlockObject (HGDIOBJ Obj) +{ + /* FIXME: write this */ + return TRUE; +} +