[PATCH 2/3] winex11.drv: Fix handling of CF_DIBV5 clipboard data.

Charles Davis cdavis5x at gmail.com
Fri Feb 26 03:55:29 CST 2016


Signed-off-by: Charles Davis <cdavis5x at gmail.com>
---
 dlls/winex11.drv/clipboard.c | 72 ++++++++++++++++++++++++++++++++------------
 1 file changed, 53 insertions(+), 19 deletions(-)

diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index 5dc5e3c..1a88df6 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -166,7 +166,7 @@ static BOOL X11DRV_CLIPBOARD_RenderFormat(Display *display, LPWINE_CLIPDATA lpDa
 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(Display *display, LPWINE_CLIPDATA lpData);
-static BOOL X11DRV_CLIPBOARD_RenderSynthesizedDIB(Display *display);
+static BOOL X11DRV_CLIPBOARD_RenderSynthesizedDIB(Display *display, BOOL isV5);
 static BOOL X11DRV_CLIPBOARD_RenderSynthesizedBitmap(Display *display);
 static BOOL X11DRV_CLIPBOARD_RenderSynthesizedEnhMetaFile(Display *display);
 static void X11DRV_HandleSelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple );
@@ -191,6 +191,7 @@ static const struct
     { CF_TIFF, XATOM_WCF_TIFF, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
     { CF_OEMTEXT, XATOM_WCF_OEMTEXT, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
     { CF_DIB, XA_PIXMAP, X11DRV_CLIPBOARD_ImportXAPIXMAP, X11DRV_CLIPBOARD_ExportXAPIXMAP },
+    { CF_DIBV5, XA_PIXMAP, X11DRV_CLIPBOARD_ImportXAPIXMAP, X11DRV_CLIPBOARD_ExportXAPIXMAP },
     { CF_PALETTE, XATOM_WCF_PALETTE, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
     { CF_PENDATA, XATOM_WCF_PENDATA, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
     { CF_RIFF, XATOM_WCF_RIFF, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
@@ -201,13 +202,13 @@ static const struct
     { CF_ENHMETAFILE, XATOM_WCF_ENHMETAFILE, X11DRV_CLIPBOARD_ImportEnhMetaFile, X11DRV_CLIPBOARD_ExportEnhMetaFile },
     { CF_HDROP, XATOM_text_uri_list, X11DRV_CLIPBOARD_ImportTextUriList, X11DRV_CLIPBOARD_ExportHDROP },
     { CF_LOCALE, XATOM_WCF_LOCALE, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
-    { CF_DIBV5, XATOM_WCF_DIBV5, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
     { CF_OWNERDISPLAY, XATOM_WCF_OWNERDISPLAY, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
     { CF_DSPTEXT, XATOM_WCF_DSPTEXT, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
     { CF_DSPBITMAP, XATOM_WCF_DSPBITMAP, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
     { CF_DSPMETAFILEPICT, XATOM_WCF_DSPMETAFILEPICT, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
     { CF_DSPENHMETAFILE, XATOM_WCF_DSPENHMETAFILE, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
     { CF_DIB, XATOM_image_bmp, X11DRV_CLIPBOARD_ImportImageBmp, X11DRV_CLIPBOARD_ExportImageBmp },
+    { CF_DIBV5, XATOM_image_bmp, X11DRV_CLIPBOARD_ImportImageBmp, X11DRV_CLIPBOARD_ExportImageBmp },
 };
 
 static struct list format_list = LIST_INIT( format_list );
@@ -581,12 +582,14 @@ static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData)
         lpData->wFormatID <= CF_GDIOBJLAST) || 
         lpData->wFormatID == CF_BITMAP || 
         lpData->wFormatID == CF_DIB || 
+        lpData->wFormatID == CF_DIBV5 ||
         lpData->wFormatID == CF_PALETTE)
     {
       if (lpData->hData)
 	DeleteObject(lpData->hData);
 
-      if ((lpData->wFormatID == CF_DIB) && lpData->drvData)
+      if ((lpData->wFormatID == CF_DIB || lpData->wFormatID == CF_DIBV5) &&
+          lpData->drvData)
           XFreePixmap(gdi_display, lpData->drvData);
     }
     else if (lpData->wFormatID == CF_METAFILEPICT)
@@ -773,7 +776,8 @@ static BOOL X11DRV_CLIPBOARD_RenderSynthesizedFormat(Display *display, LPWINE_CL
             switch (wFormatID)
 	    {
                 case CF_DIB:
-                    bret = X11DRV_CLIPBOARD_RenderSynthesizedDIB( display );
+                case CF_DIBV5:
+                    bret = X11DRV_CLIPBOARD_RenderSynthesizedDIB( display, wFormatID == CF_DIBV5 );
                     break;
 
                 case CF_BITMAP:
@@ -1086,14 +1090,15 @@ static WCHAR* uri_to_dos(char *encodedURI)
  *
  * Renders synthesized DIB
  */
-static BOOL X11DRV_CLIPBOARD_RenderSynthesizedDIB(Display *display)
+static BOOL X11DRV_CLIPBOARD_RenderSynthesizedDIB(Display *display, BOOL isV5)
 {
     BOOL bret = FALSE;
     LPWINE_CLIPDATA lpSource = NULL;
+    UINT cf = isV5 ? CF_DIBV5 : CF_DIB;
 
     TRACE("\n");
 
-    if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_DIB)) && lpSource->hData)
+    if ((lpSource = X11DRV_CLIPBOARD_LookupData(cf)) && lpSource->hData)
     {
         bret = TRUE;
     }
@@ -1107,7 +1112,7 @@ static BOOL X11DRV_CLIPBOARD_RenderSynthesizedDIB(Display *display)
             HGLOBAL hData = create_dib_from_bitmap( lpSource->hData );
             if (hData)
             {
-                X11DRV_CLIPBOARD_InsertClipboardData(CF_DIB, hData, 0, NULL, TRUE);
+                X11DRV_CLIPBOARD_InsertClipboardData(cf, hData, 0, NULL, TRUE);
                 bret = TRUE;
             }
         }
@@ -1149,9 +1154,7 @@ static BOOL X11DRV_CLIPBOARD_RenderSynthesizedBitmap(Display *display)
             lpbmih = GlobalLock(lpSource->hData);
             if (lpbmih)
             {
-                offset = sizeof(BITMAPINFOHEADER)
-                      + ((lpbmih->biBitCount <= 8) ? (sizeof(RGBQUAD) *
-                        (1 << lpbmih->biBitCount)) : 0);
+                offset = lpbmih->biSize - lpbmih->biSizeImage;
 
                 hData = CreateDIBitmap(hdc, lpbmih, CBM_INIT, (LPBYTE)lpbmih +
                     offset, (LPBITMAPINFO) lpbmih, DIB_RGB_COLORS);
@@ -1167,6 +1170,37 @@ static BOOL X11DRV_CLIPBOARD_RenderSynthesizedBitmap(Display *display)
             }
         }
     }
+    else if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_DIBV5)) &&
+        (!(lpSource->wFlags & CF_FLAG_SYNTHESIZED) || lpSource->hData))
+    {
+        /* Render source if required */
+        if (lpSource->hData || X11DRV_CLIPBOARD_RenderFormat(display, lpSource))
+        {
+            HDC hdc;
+            HBITMAP hData = NULL;
+            unsigned int offset;
+            LPBITMAPV5HEADER lpbmih;
+
+            hdc = GetDC(NULL);
+            lpbmih = GlobalLock(lpSource->hData);
+            if (lpbmih)
+            {
+                offset = lpbmih->bV5Size - lpbmih->bV5SizeImage;
+
+                hData = CreateDIBitmap(hdc, (BITMAPINFOHEADER *) lpbmih, CBM_INIT, (LPBYTE)lpbmih +
+                    offset, (LPBITMAPINFO) lpbmih, DIB_RGB_COLORS);
+
+                GlobalUnlock(lpSource->hData);
+            }
+            ReleaseDC(NULL, hdc);
+
+            if (hData)
+            {
+                X11DRV_CLIPBOARD_InsertClipboardData(CF_BITMAP, hData, 0, NULL, TRUE);
+                bret = TRUE;
+            }
+        }
+    }
 
     return bret;
 }
@@ -3201,15 +3235,14 @@ static BOOL X11DRV_CLIPBOARD_SynthesizeData(UINT wFormatID)
         bsyn = (lpSource = X11DRV_CLIPBOARD_LookupData(CF_ENHMETAFILE)) &&
             ~lpSource->wFlags & CF_FLAG_SYNTHESIZED;
     }
-    else if (wFormatID == CF_DIB)
+    else if (wFormatID == CF_BITMAP || wFormatID == CF_DIB || wFormatID == CF_DIBV5)
     {
-        bsyn = (lpSource = X11DRV_CLIPBOARD_LookupData(CF_BITMAP)) &&
-            ~lpSource->wFlags & CF_FLAG_SYNTHESIZED;
-    }
-    else if (wFormatID == CF_BITMAP)
-    {
-        bsyn = (lpSource = X11DRV_CLIPBOARD_LookupData(CF_DIB)) &&
-            ~lpSource->wFlags & CF_FLAG_SYNTHESIZED;
+        bsyn = ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_BITMAP)) &&
+            ~lpSource->wFlags & CF_FLAG_SYNTHESIZED) ||
+            ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_DIB)) &&
+            ~lpSource->wFlags & CF_FLAG_SYNTHESIZED) ||
+            ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_DIBV5)) &&
+            ~lpSource->wFlags & CF_FLAG_SYNTHESIZED);
     }
 
     if (bsyn)
@@ -3239,8 +3272,9 @@ void CDECL X11DRV_EndClipboardUpdate(void)
     X11DRV_CLIPBOARD_SynthesizeData(CF_METAFILEPICT);
 
     /* DIB <-> Bitmap mapping */
-    X11DRV_CLIPBOARD_SynthesizeData(CF_DIB);
     X11DRV_CLIPBOARD_SynthesizeData(CF_BITMAP);
+    X11DRV_CLIPBOARD_SynthesizeData(CF_DIB);
+    X11DRV_CLIPBOARD_SynthesizeData(CF_DIBV5);
 
     TRACE("%d formats added to cached data\n", ClipDataCount - count);
 }
-- 
2.7.2




More information about the wine-patches mailing list