summaryrefslogtreecommitdiff
path: root/hw/xwin/winclipboard/wndproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xwin/winclipboard/wndproc.c')
-rw-r--r--hw/xwin/winclipboard/wndproc.c325
1 files changed, 83 insertions, 242 deletions
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index ec5543ab6..bc954c0c6 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -30,24 +30,18 @@
* Colin Harrison
*/
+#define WINVER 0x0600
+
#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
-/*
- * Including any server header might define the macro _XSERVER64 on 64 bit machines.
- * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen.
- * So let's undef that macro if necessary.
- */
-#ifdef _XSERVER64
-#undef _XSERVER64
-#endif
-
#include <sys/types.h>
#include <sys/time.h>
#include <limits.h>
-#include <X11/Xatom.h>
+#include <xcb/xproto.h>
+#include <xcb/xcb_aux.h>
#include "internal.h"
#include "winclipboard.h"
@@ -58,16 +52,12 @@
#define WIN_POLL_TIMEOUT 1
-#ifndef WM_CLIPBOARDUPDATE
-#define WM_CLIPBOARDUPDATE 0x031D
-#endif
-
/*
* Process X events up to specified timeout
*/
static int
-winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
+winProcessXEventsTimeout(HWND hwnd, xcb_window_t iWindow, xcb_connection_t *conn,
ClipboardConversionData *data, ClipboardAtoms *atoms, int iTimeoutSec)
{
int iConnNumber;
@@ -78,7 +68,7 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
iTimeoutSec);
/* Get our connection number */
- iConnNumber = XConnectionNumber(pDisplay);
+ iConnNumber = xcb_get_file_descriptor(conn);
/* Loop for X events */
while (1) {
@@ -86,7 +76,7 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
long remainingTime;
/* Process X events */
- iReturn = winClipboardFlushXEvents(hwnd, iWindow, pDisplay, data, atoms);
+ iReturn = winClipboardFlushXEvents(hwnd, iWindow, conn, data, atoms);
winDebug("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n", iReturn);
@@ -96,7 +86,7 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
}
/* We need to ensure that all pending requests are sent */
- XFlush(pDisplay);
+ xcb_flush(conn);
/* Setup the file descriptor set */
FD_ZERO(&fdsRead);
@@ -138,12 +128,10 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
LRESULT CALLBACK
winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
- static HWND s_hwndNextViewer;
- static Bool s_fCBCInitialized;
- static Display *pDisplay;
- static Window iWindow;
+ static xcb_connection_t *conn;
+ static xcb_window_t iWindow;
static ClipboardAtoms *atoms;
- static Bool fRunning;
+ static BOOL fRunning;
/* Branch on message type */
switch (message) {
@@ -151,18 +139,11 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
winDebug("winClipboardWindowProc - WM_DESTROY\n");
- if (g_fHasModernClipboardApi)
- {
- /* Remove clipboard listener */
- g_fpRemoveClipboardFormatListener(hwnd);
- }
- else
- {
- /* Remove ourselves from the clipboard chain */
- ChangeClipboardChain(hwnd, s_hwndNextViewer);
- }
-
- s_hwndNextViewer = NULL;
+ /* Remove clipboard listener */
+ typedef WINBOOL WINAPI (*REMOVECLIPBOARDFORMATLISTENERPROC)(HWND hwnd);
+ REMOVECLIPBOARDFORMATLISTENERPROC fpRemoveClipboardFormatListener = (REMOVECLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"RemoveClipboardFormatListener");
+ if (fpRemoveClipboardFormatListener)
+ fpRemoveClipboardFormatListener(hwnd);
}
return 0;
@@ -180,143 +161,24 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
winDebug("winClipboardWindowProc - WM_CREATE\n");
- pDisplay = cwcp->pClipboardDisplay;
+ conn = cwcp->pClipboardDisplay;
iWindow = cwcp->iClipboardWindow;
atoms = cwcp->atoms;
fRunning = TRUE;
- if (g_fHasModernClipboardApi)
- {
- g_fpAddClipboardFormatListener(hwnd);
- }
- else
- {
- 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;
-
- case WM_CHANGECBCHAIN:
- {
- winDebug("winClipboardWindowProc - WM_CHANGECBCHAIN: wParam(%p) "
- "lParam(%p) s_hwndNextViewer(%p)\n",
- (HWND)wParam, (HWND)lParam, s_hwndNextViewer);
-
- if ((HWND) wParam == s_hwndNextViewer) {
- s_hwndNextViewer = (HWND) lParam;
- if (s_hwndNextViewer == hwnd) {
- s_hwndNextViewer = NULL;
- ErrorF("winClipboardWindowProc - WM_CHANGECBCHAIN: "
- "attempted to set next window to ourselves.");
- }
- }
- else if (s_hwndNextViewer)
- SendMessage(s_hwndNextViewer, message, wParam, lParam);
-
- }
- winDebug("winClipboardWindowProc - WM_CHANGECBCHAIN: Exit\n");
- return 0;
-
- case WM_WM_REINIT:
- {
- /* Ensure that we're in the clipboard chain. Some apps,
- * WinXP's remote desktop for one, don't play nice with the
- * chain. This message is called whenever we receive a
- * WM_ACTIVATEAPP message to ensure that we continue to
- * receive clipboard messages.
- *
- * It might be possible to detect if we're still in the chain
- * by calling SendMessage (GetClipboardViewer(),
- * WM_DRAWCLIPBOARD, 0, 0); and then seeing if we get the
- * WM_DRAWCLIPBOARD message. That, however, might be more
- * expensive than just putting ourselves back into the chain.
- */
-
- HWND first, next;
- DWORD error_code = 0;
-
- 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! */
- winDebug(" WM_WM_REINIT: Replacing us(%p) with %p at head "
- "of chain\n", hwnd, s_hwndNextViewer);
- s_fCBCInitialized = FALSE;
- ChangeClipboardChain(hwnd, s_hwndNextViewer);
- s_hwndNextViewer = NULL;
- s_fCBCInitialized = FALSE;
- winDebug(" WM_WM_REINIT: Putting us back at head of chain.\n");
- first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
- if (first == hwnd)
- return 0; /* Make sure it's not us! */
- 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;
+ typedef WINBOOL WINAPI (*ADDCLIPBOARDFORMATLISTENERPROC)(HWND hwnd);
+ ADDCLIPBOARDFORMATLISTENERPROC fpAddClipboardFormatListener = (ADDCLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"AddClipboardFormatListener");
+ if (fpAddClipboardFormatListener)
+ fpAddClipboardFormatListener(hwnd);
}
- winDebug("winClipboardWindowProc - WM_WM_REINIT: Exit\n");
return 0;
- case WM_DRAWCLIPBOARD:
case WM_CLIPBOARDUPDATE:
{
- static Bool s_fProcessingDrawClipboard = FALSE;
- int iReturn;
+ xcb_generic_error_t *error;
+ xcb_void_cookie_t cookie_set;
- if (message == WM_DRAWCLIPBOARD)
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n");
- else
- winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Enter\n");
-
- 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;
- }
- }
+ winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Enter\n");
/*
* NOTE: We cannot bail out when NULL == GetClipboardOwner ()
@@ -329,12 +191,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
/* Bail when we still own the clipboard */
if (hwnd == GetClipboardOwner()) {
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
"We own the clipboard, returning.\n");
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
- s_fProcessingDrawClipboard = FALSE;
- if (s_hwndNextViewer)
- SendMessage(s_hwndNextViewer, message, wParam, lParam);
+ winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Exit\n");
+
return 0;
}
@@ -350,7 +210,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if (!IsClipboardFormatAvailable(CF_TEXT)
&& !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ xcb_get_selection_owner_cookie_t cookie_get;
+ xcb_get_selection_owner_reply_t *reply;
+
+ winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
"Clipboard does not contain CF_TEXT nor "
"CF_UNICODETEXT.\n");
@@ -358,87 +221,78 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
* We need to make sure that the X Server has processed
* previous XSetSelectionOwner messages.
*/
- XSync(pDisplay, FALSE);
+ xcb_aux_sync(conn);
winDebug("winClipboardWindowProc - XSync done.\n");
/* Release PRIMARY selection if owned */
- iReturn = XGetSelectionOwner(pDisplay, XA_PRIMARY);
- if (iReturn == iWindow) {
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "PRIMARY selection is owned by us.\n");
- XSetSelectionOwner(pDisplay, XA_PRIMARY, None, CurrentTime);
+ cookie_get = xcb_get_selection_owner(conn, XCB_ATOM_PRIMARY);
+ reply = xcb_get_selection_owner_reply(conn, cookie_get, NULL);
+ if (reply) {
+ if (reply->owner == iWindow) {
+ winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
+ "PRIMARY selection is owned by us, releasing.\n");
+ xcb_set_selection_owner(conn, XCB_NONE, XCB_ATOM_PRIMARY, XCB_CURRENT_TIME);
+ }
+ free(reply);
}
- else if (BadWindow == iReturn || BadAtom == iReturn)
- ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "XGetSelectionOwner failed for PRIMARY: %d\n",
- iReturn);
/* Release CLIPBOARD selection if owned */
- iReturn = XGetSelectionOwner(pDisplay, atoms->atomClipboard);
- if (iReturn == iWindow) {
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "CLIPBOARD selection is owned by us, releasing\n");
- XSetSelectionOwner(pDisplay, atoms->atomClipboard, None, CurrentTime);
+ cookie_get = xcb_get_selection_owner(conn, atoms->atomClipboard);
+ reply = xcb_get_selection_owner_reply(conn, cookie_get, NULL);
+ if (reply) {
+ if (reply->owner == iWindow) {
+ winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
+ "CLIPBOARD selection is owned by us, releasing\n");
+ xcb_set_selection_owner(conn, XCB_NONE, atoms->atomClipboard, XCB_CURRENT_TIME);
+ }
+ free(reply);
}
- else if (BadWindow == iReturn || BadAtom == iReturn)
- ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "XGetSelectionOwner failed for CLIPBOARD: %d\n",
- iReturn);
-
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
- s_fProcessingDrawClipboard = FALSE;
- if (s_hwndNextViewer)
- SendMessage(s_hwndNextViewer, message, wParam, lParam);
+
+ winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Exit\n");
+
return 0;
}
/* Reassert ownership of PRIMARY */
- iReturn = XSetSelectionOwner(pDisplay,
- XA_PRIMARY, iWindow, CurrentTime);
- if (iReturn == BadAtom || iReturn == BadWindow ||
- XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) {
- ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ cookie_set = xcb_set_selection_owner_checked(conn, iWindow, XCB_ATOM_PRIMARY, XCB_CURRENT_TIME);
+ error = xcb_request_check(conn, cookie_set);
+ if (error) {
+ ErrorF("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
"Could not reassert ownership of PRIMARY\n");
- }
- else {
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ free(error);
+ } else {
+ winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
"Reasserted ownership of PRIMARY\n");
}
/* Reassert ownership of the CLIPBOARD */
- iReturn = XSetSelectionOwner(pDisplay,
- atoms->atomClipboard, iWindow, CurrentTime);
-
- if (iReturn == BadAtom || iReturn == BadWindow ||
- XGetSelectionOwner(pDisplay, atoms->atomClipboard) != iWindow) {
- ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ cookie_set = xcb_set_selection_owner_checked(conn, iWindow, atoms->atomClipboard, XCB_CURRENT_TIME);
+ error = xcb_request_check(conn, cookie_set);
+ if (error) {
+ ErrorF("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
"Could not reassert ownership of CLIPBOARD\n");
+ free(error);
}
else {
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
"Reasserted ownership of CLIPBOARD\n");
}
/* Flush the pending SetSelectionOwner event now */
- XFlush(pDisplay);
-
- s_fProcessingDrawClipboard = FALSE;
+ xcb_flush(conn);
}
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
- /* Pass the message on the next window in the clipboard viewer chain */
- if (s_hwndNextViewer)
- SendMessage(s_hwndNextViewer, message, wParam, lParam);
+ winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Exit\n");
return 0;
case WM_DESTROYCLIPBOARD:
/*
* NOTE: Intentionally do nothing.
- * Changes in the Win32 clipboard are handled by WM_DRAWCLIPBOARD
+ * Changes in the Win32 clipboard are handled by WM_CLIPBOARDUPDATE
* above. We only process this message to conform to the specs
* for delayed clipboard rendering in Win32. You might think
* that we need to release ownership of the X11 selections, but
- * we do not, because a WM_DRAWCLIPBOARD message will closely
+ * we do not, because a WM_CLIPBOARDUPDATE message will closely
* follow this message and reassert ownership of the X11
* selections, handling the issue for us.
*/
@@ -462,20 +316,16 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_RENDERFORMAT:
{
int iReturn;
- Bool fConvertToUnicode;
- Bool pasted = FALSE;
- Atom selection;
+ BOOL pasted = FALSE;
+ xcb_atom_t selection;
ClipboardConversionData data;
int best_target = 0;
winDebug("winClipboardWindowProc - WM_RENDERFORMAT %d - Hello.\n",
(int)wParam);
- /* Flag whether to convert to Unicode or not */
- fConvertToUnicode = (CF_UNICODETEXT == wParam);
-
selection = winClipboardGetLastOwnedSelectionAtom(atoms);
- if (selection == None) {
+ if (selection == XCB_NONE) {
ErrorF("winClipboardWindowProc - no monitored selection is owned\n");
goto fake_paste;
}
@@ -483,20 +333,16 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
winDebug("winClipboardWindowProc - requesting targets for selection from owner\n");
/* Request the selection's supported conversion targets */
- XConvertSelection(pDisplay,
- selection,
- atoms->atomTargets,
- atoms->atomLocalProperty,
- iWindow, CurrentTime);
+ xcb_convert_selection(conn, iWindow, selection, atoms->atomTargets,
+ atoms->atomLocalProperty, XCB_CURRENT_TIME);
/* Process X events */
- data.fUseUnicode = fConvertToUnicode;
data.incr = NULL;
data.incrsize = 0;
iReturn = winProcessXEventsTimeout(hwnd,
iWindow,
- pDisplay,
+ conn,
&data,
atoms,
WIN_POLL_TIMEOUT);
@@ -511,17 +357,15 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
struct target_priority
{
- Atom target;
+ xcb_atom_t target;
unsigned int priority;
};
struct target_priority target_priority_table[] =
{
-#ifdef X_HAVE_UTF8_STRING
{ atoms->atomUTF8String, 0 },
-#endif
- { atoms->atomCompoundText, 1 },
- { XA_STRING, 2 },
+ // { atoms->atomCompoundText, 1 }, not implemented (yet?)
+ { XCB_ATOM_STRING, 2 },
};
int best_priority = INT_MAX;
@@ -553,16 +397,13 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
winDebug("winClipboardWindowProc - requesting selection from owner\n");
/* Request the selection contents */
- XConvertSelection(pDisplay,
- selection,
- best_target,
- atoms->atomLocalProperty,
- iWindow, CurrentTime);
+ xcb_convert_selection(conn, iWindow, selection, best_target,
+ atoms->atomLocalProperty, XCB_CURRENT_TIME);
/* Process X events */
iReturn = winProcessXEventsTimeout(hwnd,
iWindow,
- pDisplay,
+ conn,
&data,
atoms,
WIN_POLL_TIMEOUT);
@@ -605,7 +446,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
* Process any pending Windows messages
*/
-Bool
+BOOL
winClipboardFlushWindowsMessageQueue(HWND hwnd)
{
MSG msg;