clipboard

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch fixes cut and paste problems with Agent as reported by Rein
Klazes.

Changlog:
  fix handling of synthesized data
  don't report errors when there is no selection owner
  reintegrate the COMPOUND_TEXT patch by Kusanagi Kouichi
Index: dlls/x11drv/clipboard.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/clipboard.c,v
retrieving revision 1.9
diff -u -w -r1.9 clipboard.c
--- dlls/x11drv/clipboard.c	23 Jun 2003 23:02:03 -0000	1.9
+++ dlls/x11drv/clipboard.c	3 Jul 2003 20:15:40 -0000
@@ -84,10 +84,10 @@
 
 #define HGDIOBJ_32(handle16)  ((HGDIOBJ)(ULONG_PTR)(handle16))
 
-/* Maximum wait time for slection notify */
+/* Maximum wait time for selection notify */
 #define SELECTION_RETRIES 500  /* wait for .1 seconds */
 #define SELECTION_WAIT    1000 /* us */
-/* Minium seconds that must lapse between owner queries */
+/* Minimum seconds that must lapse between owner queries */
 #define OWNERQUERYLAPSETIME 1
 
 /* Selection masks */
@@ -95,15 +95,20 @@
 #define S_PRIMARY        1
 #define S_CLIPBOARD      2
 
-#define _CLIPBOARD    "CLIPBOARD"              /* CLIPBOARD atom name */
+/* CLIPBOARD atom names */
+#define _CLIPBOARD     "CLIPBOARD"
 #define _TARGETS      "TARGETS"
 #define _MULTIPLE     "MULTIPLE"
 #define _SELECTIONDATA "SELECTION_DATA"
+#define _TEXT          "TEXT"
+#define _COMPOUNDTEXT  "COMPOUND_TEXT"
 
 Atom xaClipboard = None;
 Atom xaTargets = None;
 Atom xaMultiple = None;
 Atom xaSelectionData = None;
+Atom xaText = None;
+Atom xaCompoundText = None;
 
 static int selectionAcquired = 0;              /* Contains the current selection masks */
 static Window selectionWindow = None;          /* The top level X window which owns the selection */
@@ -120,14 +125,19 @@
 HANDLE X11DRV_CLIPBOARD_ImportMetaFilePict(LPBYTE lpdata, UINT cBytes);
 HANDLE X11DRV_CLIPBOARD_ImportXAPIXMAP(LPBYTE lpdata, UINT cBytes);
 HANDLE X11DRV_CLIPBOARD_ImportXAString(LPBYTE lpdata, UINT cBytes);
-HANDLE X11DRV_CLIPBOARD_ExportClipboardData(LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
-HANDLE X11DRV_CLIPBOARD_ExportXAString(LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
-HANDLE X11DRV_CLIPBOARD_ExportXAPIXMAP(LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
-HANDLE X11DRV_CLIPBOARD_ExportMetaFilePict(LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
-HANDLE X11DRV_CLIPBOARD_ExportEnhMetaFile(LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
+HANDLE X11DRV_CLIPBOARD_ExportClipboardData(Window requestor, Atom aTarget,
+    Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
+HANDLE X11DRV_CLIPBOARD_ExportString(Window requestor, Atom aTarget,
+    Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
+HANDLE X11DRV_CLIPBOARD_ExportXAPIXMAP(Window requestor, Atom aTarget,
+    Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
+HANDLE X11DRV_CLIPBOARD_ExportMetaFilePict(Window requestor, Atom aTarget,
+    Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
+HANDLE X11DRV_CLIPBOARD_ExportEnhMetaFile(Window requestor, Atom aTarget,
+    Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
 UINT X11DRV_CLIPBOARD_InsertClipboardFormat(LPCSTR FormatName, LPCSTR PropertyName);
 static BOOL X11DRV_CLIPBOARD_ReadSelection(LPWINE_CLIPFORMAT lpData, Window w, Atom prop);
-static BOOL X11DRV_CLIPBOARD_RenderText(UINT wFormatID);
+static BOOL X11DRV_CLIPBOARD_RenderSynthesizedText(UINT wFormatID);
 static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData);
 static BOOL X11DRV_CLIPBOARD_IsSelectionOwner(void);
 static int X11DRV_CLIPBOARD_QueryAvailableData(LPCLIPBOARDINFO lpcbinfo);
@@ -180,7 +190,7 @@
         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[10], &ClipFormats[12]},
 
     { CF_UNICODETEXT, "WCF_UNICODETEXT", XA_STRING, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportXAString,
-	X11DRV_CLIPBOARD_ExportXAString, &ClipFormats[11], &ClipFormats[13]},
+	X11DRV_CLIPBOARD_ExportString, &ClipFormats[11], &ClipFormats[13]},
 
     { CF_ENHMETAFILE, "WCF_ENHMETAFILE", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportEnhMetaFile,
         X11DRV_CLIPBOARD_ExportEnhMetaFile, &ClipFormats[12], &ClipFormats[14]},
@@ -227,6 +237,8 @@
 { 
     /* lpszProperty, Alias */
     { "text/rtf", 0, "text/richtext", 0 },
+    { "XAString", XA_STRING, _COMPOUNDTEXT, 0 },
+    { "XAString", XA_STRING, _TEXT, 0 },
 };
 
 
@@ -259,6 +271,8 @@
     xaTargets = TSXInternAtom( display, _TARGETS, FALSE );
     xaMultiple = TSXInternAtom(display, _MULTIPLE, False);
     xaSelectionData = TSXInternAtom(display, _SELECTIONDATA, False);
+    xaText = TSXInternAtom(display, _TEXT, False);
+    xaCompoundText = TSXInternAtom(display, _COMPOUNDTEXT, False);
 
     if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Clipboard", &hkey))
     {
@@ -290,7 +304,9 @@
     for (i = 0; i < sizeof(PropertyAliasMap)/sizeof(PROPERTYALIASMAP); i++)
     {
         lpalias = &PropertyAliasMap[i];
+        if (!lpalias->drvDataProperty)
         lpalias->drvDataProperty = TSXInternAtom(display, lpalias->lpszProperty, False);
+        if (!lpalias->drvDataAlias)
         lpalias->drvDataAlias = TSXInternAtom(display, lpalias->lpszAlias, False);
     }
 
@@ -658,7 +674,7 @@
         {
             X11DRV_EmptyClipboard();
 
-            if (!X11DRV_CLIPBOARD_QueryAvailableData(lpcbinfo))
+            if (X11DRV_CLIPBOARD_QueryAvailableData(lpcbinfo) < 0)
             {
                 ERR("Failed to cache clipboard data owned by another process.\n");
                 bret = FALSE;
@@ -689,7 +705,9 @@
     if (lpData->hData32 || lpData->hData16)
         return bret; /* Already rendered */
 
-    if (!X11DRV_CLIPBOARD_IsSelectionOwner())
+    if (lpData->wFlags & CF_FLAG_SYNTHESIZED)
+        bret = X11DRV_CLIPBOARD_RenderSynthesizedFormat(lpData);
+    else if (!X11DRV_CLIPBOARD_IsSelectionOwner())
     {
         if (!X11DRV_CLIPBOARD_ReadClipboardData(lpData->wFormatID))
         {
@@ -700,14 +718,9 @@
     }
     else
     {
-        if (lpData->wFlags & CF_FLAG_SYNTHESIZED)
-            bret = X11DRV_CLIPBOARD_RenderSynthesizedFormat(lpData);
-        else
-        {
             CLIPBOARDINFO cbInfo;
 
-            if (X11DRV_CLIPBOARD_GetClipboardInfo(&cbInfo) &&
-                cbInfo.hWndOwner)
+        if (X11DRV_CLIPBOARD_GetClipboardInfo(&cbInfo) && cbInfo.hWndOwner)
             {
                 /* Send a WM_RENDERFORMAT message to notify the owner to render the
                  * data requested into the clipboard.
@@ -724,7 +737,6 @@
                 bret = FALSE;
             }
         }
-    }
 
     return bret;
 }
@@ -791,12 +803,14 @@
 {
     BOOL bret = FALSE;
 
+    TRACE("\n");
+
     if (lpData->wFlags & CF_FLAG_SYNTHESIZED)
     {
         UINT wFormatID = lpData->wFormatID;
 
         if (wFormatID == CF_UNICODETEXT || wFormatID == CF_TEXT || wFormatID == CF_OEMTEXT)
-            bret = X11DRV_CLIPBOARD_RenderText(wFormatID);
+            bret = X11DRV_CLIPBOARD_RenderSynthesizedText(wFormatID);
         else 
         {
             switch (wFormatID)
@@ -822,14 +836,11 @@
 
 
 /**************************************************************************
- *                      X11DRV_CLIPBOARD_RenderText
- *
- * Renders text to the clipboard buffer converting between UNIX and DOS formats.
- *
- * FIXME: Should be a pair of driver functions that convert between OEM text and Windows.
+ *                      X11DRV_CLIPBOARD_RenderSynthesizedText
  *
+ * Renders synthesized text
  */
-static BOOL X11DRV_CLIPBOARD_RenderText(UINT wFormatID)
+static BOOL X11DRV_CLIPBOARD_RenderSynthesizedText(UINT wFormatID)
 {
     LPCSTR lpstrS;
     LPSTR  lpstrT;
@@ -839,27 +850,33 @@
 
     TRACE(" %d\n", wFormatID);
 
-    if (X11DRV_CLIPBOARD_LookupData(wFormatID))
+    if ((lpSource = X11DRV_CLIPBOARD_LookupData(wFormatID)) &&
+        lpSource->hData32)
         return TRUE;
 
-    if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_UNICODETEXT)))
+    /* Look for rendered source or non-synthesized source */
+    if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_UNICODETEXT)) &&
+        (!(lpSource->wFlags & CF_FLAG_SYNTHESIZED) || lpSource->hData32))
     {
         TRACE("UNICODETEXT -> %d\n", wFormatID);
     }
-    else if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_TEXT)))
+    else if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_TEXT)) &&
+        (!(lpSource->wFlags & CF_FLAG_SYNTHESIZED) || lpSource->hData32))
     {
         TRACE("TEXT -> %d\n", wFormatID);
     }
-    else if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_OEMTEXT)))
+    else if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_OEMTEXT)) &&
+        (!(lpSource->wFlags & CF_FLAG_SYNTHESIZED) || lpSource->hData32))
     {
         TRACE("OEMTEXT -> %d\n", wFormatID);
     }
 
-    if (!lpSource)
+    if (!lpSource || (lpSource->wFlags & CF_FLAG_SYNTHESIZED &&
+        !lpSource->hData32))
         return FALSE;
 
-    /* First render the source text format */
-    if (!X11DRV_CLIPBOARD_RenderFormat(lpSource))
+    /* Ask the clipboard owner to render the source text if necessary */
+    if (!lpSource->hData32 && !X11DRV_CLIPBOARD_RenderFormat(lpSource))
         return FALSE;
 
     if (lpSource->hData32)
@@ -1042,7 +1059,8 @@
  *
  *  Generic export clipboard data routine.
  */
-HANDLE X11DRV_CLIPBOARD_ExportClipboardData(LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
+HANDLE X11DRV_CLIPBOARD_ExportClipboardData(Window requestor, Atom aTarget,
+    Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
 {
     LPVOID lpClipData;
     UINT cBytes = 0;
@@ -1077,7 +1095,8 @@
 /**************************************************************************
  *		X11DRV_CLIPBOARD_ExportXAString
  *
- *  Export CF_UNICODE converting the string to XA_STRING
+ *  Export CF_UNICODE converting the string to XA_STRING.
+ *  Helper function for X11DRV_CLIPBOARD_ExportString.
  */
 HANDLE X11DRV_CLIPBOARD_ExportXAString(LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
 {
@@ -1092,12 +1111,6 @@
     GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTUNIXCODEPAGE | 
         LOCALE_RETURN_NUMBER, (WCHAR *)&text_cp, (sizeof(UINT)/sizeof(WCHAR)));
 
-    if (!X11DRV_CLIPBOARD_RenderFormat(lpData))
-    {
-        ERR("Failed to export %d format\n", lpData->wFormatID);
-        return 0;
-    }
-
     uni_text = GlobalLock(lpData->hData32);
 
     size = WideCharToMultiByte(text_cp, 0, uni_text, -1, NULL, 0, NULL, NULL);
@@ -1129,11 +1142,75 @@
 
 
 /**************************************************************************
+ *		X11DRV_CLIPBOARD_ExportCompoundText
+ *
+ *  Export CF_UNICODE to COMPOUND_TEXT or TEXT
+ *  Helper function for X11DRV_CLIPBOARD_ExportString.
+ */
+HANDLE X11DRV_CLIPBOARD_ExportCompoundText(Window requestor, Atom aTarget, Atom rprop,
+    LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
+{
+    Display *display = thread_display();
+    char* lpstr = 0;
+    XTextProperty prop;
+    XICCEncodingStyle style;
+
+    lpstr = (char*) X11DRV_CLIPBOARD_ExportXAString(lpData, lpBytes);
+
+    if (lpstr)
+    {
+        if (aTarget == xaCompoundText)
+           style = XCompoundTextStyle;
+        else
+           style = XStdICCTextStyle;
+
+        /* Update the X property */
+        wine_tsx11_lock();
+        if (XmbTextListToTextProperty(display, &lpstr, 1, style, &prop) == Success)
+        {
+           XSetTextProperty(display, requestor, &prop, rprop);
+           XFree(prop.value);
+        }
+        wine_tsx11_unlock();
+
+        HeapFree( GetProcessHeap(), 0, lpstr );
+    }
+
+    return 0;
+}
+
+/**************************************************************************
+ *		X11DRV_CLIPBOARD_ExportString
+ *
+ *  Export CF_UNICODE string
+ */
+HANDLE X11DRV_CLIPBOARD_ExportString(Window requestor, Atom aTarget, Atom rprop,
+    LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
+{
+    if (X11DRV_CLIPBOARD_RenderFormat(lpData))
+    {
+        if (aTarget == XA_STRING)
+            return X11DRV_CLIPBOARD_ExportXAString(lpData, lpBytes);
+        else if (aTarget == xaCompoundText || aTarget == xaText)
+            return X11DRV_CLIPBOARD_ExportCompoundText(requestor, aTarget,
+                rprop, lpData, lpBytes);
+        else
+            ERR("Unknown target %ld to %d format\n", aTarget, lpData->wFormatID);
+    }
+    else
+        ERR("Failed to render %d format\n", lpData->wFormatID);
+
+    return 0;
+}
+
+
+/**************************************************************************
  *		X11DRV_CLIPBOARD_ExportXAPIXMAP
  *
  *  Export CF_DIB to XA_PIXMAP.
  */
-HANDLE X11DRV_CLIPBOARD_ExportXAPIXMAP(LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
+HANDLE X11DRV_CLIPBOARD_ExportXAPIXMAP(Window requestor, Atom aTarget, Atom rprop,
+    LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
 {
     HDC hdc;
     Pixmap pixmap;
@@ -1161,7 +1238,8 @@
  *
  *  Export MetaFilePict.
  */
-HANDLE X11DRV_CLIPBOARD_ExportMetaFilePict(LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
+HANDLE X11DRV_CLIPBOARD_ExportMetaFilePict(Window requestor, Atom aTarget, Atom rprop,
+    LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
 {
     if (!X11DRV_CLIPBOARD_RenderFormat(lpdata))
     {
@@ -1179,7 +1257,8 @@
  *
  *  Export EnhMetaFile.
  */
-HANDLE X11DRV_CLIPBOARD_ExportEnhMetaFile(LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
+HANDLE X11DRV_CLIPBOARD_ExportEnhMetaFile(Window requestor, Atom aTarget, Atom rprop,
+    LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
 {
     if (!X11DRV_CLIPBOARD_RenderFormat(lpdata))
     {
@@ -1268,7 +1347,7 @@
         }
 	else
 	{
-            return 0; /* Prevent self request */
+            return -1; /* Prevent self request */
 	}
     }
 
@@ -1282,7 +1361,7 @@
     if (!hWndClipWindow)
     {
         WARN("No window available to retrieve selection!n");
-        return 0;
+        return -1;
     }
 
     w = X11DRV_get_whole_window(GetAncestor(hWndClipWindow, GA_ROOT));
@@ -1290,11 +1369,17 @@
     /*
      * Query the selection owner for the TARGETS property
      */
+    if (TSXGetSelectionOwner(display,XA_PRIMARY) ||
+        TSXGetSelectionOwner(display,xaClipboard))
+    {
     if (X11DRV_CLIPBOARD_QueryTargets(display, w, XA_PRIMARY, &xe))
         selectionCacheSrc = XA_PRIMARY;
     else if (X11DRV_CLIPBOARD_QueryTargets(display, w, xaClipboard, &xe))
         selectionCacheSrc = xaClipboard;
     else
+            return -1;
+    }
+    else /* No selection owner so report 0 targets available */
         return 0;
 
     /* Read the TARGETS property contents */
@@ -1659,7 +1744,7 @@
 	       * this case, if we clear any selection we may clear the
 	       * new owners selection. To prevent this common case we
 	       * try to open the clipboard. If we can't, we assume it
-	       * was a wine apps that took it and has taken both selectons.
+	       * was a wine apps that took it and has taken both selections.
 	       * In this case, don't bother releasing the other selection.
 	       * Otherwise only release the selection if we still own it.
                */
@@ -1826,7 +1911,12 @@
      */
     if (!(selectionAcquired == (S_PRIMARY | S_CLIPBOARD)))
     {
-        Window owner = X11DRV_get_whole_window(GetAncestor(hWndClipWindow, GA_ROOT));
+        Window owner;
+
+        if (!hWndClipWindow)
+            hWndClipWindow = GetActiveWindow();
+
+        owner = X11DRV_get_whole_window(GetAncestor(hWndClipWindow, GA_ROOT));
 
         /* Grab PRIMARY selection if not owned */
         if (!(selectionAcquired & S_PRIMARY))
@@ -2097,7 +2187,7 @@
     Window selectionPrevWindow;
 
     /* There is nothing to do if we don't own the selection,
-     * or if the X window which currently owns the selecion is different
+     * or if the X window which currently owns the selection is different
      * from the one passed in.
      */
     if (!selectionAcquired || XWnd != selectionWindow
Index: dlls/x11drv/event.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/event.c,v
retrieving revision 1.21
diff -u -w -r1.21 event.c
--- dlls/x11drv/event.c	23 Jun 2003 23:02:03 -0000	1.21
+++ dlls/x11drv/event.c	3 Jul 2003 20:15:43 -0000
@@ -829,7 +829,8 @@
           {
               unsigned char* lpClipData;
               DWORD cBytes;
-              HANDLE hClipData = lpFormat->lpDrvExportFunc(lpData, &cBytes);
+              HANDLE hClipData = lpFormat->lpDrvExportFunc(request, event->target,
+                  rprop, lpData, &cBytes);
 
               if (hClipData && (lpClipData = GlobalLock(hClipData)))
               {
Index: dlls/x11drv/x11drv.h
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv.h,v
retrieving revision 1.2
diff -u -w -r1.2 x11drv.h
--- dlls/x11drv/x11drv.h	23 Jun 2003 23:02:03 -0000	1.2
+++ dlls/x11drv/x11drv.h	3 Jul 2003 20:15:44 -0000
@@ -396,7 +396,8 @@
     struct tagWINE_CLIPDATA *NextData;
 } WINE_CLIPDATA, *LPWINE_CLIPDATA;
 
-typedef HANDLE (*DRVEXPORTFUNC)(LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
+typedef HANDLE (*DRVEXPORTFUNC)(Window requestor, Atom aTarget, Atom rprop,
+    LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
 typedef HANDLE (*DRVIMPORTFUNC)(LPBYTE hData, UINT cBytes);
 
 typedef struct tagWINE_CLIPFORMAT {

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux