diff options
Diffstat (limited to 'hw/xwin/winclipboard/wndproc.c')
-rw-r--r-- | hw/xwin/winclipboard/wndproc.c | 325 |
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; |