mirror of
https://github.com/reactos/wine.git
synced 2025-02-27 00:08:18 +00:00
winex11.drv: Handle clipboard on an auxiliary thread for windowless apps.
This commit is contained in:
parent
f27d88e16f
commit
f1c131ba27
@ -2504,42 +2504,11 @@ INT CDECL X11DRV_GetClipboardFormatName(UINT wFormat, LPWSTR retStr, INT maxlen)
|
|||||||
return strlenW(retStr);
|
return strlenW(retStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void selection_acquire(void)
|
||||||
/**************************************************************************
|
|
||||||
* AcquireClipboard (X11DRV.@)
|
|
||||||
*/
|
|
||||||
int CDECL X11DRV_AcquireClipboard(HWND hWndClipWindow)
|
|
||||||
{
|
{
|
||||||
DWORD procid;
|
|
||||||
Window owner;
|
Window owner;
|
||||||
Display *display;
|
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();
|
owner = thread_selection_wnd();
|
||||||
display = thread_display();
|
display = thread_display();
|
||||||
|
|
||||||
@ -2568,6 +2537,70 @@ int CDECL X11DRV_AcquireClipboard(HWND hWndClipWindow)
|
|||||||
selectionWindow = owner;
|
selectionWindow = owner;
|
||||||
TRACE("Grabbed X selection, owner=(%08x)\n", (unsigned) 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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user