summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/xwin/winclipboard/internal.h8
-rw-r--r--hw/xwin/winclipboard/thread.c8
-rw-r--r--hw/xwin/winclipboard/wndproc.c109
3 files changed, 86 insertions, 39 deletions
diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h
index 6c26caf2e..d0d8fbda1 100644
--- a/hw/xwin/winclipboard/internal.h
+++ b/hw/xwin/winclipboard/internal.h
@@ -77,6 +77,14 @@ typedef struct
Atom atomTargets;
} ClipboardAtoms;
+/* Modern clipboard API functions */
+typedef wBOOL WINAPI (*ADDCLIPBOARDFORMATLISTENERPROC)(HWND hwnd);
+typedef wBOOL WINAPI (*REMOVECLIPBOARDFORMATLISTENERPROC)(HWND hwnd);
+
+extern Bool g_fHasModernClipboardApi;
+extern ADDCLIPBOARDFORMATLISTENERPROC g_fpAddClipboardFormatListener;
+extern REMOVECLIPBOARDFORMATLISTENERPROC g_fpRemoveClipboardFormatListener;
+
/*
* winclipboardwndproc.c
*/
diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c
index 456e7973a..58b3bf74d 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -84,6 +84,10 @@ static pthread_t g_winClipboardProcThread;
int xfixes_event_base;
int xfixes_error_base;
+Bool g_fHasModernClipboardApi = FALSE;
+ADDCLIPBOARDFORMATLISTENERPROC g_fpAddClipboardFormatListener;
+REMOVECLIPBOARDFORMATLISTENERPROC g_fpRemoveClipboardFormatListener;
+
/*
* Local function prototypes
*/
@@ -127,6 +131,10 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
winDebug("winClipboardProc - Hello\n");
+ g_fpAddClipboardFormatListener = (ADDCLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"AddClipboardFormatListener");
+ g_fpRemoveClipboardFormatListener = (REMOVECLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"RemoveClipboardFormatListener");
+ g_fHasModernClipboardApi = g_fpAddClipboardFormatListener && g_fpRemoveClipboardFormatListener;
+ ErrorF("OS maintains clipboard viewer chain: %s\n", g_fHasModernClipboardApi ? "yes" : "no");
g_winClipboardProcThread = pthread_self();
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index 682f2280e..91f874f61 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -58,6 +58,9 @@
#define WIN_POLL_TIMEOUT 1
+#ifndef WM_CLIPBOARDUPDATE
+#define WM_CLIPBOARDUPDATE 0x031D
+#endif
/*
* Process X events up to specified timeout
@@ -151,8 +154,16 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
winDebug("winClipboardWindowProc - WM_DESTROY\n");
- /* Remove ourselves from the clipboard chain */
- ChangeClipboardChain(hwnd, s_hwndNextViewer);
+ if (g_fHasModernClipboardApi)
+ {
+ /* Remove clipboard listener */
+ g_fpRemoveClipboardFormatListener(hwnd);
+ }
+ else
+ {
+ /* Remove ourselves from the clipboard chain */
+ ChangeClipboardChain(hwnd, s_hwndNextViewer);
+ }
s_hwndNextViewer = NULL;
}
@@ -168,8 +179,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_CREATE:
{
- HWND first, next;
- DWORD error_code = 0;
ClipboardWindowCreationParams *cwcp = (ClipboardWindowCreationParams *)((CREATESTRUCT *)lParam)->lpCreateParams;
winDebug("winClipboardWindowProc - WM_CREATE\n");
@@ -179,16 +188,26 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
atoms = cwcp->atoms;
fRunning = TRUE;
- first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
- if (first == hwnd)
- return 0; /* Make sure it's not us! */
- /* Add ourselves to the clipboard viewer chain */
- next = SetClipboardViewer(hwnd);
- error_code = GetLastError();
- if (SUCCEEDED(error_code) && (next == first)) /* SetClipboardViewer must have succeeded, and the handle */
- s_hwndNextViewer = next; /* it returned must have been the first window in the chain */
+ if (g_fHasModernClipboardApi)
+ {
+ g_fpAddClipboardFormatListener(hwnd);
+ }
else
- s_fCBCInitialized = FALSE;
+ {
+ HWND first, next;
+ DWORD error_code = 0;
+
+ first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
+ if (first == hwnd)
+ return 0; /* Make sure it's not us! */
+ /* Add ourselves to the clipboard viewer chain */
+ next = SetClipboardViewer(hwnd);
+ error_code = GetLastError();
+ if (SUCCEEDED(error_code) && (next == first)) /* SetClipboardViewer must have succeeded, and the handle */
+ s_hwndNextViewer = next; /* it returned must have been the first window in the chain */
+ else
+ s_fCBCInitialized = FALSE;
+ }
}
return 0;
@@ -233,6 +252,11 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
winDebug("winClipboardWindowProc - WM_WM_REINIT: Enter\n");
+ if (g_fHasModernClipboardApi)
+ {
+ return 0;
+ }
+
first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
if (first == hwnd)
return 0; /* Make sure it's not us! */
@@ -257,38 +281,45 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
return 0;
case WM_DRAWCLIPBOARD:
+ case WM_CLIPBOARDUPDATE:
{
static Bool s_fProcessingDrawClipboard = FALSE;
int iReturn;
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n");
+ if (message == WM_DRAWCLIPBOARD)
+ winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n");
+ else
+ winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Enter\n");
- /*
- * We've occasionally seen a loop in the clipboard chain.
- * Try and fix it on the first hint of recursion.
- */
- if (!s_fProcessingDrawClipboard) {
- s_fProcessingDrawClipboard = TRUE;
- }
- else {
- /* Attempt to break the nesting by getting out of the chain, twice?, and then fix and bail */
- s_fCBCInitialized = FALSE;
- ChangeClipboardChain(hwnd, s_hwndNextViewer);
- winFixClipboardChain();
- ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "Nested calls detected. Re-initing.\n");
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
- s_fProcessingDrawClipboard = FALSE;
- return 0;
- }
+ if (!g_fHasModernClipboardApi)
+ {
+ /*
+ * We've occasionally seen a loop in the clipboard chain.
+ * Try and fix it on the first hint of recursion.
+ */
+ if (!s_fProcessingDrawClipboard) {
+ s_fProcessingDrawClipboard = TRUE;
+ }
+ else {
+ /* Attempt to break the nesting by getting out of the chain, twice?, and then fix and bail */
+ s_fCBCInitialized = FALSE;
+ ChangeClipboardChain(hwnd, s_hwndNextViewer);
+ winFixClipboardChain();
+ ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Nested calls detected. Re-initing.\n");
+ winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
+ s_fProcessingDrawClipboard = FALSE;
+ return 0;
+ }
- /* Bail on first message */
- if (!s_fCBCInitialized) {
- s_fCBCInitialized = TRUE;
- s_fProcessingDrawClipboard = FALSE;
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
- return 0;
- }
+ /* Bail on first message */
+ if (!s_fCBCInitialized) {
+ s_fCBCInitialized = TRUE;
+ s_fProcessingDrawClipboard = FALSE;
+ winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
+ return 0;
+ }
+ }
/*
* NOTE: We cannot bail out when NULL == GetClipboardOwner ()