From 455a22394a88f42b53c2988e4cd2b0d01b8fdb95 Mon Sep 17 00:00:00 2001 From: Ulrich Czekalla Date: Fri, 20 Feb 2004 05:43:00 +0000 Subject: [PATCH] Implemented rendering synthesized BITMAP and DIB formats. --- dlls/x11drv/clipboard.c | 193 +++++++++++++++++++++++++++++++--------- dlls/x11drv/event.c | 20 +++-- dlls/x11drv/window.c | 1 + dlls/x11drv/x11drv.h | 2 + 4 files changed, 168 insertions(+), 48 deletions(-) diff --git a/dlls/x11drv/clipboard.c b/dlls/x11drv/clipboard.c index 957f97cbbed..e9555a7395a 100644 --- a/dlls/x11drv/clipboard.c +++ b/dlls/x11drv/clipboard.c @@ -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); } } diff --git a/dlls/x11drv/event.c b/dlls/x11drv/event.c index 9cc9fb7a93e..3187d9f62e9 100644 --- a/dlls/x11drv/event.c +++ b/dlls/x11drv/event.c @@ -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); diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c index 133a48cd0ab..08805d95bff 100644 --- a/dlls/x11drv/window.c +++ b/dlls/x11drv/window.c @@ -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", diff --git a/dlls/x11drv/x11drv.h b/dlls/x11drv/x11drv.h index 9f756dec6f0..e7d27a1db25 100644 --- a/dlls/x11drv/x11drv.h +++ b/dlls/x11drv/x11drv.h @@ -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;