winex11.drv: Handle clipboard on an auxiliary thread for windowless apps
Yuri Khan
yurivkhan at gmail.com
Sun Jul 5 03:02:55 CDT 2009
Fixes clipboard copying in applications that don't handle window
messages. Per Alexandre Julliard's suggestion, no thread is started if
the application passes a non-null window handle to OpenClipboard, so
in the majority of cases the behavior is the same as previously.
-------------- next part --------------
diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index 3806080..0d0389f 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -2504,6 +2504,54 @@ INT CDECL X11DRV_GetClipboardFormatName(UINT wFormat, LPWSTR retStr, INT maxlen)
return strlenW(retStr);
}
+void selection_acquire(void)
+{
+ Window owner;
+ Display *display;
+
+ 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);
+ }
+}
+
+DWORD WINAPI selection_thread_proc(LPVOID lphwnd)
+{
+ HANDLE handles[1];
+
+ selection_acquire();
+
+ while (selectionAcquired)
+ {
+ MsgWaitForMultipleObjectsEx(0, handles, INFINITE, 0, 0);
+ }
+
+ return 0;
+}
/**************************************************************************
* AcquireClipboard (X11DRV.@)
@@ -2511,8 +2559,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);
@@ -2540,33 +2587,21 @@ 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);
-
- /* 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;
+ if (hWndClipWindow)
+ {
+ selection_acquire();
+ }
+ else
+ {
+ selectionThread = CreateThread(NULL, 0, &selection_thread_proc, NULL, 0, NULL);
- wine_tsx11_unlock();
+ if (!selectionThread)
+ {
+ WARN("Could not start clipboard thread\n");
+ return 0;
+ }
- if (selectionAcquired)
- {
- selectionWindow = owner;
- TRACE("Grabbed X selection, owner=(%08x)\n", (unsigned) owner);
+ 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