winex11.drv: Handle clipboard on an auxiliary thread for windowless apps.

This commit is contained in:
Yuri Khan 2009-07-10 07:53:00 +07:00 committed by Alexandre Julliard
parent f27d88e16f
commit f1c131ba27
1 changed files with 65 additions and 32 deletions

View File

@ -2504,42 +2504,11 @@ INT CDECL X11DRV_GetClipboardFormatName(UINT wFormat, LPWSTR retStr, INT maxlen)
return strlenW(retStr);
}
/**************************************************************************
* AcquireClipboard (X11DRV.@)
*/
int CDECL X11DRV_AcquireClipboard(HWND hWndClipWindow)
static void selection_acquire(void)
{
DWORD procid;
Window owner;
Display *display;
TRACE(" %p\n", hWndClipWindow);
/*
* It's important that the selection get acquired from the thread
* that owns the clipboard window. The primary reason is that we know
* it is running a message loop and therefore can process the
* X selection events.
*/
if (hWndClipWindow &&
GetCurrentThreadId() != GetWindowThreadProcessId(hWndClipWindow, &procid))
{
if (procid != GetCurrentProcessId())
{
WARN("Setting clipboard owner to other process is not supported\n");
hWndClipWindow = NULL;
}
else
{
TRACE("Thread %x is acquiring selection with thread %x's window %p\n",
GetCurrentThreadId(),
GetWindowThreadProcessId(hWndClipWindow, NULL), hWndClipWindow);
return SendMessageW(hWndClipWindow, WM_X11DRV_ACQUIRE_SELECTION, 0, 0);
}
}
owner = thread_selection_wnd();
display = thread_display();
@ -2568,6 +2537,70 @@ int CDECL X11DRV_AcquireClipboard(HWND hWndClipWindow)
selectionWindow = owner;
TRACE("Grabbed X selection, owner=(%08x)\n", (unsigned) owner);
}
}
static DWORD WINAPI selection_thread_proc(LPVOID unused)
{
selection_acquire();
while (selectionAcquired)
{
MsgWaitForMultipleObjectsEx(0, NULL, INFINITE, QS_SENDMESSAGE, 0);
}
return 0;
}
/**************************************************************************
* AcquireClipboard (X11DRV.@)
*/
int CDECL X11DRV_AcquireClipboard(HWND hWndClipWindow)
{
DWORD procid;
HANDLE selectionThread;
TRACE(" %p\n", hWndClipWindow);
/*
* It's important that the selection get acquired from the thread
* that owns the clipboard window. The primary reason is that we know
* it is running a message loop and therefore can process the
* X selection events.
*/
if (hWndClipWindow &&
GetCurrentThreadId() != GetWindowThreadProcessId(hWndClipWindow, &procid))
{
if (procid != GetCurrentProcessId())
{
WARN("Setting clipboard owner to other process is not supported\n");
hWndClipWindow = NULL;
}
else
{
TRACE("Thread %x is acquiring selection with thread %x's window %p\n",
GetCurrentThreadId(),
GetWindowThreadProcessId(hWndClipWindow, NULL), hWndClipWindow);
return SendMessageW(hWndClipWindow, WM_X11DRV_ACQUIRE_SELECTION, 0, 0);
}
}
if (hWndClipWindow)
{
selection_acquire();
}
else
{
selectionThread = CreateThread(NULL, 0, &selection_thread_proc, NULL, 0, NULL);
if (!selectionThread)
{
WARN("Could not start clipboard thread\n");
return 0;
}
CloseHandle(selectionThread);
}
return 1;
}