clipboard

Ulrich Czekalla ulrich at codeweavers.com
Thu Feb 19 11:56:19 CST 2004


ChangeLog:
    Ulrich Czekalla <ulrich at codeweavers.com>
    Implement rendering synthesized BITMAP and DIB formats
-------------- next part --------------
Index: dlls/x11drv/clipboard.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/clipboard.c,v
retrieving revision 1.22
diff -u -w -r1.22 clipboard.c
--- dlls/x11drv/clipboard.c	19 Feb 2004 01:10:16 -0000	1.22
+++ dlls/x11drv/clipboard.c	19 Feb 2004 17:45:58 -0000
@@ -145,6 +145,8 @@
 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();
+static BOOL X11DRV_CLIPBOARD_RenderSynthesizedBitmap();
 
 /* Clipboard formats
  * WARNING: This data ordering is dependent on the WINE_CLIPFORMAT structure
@@ -156,7 +158,7 @@
         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 @@
     { XATOM_text_rtf,  XATOM_text_richtext },
     { XA_STRING,       XATOM_COMPOUND_TEXT },
     { XA_STRING,       XATOM_TEXT },
+    { XATOM_dib,       XA_PIXMAP },
 };
 
 
@@ -599,6 +602,7 @@
         lpData->wFormatID = wFormat;
         lpData->hData16 = hData16;  /* 0 is legal, see WM_RENDERFORMAT */
         lpData->hData32 = hData32;
+        lpData->drvData = 0;
 
 	if (ClipData)
         {
@@ -646,6 +650,9 @@
 
       if (lpData->hData16)
 	DeleteObject(HGDIOBJ_32(lpData->hData16));
+
+      if ((lpData->wFormatID == CF_DIB) && lpData->drvData)
+          XFreePixmap(thread_display(), lpData->drvData);
     }
     else if (lpData->wFormatID == CF_METAFILEPICT)
     {
@@ -692,6 +699,7 @@
 
     lpData->hData16 = 0;
     lpData->hData32 = 0;
+    lpData->drvData = 0;
 }
 
 
@@ -854,10 +862,16 @@
         {
             switch (wFormatID)
 	    {
-                case CF_ENHMETAFILE:
-                case CF_METAFILEPICT:
                 case CF_DIB:
+                    bret = X11DRV_CLIPBOARD_RenderSynthesizedDIB();
+                    break;
+
                 case CF_BITMAP:
+                    bret = X11DRV_CLIPBOARD_RenderSynthesizedBitmap();
+                    break;
+
+                case CF_ENHMETAFILE:
+                case CF_METAFILEPICT:
 		    FIXME("Synthesizing wFormatID(0x%08x) not implemented\n", wFormatID);
                     break;
 
@@ -975,6 +989,101 @@
 
 
 /**************************************************************************
+ *                      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
  *
  *  Import XA_STRING, converting the string to CF_UNICODE.
@@ -1244,7 +1353,8 @@
     LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
 {
     HDC hdc;
-    Pixmap pixmap;
+    HANDLE hData;
+    unsigned char* lpData;
 
     if (!X11DRV_CLIPBOARD_RenderFormat(lpdata))
     {
@@ -1252,15 +1362,23 @@
         return 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 @@
     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 @@
      */
     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 @@
     }
 
     /* 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;
 
-    /* Read property in 4K blocks */
-    if (XGetWindowProperty(display,w,prop,0,4096,False, AnyPropertyType/*reqType*/, 
-        &atype, &aformat, &nitems, &remain, &buffer) != Success)
-    {
-        wine_tsx11_unlock();
-        WARN("Failed to read property\n");
-        return bRet;
-    }
+    TRACE("Retrieving %ld bytes\n", reqlen);
 
-    val = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nitems*bwc);
-    memcpy(val,buffer,nitems*bwc);
-
-    XFree(buffer);
+    val = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, reqlen);
 
-    for (total = nitems*bwc, val_cnt = 0; remain;)
+    /* Read property in 4K blocks */
+    for (total = 0, 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 @@
            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 @@
         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 @@
             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);
             }
         }
Index: dlls/x11drv/event.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/event.c,v
retrieving revision 1.32
diff -u -w -r1.32 event.c
--- dlls/x11drv/event.c	21 Jan 2004 02:22:27 -0000	1.32
+++ dlls/x11drv/event.c	19 Feb 2004 17:45:59 -0000
@@ -608,6 +608,7 @@
     UINT wFormat;
     UINT alias;
     ULONG cTargets;
+    LPWINE_CLIPFORMAT lpFormat;
 
     /*
      * Count the number of items we wish to expose as selection targets.
@@ -617,10 +618,17 @@
 
     for (wFormat = 0; (wFormat = X11DRV_EnumClipboardFormats(wFormat));)
     {
-        LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
-        if (lpFormat && X11DRV_CLIPBOARD_LookupPropertyAlias(lpFormat->drvData))
+        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 @@
     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 @@
       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 @@
 
               if (hClipData && (lpClipData = GlobalLock(hClipData)))
               {
-
                   TRACE_(clipboard)("\tUpdating property %s, %ld bytes\n",
                       lpFormat->Name, cBytes);
 
Index: dlls/x11drv/window.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/window.c,v
retrieving revision 1.70
diff -u -w -r1.70 window.c
--- dlls/x11drv/window.c	6 Feb 2004 05:17:55 -0000	1.70
+++ dlls/x11drv/window.c	19 Feb 2004 17:46:00 -0000
@@ -98,6 +98,7 @@
     "XdndSelection",
     "XdndTarget",
     "XdndTypeList",
+    "WCF_DIB",
     "image/gif",
     "text/html",
     "text/plain",
Index: dlls/x11drv/x11drv.h
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv.h,v
retrieving revision 1.22
diff -u -w -r1.22 x11drv.h
--- dlls/x11drv/x11drv.h	13 Feb 2004 20:26:27 -0000	1.22
+++ dlls/x11drv/x11drv.h	19 Feb 2004 17:46:01 -0000
@@ -435,6 +435,7 @@
     XATOM_XdndSelection,
     XATOM_XdndTarget,
     XATOM_XdndTypeList,
+    XATOM_dib,
     XATOM_image_gif,
     XATOM_text_html,
     XATOM_text_plain,
@@ -453,6 +454,7 @@
     UINT        wFormatID;
     HANDLE16    hData16;
     HANDLE      hData32;
+    UINT        drvData;
     UINT        wFlags;
     struct tagWINE_CLIPDATA *PrevData;
     struct tagWINE_CLIPDATA *NextData;


More information about the wine-patches mailing list