Clipboard between applications

Ferenc Wagner wferi at tba.elte.hu
Sun Mar 23 18:52:57 CST 2003


I wrote:

> In short, the copying application can read the clipboard,
> but the other one can't.
> [...]
> ### Application startup:
> trace:clipboard:OpenClipboard ((nil))...
> trace:clipboard:OpenClipboard    returning 1
> trace:clipboard:EmptyClipboard ()
> trace:clipboard:GetOpenClipboardWindow ()
> trace:clipboard:X11DRV_AcquireClipboard Grabbed X selection, owner=(00000000)
> trace:clipboard:CloseClipboard ()
> trace:clipboard:X11DRV_IsSelectionOwner status: 3

I found a problem right here.  Accoring to MSDN,
OpenClipboard can be passed the NULL handle:

    "If this parameter is NULL, the open clipboard is
     associated with the current task."

    "If an application or dynamic-link library (DLL)
     specifies a NULL window handle when calling the
     OpenClipboard function, the clipboard is opened but is
     not associated with a window. In such a case,
     GetOpenClipboardWindow returns NULL."

However, Wine doesn't implement this special case.  The NULL
handle rolls through to X11DRV_AcquireClipboard, which grabs
the selection to None (X11 terminology).

As far as I understand, the X selection must be attached to
a window, so I invented the following hack: create a
temporary window, grab the selection for it, then destroy
the window and let Wine take care of the rest (assign the
selection to another window or launch wineclipsrv).  Not
nice, but works.  Unfortunately, I found no way of tricking
X11DRV_ResetSelectionOwner into doing this for me.
Opinions?
                                                Feri.

Index: clipboard.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/clipboard.c,v
retrieving revision 1.8
diff -u -r1.8 clipboard.c
--- clipboard.c	23 Jan 2003 21:32:35 -0000	1.8
+++ clipboard.c	24 Mar 2003 00:49:02 -0000
@@ -947,6 +947,16 @@
     if ( !(selectionAcquired == (S_PRIMARY | S_CLIPBOARD)) )
     {
         Atom xaClipboard = TSXInternAtom(display, _CLIPBOARD, False);
+        BOOL TempWndCreated = False;
+
+        if (hWndClipWindow == NULL)
+        {
+            hWndClipWindow = CreateWindowA ("STATIC", NULL, 0,
+                                            0, 0, 0, 0,
+                                            NULL, NULL, NULL, NULL);
+            TempWndCreated = True;
+          }
+
         owner = X11DRV_get_whole_window( GetAncestor( hWndClipWindow, GA_ROOT ) );
 
         /* Grab PRIMARY selection if not owned */
@@ -968,6 +978,9 @@
 	    selectionWindow = owner;
 	    TRACE("Grabbed X selection, owner=(%08x)\n", (unsigned) owner);
         }
+
+        if (TempWndCreated)
+            DestroyWindow (hWndClipWindow);
     }
 }
 



More information about the wine-devel mailing list