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 BOOL X11DRV_CLIPBOARD_SynthesizeData(UINT wFormatID);
static BOOL X11DRV_CLIPBOARD_RenderSynthesizedFormat(LPWINE_CLIPDATA lpData);
static BOOL X11DRV_CLIPBOARD_RenderSynthesizedDIB(void);
static BOOL X11DRV_CLIPBOARD_RenderSynthesizedBitmap(void);
/* Clipboard formats
* 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]},
{ 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,
X11DRV_CLIPBOARD_ExportMetaFilePict, &ClipFormats[1], &ClipFormats[3]},
@ -247,6 +249,7 @@ static const struct
{ XATOM_text_rtf, XATOM_text_richtext },
{ XA_STRING, XATOM_COMPOUND_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->hData16 = hData16; /* 0 is legal, see WM_RENDERFORMAT */
lpData->hData32 = hData32;
lpData->drvData = 0;
if (ClipData)
{
@ -646,6 +650,9 @@ static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData)
if (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)
{
@ -692,6 +699,7 @@ static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData)
lpData->hData16 = 0;
lpData->hData32 = 0;
lpData->drvData = 0;
}
@ -854,10 +862,16 @@ static BOOL X11DRV_CLIPBOARD_RenderSynthesizedFormat(LPWINE_CLIPDATA lpData)
{
switch (wFormatID)
{
case CF_DIB:
bret = X11DRV_CLIPBOARD_RenderSynthesizedDIB();
break;
case CF_BITMAP:
bret = X11DRV_CLIPBOARD_RenderSynthesizedBitmap();
break;
case CF_ENHMETAFILE:
case CF_METAFILEPICT:
case CF_DIB:
case CF_BITMAP:
FIXME("Synthesizing wFormatID(0x%08x) not implemented\n", wFormatID);
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
*
@ -1244,7 +1353,8 @@ HANDLE X11DRV_CLIPBOARD_ExportXAPIXMAP(Window requestor, Atom aTarget, Atom rpro
LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
{
HDC hdc;
Pixmap pixmap;
HANDLE hData;
unsigned char* lpData;
if (!X11DRV_CLIPBOARD_RenderFormat(lpdata))
{
@ -1252,15 +1362,23 @@ HANDLE X11DRV_CLIPBOARD_ExportXAPIXMAP(Window requestor, Atom aTarget, Atom rpro
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 */
pixmap = X11DRV_DIB_CreatePixmapFromDIB(lpdata, hdc);
*lpBytes = 4; /* pixmap is a 32bit value */
*lpBytes = sizeof(Pixmap); /* 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();
Atom atype=AnyPropertyType;
int aformat;
unsigned long total,nitems,remain,itemSize,val_cnt;
long lRequestLength,bwc;
unsigned long total,nitems,remain,val_cnt;
long reqlen, bwc;
unsigned char* val;
unsigned char* buffer;
BOOL bRet = FALSE;
@ -1637,7 +1755,7 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(LPWINE_CLIPFORMAT lpData, Window w, A
*/
wine_tsx11_lock();
if(XGetWindowProperty(display,w,prop,0,0,False, AnyPropertyType,
&atype, &aformat, &nitems, &itemSize, &val) != Success)
&atype, &aformat, &nitems, &remain, &buffer) != Success)
{
wine_tsx11_unlock();
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 */
if (val)
if (buffer)
{
XFree(val);
val = NULL;
XFree(buffer);
buffer = NULL;
}
TRACE("Retrieving %ld bytes\n", itemSize * aformat/8);
lRequestLength = (itemSize * aformat/8)/4 + 1;
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 */
if (XGetWindowProperty(display,w,prop,0,4096,False, AnyPropertyType/*reqType*/,
&atype, &aformat, &nitems, &remain, &buffer) != Success)
for (total = 0, val_cnt = 0; remain;)
{
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,
AnyPropertyType, &atype, &aformat, &nitems, &remain, &buffer) != Success)
{
@ -1682,9 +1788,10 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(LPWINE_CLIPFORMAT lpData, Window w, A
return bRet;
}
bwc = aformat/8;
memcpy(&val[val_cnt], buffer, nitems * bwc);
val_cnt += nitems * bwc;
total += nitems*bwc;
HeapReAlloc(GetProcessHeap(),0,val, total);
memcpy(&val[val_cnt], buffer, nitems*(aformat/8));
XFree(buffer);
}
wine_tsx11_unlock();
@ -1720,7 +1827,7 @@ static HANDLE X11DRV_CLIPBOARD_SerializeMetafile(INT wformat, HANDLE hdata, LPDW
if (wformat == CF_METAFILEPICT)
{
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));
if (h)
@ -1760,12 +1867,14 @@ static HANDLE X11DRV_CLIPBOARD_SerializeMetafile(INT wformat, HANDLE hdata, LPDW
h = GlobalAlloc(0, sizeof(METAFILEPICT));
if (h)
{
LPMETAFILEPICT pmfp = (LPMETAFILEPICT) GlobalLock(h);
memcpy(pmfp, (LPVOID)hdata, sizeof(METAFILEPICT));
pmfp->hMF = SetMetaFileBitsEx(*lpcbytes - sizeof(METAFILEPICT),
(char *)hdata + sizeof(METAFILEPICT));
unsigned int wiresize, size;
LPMETAFILEPICT lpmfp = (LPMETAFILEPICT) GlobalLock(h);
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);
}
}

View File

@ -608,6 +608,7 @@ static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
UINT wFormat;
UINT alias;
ULONG cTargets;
LPWINE_CLIPFORMAT lpFormat;
/*
* 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));)
{
LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
if (lpFormat && X11DRV_CLIPBOARD_LookupPropertyAlias(lpFormat->drvData))
cTargets++;
lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
if (lpFormat)
{
if (!lpFormat->lpDrvExportFunc)
cTargets--;
if (X11DRV_CLIPBOARD_LookupPropertyAlias(lpFormat->drvData))
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;
(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);
/* Check if any alias should be listed */
@ -835,7 +844,7 @@ static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BO
if (!lpFormat)
lpFormat = X11DRV_CLIPBOARD_LookupAliasProperty(event->target);
if (lpFormat)
if (lpFormat && lpFormat->lpDrvExportFunc)
{
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)))
{
TRACE_(clipboard)("\tUpdating property %s, %ld bytes\n",
lpFormat->Name, cBytes);

View File

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

View File

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