Implemented rendering synthesized BITMAP and DIB formats.

This commit is contained in:
Ulrich Czekalla 2004-02-20 05:43:00 +00:00 committed by Alexandre Julliard
parent 4d984fd9c1
commit 455a22394a
4 changed files with 168 additions and 48 deletions

View File

@ -145,6 +145,8 @@ static BOOL X11DRV_CLIPBOARD_RenderFormat(LPWINE_CLIPDATA lpData);
static HANDLE X11DRV_CLIPBOARD_SerializeMetafile(INT wformat, HANDLE hdata, LPDWORD lpcbytes, BOOL out); static HANDLE X11DRV_CLIPBOARD_SerializeMetafile(INT wformat, HANDLE hdata, LPDWORD lpcbytes, BOOL out);
static BOOL X11DRV_CLIPBOARD_SynthesizeData(UINT wFormatID); static BOOL X11DRV_CLIPBOARD_SynthesizeData(UINT wFormatID);
static BOOL X11DRV_CLIPBOARD_RenderSynthesizedFormat(LPWINE_CLIPDATA lpData); static BOOL X11DRV_CLIPBOARD_RenderSynthesizedFormat(LPWINE_CLIPDATA lpData);
static BOOL X11DRV_CLIPBOARD_RenderSynthesizedDIB(void);
static BOOL X11DRV_CLIPBOARD_RenderSynthesizedBitmap(void);
/* Clipboard formats /* Clipboard formats
* WARNING: This data ordering is dependent on the WINE_CLIPFORMAT structure * WARNING: This data ordering is dependent on the WINE_CLIPFORMAT structure
@ -156,7 +158,7 @@ static WINE_CLIPFORMAT ClipFormats[] =
X11DRV_CLIPBOARD_ExportClipboardData, NULL, &ClipFormats[1]}, X11DRV_CLIPBOARD_ExportClipboardData, NULL, &ClipFormats[1]},
{ CF_BITMAP, "WCF_BITMAP", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData, { CF_BITMAP, "WCF_BITMAP", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[0], &ClipFormats[2]}, NULL, &ClipFormats[0], &ClipFormats[2]},
{ CF_METAFILEPICT, "WCF_METAFILEPICT", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportMetaFilePict, { CF_METAFILEPICT, "WCF_METAFILEPICT", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportMetaFilePict,
X11DRV_CLIPBOARD_ExportMetaFilePict, &ClipFormats[1], &ClipFormats[3]}, X11DRV_CLIPBOARD_ExportMetaFilePict, &ClipFormats[1], &ClipFormats[3]},
@ -247,6 +249,7 @@ static const struct
{ XATOM_text_rtf, XATOM_text_richtext }, { XATOM_text_rtf, XATOM_text_richtext },
{ XA_STRING, XATOM_COMPOUND_TEXT }, { XA_STRING, XATOM_COMPOUND_TEXT },
{ XA_STRING, XATOM_TEXT }, { XA_STRING, XATOM_TEXT },
{ XATOM_WCF_DIB, XA_PIXMAP },
}; };
@ -599,6 +602,7 @@ static BOOL X11DRV_CLIPBOARD_InsertClipboardData(UINT wFormat, HANDLE16 hData16,
lpData->wFormatID = wFormat; lpData->wFormatID = wFormat;
lpData->hData16 = hData16; /* 0 is legal, see WM_RENDERFORMAT */ lpData->hData16 = hData16; /* 0 is legal, see WM_RENDERFORMAT */
lpData->hData32 = hData32; lpData->hData32 = hData32;
lpData->drvData = 0;
if (ClipData) if (ClipData)
{ {
@ -646,6 +650,9 @@ static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData)
if (lpData->hData16) if (lpData->hData16)
DeleteObject(HGDIOBJ_32(lpData->hData16)); DeleteObject(HGDIOBJ_32(lpData->hData16));
if ((lpData->wFormatID == CF_DIB) && lpData->drvData)
XFreePixmap(gdi_display, lpData->drvData);
} }
else if (lpData->wFormatID == CF_METAFILEPICT) else if (lpData->wFormatID == CF_METAFILEPICT)
{ {
@ -692,6 +699,7 @@ static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData)
lpData->hData16 = 0; lpData->hData16 = 0;
lpData->hData32 = 0; lpData->hData32 = 0;
lpData->drvData = 0;
} }
@ -854,10 +862,16 @@ static BOOL X11DRV_CLIPBOARD_RenderSynthesizedFormat(LPWINE_CLIPDATA lpData)
{ {
switch (wFormatID) switch (wFormatID)
{ {
case CF_DIB:
bret = X11DRV_CLIPBOARD_RenderSynthesizedDIB();
break;
case CF_BITMAP:
bret = X11DRV_CLIPBOARD_RenderSynthesizedBitmap();
break;
case CF_ENHMETAFILE: case CF_ENHMETAFILE:
case CF_METAFILEPICT: case CF_METAFILEPICT:
case CF_DIB:
case CF_BITMAP:
FIXME("Synthesizing wFormatID(0x%08x) not implemented\n", wFormatID); FIXME("Synthesizing wFormatID(0x%08x) not implemented\n", wFormatID);
break; break;
@ -974,6 +988,101 @@ static BOOL X11DRV_CLIPBOARD_RenderSynthesizedText(UINT wFormatID)
} }
/**************************************************************************
* X11DRV_CLIPBOARD_RenderSynthesizedDIB
*
* Renders synthesized DIB
*/
static BOOL X11DRV_CLIPBOARD_RenderSynthesizedDIB()
{
BOOL bret = FALSE;
LPWINE_CLIPDATA lpSource = NULL;
TRACE("\n");
if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_DIB)) && lpSource->hData32)
{
bret = TRUE;
}
/* If we have a bitmap and it's not synthesized or it has been rendered */
else if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_BITMAP)) &&
(!(lpSource->wFlags & CF_FLAG_SYNTHESIZED) || lpSource->hData32))
{
/* Render source if required */
if (lpSource->hData32 || X11DRV_CLIPBOARD_RenderFormat(lpSource))
{
HDC hdc;
HGLOBAL hData32;
hdc = GetDC(NULL);
hData32 = X11DRV_DIB_CreateDIBFromBitmap(hdc, lpSource->hData32);
ReleaseDC(NULL, hdc);
if (hData32)
{
X11DRV_CLIPBOARD_InsertClipboardData(CF_DIB, 0, hData32, 0);
bret = TRUE;
}
}
}
return bret;
}
/**************************************************************************
* X11DRV_CLIPBOARD_RenderSynthesizedBitmap
*
* Renders synthesized bitmap
*/
static BOOL X11DRV_CLIPBOARD_RenderSynthesizedBitmap()
{
BOOL bret = FALSE;
LPWINE_CLIPDATA lpSource = NULL;
TRACE("\n");
if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_BITMAP)) && lpSource->hData32)
{
bret = TRUE;
}
/* If we have a dib and it's not synthesized or it has been rendered */
else if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_DIB)) &&
(!(lpSource->wFlags & CF_FLAG_SYNTHESIZED) || lpSource->hData32))
{
/* Render source if required */
if (lpSource->hData32 || X11DRV_CLIPBOARD_RenderFormat(lpSource))
{
HDC hdc;
HBITMAP hData32;
unsigned int offset;
LPBITMAPINFOHEADER lpbmih;
hdc = GetDC(NULL);
lpbmih = (LPBITMAPINFOHEADER) GlobalLock(lpSource->hData32);
offset = sizeof(BITMAPINFOHEADER)
+ ((lpbmih->biBitCount <= 8) ? (sizeof(RGBQUAD) *
(1 << lpbmih->biBitCount)) : 0);
hData32 = CreateDIBitmap(hdc, lpbmih, CBM_INIT, (LPBYTE)lpbmih +
offset, (LPBITMAPINFO) lpbmih, DIB_RGB_COLORS);
GlobalUnlock(lpSource->hData32);
ReleaseDC(NULL, hdc);
if (hData32)
{
X11DRV_CLIPBOARD_InsertClipboardData(CF_BITMAP, 0, hData32, 0);
bret = TRUE;
}
}
}
return bret;
}
/************************************************************************** /**************************************************************************
* X11DRV_CLIPBOARD_ImportXAString * X11DRV_CLIPBOARD_ImportXAString
* *
@ -1244,7 +1353,8 @@ HANDLE X11DRV_CLIPBOARD_ExportXAPIXMAP(Window requestor, Atom aTarget, Atom rpro
LPWINE_CLIPDATA lpdata, LPDWORD lpBytes) LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
{ {
HDC hdc; HDC hdc;
Pixmap pixmap; HANDLE hData;
unsigned char* lpData;
if (!X11DRV_CLIPBOARD_RenderFormat(lpdata)) if (!X11DRV_CLIPBOARD_RenderFormat(lpdata))
{ {
@ -1252,15 +1362,23 @@ HANDLE X11DRV_CLIPBOARD_ExportXAPIXMAP(Window requestor, Atom aTarget, Atom rpro
return 0; return 0;
} }
hdc = GetDC(0); if (!lpdata->drvData) /* If not already rendered */
{
/* For convert from packed DIB to Pixmap */
hdc = GetDC(0);
lpdata->drvData = (UINT) X11DRV_DIB_CreatePixmapFromDIB(lpdata->hData32, hdc);
ReleaseDC(0, hdc);
}
/* For convert from packed DIB to Pixmap */ *lpBytes = sizeof(Pixmap); /* pixmap is a 32bit value */
pixmap = X11DRV_DIB_CreatePixmapFromDIB(lpdata, hdc);
*lpBytes = 4; /* pixmap is a 32bit value */
ReleaseDC(0, hdc); /* Wrap pixmap so we can return a handle */
hData = GlobalAlloc(0, *lpBytes);
lpData = GlobalLock(hData);
memcpy(lpData, &lpdata->drvData, *lpBytes);
GlobalUnlock(hData);
return (HANDLE) pixmap; return (HANDLE) hData;
} }
@ -1621,8 +1739,8 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(LPWINE_CLIPFORMAT lpData, Window w, A
Display *display = thread_display(); Display *display = thread_display();
Atom atype=AnyPropertyType; Atom atype=AnyPropertyType;
int aformat; int aformat;
unsigned long total,nitems,remain,itemSize,val_cnt; unsigned long total,nitems,remain,val_cnt;
long lRequestLength,bwc; long reqlen, bwc;
unsigned char* val; unsigned char* val;
unsigned char* buffer; unsigned char* buffer;
BOOL bRet = FALSE; BOOL bRet = FALSE;
@ -1637,7 +1755,7 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(LPWINE_CLIPFORMAT lpData, Window w, A
*/ */
wine_tsx11_lock(); wine_tsx11_lock();
if(XGetWindowProperty(display,w,prop,0,0,False, AnyPropertyType, if(XGetWindowProperty(display,w,prop,0,0,False, AnyPropertyType,
&atype, &aformat, &nitems, &itemSize, &val) != Success) &atype, &aformat, &nitems, &remain, &buffer) != Success)
{ {
wine_tsx11_unlock(); wine_tsx11_unlock();
WARN("Failed to get property size\n"); WARN("Failed to get property size\n");
@ -1645,34 +1763,22 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(LPWINE_CLIPFORMAT lpData, Window w, A
} }
/* Free zero length return data if any */ /* Free zero length return data if any */
if (val) if (buffer)
{ {
XFree(val); XFree(buffer);
val = NULL; buffer = NULL;
} }
TRACE("Retrieving %ld bytes\n", itemSize * aformat/8);
lRequestLength = (itemSize * aformat/8)/4 + 1;
bwc = aformat/8; bwc = aformat/8;
reqlen = remain * bwc;
TRACE("Retrieving %ld bytes\n", reqlen);
val = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, reqlen);
/* Read property in 4K blocks */ /* Read property in 4K blocks */
if (XGetWindowProperty(display,w,prop,0,4096,False, AnyPropertyType/*reqType*/, for (total = 0, val_cnt = 0; remain;)
&atype, &aformat, &nitems, &remain, &buffer) != Success)
{ {
wine_tsx11_unlock();
WARN("Failed to read property\n");
return bRet;
}
val = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nitems*bwc);
memcpy(val,buffer,nitems*bwc);
XFree(buffer);
for (total = nitems*bwc, val_cnt = 0; remain;)
{
val_cnt +=nitems*bwc;
if (XGetWindowProperty(display, w, prop, (total / 4), 4096, False, if (XGetWindowProperty(display, w, prop, (total / 4), 4096, False,
AnyPropertyType, &atype, &aformat, &nitems, &remain, &buffer) != Success) AnyPropertyType, &atype, &aformat, &nitems, &remain, &buffer) != Success)
{ {
@ -1682,9 +1788,10 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(LPWINE_CLIPFORMAT lpData, Window w, A
return bRet; return bRet;
} }
bwc = aformat/8;
memcpy(&val[val_cnt], buffer, nitems * bwc);
val_cnt += nitems * bwc;
total += nitems*bwc; total += nitems*bwc;
HeapReAlloc(GetProcessHeap(),0,val, total);
memcpy(&val[val_cnt], buffer, nitems*(aformat/8));
XFree(buffer); XFree(buffer);
} }
wine_tsx11_unlock(); wine_tsx11_unlock();
@ -1720,7 +1827,7 @@ static HANDLE X11DRV_CLIPBOARD_SerializeMetafile(INT wformat, HANDLE hdata, LPDW
if (wformat == CF_METAFILEPICT) if (wformat == CF_METAFILEPICT)
{ {
LPMETAFILEPICT lpmfp = (LPMETAFILEPICT) GlobalLock(hdata); LPMETAFILEPICT lpmfp = (LPMETAFILEPICT) GlobalLock(hdata);
int size = GetMetaFileBitsEx(lpmfp->hMF, 0, NULL); unsigned int size = GetMetaFileBitsEx(lpmfp->hMF, 0, NULL);
h = GlobalAlloc(0, size + sizeof(METAFILEPICT)); h = GlobalAlloc(0, size + sizeof(METAFILEPICT));
if (h) if (h)
@ -1760,12 +1867,14 @@ static HANDLE X11DRV_CLIPBOARD_SerializeMetafile(INT wformat, HANDLE hdata, LPDW
h = GlobalAlloc(0, sizeof(METAFILEPICT)); h = GlobalAlloc(0, sizeof(METAFILEPICT));
if (h) if (h)
{ {
LPMETAFILEPICT pmfp = (LPMETAFILEPICT) GlobalLock(h); unsigned int wiresize, size;
LPMETAFILEPICT lpmfp = (LPMETAFILEPICT) GlobalLock(h);
memcpy(pmfp, (LPVOID)hdata, sizeof(METAFILEPICT));
pmfp->hMF = SetMetaFileBitsEx(*lpcbytes - sizeof(METAFILEPICT),
(char *)hdata + sizeof(METAFILEPICT));
memcpy(lpmfp, (LPVOID)hdata, sizeof(METAFILEPICT));
wiresize = *lpcbytes - sizeof(METAFILEPICT);
lpmfp->hMF = SetMetaFileBitsEx(wiresize,
((char *)hdata) + sizeof(METAFILEPICT));
size = GetMetaFileBitsEx(lpmfp->hMF, 0, NULL);
GlobalUnlock(h); GlobalUnlock(h);
} }
} }

View File

@ -608,6 +608,7 @@ static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
UINT wFormat; UINT wFormat;
UINT alias; UINT alias;
ULONG cTargets; ULONG cTargets;
LPWINE_CLIPFORMAT lpFormat;
/* /*
* Count the number of items we wish to expose as selection targets. * Count the number of items we wish to expose as selection targets.
@ -617,9 +618,16 @@ static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
for (wFormat = 0; (wFormat = X11DRV_EnumClipboardFormats(wFormat));) for (wFormat = 0; (wFormat = X11DRV_EnumClipboardFormats(wFormat));)
{ {
LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat); lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
if (lpFormat && X11DRV_CLIPBOARD_LookupPropertyAlias(lpFormat->drvData))
cTargets++; if (lpFormat)
{
if (!lpFormat->lpDrvExportFunc)
cTargets--;
if (X11DRV_CLIPBOARD_LookupPropertyAlias(lpFormat->drvData))
cTargets++;
}
} }
TRACE_(clipboard)(" found %ld formats\n", cTargets); TRACE_(clipboard)(" found %ld formats\n", cTargets);
@ -633,8 +641,9 @@ static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
for (targets[0] = x11drv_atom(TARGETS), cTargets = 1, wFormat = 0; for (targets[0] = x11drv_atom(TARGETS), cTargets = 1, wFormat = 0;
(wFormat = X11DRV_EnumClipboardFormats(wFormat));) (wFormat = X11DRV_EnumClipboardFormats(wFormat));)
{ {
LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat); lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
if (lpFormat->lpDrvExportFunc)
EVENT_SelectionRequest_AddTARGETS(targets, &cTargets, lpFormat->drvData); EVENT_SelectionRequest_AddTARGETS(targets, &cTargets, lpFormat->drvData);
/* Check if any alias should be listed */ /* Check if any alias should be listed */
@ -835,7 +844,7 @@ static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BO
if (!lpFormat) if (!lpFormat)
lpFormat = X11DRV_CLIPBOARD_LookupAliasProperty(event->target); lpFormat = X11DRV_CLIPBOARD_LookupAliasProperty(event->target);
if (lpFormat) if (lpFormat && lpFormat->lpDrvExportFunc)
{ {
LPWINE_CLIPDATA lpData = X11DRV_CLIPBOARD_LookupData(lpFormat->wFormatID); LPWINE_CLIPDATA lpData = X11DRV_CLIPBOARD_LookupData(lpFormat->wFormatID);
@ -848,7 +857,6 @@ static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BO
if (hClipData && (lpClipData = GlobalLock(hClipData))) if (hClipData && (lpClipData = GlobalLock(hClipData)))
{ {
TRACE_(clipboard)("\tUpdating property %s, %ld bytes\n", TRACE_(clipboard)("\tUpdating property %s, %ld bytes\n",
lpFormat->Name, cBytes); lpFormat->Name, cBytes);

View File

@ -98,6 +98,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
"XdndSelection", "XdndSelection",
"XdndTarget", "XdndTarget",
"XdndTypeList", "XdndTypeList",
"WCF_DIB",
"image/gif", "image/gif",
"text/html", "text/html",
"text/plain", "text/plain",

View File

@ -435,6 +435,7 @@ enum x11drv_atoms
XATOM_XdndSelection, XATOM_XdndSelection,
XATOM_XdndTarget, XATOM_XdndTarget,
XATOM_XdndTypeList, XATOM_XdndTypeList,
XATOM_WCF_DIB,
XATOM_image_gif, XATOM_image_gif,
XATOM_text_html, XATOM_text_html,
XATOM_text_plain, XATOM_text_plain,
@ -453,6 +454,7 @@ typedef struct tagWINE_CLIPDATA {
UINT wFormatID; UINT wFormatID;
HANDLE16 hData16; HANDLE16 hData16;
HANDLE hData32; HANDLE hData32;
UINT drvData;
UINT wFlags; UINT wFlags;
struct tagWINE_CLIPDATA *PrevData; struct tagWINE_CLIPDATA *PrevData;
struct tagWINE_CLIPDATA *NextData; struct tagWINE_CLIPDATA *NextData;