diff --git a/graphics/metafiledrv/init.c b/graphics/metafiledrv/init.c index 38695205aa8..9287b5f3621 100644 --- a/graphics/metafiledrv/init.c +++ b/graphics/metafiledrv/init.c @@ -17,7 +17,9 @@ static const DC_FUNCTIONS MFDRV_Funcs = { MFDRV_Arc, /* pArc */ MFDRV_BitBlt, /* pBitBlt */ + NULL, /* pBitmapBits */ MFDRV_Chord, /* pChord */ + NULL, /* pCreateBitmap */ NULL, /* no implementation */ /* pCreateDC */ NULL, /* no implementation */ /* pDeleteDC */ NULL, /* pDeleteObject */ diff --git a/graphics/psdrv/init.c b/graphics/psdrv/init.c index 55d4d81ff9b..6e42e9b4949 100644 --- a/graphics/psdrv/init.c +++ b/graphics/psdrv/init.c @@ -22,7 +22,9 @@ static const DC_FUNCTIONS PSDRV_Funcs = { PSDRV_Arc, /* pArc */ NULL, /* pBitBlt */ + NULL, /* pBitmapBits */ PSDRV_Chord, /* pChord */ + NULL, /* pCreateBitmap */ PSDRV_CreateDC, /* pCreateDC */ PSDRV_DeleteDC, /* pDeleteDC */ NULL, /* pDeleteObject */ diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c index d389b98ef57..e119cfb31d5 100644 --- a/graphics/win16drv/init.c +++ b/graphics/win16drv/init.c @@ -51,7 +51,9 @@ static const DC_FUNCTIONS WIN16DRV_Funcs = { NULL, /* pArc */ NULL, /* pBitBlt */ + NULL, /* pBitmapBits */ NULL, /* pChord */ + NULL, /* pCreateBitmap */ WIN16DRV_CreateDC, /* pCreateDC */ NULL, /* pDeleteDC */ NULL, /* pDeleteObject */ diff --git a/graphics/x11drv/bitmap.c b/graphics/x11drv/bitmap.c index 96694579dee..128a32e72e5 100644 --- a/graphics/x11drv/bitmap.c +++ b/graphics/x11drv/bitmap.c @@ -1,5 +1,5 @@ /* - * GDI bitmap objects + * X11DRV bitmap objects * * Copyright 1993 Alexandre Julliard */ @@ -14,6 +14,24 @@ #include "bitmap.h" #include "heap.h" #include "debug.h" +#include "xmalloc.h" +#include "x11drv.h" + +#ifdef PRELIMINARY_WING16_SUPPORT +#include +#include +#include +#endif + + + /* GCs used for B&W and color bitmap operations */ +GC BITMAP_monoGC = 0, BITMAP_colorGC = 0; + + +#define BITMAP_WIDTH_BYTES(width,bpp) \ + (((bpp) == 24) ? (width) * 4 : ( ((bpp) == 15) ? (width) * 2 : \ + ((width) * (bpp) + 15) / 16 * 2 )) + /*********************************************************************** * X11DRV_BITMAP_Init @@ -51,9 +69,21 @@ HBITMAP32 X11DRV_BITMAP_SelectObject( DC * dc, HBITMAP32 hbitmap, { HRGN32 hrgn; HBITMAP32 prevHandle = dc->w.hBitmap; - + X11DRV_PHYSBITMAP *pbitmap; + if (!(dc->w.flags & DC_MEMORY)) return 0; + if(!bmp->DDBitmap) + if(!X11DRV_CreateBitmap(hbitmap)) + return 0; + + if(bmp->DDBitmap->funcs != dc->funcs) { + WARN(bitmap, "Trying to select non-X11 DDB into an X11 dc\n"); + return 0; + } + + pbitmap = bmp->DDBitmap->physBitmap; + dc->w.totalExtent.left = 0; dc->w.totalExtent.top = 0; dc->w.totalExtent.right = bmp->bitmap.bmWidth; @@ -69,7 +99,7 @@ HBITMAP32 X11DRV_BITMAP_SelectObject( DC * dc, HBITMAP32 hbitmap, dc->w.hVisRgn = hrgn; } - dc->u.x.drawable = bmp->pixmap; + dc->u.x.drawable = pbitmap->pixmap; dc->w.hBitmap = hbitmap; /* Change GC depth if needed */ @@ -84,3 +114,422 @@ HBITMAP32 X11DRV_BITMAP_SelectObject( DC * dc, HBITMAP32 hbitmap, else CLIPPING_UpdateGCRegion( dc ); /* Just update GC clip region */ return prevHandle; } + + +/*********************************************************************** + * XPutImage_wrapper + * + * Wrapper to call XPutImage with CALL_LARGE_STACK. + */ + +struct XPutImage_descr +{ + BITMAPOBJ *bmp; + XImage *image; + INT32 width; + INT32 height; +}; + +static int XPutImage_wrapper( const struct XPutImage_descr *descr ) +{ + return XPutImage( display, + ((X11DRV_PHYSBITMAP *)descr->bmp->DDBitmap->physBitmap)->pixmap, + BITMAP_GC(descr->bmp), + descr->image, 0, 0, 0, 0, descr->width, descr->height ); +} + + +/*************************************************************************** + * + * X11DRV_AllocBitmap + * + * Allocate DDBitmap and physBitmap + * + */ +X11DRV_PHYSBITMAP *X11DRV_AllocBitmap( BITMAPOBJ *bmp ) +{ + X11DRV_PHYSBITMAP *pbitmap; + + if(!(bmp->DDBitmap = HeapAlloc(GetProcessHeap(), 0, sizeof(DDBITMAP)))) { + WARN(bitmap, "Can't alloc DDBITMAP\n"); + return NULL; + } + + if(!(pbitmap = HeapAlloc(GetProcessHeap(), 0,sizeof(X11DRV_PHYSBITMAP)))) { + WARN(bitmap, "Can't alloc X11DRV_PHYSBITMAP\n"); + HeapFree(GetProcessHeap(), 0, bmp->DDBitmap); + return NULL; + } + + bmp->DDBitmap->physBitmap = pbitmap; + bmp->DDBitmap->funcs = DRIVER_FindDriver( "DISPLAY" ); + + return pbitmap; +} + + +/**************************************************************************** + * + * X11DRV_CreateBitmap + * + * Create a device dependent X11 bitmap + * + * Returns TRUE on success else FALSE + * + */ + +BOOL32 X11DRV_CreateBitmap( HBITMAP32 hbitmap ) +{ + X11DRV_PHYSBITMAP *pbitmap; + BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); + + if(!bmp) { + WARN(bitmap, "Bad bitmap handle %08x\n", hbitmap); + return FALSE; + } + + /* Check parameters */ + if (bmp->bitmap.bmPlanes != 1) return 0; + if ((bmp->bitmap.bmBitsPixel != 1) && + (bmp->bitmap.bmBitsPixel != screenDepth)) { + GDI_HEAP_UNLOCK( hbitmap ); + return FALSE; + } + + pbitmap = X11DRV_AllocBitmap( bmp ); + if(!pbitmap) return FALSE; + + /* Create the pixmap */ + pbitmap->pixmap = TSXCreatePixmap(display, rootWindow, bmp->bitmap.bmWidth, + bmp->bitmap.bmHeight, bmp->bitmap.bmBitsPixel); + if (!pbitmap->pixmap) { + WARN(bitmap, "Can't create Pixmap\n"); + HeapFree(GetProcessHeap(), 0, bmp->DDBitmap->physBitmap); + HeapFree(GetProcessHeap(), 0, bmp->DDBitmap); + GDI_HEAP_UNLOCK( hbitmap ); + return FALSE; + } + + if (bmp->bitmap.bmBits) /* Set bitmap bits */ + X11DRV_BitmapBits( hbitmap, bmp->bitmap.bmBits, + bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes, + DDB_SET ); + + GDI_HEAP_UNLOCK( hbitmap ); + return TRUE; +} + + +/*********************************************************************** + * X11DRV_BITMAP_GetXImage + * + * Get an X image for a bitmap. For use with CALL_LARGE_STACK. + */ +XImage *X11DRV_BITMAP_GetXImage( const BITMAPOBJ *bmp ) +{ + return XGetImage( display, + ((X11DRV_PHYSBITMAP *)bmp->DDBitmap->physBitmap)->pixmap, + 0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, + AllPlanes, ZPixmap ); +} + + +/*********************************************************************** + * X11DRV_GetBitmapBits + * + * RETURNS + * Success: Number of bytes copied + * Failure: 0 + */ +static LONG X11DRV_GetBitmapBits(BITMAPOBJ *bmp, void *buffer, LONG count) +{ + LONG old_height, height; + XImage *image; + LPBYTE tbuf; + int h, w, pad; + + pad = BITMAP_GetBitsPadding(bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel); + + if (pad == -1) + return 0; + + EnterCriticalSection( &X11DRV_CritSection ); + + /* Hack: change the bitmap height temporarily to avoid */ + /* getting unnecessary bitmap rows. */ + + old_height = bmp->bitmap.bmHeight; + height = bmp->bitmap.bmHeight = count / bmp->bitmap.bmWidthBytes; + + image = (XImage *)CALL_LARGE_STACK( X11DRV_BITMAP_GetXImage, bmp ); + + bmp->bitmap.bmHeight = old_height; + + /* copy XImage to 16 bit padded image buffer with real bitsperpixel */ + + tbuf = buffer; + switch (bmp->bitmap.bmBitsPixel) + { + case 1: + for (h=0;hbitmap.bmWidth;w++) + { + if ((w%8) == 0) + *tbuf = 0; + *tbuf |= XGetPixel(image,w,h)<<(7-(w&7)); + if ((w&7) == 7) ++tbuf; + } + tbuf += pad; + } + break; + case 4: + for (h=0;hbitmap.bmWidth;w++) + { + if (!(w & 1)) *tbuf = XGetPixel( image, w, h) << 4; + else *tbuf++ |= XGetPixel( image, w, h) & 0x0f; + } + tbuf += pad; + } + break; + case 8: + for (h=0;hbitmap.bmWidth;w++) + *tbuf++ = XGetPixel(image,w,h); + tbuf += pad; + } + break; + case 15: + case 16: + for (h=0;hbitmap.bmWidth;w++) + { + long pixel = XGetPixel(image,w,h); + + *tbuf++ = pixel & 0xff; + *tbuf++ = (pixel>>8) & 0xff; + } + } + break; + case 24: + for (h=0;hbitmap.bmWidth;w++) + { + long pixel = XGetPixel(image,w,h); + + *tbuf++ = pixel & 0xff; + *tbuf++ = (pixel>> 8) & 0xff; + *tbuf++ = (pixel>>16) & 0xff; + } + tbuf += pad; + } + break; + + case 32: + for (h=0;hbitmap.bmWidth;w++) + { + long pixel = XGetPixel(image,w,h); + + *tbuf++ = pixel & 0xff; + *tbuf++ = (pixel>> 8) & 0xff; + *tbuf++ = (pixel>>16) & 0xff; + *tbuf++ = (pixel>>24) & 0xff; + } + tbuf += pad; + } + break; + default: + FIXME(bitmap, "Unhandled bits:%d\n", bmp->bitmap.bmBitsPixel); + } + XDestroyImage( image ); + LeaveCriticalSection( &X11DRV_CritSection ); + + return count; +} + + + +/****************************************************************************** + * X11DRV_SetBitmapBits + * + * RETURNS + * Success: Number of bytes used in setting the bitmap bits + * Failure: 0 + */ +static LONG X11DRV_SetBitmapBits(BITMAPOBJ *bmp, void *bits, LONG count) +{ + struct XPutImage_descr descr; + LONG height; + XImage *image; + LPBYTE sbuf, tmpbuffer; + int w, h, pad, widthbytes; + + pad = BITMAP_GetBitsPadding(bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel); + + if (pad == -1) + return 0; + + sbuf = (LPBYTE)bits; + + widthbytes = (((bmp->bitmap.bmWidth * bmp->bitmap.bmBitsPixel) + 31) / + 32) * 4; + height = bmp->bitmap.bmHeight; + tmpbuffer = (LPBYTE)xmalloc(widthbytes*height); + + EnterCriticalSection( &X11DRV_CritSection ); + image = XCreateImage( display, DefaultVisualOfScreen(screen), + bmp->bitmap.bmBitsPixel, ZPixmap, 0, tmpbuffer, + bmp->bitmap.bmWidth,height,32,widthbytes ); + + /* copy 16 bit padded image buffer with real bitsperpixel to XImage */ + sbuf = (LPBYTE)bits; + switch (bmp->bitmap.bmBitsPixel) + { + case 1: + for (h=0;hbitmap.bmWidth;w++) + { + XPutPixel(image,w,h,(sbuf[0]>>(7-(w&7))) & 1); + if ((w&7) == 7) + sbuf++; + } + sbuf += pad; + } + break; + case 4: + for (h=0;hbitmap.bmWidth;w++) + { + if (!(w & 1)) XPutPixel( image, w, h, *sbuf >> 4 ); + else XPutPixel( image, w, h, *sbuf++ & 0xf ); + } + sbuf += pad; + } + break; + case 8: + for (h=0;hbitmap.bmWidth;w++) + XPutPixel(image,w,h,*sbuf++); + sbuf += pad; + } + break; + case 15: + case 16: + for (h=0;hbitmap.bmWidth;w++) + { + XPutPixel(image,w,h,sbuf[1]*256+sbuf[0]); + sbuf+=2; + } + } + break; + case 24: + for (h=0;hbitmap.bmWidth;w++) + { + XPutPixel(image,w,h,(sbuf[2]<<16)+(sbuf[1]<<8)+sbuf[0]); + sbuf += 3; + } + sbuf += pad; + } + break; + case 32: + for (h=0;hbitmap.bmWidth;w++) + { + XPutPixel(image,w,h,(sbuf[3]<<24)+(sbuf[2]<<16)+(sbuf[1]<<8)+sbuf[0]); + sbuf += 4; + } + sbuf += pad; + } + break; + default: + FIXME(bitmap, "Unhandled bits:%d\n", bmp->bitmap.bmBitsPixel); + + } + + descr.bmp = bmp; + descr.image = image; + descr.width = bmp->bitmap.bmWidth; + descr.height = height; + CALL_LARGE_STACK( XPutImage_wrapper, &descr ); + XDestroyImage( image ); /* frees tmpbuffer too */ + LeaveCriticalSection( &X11DRV_CritSection ); + + return count; +} + +/*********************************************************************** + * X11DRV_BitmapBits + */ +LONG X11DRV_BitmapBits(HBITMAP32 hbitmap, void *bits, LONG count, WORD flags) +{ + BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); + LONG ret; + if(!bmp) { + WARN(bitmap, "Bad bitmap handle %08x\n", hbitmap); + return FALSE; + } + + if(flags == DDB_GET) + ret = X11DRV_GetBitmapBits(bmp, bits, count); + else if(flags == DDB_SET) + ret = X11DRV_SetBitmapBits(bmp, bits, count); + else { + ERR(bitmap, "Unknown flags value %d\n", flags); + ret = 0; + } + + GDI_HEAP_UNLOCK( hbitmap ); + return ret; +} + +/*********************************************************************** + * X11DRV_BITMAP_DeleteObject + */ +BOOL32 X11DRV_BITMAP_DeleteObject( HBITMAP32 hbitmap, BITMAPOBJ * bmp ) +{ + X11DRV_PHYSBITMAP *pbitmap = bmp->DDBitmap->physBitmap; + +#ifdef PRELIMINARY_WING16_SUPPORT + if( bmp->bitmap.bmBits ) + TSXShmDetach( display, (XShmSegmentInfo*)bmp->bitmap.bmBits ); +#endif + + TSXFreePixmap( display, pbitmap->pixmap ); + + +#ifdef PRELIMINARY_WING16_SUPPORT + if( bmp->bitmap.bmBits ) + { + __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits; + WORD sel = HIWORD(p->bits); + unsigned long l, limit = GetSelectorLimit(sel); + + for( l = 0; l < limit; l += 0x10000, sel += __AHINCR ) + FreeSelector(sel); + shmctl(p->si.shmid, IPC_RMID, NULL); + shmdt(p->si.shmaddr); /* already marked for destruction */ + } +#endif + + HeapFree( GetProcessHeap(), 0, bmp->DDBitmap->physBitmap ); + HeapFree( GetProcessHeap(), 0, bmp->DDBitmap ); + bmp->DDBitmap = NULL; + + return TRUE; +} diff --git a/graphics/x11drv/brush.c b/graphics/x11drv/brush.c index 786d8b2ee63..1d25c916009 100644 --- a/graphics/x11drv/brush.c +++ b/graphics/x11drv/brush.c @@ -163,22 +163,34 @@ static void BRUSH_SelectSolidBrush( DC *dc, COLORREF color ) */ static BOOL32 BRUSH_SelectPatternBrush( DC * dc, HBITMAP32 hbitmap ) { + X11DRV_PHYSBITMAP *pbitmap; BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); if (!bmp) return FALSE; + if(!bmp->DDBitmap) + if(!X11DRV_CreateBitmap(hbitmap)) + return 0; + + if(bmp->DDBitmap->funcs != dc->funcs) { + WARN(bitmap, "Trying to select non-X11 DDB into an X11 dc\n"); + return 0; + } + + pbitmap = bmp->DDBitmap->physBitmap; + if ((dc->w.bitsPerPixel == 1) && (bmp->bitmap.bmBitsPixel != 1)) { /* Special case: a color pattern on a monochrome DC */ dc->u.x.brush.pixmap = TSXCreatePixmap( display, rootWindow, 8, 8, 1 ); /* FIXME: should probably convert to monochrome instead */ - TSXCopyPlane( display, bmp->pixmap, dc->u.x.brush.pixmap, + TSXCopyPlane( display, pbitmap->pixmap, dc->u.x.brush.pixmap, BITMAP_monoGC, 0, 0, 8, 8, 0, 0, 1 ); } else { dc->u.x.brush.pixmap = TSXCreatePixmap( display, rootWindow, 8, 8, bmp->bitmap.bmBitsPixel ); - TSXCopyArea( display, bmp->pixmap, dc->u.x.brush.pixmap, + TSXCopyArea( display, pbitmap->pixmap, dc->u.x.brush.pixmap, BITMAP_GC(bmp), 0, 0, 8, 8, 0, 0 ); } diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c index 5b2ad9e6309..0a395b03f7a 100644 --- a/graphics/x11drv/init.c +++ b/graphics/x11drv/init.c @@ -21,10 +21,12 @@ static const DC_FUNCTIONS X11DRV_Funcs = { X11DRV_Arc, /* pArc */ X11DRV_BitBlt, /* pBitBlt */ + X11DRV_BitmapBits, /* pBitmapBits */ X11DRV_Chord, /* pChord */ + X11DRV_CreateBitmap, /* pCreateBitmap */ X11DRV_CreateDC, /* pCreateDC */ X11DRV_DeleteDC, /* pDeleteDC */ - NULL, /* pDeleteObject */ + X11DRV_DeleteObject, /* pDeleteObject */ X11DRV_Ellipse, /* pEllipse */ X11DRV_EnumDeviceFonts, /* pEnumDeviceFonts */ X11DRV_Escape, /* pEscape */ @@ -173,10 +175,13 @@ static BOOL32 X11DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device, dc->w.devCaps = &X11DRV_DevCaps; if (dc->w.flags & DC_MEMORY) { + X11DRV_PHYSBITMAP *pbitmap; BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( dc->w.hBitmap, BITMAP_MAGIC ); - physDev->drawable = bmp->pixmap; - physDev->gc = TSXCreateGC( display, physDev->drawable, 0, NULL ); + X11DRV_CreateBitmap( dc->w.hBitmap ); + pbitmap = bmp->DDBitmap->physBitmap; + physDev->drawable = pbitmap->pixmap; + physDev->gc = TSXCreateGC(display, physDev->drawable, 0, NULL); dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel; dc->w.totalExtent.left = 0; diff --git a/graphics/x11drv/objects.c b/graphics/x11drv/objects.c index 8fc77bdce6a..a2a59767e2c 100644 --- a/graphics/x11drv/objects.c +++ b/graphics/x11drv/objects.c @@ -21,6 +21,7 @@ extern HFONT32 X11DRV_FONT_SelectObject( DC * dc, HFONT32 hfont, FONTOBJ * font ); extern HPEN32 X11DRV_PEN_SelectObject( DC * dc, HPEN32 hpen, PENOBJ * pen ); +extern BOOL32 X11DRV_BITMAP_DeleteObject( HBITMAP32 hbitmap, BITMAPOBJ *bmp ); /*********************************************************************** * X11DRV_SelectObject @@ -54,3 +55,28 @@ HGDIOBJ32 X11DRV_SelectObject( DC *dc, HGDIOBJ32 handle ) GDI_HEAP_UNLOCK( handle ); return ret; } + + +/*********************************************************************** + * X11DRV_DeleteObject + */ +BOOL32 X11DRV_DeleteObject( HGDIOBJ32 handle ) +{ + GDIOBJHDR *ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ); + BOOL32 ret = 0; + + if (!ptr) return FALSE; + + switch(ptr->wMagic) { + case BITMAP_MAGIC: + ret = X11DRV_BITMAP_DeleteObject( handle, (BITMAPOBJ *)ptr ); + break; + + default: + ERR(gdi, "Shouldn't be here!\n"); + ret = FALSE; + break; + } + GDI_HEAP_UNLOCK( handle ); + return ret; +} diff --git a/include/bitmap.h b/include/bitmap.h index 8afe1288c1f..aa07e6644e7 100644 --- a/include/bitmap.h +++ b/include/bitmap.h @@ -8,19 +8,6 @@ #define __WINE_BITMAP_H #include "gdi.h" -#include "xmalloc.h" - -#ifdef PRELIMINARY_WING16_SUPPORT -/* FIXME: this doesn't belong here */ -#include "ts_xshm.h" - -typedef struct -{ - XShmSegmentInfo si; - SEGPTR bits; -} __ShmBitmapCtl; - -#endif /* Additional info for DIB section objects */ typedef struct @@ -40,52 +27,51 @@ typedef struct } DIBSECTIONOBJ; +/* Flags used for BitmapBits. We only use the first two at the moment */ + +#define DDB_SET 1 +#define DDB_GET 2 +#define DDB_COPY 4 +#define DDB_SETWITHFILLER 8 + +typedef struct { + const struct tagDC_FUNCS *funcs; /* DC function table */ + void *physBitmap; /* ptr to device specific data */ +} DDBITMAP; + /* GDI logical bitmap object */ -typedef struct +typedef struct tagBITMAPOBJ { GDIOBJHDR header; - BITMAP16 bitmap; - Pixmap pixmap; - SIZE16 size; /* For SetBitmapDimension() */ + BITMAP32 bitmap; + SIZE32 size; /* For SetBitmapDimension() */ + + DDBITMAP *DDBitmap; /* For device-independent bitmaps: */ DIBSECTIONOBJ *dib; } BITMAPOBJ; - /* GCs used for B&W and color bitmap operations */ -extern GC BITMAP_monoGC, BITMAP_colorGC; - -#define BITMAP_GC(bmp) \ - (((bmp)->bitmap.bmBitsPixel == 1) ? BITMAP_monoGC : BITMAP_colorGC) - #define BITMAP_WIDTH_BYTES(width,bpp) \ (((bpp) == 24) ? (width) * 4 : ( ((bpp) == 15) ? (width) * 2 : \ ((width) * (bpp) + 15) / 16 * 2 )) -#define XCREATEIMAGE(image,width,height,bpp) \ -{ \ - int width_bytes = DIB_GetXImageWidthBytes( (width), (bpp) ); \ - (image) = TSXCreateImage(display, DefaultVisualOfScreen(screen), \ - (bpp), ZPixmap, 0, xcalloc( (height)*width_bytes ),\ - (width), (height), 32, width_bytes ); \ -} - /* objects/bitmap.c */ -extern BOOL32 BITMAP_Init(void); extern INT16 BITMAP_GetObject16( BITMAPOBJ * bmp, INT16 count, LPVOID buffer ); extern INT32 BITMAP_GetObject32( BITMAPOBJ * bmp, INT32 count, LPVOID buffer ); extern BOOL32 BITMAP_DeleteObject( HBITMAP16 hbitmap, BITMAPOBJ * bitmap ); -extern XImage *BITMAP_GetXImage( const BITMAPOBJ *bmp ); extern INT32 BITMAP_GetBitsPadding( int width, int depth ); extern INT32 BITMAP_GetBitsWidth( int width, int depth ); extern HBITMAP32 BITMAP_LoadBitmap32W(HINSTANCE32 instance,LPCWSTR name, UINT32 loadflags); +extern HBITMAP32 BITMAP_CopyBitmap( HBITMAP32 hbitmap ); /* objects/dib.c */ extern int DIB_GetDIBWidthBytes( int width, int depth ); -extern int DIB_GetXImageWidthBytes( int width, int depth ); extern int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse ); +extern int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width, + int *height, WORD *bpp, WORD *compr ); extern void DIB_UpdateDIBSection( DC *dc, BOOL32 toDIB ); extern void DIB_DeleteDIBSection( BITMAPOBJ *bmp ); extern void DIB_SelectDIBSection( DC *dc, BITMAPOBJ *bmp ); diff --git a/include/gdi.h b/include/gdi.h index 21f0f062747..31d49f2575b 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -173,10 +173,12 @@ typedef struct tagDC_FUNCS { BOOL32 (*pArc)(DC*,INT32,INT32,INT32,INT32,INT32,INT32,INT32,INT32); BOOL32 (*pBitBlt)(DC*,INT32,INT32,INT32,INT32,DC*,INT32,INT32,DWORD); + LONG (*pBitmapBits)(HBITMAP32,void*,LONG,WORD); BOOL32 (*pChord)(DC*,INT32,INT32,INT32,INT32,INT32,INT32,INT32,INT32); + BOOL32 (*pCreateBitmap)(HBITMAP32); BOOL32 (*pCreateDC)(DC*,LPCSTR,LPCSTR,LPCSTR,const DEVMODE16*); BOOL32 (*pDeleteDC)(DC*); - BOOL32 (*pDeleteObject)(HGDIOBJ16); + BOOL32 (*pDeleteObject)(HGDIOBJ32); BOOL32 (*pEllipse)(DC*,INT32,INT32,INT32,INT32); BOOL32 (*pEnumDeviceFonts)(DC*,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM); INT32 (*pEscape)(DC*,INT32,INT32,SEGPTR,SEGPTR); diff --git a/include/x11drv.h b/include/x11drv.h index cb05e0d1971..de9b91cbb5e 100644 --- a/include/x11drv.h +++ b/include/x11drv.h @@ -9,6 +9,7 @@ #include "ts_xutil.h" #include "winbase.h" #include "windows.h" +#include "xmalloc.h" /* for XCREATEIMAGE macro */ /* X physical pen */ typedef struct @@ -47,6 +48,17 @@ typedef struct int textPixel; } X11DRV_PDEVICE; + +typedef struct { + Pixmap pixmap; +} X11DRV_PHYSBITMAP; + + /* GCs used for B&W and color bitmap operations */ +extern GC BITMAP_monoGC, BITMAP_colorGC; + +#define BITMAP_GC(bmp) \ + (((bmp)->bitmap.bmBitsPixel == 1) ? BITMAP_monoGC : BITMAP_colorGC) + typedef INT32 (*DEVICEFONTENUMPROC)(LPENUMLOGFONT16,LPNEWTEXTMETRIC16,UINT16,LPARAM); /* Wine driver X11 functions */ @@ -111,18 +123,45 @@ extern BOOL32 X11DRV_ExtFloodFill( struct tagDC *dc, INT32 x, INT32 y, extern BOOL32 X11DRV_ExtTextOut( struct tagDC *dc, INT32 x, INT32 y, UINT32 flags, const RECT32 *lprect, LPCSTR str, UINT32 count, const INT32 *lpDx ); - - +extern BOOL32 X11DRV_CreateBitmap( HBITMAP32 hbitmap ); +extern BOOL32 X11DRV_DeleteObject( HGDIOBJ32 handle ); +extern LONG X11DRV_BitmapBits( HBITMAP32 hbitmap, void *bits, LONG count, + WORD flags ); +extern INT32 X11DRV_SetDIBitsToDevice( struct tagDC *dc, INT32 xDest, + INT32 yDest, DWORD cx, DWORD cy, + INT32 xSrc, INT32 ySrc, + UINT32 startscan, UINT32 lines, + LPCVOID bits, const BITMAPINFO *info, + UINT32 coloruse ); +extern INT32 X11DRV_DeviceBitmapBits( struct tagDC *dc, HBITMAP32 hbitmap, + WORD fGet, UINT32 startscan, + UINT32 lines, LPSTR bits, + LPBITMAPINFO info, UINT32 coloruse ); /* X11 driver internal functions */ extern BOOL32 X11DRV_BITMAP_Init(void); extern BOOL32 X11DRV_BRUSH_Init(void); extern BOOL32 X11DRV_FONT_Init( struct tagDeviceCaps* ); +struct tagBITMAPOBJ; +extern XImage *X11DRV_BITMAP_GetXImage( const struct tagBITMAPOBJ *bmp ); +extern int X11DRV_DIB_GetXImageWidthBytes( int width, int depth ); +extern BOOL32 X11DRV_DIB_Init(void); +extern X11DRV_PHYSBITMAP *X11DRV_AllocBitmap( struct tagBITMAPOBJ *bmp ); + /* Xlib critical section */ extern CRITICAL_SECTION X11DRV_CritSection; extern void _XInitImageFuncPtrs(XImage *); +#define XCREATEIMAGE(image,width,height,bpp) \ +{ \ + int width_bytes = X11DRV_DIB_GetXImageWidthBytes( (width), (bpp) ); \ + (image) = TSXCreateImage(display, DefaultVisualOfScreen(screen), \ + (bpp), ZPixmap, 0, xcalloc( (height)*width_bytes ),\ + (width), (height), 32, width_bytes ); \ +} + #endif /* __WINE_X11DRV_H */ + diff --git a/objects/bitmap.c b/objects/bitmap.c index f3a77e49e6a..2aa3b3f289b 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c @@ -2,51 +2,21 @@ * GDI bitmap objects * * Copyright 1993 Alexandre Julliard + * 1998 Huw D M Davies */ #include #include -#include "ts_xlib.h" -#include "ts_xutil.h" #include "gdi.h" -#include "callback.h" #include "dc.h" #include "bitmap.h" #include "heap.h" #include "global.h" -#include "debug.h" #include "sysmetrics.h" #include "cursoricon.h" #include "color.h" +#include "debug.h" -#ifdef PRELIMINARY_WING16_SUPPORT -#include -#include -#include -#endif - - /* GCs used for B&W and color bitmap operations */ -GC BITMAP_monoGC = 0, BITMAP_colorGC = 0; - -/*********************************************************************** - * XPutImage_wrapper - * - * Wrapper to call XPutImage with CALL_LARGE_STACK. - */ - -struct XPutImage_descr -{ - BITMAPOBJ *bmp; - XImage *image; - INT32 width; - INT32 height; -}; - -static int XPutImage_wrapper( const struct XPutImage_descr *descr ) -{ - return XPutImage( display, descr->bmp->pixmap, BITMAP_GC(descr->bmp), - descr->image, 0, 0, 0, 0, descr->width, descr->height ); -} /*********************************************************************** * BITMAP_GetBitsPadding @@ -142,7 +112,6 @@ HBITMAP16 WINAPI CreateUserDiscardableBitmap16( WORD dummy, } - /*********************************************************************** * CreateBitmap16 (GDI.48) */ @@ -165,51 +134,51 @@ HBITMAP16 WINAPI CreateBitmap16( INT16 width, INT16 height, UINT16 planes, * * RETURNS * Success: Handle to bitmap - * Failure: NULL + * Failure: 0 */ HBITMAP32 WINAPI CreateBitmap32( INT32 width, INT32 height, UINT32 planes, UINT32 bpp, LPCVOID bits ) { - BITMAPOBJ * bmpObjPtr; + BITMAPOBJ *bmp; HBITMAP32 hbitmap; planes = (BYTE)planes; bpp = (BYTE)bpp; - TRACE(gdi, "%dx%d, %d colors\n", width, height, 1 << (planes*bpp) ); /* Check parameters */ - if (!height || !width || planes != 1) return 0; - if ((bpp != 1) && (bpp != screenDepth)) return 0; + if (!height || !width) return 0; + if (planes != 1) { + FIXME(bitmap, "planes = %d\n", planes); + return 0; + } if (height < 0) height = -height; if (width < 0) width = -width; /* Create the BITMAPOBJ */ hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC ); if (!hbitmap) return 0; - bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LOCK( hbitmap ); - bmpObjPtr->size.cx = 0; - bmpObjPtr->size.cy = 0; - bmpObjPtr->bitmap.bmType = 0; - bmpObjPtr->bitmap.bmWidth = (INT16)width; - bmpObjPtr->bitmap.bmHeight = (INT16)height; - bmpObjPtr->bitmap.bmPlanes = (BYTE)planes; - bmpObjPtr->bitmap.bmBitsPixel = (BYTE)bpp; - bmpObjPtr->bitmap.bmWidthBytes = (INT16)BITMAP_WIDTH_BYTES( width, bpp ); - bmpObjPtr->bitmap.bmBits = 0; + TRACE(bitmap, "%dx%d, %d colors returning %08x\n", width, height, + 1 << (planes*bpp), hbitmap); - bmpObjPtr->dib = NULL; + bmp = (BITMAPOBJ *) GDI_HEAP_LOCK( hbitmap ); - /* Create the pixmap */ - bmpObjPtr->pixmap = TSXCreatePixmap(display, rootWindow, width, height, bpp); - if (!bmpObjPtr->pixmap) - { - GDI_HEAP_FREE( hbitmap ); - hbitmap = 0; - } - else if (bits) /* Set bitmap bits */ - SetBitmapBits32( hbitmap, height * bmpObjPtr->bitmap.bmWidthBytes, + bmp->size.cx = 0; + bmp->size.cy = 0; + bmp->bitmap.bmType = 0; + bmp->bitmap.bmWidth = (INT16)width; + bmp->bitmap.bmHeight = (INT16)height; + bmp->bitmap.bmPlanes = (BYTE)planes; + bmp->bitmap.bmBitsPixel = (BYTE)bpp; + bmp->bitmap.bmWidthBytes = (INT16)BITMAP_WIDTH_BYTES( width, bpp ); + bmp->bitmap.bmBits = NULL; + + bmp->DDBitmap = NULL; + bmp->dib = NULL; + + if (bits) /* Set bitmap bits */ + SetBitmapBits32( hbitmap, height * bmp->bitmap.bmWidthBytes, bits ); GDI_HEAP_UNLOCK( hbitmap ); return hbitmap; @@ -235,23 +204,26 @@ HBITMAP16 WINAPI CreateCompatibleBitmap16(HDC16 hdc, INT16 width, INT16 height) * * RETURNS * Success: Handle to bitmap - * Failure: NULL + * Failure: 0 */ HBITMAP32 WINAPI CreateCompatibleBitmap32( HDC32 hdc, INT32 width, INT32 height) { HBITMAP32 hbmpRet = 0; DC *dc; - TRACE(gdi, "(%04x,%d,%d) = \n", hdc, width, height ); + TRACE(bitmap, "(%04x,%d,%d) = \n", hdc, width, height ); if (!(dc = DC_GetDCPtr( hdc ))) return 0; - if ((width >0x1000) || (height > 0x1000)) - { - FIXME(gdi,"got bad width %d or height %d, please look for reason\n", - width, height ); + if ((width >0x1000) || (height > 0x1000)) { + FIXME(bitmap,"got bad width %d or height %d, please look for reason\n", + width, height ); return 0; - } + } hbmpRet = CreateBitmap32( width, height, 1, dc->w.bitsPerPixel, NULL ); - TRACE(gdi,"\t\t%04x\n", hbmpRet); + + if(dc->funcs->pCreateBitmap) + dc->funcs->pCreateBitmap( hbmpRet ); + + TRACE(bitmap,"\t\t%04x\n", hbmpRet); return hbmpRet; } @@ -281,18 +253,6 @@ HBITMAP32 WINAPI CreateBitmapIndirect32( } -/*********************************************************************** - * BITMAP_GetXImage - * - * Get an X image for a bitmap. For use with CALL_LARGE_STACK. - */ -XImage *BITMAP_GetXImage( const BITMAPOBJ *bmp ) -{ - return XGetImage( display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth, - bmp->bitmap.bmHeight, AllPlanes, ZPixmap ); -} - - /*********************************************************************** * GetBitmapBits16 (GDI.74) */ @@ -312,136 +272,52 @@ LONG WINAPI GetBitmapBits16( HBITMAP16 hbitmap, LONG count, LPVOID buffer ) LONG WINAPI GetBitmapBits32( HBITMAP32 hbitmap, /* [in] Handle to bitmap */ LONG count, /* [in] Number of bytes to copy */ - LPVOID buffer) /* [out] Pointer to buffer to receive bits */ + LPVOID bits) /* [out] Pointer to buffer to receive bits */ { - BITMAPOBJ * bmp; - LONG height, old_height; - XImage * image; - LPBYTE tbuf; - int h,w,pad; + BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); + LONG height, ret; - /* KLUDGE! */ + if (!bmp) return 0; + if (count < 0) { WARN(bitmap, "(%ld): Negative number of bytes passed???\n", count ); count = -count; } - bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); - if (!bmp) return 0; - /* Only get entire lines */ + /* Only get entire lines */ height = count / bmp->bitmap.bmWidthBytes; if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight; + count = height * bmp->bitmap.bmWidthBytes; - TRACE(bitmap, "%dx%d %d colors %p fetched height: %ld\n", - bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, - 1 << bmp->bitmap.bmBitsPixel, buffer, height ); + TRACE(bitmap, "(%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 ); - pad = BITMAP_GetBitsPadding( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel ); + if(bmp->DDBitmap) { - if (!height || (pad == -1)) - { - GDI_HEAP_UNLOCK( hbitmap ); - return 0; - } + TRACE(bitmap, "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; + } - EnterCriticalSection( &X11DRV_CritSection ); + } else { - /* Hack: change the bitmap height temporarily to avoid */ - /* getting unnecessary bitmap rows. */ - old_height = bmp->bitmap.bmHeight; - bmp->bitmap.bmHeight = height; - image = (XImage *)CALL_LARGE_STACK( BITMAP_GetXImage, bmp ); - bmp->bitmap.bmHeight = old_height; - - /* copy XImage to 16 bit padded image buffer with real bitsperpixel */ - - tbuf = buffer; - switch (bmp->bitmap.bmBitsPixel) - { - case 1: - for (h=0;hbitmap.bmWidth;w++) - { - if ((w%8) == 0) - *tbuf = 0; - *tbuf |= XGetPixel(image,w,h)<<(7-(w&7)); - if ((w&7) == 7) ++tbuf; - } - tbuf += pad; - } - break; - case 4: - for (h=0;hbitmap.bmWidth;w++) - { - if (!(w & 1)) *tbuf = XGetPixel( image, w, h) << 4; - else *tbuf++ |= XGetPixel( image, w, h) & 0x0f; - } - tbuf += pad; - } - break; - case 8: - for (h=0;hbitmap.bmWidth;w++) - *tbuf++ = XGetPixel(image,w,h); - tbuf += pad; - } - break; - case 15: - case 16: - for (h=0;hbitmap.bmWidth;w++) - { - long pixel = XGetPixel(image,w,h); - - *tbuf++ = pixel & 0xff; - *tbuf++ = (pixel>>8) & 0xff; - } - } - break; - case 24: - for (h=0;hbitmap.bmWidth;w++) - { - long pixel = XGetPixel(image,w,h); - - *tbuf++ = pixel & 0xff; - *tbuf++ = (pixel>> 8) & 0xff; - *tbuf++ = (pixel>>16) & 0xff; - } - tbuf += pad; + if(!bmp->bitmap.bmBits) { + WARN(bitmap, "Bitmap is empty\n"); + ret = 0; + } else { + memcpy(bits, bmp->bitmap.bmBits, count); + ret = count; } - break; - case 32: - for (h=0;hbitmap.bmWidth;w++) - { - long pixel = XGetPixel(image,w,h); - - *tbuf++ = pixel & 0xff; - *tbuf++ = (pixel>> 8) & 0xff; - *tbuf++ = (pixel>>16) & 0xff; - *tbuf++ = (pixel>>24) & 0xff; - } - tbuf += pad; - } - break; - default: - FIXME(bitmap, "Unhandled bits:%d\n", bmp->bitmap.bmBitsPixel); } - XDestroyImage( image ); - LeaveCriticalSection( &X11DRV_CritSection ); GDI_HEAP_UNLOCK( hbitmap ); - return height * bmp->bitmap.bmWidthBytes; + return ret; } @@ -464,132 +340,53 @@ LONG WINAPI SetBitmapBits16( HBITMAP16 hbitmap, LONG count, LPCVOID buffer ) LONG WINAPI SetBitmapBits32( HBITMAP32 hbitmap, /* [in] Handle to bitmap */ LONG count, /* [in] Number of bytes in bitmap array */ - LPCVOID buffer) /* [in] Address of array with bitmap bits */ + LPCVOID bits) /* [in] Address of array with bitmap bits */ { - struct XPutImage_descr descr; - BITMAPOBJ * bmp; - LONG height; - XImage * image; - LPBYTE sbuf,tmpbuffer; - int w,h,pad,widthbytes; + BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); + LONG height, ret; - /* KLUDGE! */ + if (!bmp) return 0; + if (count < 0) { WARN(bitmap, "(%ld): Negative number of bytes passed???\n", count ); count = -count; } - bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); - if (!bmp) return 0; - TRACE(bitmap, "%dx%d %d colors %p\n", - bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, - 1 << bmp->bitmap.bmBitsPixel, buffer ); - - /* Only set entire lines */ + /* Only get entire lines */ height = count / bmp->bitmap.bmWidthBytes; if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight; + count = height * bmp->bitmap.bmWidthBytes; - pad = BITMAP_GetBitsPadding( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel ); + TRACE(bitmap, "(%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 (!height || (pad == -1)) - { - GDI_HEAP_UNLOCK( hbitmap ); - return 0; - } + if(bmp->DDBitmap) { + + TRACE(bitmap, "Calling device specific BitmapBits\n"); + if(bmp->DDBitmap->funcs->pBitmapBits) + ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, (void *) bits, + count, DDB_SET); + else { + ERR(bitmap, "BitmapBits == NULL??\n"); + ret = 0; + } - sbuf = (LPBYTE)buffer; - - widthbytes = DIB_GetXImageWidthBytes(bmp->bitmap.bmWidth,bmp->bitmap.bmBitsPixel); - tmpbuffer = (LPBYTE)xmalloc(widthbytes*height); - - EnterCriticalSection( &X11DRV_CritSection ); - image = XCreateImage( display, DefaultVisualOfScreen(screen), - bmp->bitmap.bmBitsPixel, ZPixmap, 0, tmpbuffer, - bmp->bitmap.bmWidth,height,32,widthbytes ); - - /* copy 16 bit padded image buffer with real bitsperpixel to XImage */ - sbuf = (LPBYTE)buffer; - switch (bmp->bitmap.bmBitsPixel) - { - case 1: - for (h=0;hbitmap.bmWidth;w++) - { - XPutPixel(image,w,h,(sbuf[0]>>(7-(w&7))) & 1); - if ((w&7) == 7) - sbuf++; - } - sbuf += pad; - } - break; - case 4: - for (h=0;hbitmap.bmWidth;w++) - { - if (!(w & 1)) XPutPixel( image, w, h, *sbuf >> 4 ); - else XPutPixel( image, w, h, *sbuf++ & 0xf ); - } - sbuf += pad; - } - break; - case 8: - for (h=0;hbitmap.bmWidth;w++) - XPutPixel(image,w,h,*sbuf++); - sbuf += pad; - } - break; - case 15: - case 16: - for (h=0;hbitmap.bmWidth;w++) - { - XPutPixel(image,w,h,sbuf[1]*256+sbuf[0]); - sbuf+=2; - } - } - break; - case 24: - for (h=0;hbitmap.bmWidth;w++) - { - XPutPixel(image,w,h,(sbuf[2]<<16)+(sbuf[1]<<8)+sbuf[0]); - sbuf += 3; - } - sbuf += pad; - } - break; - case 32: - for (h=0;hbitmap.bmWidth;w++) - { - XPutPixel(image,w,h,(sbuf[3]<<24)+(sbuf[2]<<16)+(sbuf[1]<<8)+sbuf[0]); - sbuf += 4; - } - sbuf += pad; - } - break; - default: - FIXME(bitmap, "Unhandled bits:%d\n", bmp->bitmap.bmBitsPixel); + } else { + if(!bmp->bitmap.bmBits) /* Alloc enough for entire bitmap */ + bmp->bitmap.bmBits = HeapAlloc( GetProcessHeap(), 0, count ); + if(!bmp->bitmap.bmBits) { + WARN(bitmap, "Unable to allocate bit buffer\n"); + ret = 0; + } else { + memcpy(bmp->bitmap.bmBits, bits, count); + ret = count; + } } - descr.bmp = bmp; - descr.image = image; - descr.width = bmp->bitmap.bmWidth; - descr.height = height; - CALL_LARGE_STACK( XPutImage_wrapper, &descr ); - XDestroyImage( image ); /* frees tmpbuffer too */ - LeaveCriticalSection( &X11DRV_CritSection ); - GDI_HEAP_UNLOCK( hbitmap ); - return height * bmp->bitmap.bmWidthBytes; + return ret; } /*********************************************************************** @@ -691,22 +488,30 @@ HANDLE32 WINAPI LoadImage32W( HINSTANCE32 hinst, LPCWSTR name, UINT32 type, /********************************************************************** - * CopyBitmap32 (not an API) - * - * NOTES - * If it is not an API, why is it declared with WINAPI? + * BITMAP_CopyBitmap * */ -HBITMAP32 WINAPI CopyBitmap32 (HBITMAP32 hnd) +HBITMAP32 BITMAP_CopyBitmap(HBITMAP32 hbitmap) { + BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); HBITMAP32 res = 0; - BITMAP32 bmp; + BITMAP32 bm; - if (GetObject32A (hnd, sizeof (bmp), &bmp)) - { - res = CreateBitmapIndirect32 (&bmp); - SetBitmapBits32 (res, bmp.bmWidthBytes * bmp.bmHeight, bmp.bmBits); + if(!bmp) return 0; + + bm = bmp->bitmap; + bm.bmBits = NULL; + res = CreateBitmapIndirect32(&bm); + + if(res) { + char *buf = HeapAlloc( GetProcessHeap(), 0, bm.bmWidthBytes * + bm.bmHeight ); + GetBitmapBits32 (hbitmap, bm.bmWidthBytes * bm.bmHeight, buf); + SetBitmapBits32 (res, bm.bmWidthBytes * bm.bmHeight, buf); + HeapFree( GetProcessHeap(), 0, buf ); } + + GDI_HEAP_UNLOCK( hbitmap ); return res; } @@ -734,7 +539,7 @@ HICON32 WINAPI CopyImage32( HANDLE32 hnd, UINT32 type, INT32 desiredx, switch (type) { case IMAGE_BITMAP: - return CopyBitmap32(hnd); + return BITMAP_CopyBitmap(hnd); case IMAGE_ICON: return CopyIcon32(hnd); case IMAGE_CURSOR: @@ -879,25 +684,13 @@ HBITMAP32 WINAPI LoadBitmap32A( HINSTANCE32 instance, LPCSTR name ) */ BOOL32 BITMAP_DeleteObject( HBITMAP16 hbitmap, BITMAPOBJ * bmp ) { -#ifdef PRELIMINARY_WING16_SUPPORT - if( bmp->bitmap.bmBits ) - TSXShmDetach( display, (XShmSegmentInfo*)bmp->bitmap.bmBits ); -#endif - - TSXFreePixmap( display, bmp->pixmap ); -#ifdef PRELIMINARY_WING16_SUPPORT - if( bmp->bitmap.bmBits ) - { - __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits; - WORD sel = HIWORD(p->bits); - unsigned long l, limit = GetSelectorLimit(sel); - - for( l = 0; l < limit; l += 0x10000, sel += __AHINCR ) - FreeSelector(sel); - shmctl(p->si.shmid, IPC_RMID, NULL); - shmdt(p->si.shmaddr); /* already marked for destruction */ + if( bmp->DDBitmap ) { + if( bmp->DDBitmap->funcs->pDeleteObject ) + bmp->DDBitmap->funcs->pDeleteObject( hbitmap ); } -#endif + + if( bmp->bitmap.bmBits ) + HeapFree( GetProcessHeap(), 0, bmp->bitmap.bmBits ); DIB_DeleteDIBSection( bmp ); @@ -922,7 +715,7 @@ INT16 BITMAP_GetObject16( BITMAPOBJ * bmp, INT16 count, LPVOID buffer ) bmp16.bmWidthBytes = bmp32->bmWidthBytes; bmp16.bmPlanes = bmp32->bmPlanes; bmp16.bmBitsPixel = bmp32->bmBitsPixel; - bmp16.bmBits = NULL; + bmp16.bmBits = (SEGPTR)0; memcpy( buffer, &bmp16, count ); return count; } @@ -934,8 +727,16 @@ INT16 BITMAP_GetObject16( BITMAPOBJ * bmp, INT16 count, LPVOID buffer ) } else { - if (count > sizeof(bmp->bitmap)) count = sizeof(bmp->bitmap); - memcpy( buffer, &bmp->bitmap, count ); + BITMAP16 bmp16; + bmp16.bmType = bmp->bitmap.bmType; + bmp16.bmWidth = bmp->bitmap.bmWidth; + bmp16.bmHeight = bmp->bitmap.bmHeight; + bmp16.bmWidthBytes = bmp->bitmap.bmWidthBytes; + bmp16.bmPlanes = bmp->bitmap.bmPlanes; + bmp16.bmBitsPixel = bmp->bitmap.bmBitsPixel; + bmp16.bmBits = (SEGPTR)0; + if (count > sizeof(bmp16)) count = sizeof(bmp16); + memcpy( buffer, &bmp16, count ); return count; } } @@ -962,16 +763,8 @@ INT32 BITMAP_GetObject32( BITMAPOBJ * bmp, INT32 count, LPVOID buffer ) } else { - BITMAP32 bmp32; - bmp32.bmType = bmp->bitmap.bmType; - bmp32.bmWidth = bmp->bitmap.bmWidth; - bmp32.bmHeight = bmp->bitmap.bmHeight; - bmp32.bmWidthBytes = bmp->bitmap.bmWidthBytes; - bmp32.bmPlanes = bmp->bitmap.bmPlanes; - bmp32.bmBitsPixel = bmp->bitmap.bmBitsPixel; - bmp32.bmBits = NULL; - if (count > sizeof(bmp32)) count = sizeof(bmp32); - memcpy( buffer, &bmp32, count ); + if (count > sizeof(BITMAP32)) count = sizeof(BITMAP32); + memcpy( buffer, &bmp->bitmap, count ); return count; } } @@ -1013,7 +806,7 @@ BOOL16 WINAPI GetBitmapDimensionEx16( HBITMAP16 hbitmap, LPSIZE16 size ) { BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); if (!bmp) return FALSE; - *size = bmp->size; + CONV_SIZE32TO16( &bmp->size, size ); GDI_HEAP_UNLOCK( hbitmap ); return TRUE; } @@ -1032,8 +825,7 @@ BOOL32 WINAPI GetBitmapDimensionEx32( { BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); if (!bmp) return FALSE; - size->cx = (INT32)bmp->size.cx; - size->cy = (INT32)bmp->size.cy; + *size = bmp->size; GDI_HEAP_UNLOCK( hbitmap ); return TRUE; } @@ -1058,7 +850,7 @@ BOOL16 WINAPI SetBitmapDimensionEx16( HBITMAP16 hbitmap, INT16 x, INT16 y, { BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); if (!bmp) return FALSE; - if (prevSize) *prevSize = bmp->size; + if (prevSize) CONV_SIZE32TO16( &bmp->size, prevSize ); bmp->size.cx = x; bmp->size.cy = y; GDI_HEAP_UNLOCK( hbitmap ); @@ -1081,9 +873,9 @@ BOOL32 WINAPI SetBitmapDimensionEx32( { BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); if (!bmp) return FALSE; - if (prevSize) CONV_SIZE16TO32( &bmp->size, prevSize ); - bmp->size.cx = (INT16)x; - bmp->size.cy = (INT16)y; + if (prevSize) *prevSize = bmp->size; + bmp->size.cx = x; + bmp->size.cy = y; GDI_HEAP_UNLOCK( hbitmap ); return TRUE; } diff --git a/objects/brush.c b/objects/brush.c index 7add6d2351d..2bed5915cf3 100644 --- a/objects/brush.c +++ b/objects/brush.c @@ -85,27 +85,13 @@ HBRUSH16 WINAPI CreatePatternBrush16( HBITMAP16 hbitmap ) HBRUSH32 WINAPI CreatePatternBrush32( HBITMAP32 hbitmap ) { LOGBRUSH32 logbrush = { BS_PATTERN, 0, 0 }; - BITMAPOBJ *bmp, *newbmp; - TRACE(gdi, "%04x\n", hbitmap ); - /* Make a copy of the bitmap */ - - if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) - return 0; - logbrush.lbHatch = (INT32)CreateBitmapIndirect16( &bmp->bitmap ); - newbmp = (BITMAPOBJ *) GDI_GetObjPtr( (HGDIOBJ32)logbrush.lbHatch, - BITMAP_MAGIC ); - if (!newbmp) - { - GDI_HEAP_UNLOCK( hbitmap ); - return 0; - } - TSXCopyArea( display, bmp->pixmap, newbmp->pixmap, BITMAP_GC(bmp), - 0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, 0, 0 ); - GDI_HEAP_UNLOCK( hbitmap ); - GDI_HEAP_UNLOCK( logbrush.lbHatch ); - return CreateBrushIndirect32( &logbrush ); + logbrush.lbHatch = (INT32)BITMAP_CopyBitmap( hbitmap ); + if(!logbrush.lbHatch) + return 0; + else + return CreateBrushIndirect32( &logbrush ); } diff --git a/objects/dib.c b/objects/dib.c index 72cea4defcd..a746cf97267 100644 --- a/objects/dib.c +++ b/objects/dib.c @@ -67,7 +67,7 @@ BOOL32 DIB_Init(void) * * Return the width of an X image in bytes */ -int DIB_GetXImageWidthBytes( int width, int depth ) +int X11DRV_DIB_GetXImageWidthBytes( int width, int depth ) { int i; @@ -144,7 +144,7 @@ int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse ) * Get the info from a bitmap header. * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error. */ -static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width, +int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width, int *height, WORD *bpp, WORD *compr ) { if (header->biSize == sizeof(BITMAPINFOHEADER)) @@ -1282,11 +1282,18 @@ INT32 WINAPI SetDIBits32( HDC32 hdc, HBITMAP32 hbitmap, UINT32 startscan, } } + /* HACK for now */ + if(!bmp->DDBitmap) + X11DRV_CreateBitmap(hbitmap); +{ + X11DRV_PHYSBITMAP *pbitmap = bmp->DDBitmap->physBitmap; + + descr.bits = bits; descr.image = NULL; descr.lines = tmpheight >= 0 ? lines : -lines; descr.depth = bmp->bitmap.bmBitsPixel; - descr.drawable = bmp->pixmap; + descr.drawable = pbitmap->pixmap; descr.gc = BITMAP_GC(bmp); descr.xSrc = 0; descr.ySrc = 0; @@ -1294,7 +1301,7 @@ INT32 WINAPI SetDIBits32( HDC32 hdc, HBITMAP32 hbitmap, UINT32 startscan, descr.yDest = height - startscan - lines; descr.width = bmp->bitmap.bmWidth; descr.height = lines; - +} EnterCriticalSection( &X11DRV_CritSection ); result = CALL_LARGE_STACK( DIB_SetImageBits, &descr ); LeaveCriticalSection( &X11DRV_CritSection ); @@ -1598,8 +1605,12 @@ INT32 WINAPI GetDIBits32( xend = info->bmiHeader.biWidth; } + /* HACK for now */ + if(!bmp->DDBitmap) + X11DRV_CreateBitmap(hbitmap); + EnterCriticalSection( &X11DRV_CritSection ); - bmpImage = (XImage *)CALL_LARGE_STACK( BITMAP_GetXImage, bmp ); + bmpImage = (XImage *)CALL_LARGE_STACK( X11DRV_BITMAP_GetXImage, bmp ); switch( info->bmiHeader.biBitCount ) { @@ -1822,7 +1833,9 @@ static void DIB_DoUpdateDIBSection( BITMAPOBJ *bmp, BOOL32 toDIB ) descr.nColorMap = dib->nColorMap; descr.bits = dib->dibSection.dsBm.bmBits; descr.depth = bmp->bitmap.bmBitsPixel; - descr.drawable = bmp->pixmap; + + /* Hack for now */ + descr.drawable = ((X11DRV_PHYSBITMAP *)bmp->DDBitmap->physBitmap)->pixmap; descr.gc = BITMAP_GC(bmp); descr.xSrc = 0; descr.ySrc = 0; @@ -2062,6 +2075,10 @@ HBITMAP32 WINAPI CreateDIBSection32 (HDC32 hdc, BITMAPINFO *bmi, UINT32 usage, res = CreateDIBitmap32(hdc, bi, 0, NULL, bmi, usage); bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC); if (bmp) bmp->dib = dib; + + /* HACK for now */ + if(!bmp->DDBitmap) + X11DRV_CreateBitmap(res); } /* Create XImage */ diff --git a/objects/oembitmap.c b/objects/oembitmap.c index e9e9e9e72f4..d79b60f59af 100644 --- a/objects/oembitmap.c +++ b/objects/oembitmap.c @@ -319,6 +319,7 @@ static HBITMAP16 OBM_MakeBitmap( WORD width, WORD height, { HBITMAP16 hbitmap; BITMAPOBJ * bmpObjPtr; + X11DRV_PHYSBITMAP *pbitmap; if (!pixmap) return 0; @@ -328,16 +329,19 @@ static HBITMAP16 OBM_MakeBitmap( WORD width, WORD height, bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LOCK( hbitmap ); bmpObjPtr->size.cx = width; bmpObjPtr->size.cy = height; - bmpObjPtr->pixmap = pixmap; bmpObjPtr->bitmap.bmType = 0; bmpObjPtr->bitmap.bmWidth = width; bmpObjPtr->bitmap.bmHeight = height; bmpObjPtr->bitmap.bmWidthBytes = BITMAP_WIDTH_BYTES( width, bpp ); bmpObjPtr->bitmap.bmPlanes = 1; bmpObjPtr->bitmap.bmBitsPixel = bpp; - bmpObjPtr->bitmap.bmBits = (SEGPTR)NULL; + bmpObjPtr->bitmap.bmBits = NULL; bmpObjPtr->dib = NULL; + pbitmap = X11DRV_AllocBitmap(bmpObjPtr); + + pbitmap->pixmap = pixmap; + GDI_HEAP_UNLOCK( hbitmap ); return hbitmap; } @@ -493,10 +497,11 @@ HGLOBAL16 OBM_LoadCursorIcon( WORD id, BOOL32 fCursor ) if (descr.mask) { + X11DRV_PHYSBITMAP *pbitmapAnd = bmpAnd->DDBitmap->physBitmap; /* Invert the mask */ TSXSetFunction( display, BITMAP_monoGC, GXinvert ); - TSXFillRectangle( display, bmpAnd->pixmap, BITMAP_monoGC, 0, 0, + TSXFillRectangle( display, pbitmapAnd->pixmap, BITMAP_monoGC, 0, 0, bmpAnd->bitmap.bmWidth, bmpAnd->bitmap.bmHeight ); TSXSetFunction( display, BITMAP_monoGC, GXcopy ); @@ -504,11 +509,12 @@ HGLOBAL16 OBM_LoadCursorIcon( WORD id, BOOL32 fCursor ) if (bmpXor->bitmap.bmBitsPixel != 1) { + X11DRV_PHYSBITMAP *pbitmapXor = bmpXor->DDBitmap->physBitmap; TSXSetForeground( display, BITMAP_colorGC, COLOR_ToPhysical( NULL, RGB(0,0,0) )); TSXSetBackground( display, BITMAP_colorGC, 0 ); TSXSetFunction( display, BITMAP_colorGC, GXor ); - TSXCopyPlane(display, bmpAnd->pixmap, bmpXor->pixmap, BITMAP_colorGC, + TSXCopyPlane(display, pbitmapAnd->pixmap, pbitmapXor->pixmap, BITMAP_colorGC, 0, 0, bmpXor->bitmap.bmWidth, bmpXor->bitmap.bmHeight, 0, 0, 1 ); TSXSetFunction( display, BITMAP_colorGC, GXcopy ); diff --git a/windows/graphics.c b/windows/graphics.c index 2a1e9e20969..c949f466acc 100644 --- a/windows/graphics.c +++ b/windows/graphics.c @@ -71,6 +71,7 @@ BOOL32 GRAPH_DrawBitmap( HDC32 hdc, HBITMAP32 hbitmap, BITMAPOBJ *bmp; DC *dc; BOOL32 ret = TRUE; + X11DRV_PHYSBITMAP *pbitmap; if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE; if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) @@ -79,6 +80,8 @@ BOOL32 GRAPH_DrawBitmap( HDC32 hdc, HBITMAP32 hbitmap, return FALSE; } + pbitmap = bmp->DDBitmap->physBitmap; + xdest += dc->w.DCOrgX; ydest += dc->w.DCOrgY; TSXSetFunction( display, dc->u.x.gc, GXcopy ); @@ -86,7 +89,7 @@ BOOL32 GRAPH_DrawBitmap( HDC32 hdc, HBITMAP32 hbitmap, { TSXSetForeground( display, dc->u.x.gc, dc->u.x.backgroundPixel ); TSXSetBackground( display, dc->u.x.gc, dc->u.x.textPixel ); - TSXCopyPlane( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc, + TSXCopyPlane( display, pbitmap->pixmap, dc->u.x.drawable, dc->u.x.gc, xsrc, ysrc, width, height, xdest, ydest, 1 ); } else if (bmp->bitmap.bmBitsPixel == dc->w.bitsPerPixel) @@ -105,12 +108,12 @@ BOOL32 GRAPH_DrawBitmap( HDC32 hdc, HBITMAP32 hbitmap, TSXSetForeground(display, dc->u.x.gc, dc->u.x.textPixel); TSXSetBackground(display, dc->u.x.gc, dc->u.x.backgroundPixel); } - TSXCopyPlane( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc, + TSXCopyPlane( display, pbitmap->pixmap, dc->u.x.drawable, dc->u.x.gc, xsrc, ysrc, width, height, xdest, ydest, plane ); } else { - TSXCopyArea( display, bmp->pixmap, dc->u.x.drawable, + TSXCopyArea( display, pbitmap->pixmap, dc->u.x.drawable, dc->u.x.gc, xsrc, ysrc, width, height, xdest, ydest ); } } @@ -235,6 +238,7 @@ BOOL32 GRAPH_SelectClipMask( HDC32 hdc, HBITMAP32 hMonoBitmap, INT32 x, INT32 y) { BITMAPOBJ *bmp = NULL; DC *dc; + X11DRV_PHYSBITMAP *pbitmap = NULL; if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE; if ( hMonoBitmap ) @@ -245,10 +249,11 @@ BOOL32 GRAPH_SelectClipMask( HDC32 hdc, HBITMAP32 hMonoBitmap, INT32 x, INT32 y) GDI_HEAP_UNLOCK( hdc ); return FALSE; } + pbitmap = bmp->DDBitmap->physBitmap; TSXSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX + x, dc->w.DCOrgY + y); } - TSXSetClipMask( display, dc->u.x.gc, (bmp) ? bmp->pixmap : None ); + TSXSetClipMask( display, dc->u.x.gc, (bmp) ? pbitmap->pixmap : None ); GDI_HEAP_UNLOCK( hdc ); GDI_HEAP_UNLOCK( hMonoBitmap );