winex11.drv: Move clipboard handling to a separate thread

Yuri Khan yurivkhan at gmail.com
Mon Jun 22 12:47:13 CDT 2009


-------------- next part --------------
diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index b634451..a1808b3 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -2500,6 +2500,48 @@ INT CDECL X11DRV_GetClipboardFormatName(UINT wFormat, LPWSTR retStr, INT maxlen)
     return strlenW(retStr);
 }
 
+DWORD WINAPI selection_thread_proc(LPVOID lphwnd)
+{
+    Window owner;
+    Display *display;
+    HANDLE handles[1];
+
+    owner = thread_selection_wnd();
+    display = thread_display();
+
+    wine_tsx11_lock();
+
+    selectionAcquired = 0;
+    selectionWindow = 0;
+
+    /* Grab PRIMARY selection if not owned */
+    if (use_primary_selection)
+        XSetSelectionOwner(display, XA_PRIMARY, owner, CurrentTime);
+
+    /* Grab CLIPBOARD selection if not owned */
+    XSetSelectionOwner(display, x11drv_atom(CLIPBOARD), owner, CurrentTime);
+
+    if (use_primary_selection && XGetSelectionOwner(display, XA_PRIMARY) == owner)
+        selectionAcquired |= S_PRIMARY;
+
+    if (XGetSelectionOwner(display,x11drv_atom(CLIPBOARD)) == owner)
+        selectionAcquired |= S_CLIPBOARD;
+
+    wine_tsx11_unlock();
+
+    if (selectionAcquired)
+    {
+        selectionWindow = owner;
+        TRACE("Grabbed X selection, owner=(%08x)\n", (unsigned) owner);
+    }
+
+    while (selectionAcquired)
+    {
+        MsgWaitForMultipleObjectsEx(0, handles, INFINITE, 0, 0);
+    }
+
+    return 0;
+}
 
 /**************************************************************************
  *		AcquireClipboard (X11DRV.@)
@@ -2507,8 +2549,7 @@ INT CDECL X11DRV_GetClipboardFormatName(UINT wFormat, LPWSTR retStr, INT maxlen)
 int CDECL X11DRV_AcquireClipboard(HWND hWndClipWindow)
 {
     DWORD procid;
-    Window owner;
-    Display *display;
+    HANDLE selectionThread;
 
     TRACE(" %p\n", hWndClipWindow);
 
@@ -2536,35 +2577,16 @@ int CDECL X11DRV_AcquireClipboard(HWND hWndClipWindow)
         }
     }
 
-    owner = thread_selection_wnd();
-    display = thread_display();
-
-    wine_tsx11_lock();
-
-    selectionAcquired = 0;
-    selectionWindow = 0;
-
-    /* Grab PRIMARY selection if not owned */
-    if (use_primary_selection)
-        XSetSelectionOwner(display, XA_PRIMARY, owner, CurrentTime);
+    selectionThread = CreateThread(NULL, 0, &selection_thread_proc, &hWndClipWindow, 0, NULL);
 
-    /* Grab CLIPBOARD selection if not owned */
-    XSetSelectionOwner(display, x11drv_atom(CLIPBOARD), owner, CurrentTime);
-
-    if (use_primary_selection && XGetSelectionOwner(display, XA_PRIMARY) == owner)
-        selectionAcquired |= S_PRIMARY;
-
-    if (XGetSelectionOwner(display,x11drv_atom(CLIPBOARD)) == owner)
-        selectionAcquired |= S_CLIPBOARD;
-
-    wine_tsx11_unlock();
-
-    if (selectionAcquired)
+    if (!selectionThread)
     {
-        selectionWindow = owner;
-        TRACE("Grabbed X selection, owner=(%08x)\n", (unsigned) owner);
+        WARN("Could not start clipboard thread\n");
+        return 0;
     }
 
+    CloseHandle(selectionThread);
+
     return 1;
 }
 
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index c746546..8933671 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -239,6 +239,9 @@ static Bool filter_event( Display *display, XEvent *event, char *arg )
     case PropertyNotify:
     case ClientMessage:
         return (mask & QS_POSTMESSAGE) != 0;
+    case SelectionClear:
+    case SelectionRequest:
+        return 1;
     default:
         return (mask & QS_SENDMESSAGE) != 0;
     }


More information about the wine-patches mailing list