Commit d05b7beb authored by Noel Borthwick's avatar Noel Borthwick Committed by Alexandre Julliard

- Add clipboard support for copying/pasting bitmaps or Pixmaps between Wine

and native Linux applications. - Respond to the MULTIPLE selection request target when Wine is the selection owner. - Relax type checking for TARGETS selection.
parent f52e109d
......@@ -3418,6 +3418,114 @@ void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
}
/**************************************************************************
* X11DRV_DIB_CreateDIBFromPixmap
*
* Allocates a packed DIB and copies the Pixmap data into it.
* If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
*/
HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
{
HBITMAP hBmp = 0;
BITMAPOBJ *pBmp = NULL;
HGLOBAL hPackedDIB = NULL;
/* Allocates an HBITMAP which references the Pixmap passed to us */
hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
if (!hBmp)
{
TRACE_(bitmap)("\tCould not create bitmap header for Pixmap\n");
goto END;
}
/*
* Create a packed DIB from the Pixmap wrapper bitmap created above.
* A packed DIB contains a BITMAPINFO structure followed immediately by
* an optional color palette and the pixel data.
*/
hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
/* Get a pointer to the BITMAPOBJ structure */
pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
/* We can now get rid of the HBITMAP wrapper we created earlier.
* Note: Simply calling DeleteObject will free the embedded Pixmap as well.
*/
if (!bDeletePixmap)
{
/* Manually free the DDBitmap internals to prevent the Pixmap
* from being deleted by DeleteObject.
*/
HeapFree( GetProcessHeap(), 0, pBmp->DDBitmap->physBitmap );
HeapFree( GetProcessHeap(), 0, pBmp->DDBitmap );
pBmp->DDBitmap = NULL;
}
DeleteObject(hBmp);
END:
TRACE_(bitmap)("\tReturning packed DIB %x\n", hPackedDIB);
return hPackedDIB;
}
/**************************************************************************
* X11DRV_DIB_CreatePixmapFromDIB
*
* Creates a Pixmap from a packed DIB
*/
Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
{
Pixmap pixmap = NULL;
HBITMAP hBmp = 0;
BITMAPOBJ *pBmp = NULL;
LPBYTE pPackedDIB = NULL;
LPBITMAPINFO pbmi = NULL;
LPBITMAPINFOHEADER pbmiHeader = NULL;
LPBYTE pbits = NULL;
/* Get a pointer to the packed DIB's data */
pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
pbmi = (LPBITMAPINFO)pPackedDIB;
pbits = (LPBYTE)(pPackedDIB
+ DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
/* Create a DDB from the DIB */
hBmp = CreateDIBitmap(hdc,
pbmiHeader,
CBM_INIT,
(LPVOID)pbits,
pbmi,
DIB_RGB_COLORS);
GlobalUnlock(hPackedDIB);
TRACE_(bitmap)("CreateDIBitmap returned %x\n", hBmp);
/* Retrieve the internal Pixmap from the DDB */
pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
if (pBmp->DDBitmap && pBmp->DDBitmap->physBitmap)
{
pixmap = ((X11DRV_PHYSBITMAP *)(pBmp->DDBitmap->physBitmap))->pixmap;
if (!pixmap)
TRACE_(bitmap)("NULL Pixmap in DDBitmap->physBitmap!\n");
/* Manually free the BITMAPOBJ internals so that we can steal its pixmap */
HeapFree( GetProcessHeap(), 0, pBmp->DDBitmap->physBitmap );
HeapFree( GetProcessHeap(), 0, pBmp->DDBitmap );
pBmp->DDBitmap = NULL; /* Its not a DDB anymore */
}
/* Delete the DDB we created earlier now that we have stolen its pixmap */
DeleteObject(hBmp);
TRACE_(bitmap)("\tReturning Pixmap %ld\n", pixmap);
return pixmap;
}
#endif /* !defined(X_DISPLAY_MISSING) */
......
......@@ -62,7 +62,7 @@ extern int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
extern void DIB_UpdateDIBSection( DC *dc, BOOL toDIB );
extern void DIB_DeleteDIBSection( BITMAPOBJ *bmp );
extern void DIB_SelectDIBSection( DC *dc, BITMAPOBJ *bmp );
extern void DIB_FixColorsToLoadflags(BITMAPINFO * bmi, UINT loadflags,
BYTE pix);
extern void DIB_FixColorsToLoadflags(BITMAPINFO * bmi, UINT loadflags, BYTE pix);
extern HGLOBAL DIB_CreateDIBFromBitmap(HDC hdc, HBITMAP hBmp);
#endif /* __WINE_BITMAP_H */
......@@ -59,6 +59,7 @@ extern int TSXConvertSelection(Display*, Atom, Atom, Atom, Window, Time);
extern int TSXCopyArea(Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int);
extern int TSXCopyPlane(Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int, unsigned long);
extern int TSXDefineCursor(Display*, Window, Cursor);
extern int TSXDeleteProperty(Display*, Window, Atom);
extern int TSXDestroyWindow(Display*, Window);
extern int TSXDisplayKeycodes(Display*, int*, int*);
extern int TSXDrawArc(Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int);
......
......@@ -169,6 +169,11 @@ extern XImage *X11DRV_BITMAP_GetXImage( const struct tagBITMAPOBJ *bmp );
extern int X11DRV_DIB_GetXImageWidthBytes( int width, int depth );
extern BOOL X11DRV_DIB_Init(void);
extern X11DRV_PHYSBITMAP *X11DRV_AllocBitmap( struct tagBITMAPOBJ *bmp );
extern HBITMAP X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(Pixmap pixmap);
extern HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap);
extern HBITMAP X11DRV_BITMAP_CreateBitmapFromPixmap(Pixmap pixmap, BOOL bDeletePixmap);
extern Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc );
extern Pixmap X11DRV_BITMAP_CreatePixmapFromBitmap( HBITMAP hBmp, HDC hdc );
extern BOOL X11DRV_SetupGCForPatBlt( struct tagDC *dc, GC gc,
BOOL fMapColors );
......@@ -325,11 +330,15 @@ extern void X11DRV_USER_EndDebugging(void);
extern struct tagCLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver;
extern void X11DRV_CLIPBOARD_FreeResources( Atom property );
extern BOOL X11DRV_CLIPBOARD_RegisterPixmapResource( Atom property, Pixmap pixmap );
extern void X11DRV_CLIPBOARD_Acquire(void);
extern void X11DRV_CLIPBOARD_Release(void);
extern void X11DRV_CLIPBOARD_SetData(UINT wFormat);
extern BOOL X11DRV_CLIPBOARD_GetData(UINT wFormat);
extern BOOL X11DRV_CLIPBOARD_IsFormatAvailable(UINT wFormat);
extern BOOL X11DRV_CLIPBOARD_IsNativeProperty(Atom prop);
extern BOOL X11DRV_CLIPBOARD_RegisterFormat( LPCSTR FormatName );
extern BOOL X11DRV_CLIPBOARD_IsSelectionowner();
extern UINT X11DRV_CLIPBOARD_MapPropertyToFormat(char *itemFmtName);
......
......@@ -978,3 +978,87 @@ void DIB_FixColorsToLoadflags(BITMAPINFO * bmi, UINT loadflags, BYTE pix)
}
}
}
/***********************************************************************
* DIB_CreateDIBFromBitmap
* Allocates a packed DIB and copies the bitmap data into it.
*/
HGLOBAL DIB_CreateDIBFromBitmap(HDC hdc, HBITMAP hBmp)
{
BITMAPOBJ *pBmp = NULL;
HGLOBAL hPackedDIB = 0;
LPBYTE pPackedDIB = NULL;
LPBITMAPINFOHEADER pbmiHeader = NULL;
unsigned int width, height, depth, cDataSize = 0, cPackedSize = 0,
OffsetBits = 0, nLinesCopied = 0;
/* Get a pointer to the BITMAPOBJ structure */
pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
/* Get the bitmap dimensions */
width = pBmp->bitmap.bmWidth;
height = pBmp->bitmap.bmHeight;
depth = pBmp->bitmap.bmBitsPixel;
/*
* A packed DIB contains a BITMAPINFO structure followed immediately by
* an optional color palette and the pixel data.
*/
/* Calculate the size of the packed DIB */
cDataSize = DIB_GetDIBImageBytes( width, height, depth );
cPackedSize = sizeof(BITMAPINFOHEADER)
+ ( (depth <= 8) ? (sizeof(RGBQUAD) * (1 << depth)) : 0 )
+ cDataSize;
/* Get the offset to the bits */
OffsetBits = cPackedSize - cDataSize;
/* Allocate the packed DIB */
TRACE("\tAllocating packed DIB of size %d\n", cPackedSize);
hPackedDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE /*| GMEM_ZEROINIT*/,
cPackedSize );
if ( !hPackedDIB )
{
WARN("Could not allocate packed DIB!\n");
goto END;
}
/* A packed DIB starts with a BITMAPINFOHEADER */
pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
/* Init the BITMAPINFOHEADER */
pbmiHeader->biSize = sizeof(BITMAPINFOHEADER);
pbmiHeader->biWidth = width;
pbmiHeader->biHeight = height;
pbmiHeader->biPlanes = 1;
pbmiHeader->biBitCount = depth;
pbmiHeader->biCompression = BI_RGB;
pbmiHeader->biSizeImage = 0;
pbmiHeader->biXPelsPerMeter = pbmiHeader->biYPelsPerMeter = 0;
pbmiHeader->biClrUsed = 0;
pbmiHeader->biClrImportant = 0;
/* Retrieve the DIB bits from the bitmap and fill in the
* DIB color table if present */
nLinesCopied = GetDIBits(hdc, /* Handle to device context */
hBmp, /* Handle to bitmap */
0, /* First scan line to set in dest bitmap */
height, /* Number of scan lines to copy */
pPackedDIB + OffsetBits, /* [out] Address of array for bitmap bits */
(LPBITMAPINFO) pbmiHeader, /* [out] Address of BITMAPINFO structure */
0); /* RGB or palette index */
GlobalUnlock(hPackedDIB);
/* Cleanup if GetDIBits failed */
if (nLinesCopied != height)
{
TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied, height);
GlobalFree(hPackedDIB);
hPackedDIB = 0;
}
END:
return hPackedDIB;
}
......@@ -34,6 +34,7 @@ XCreateRegion
XCreateWindow
XDefineCursor
XDeleteContext
XDeleteProperty
XDestroyImage
XDestroyRegion
XDestroyWindow
......
......@@ -488,6 +488,17 @@ int TSXDefineCursor(Display* a0, Window a1, Cursor a2)
return r;
}
int TSXDeleteProperty(Display* a0, Window a1, Atom a2)
{
int r;
TRACE("Call XDeleteProperty\n");
EnterCriticalSection( &X11DRV_CritSection );
r = XDeleteProperty(a0, a1, a2);
LeaveCriticalSection( &X11DRV_CritSection );
TRACE("Ret XDeleteProperty\n");
return r;
}
int TSXDestroyWindow(Display* a0, Window a1)
{
int r;
......
......@@ -796,27 +796,28 @@ HANDLE16 WINAPI GetClipboardData16( UINT16 wFormat )
if( lpRender->wFormatID == CF_METAFILEPICT )
size = sizeof( METAFILEPICT16 );
else
size = GlobalSize(lpRender->hData32);
size = GlobalSize(lpRender->hData32);
lpRender->hData16 = GlobalAlloc16(GMEM_ZEROINIT, size);
if( !lpRender->hData16 )
ERR("(%04X) -- not enough memory in 16b heap\n", wFormat);
else
{
if( lpRender->wFormatID == CF_METAFILEPICT )
{
FIXME("\timplement function CopyMetaFilePict32to16\n");
FIXME("\tin the appropriate file.\n");
#ifdef SOMEONE_IMPLEMENTED_ME
CopyMetaFilePict32to16( GlobalLock16(lpRender->hData16),
GlobalLock(lpRender->hData32) );
#endif
}
else
{
memcpy( GlobalLock16(lpRender->hData16),
GlobalLock(lpRender->hData32),
size );
}
if( lpRender->wFormatID == CF_METAFILEPICT )
{
FIXME("\timplement function CopyMetaFilePict32to16\n");
FIXME("\tin the appropriate file.\n");
#ifdef SOMEONE_IMPLEMENTED_ME
CopyMetaFilePict32to16( GlobalLock16(lpRender->hData16),
GlobalLock(lpRender->hData32) );
#endif
}
else
{
memcpy( GlobalLock16(lpRender->hData16),
GlobalLock(lpRender->hData32),
size );
}
GlobalUnlock16(lpRender->hData16);
GlobalUnlock(lpRender->hData32);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment