aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xwin/winclipboardwrappers.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xwin/winclipboardwrappers.c')
-rw-r--r--xorg-server/hw/xwin/winclipboardwrappers.c198
1 files changed, 195 insertions, 3 deletions
diff --git a/xorg-server/hw/xwin/winclipboardwrappers.c b/xorg-server/hw/xwin/winclipboardwrappers.c
index 2679f4f98..2671fc000 100644
--- a/xorg-server/hw/xwin/winclipboardwrappers.c
+++ b/xorg-server/hw/xwin/winclipboardwrappers.c
@@ -33,21 +33,37 @@
#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
-
#include "win.h"
#include "dixstruct.h"
+#include <X11/Xatom.h>
+
+/*
+ * Constants
+ */
+
+#define CLIP_NUM_SELECTIONS 2
+#define CLIP_OWN_PRIMARY 0
+#define CLIP_OWN_CLIPBOARD 1
/*
* Local function prototypes
*/
DISPATCH_PROC(winProcEstablishConnection);
+DISPATCH_PROC(winProcSetSelectionOwner);
/*
* References to external symbols
*/
+extern Bool g_fClipboardLaunched;
+extern Bool g_fClipboardStarted;
extern Bool g_fClipboard;
+extern Window g_iClipboardWindow;
+extern Atom g_atomLastOwnedSelection;
+extern HWND g_hwndClipboard;
+extern Bool g_fClipboardPrimary;
+
/*
* Wrapper for internal EstablishConnection function.
@@ -62,12 +78,14 @@ winProcEstablishConnection(ClientPtr client)
static int s_iCallCount = 0;
static unsigned long s_ulServerGeneration = 0;
+ #ifdef WINDBG
if (s_iCallCount == 0)
winDebug("winProcEstablishConnection - Hello\n");
+ #endif
/* Do nothing if clipboard is not enabled */
if (!g_fClipboard) {
- ErrorF("winProcEstablishConnection - Clipboard is not enabled, "
+ winDebug ("winProcEstablishConnection - Clipboard is not enabled, "
"returning.\n");
/* Unwrap the original function, call it, and return */
@@ -112,6 +130,13 @@ winProcEstablishConnection(ClientPtr client)
/* Clear original function pointer */
winProcEstablishConnectionOrig = NULL;
+ /* If the clipboard client has already been started, abort */
+ if (g_fClipboardLaunched) {
+ winDebug ("winProcEstablishConnection - Clipboard client already "
+ "launched, returning.\n");
+ return iReturn;
+ }
+
/* Startup the clipboard client if clipboard mode is being used */
if (g_fClipboard) {
/*
@@ -138,8 +163,175 @@ winProcEstablishConnection(ClientPtr client)
return iReturn;
}
- ErrorF("winProcEstablishConnection - winInitClipboard returned.\n");
+ winDebug ("winProcEstablishConnection - winInitClipboard returned.\n");
}
+ /* Flag that clipboard client has been launched */
+ g_fClipboardLaunched = TRUE;
+
return iReturn;
}
+
+/*
+ * Wrapper for internal SetSelectionOwner function.
+ * Grabs ownership of Windows clipboard when X11 clipboard owner changes.
+ */
+int
+winProcSetSelectionOwner(ClientPtr client)
+{
+ int i;
+ DrawablePtr pDrawable;
+ WindowPtr pWindow = None;
+ static Window s_iOwners[CLIP_NUM_SELECTIONS] = { None };
+ static unsigned long s_ulServerGeneration = 0;
+
+ REQUEST(xSetSelectionOwnerReq);
+
+ REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+
+ winDebug("winProcSetSelectionOwner - Hello.\n");
+
+ /* Watch for server reset */
+ if (s_ulServerGeneration != serverGeneration) {
+ /* Save new generation number */
+ s_ulServerGeneration = serverGeneration;
+
+ /* Initialize static variables */
+ for (i = 0; i < CLIP_NUM_SELECTIONS; ++i)
+ s_iOwners[i] = None;
+ }
+
+ /* Abort if clipboard not completely initialized yet */
+ if (!g_fClipboardStarted) {
+ winDebug ("winProcSetSelectionOwner - Clipboard not yet started, "
+ "aborting.\n");
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ /* Grab window if we have one */
+ if (None != stuff->window) {
+ /* Grab the Window from the request */
+ int rc =
+ dixLookupWindow(&pWindow, stuff->window, client, DixReadAccess);
+ if (rc != Success) {
+ ErrorF("winProcSetSelectionOwner - Found BadWindow, aborting.\n");
+ goto winProcSetSelectionOwner_Done;
+ }
+ }
+
+ /* Now we either have a valid window or None */
+
+ /* Save selection owners for monitored selections, ignore other selections */
+ if (XA_PRIMARY == stuff->selection && g_fClipboardPrimary) {
+ /* Look for owned -> not owned transition */
+ if (None == stuff->window && None != s_iOwners[CLIP_OWN_PRIMARY]) {
+ winDebug("winProcSetSelectionOwner - PRIMARY - Going from "
+ "owned to not owned.\n");
+
+ /* Adjust last owned selection */
+ if (None != s_iOwners[CLIP_OWN_CLIPBOARD])
+ g_atomLastOwnedSelection = MakeAtom("CLIPBOARD", 9, TRUE);
+ else
+ g_atomLastOwnedSelection = None;
+ }
+
+ /* Save new selection owner or None */
+ s_iOwners[CLIP_OWN_PRIMARY] = stuff->window;
+
+ winDebug ("winProcSetSelectionOwner - PRIMARY - Now owned by: 0x%x (clipboard is 0x%x)\n",
+ stuff->window,g_iClipboardWindow);
+ }
+ else if (MakeAtom("CLIPBOARD", 9, TRUE) == stuff->selection) {
+ /* Look for owned -> not owned transition */
+ if (None == stuff->window && None != s_iOwners[CLIP_OWN_CLIPBOARD]) {
+ winDebug("winProcSetSelectionOwner - CLIPBOARD - Going from "
+ "owned to not owned.\n");
+
+ /* Adjust last owned selection */
+ if ((None != s_iOwners[CLIP_OWN_PRIMARY]) && g_fClipboardPrimary)
+ g_atomLastOwnedSelection = XA_PRIMARY;
+ else
+ g_atomLastOwnedSelection = None;
+ }
+
+ /* Save new selection owner or None */
+ s_iOwners[CLIP_OWN_CLIPBOARD] = stuff->window;
+
+ winDebug ("winProcSetSelectionOwner - CLIPBOARD - Now owned by: 0x%x, clipboard is 0x%x\n",
+ stuff->window,g_iClipboardWindow);
+ }
+ else
+ goto winProcSetSelectionOwner_Done;
+
+ /*
+ * At this point, if one of the selections is still owned by the
+ * clipboard manager then it should be marked as unowned since
+ * we will be taking ownership of the Win32 clipboard.
+ */
+ if (g_iClipboardWindow == s_iOwners[CLIP_OWN_PRIMARY])
+ s_iOwners[CLIP_OWN_PRIMARY] = None;
+ if (g_iClipboardWindow == s_iOwners[CLIP_OWN_CLIPBOARD])
+ s_iOwners[CLIP_OWN_CLIPBOARD] = None;
+
+ /* Abort if no window at this point */
+ if (None == stuff->window) {
+ winDebug ("winProcSetSelectionOwner - No window, returning.\n");
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ /* Abort if invalid selection */
+ if (!ValidAtom(stuff->selection)) {
+ winDebug ("winProcSetSelectionOwner - Found BadAtom, aborting.\n");
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ /* Cast Window to Drawable */
+ pDrawable = (DrawablePtr) pWindow;
+
+ /* Abort if clipboard manager is owning the selection */
+ if (pDrawable->id == g_iClipboardWindow) {
+ winDebug ("winProcSetSelectionOwner - We changed ownership, "
+ "aborting.\n");
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ /* Abort if root window is taking ownership */
+ if (pDrawable->id == 0) {
+ winDebug ("winProcSetSelectionOwner - Root window taking ownership, "
+ "aborting\n");
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ /* Access the Windows clipboard */
+ if (!OpenClipboard(g_hwndClipboard)) {
+ ErrorF ("winProcSetSelectionOwner - OpenClipboard () failed: %08x, hwnd: %08x\n",
+ (int) GetLastError (),g_hwndClipboard);
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ /* Take ownership of the Windows clipboard */
+ if (!EmptyClipboard()) {
+ ErrorF("winProcSetSelectionOwner - EmptyClipboard () failed: %08x\n",
+ (int) GetLastError());
+ CloseClipboard ();
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ winDebug("winProcSetSelectionOwner - SetClipboardData NULL\n");
+ /* Advertise regular text and unicode */
+ SetClipboardData(CF_UNICODETEXT, NULL);
+ SetClipboardData(CF_TEXT, NULL);
+
+ /* Save handle to last owned selection */
+ g_atomLastOwnedSelection = stuff->selection;
+
+ /* Release the clipboard */
+ if (!CloseClipboard()) {
+ ErrorF("winProcSetSelectionOwner - CloseClipboard () failed: "
+ "%08x\n", (int) GetLastError());
+ goto winProcSetSelectionOwner_Done;
+ }
+
+winProcSetSelectionOwner_Done:
+ return (*winProcSetSelectionOwnerOrig) (client);
+}