aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xwin/winclipboardwndproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xwin/winclipboardwndproc.c')
-rw-r--r--xorg-server/hw/xwin/winclipboardwndproc.c251
1 files changed, 118 insertions, 133 deletions
diff --git a/xorg-server/hw/xwin/winclipboardwndproc.c b/xorg-server/hw/xwin/winclipboardwndproc.c
index e19f678a7..28348ac45 100644
--- a/xorg-server/hw/xwin/winclipboardwndproc.c
+++ b/xorg-server/hw/xwin/winclipboardwndproc.c
@@ -26,7 +26,7 @@
*the sale, use or other dealings in this Software without prior written
*authorization from the copyright holder(s) and author(s).
*
- * Authors: Harold L Hunt II
+ * Authors: Harold L Hunt II
* Colin Harrison
*/
@@ -37,12 +37,16 @@
#include <sys/time.h>
#include "winclipboard.h"
#include "misc.h"
+#include "winmsg.h"
+#include "objbase.h"
+#include "ddraw.h"
+#include "winwindow.h"
/*
* Constants
*/
-#define WIN_POLL_TIMEOUT 1
+#define WIN_POLL_TIMEOUT 1
/*
* References to external symbols
@@ -52,8 +56,10 @@ extern Bool g_fUseUnicode;
extern void *g_pClipboardDisplay;
extern Window g_iClipboardWindow;
extern Atom g_atomLastOwnedSelection;
-
-/*
+extern Bool g_fClipboardStarted;
+extern HWND g_hwndClipboard;
+extern Bool g_fClipboardPrimary;
+/*
* Local function prototypes
*/
@@ -76,8 +82,17 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
int iReturn;
DWORD dwStopTime = GetTickCount() + iTimeoutSec * 1000;
- winDebug("winProcessXEventsTimeout () - pumping X events for %d seconds\n",
- iTimeoutSec);
+ /* Make sure the output messages are sent before waiting on a response. */
+ iReturn = winClipboardFlushXEvents (hwnd,
+ iWindow,
+ pDisplay,
+ fUseUnicode,
+ TRUE);
+ if (WIN_XEVENTS_NOTIFY == iReturn)
+ {
+ /* Bail out if notify processed */
+ return iReturn;
+ }
/* Get our connection number */
iConnNumber = ConnectionNumber(pDisplay);
@@ -87,9 +102,6 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
fd_set fdsRead;
long remainingTime;
- /* We need to ensure that all pending events are processed */
- XSync(pDisplay, FALSE);
-
/* Setup the file descriptor set */
FD_ZERO(&fdsRead);
FD_SET(iConnNumber, &fdsRead);
@@ -112,8 +124,8 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
NULL, /* No exception mask */
&tv); /* Timeout */
if (iReturn < 0) {
- ErrorF("winProcessXEventsTimeout - Call to select () failed: %d. "
- "Bailing.\n", iReturn);
+ ErrorF("winProcessXEventsTimeout - Call to select () failed: %d (%x). "
+ "Bailing.\n", iReturn, WSAGetLastError());
break;
}
@@ -122,7 +134,7 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
/* Process X events */
/* Exit when we see that server is shutting down */
iReturn = winClipboardFlushXEvents(hwnd,
- iWindow, pDisplay, fUseUnicode);
+ iWindow, pDisplay, fUseUnicode, TRUE);
winDebug
("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n",
@@ -149,7 +161,6 @@ LRESULT CALLBACK
winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND s_hwndNextViewer;
- static Bool s_fCBCInitialized;
/* Branch on message type */
switch (message) {
@@ -161,7 +172,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
ChangeClipboardChain(hwnd, s_hwndNextViewer);
s_hwndNextViewer = NULL;
-
+ g_hwndClipboard = NULL;
PostQuitMessage(0);
}
return 0;
@@ -173,16 +184,16 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
winDebug("winClipboardWindowProc - WM_CREATE\n");
- 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;
+ s_hwndNextViewer = SetClipboardViewer (hwnd);
+ #ifdef _DEBUG
+ if (s_hwndNextViewer== hwnd)
+ {
+ ErrorF("WM_CREATE: SetClipboardViewer returned own window. This causes an endless loop, so reset s_hwndNextViewer. ");
+ s_hwndNextViewer=NULL;
+ }
+ #endif
+
}
return 0;
@@ -195,9 +206,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if ((HWND) wParam == s_hwndNextViewer) {
s_hwndNextViewer = (HWND) lParam;
if (s_hwndNextViewer == hwnd) {
- s_hwndNextViewer = NULL;
- winErrorFVerb(1, "winClipboardWindowProc - WM_CHANGECBCHAIN: "
- "attempted to set next window to ourselves.");
+ winDebug("WM_CHANGECBCHAIN: trying to set s_hwndNextViewer to own window. Resetting it back to NULL. ");
+ s_hwndNextViewer=NULL; /* This would cause an endless loop, so break it by ending the loop here. I have seen this happening, why??? */
}
}
else if (s_hwndNextViewer)
@@ -224,30 +234,28 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
HWND first, next;
DWORD error_code = 0;
-
+ if (!g_hwndClipboard)
+ return 0;
winDebug("winClipboardWindowProc - WM_WM_REINIT: Enter\n");
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(%x) with %x 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;
+ if (first != hwnd)
+ {
+ winDebug (" WM_WM_REINIT: Replacing us(%x) with %x at head "
+ "of chain\n", hwnd, s_hwndNextViewer);
+ if (!wParam) ChangeClipboardChain (hwnd, s_hwndNextViewer); /* When wParam is set, the window was already removed from the chain */
+ winDebug (" WM_WM_REINIT: Putting us back at head of chain.\n");
+ s_hwndNextViewer = SetClipboardViewer (hwnd);
+ #ifdef _DEBUG
+ if (s_hwndNextViewer== hwnd)
+ {
+ ErrorF("WM_WM_REINIT: SetClipboardViewer returned own window. This causes an endless loop, so reset s_hwndNextViewer. ");
+ s_hwndNextViewer=NULL;
+ }
+ #endif
+ }
+ winDebug ("winClipboardWindowProc - WM_WM_REINIT: Exit\n");
}
- winDebug("winClipboardWindowProc - WM_WM_REINIT: Exit\n");
return 0;
case WM_DRAWCLIPBOARD:
@@ -259,7 +267,14 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Window iWindow = g_iClipboardWindow;
int iReturn;
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n");
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD 0x%x 0x%x 0x%x: Enter\n",hwnd,wParam,lParam);
+
+ if (!g_fClipboardStarted) {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit with no processing\n");
+ if (s_hwndNextViewer)
+ SendMessage (s_hwndNextViewer, message, wParam, lParam);
+ return 0;
+ }
if (generation != serverGeneration) {
generation = serverGeneration;
@@ -275,44 +290,15 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
}
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();
- winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ winFixClipboardChain(1);
+ 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;
- }
-
- /*
- * NOTE: We cannot bail out when NULL == GetClipboardOwner ()
- * because some applications deal with the clipboard in a manner
- * that causes the clipboard owner to be NULL when they are in
- * fact taking ownership. One example of this is the Win32
- * native compile of emacs.
- */
-
- /* Bail when we still own the clipboard */
- if (hwnd == GetClipboardOwner()) {
-
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "We own the clipboard, returning.\n");
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
- s_fProcessingDrawClipboard = FALSE;
- if (s_hwndNextViewer)
- SendMessage(s_hwndNextViewer, message, wParam, lParam);
- return 0;
- }
-
/*
* Do not take ownership of the X11 selections when something
* other than CF_TEXT or CF_UNICODETEXT has been copied
@@ -331,20 +317,20 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
*/
XSync(pDisplay, FALSE);
- winDebug("winClipboardWindowProc - XSync done.\n");
-
- /* Release PRIMARY selection if owned */
- iReturn = XGetSelectionOwner(pDisplay, XA_PRIMARY);
- if (iReturn == g_iClipboardWindow) {
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "PRIMARY selection is owned by us.\n");
- XSetSelectionOwner(pDisplay, XA_PRIMARY, None, CurrentTime);
+ if (g_fClipboardPrimary)
+ {
+ /* Release PRIMARY selection if owned */
+ iReturn = XGetSelectionOwner (pDisplay, XA_PRIMARY);
+ if (iReturn == g_iClipboardWindow) {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "PRIMARY selection is owned by us.\n");
+ XSetSelectionOwner (pDisplay, XA_PRIMARY, None, CurrentTime);
+ }
+ else if (BadWindow == iReturn || BadAtom == iReturn)
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "XGetSelection failed for PRIMARY: %d\n",
+ iReturn);
}
- else if (BadWindow == iReturn || BadAtom == iReturn)
- winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "XGetSelection failed for PRIMARY: %d\n",
- iReturn);
-
/* Release CLIPBOARD selection if owned */
iReturn = XGetSelectionOwner(pDisplay, atomClipboard);
if (iReturn == g_iClipboardWindow) {
@@ -353,7 +339,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
XSetSelectionOwner(pDisplay, atomClipboard, None, CurrentTime);
}
else if (BadWindow == iReturn || BadAtom == iReturn)
- winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
"XGetSelection failed for CLIPBOARD: %d\n",
iReturn);
@@ -363,45 +349,48 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
SendMessage(s_hwndNextViewer, message, wParam, lParam);
return 0;
}
-
- /* Reassert ownership of PRIMARY */
- iReturn = XSetSelectionOwner(pDisplay,
- XA_PRIMARY, iWindow, CurrentTime);
- if (iReturn == BadAtom || iReturn == BadWindow ||
- XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) {
- winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "Could not reassert ownership of PRIMARY\n");
- }
- else {
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "Reasserted ownership of PRIMARY\n");
- }
-
- /* Reassert ownership of the CLIPBOARD */
- iReturn = XSetSelectionOwner(pDisplay,
- atomClipboard, iWindow, CurrentTime);
-
- if (iReturn == BadAtom || iReturn == BadWindow ||
- XGetSelectionOwner(pDisplay, atomClipboard) != iWindow) {
- winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "Could not reassert ownership of CLIPBOARD\n");
- }
- else {
- winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "Reasserted ownership of CLIPBOARD\n");
+ /* Only reassert ownership when we did not change the clipboard ourselves */
+ if (hwnd!=(HWND)wParam) {
+ if (g_fClipboardPrimary) {
+ /* 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 - "
+ "Could not reassert ownership of PRIMARY\n");
+ }
+ else {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Reasserted ownership of PRIMARY\n");
+ }
+ }
+ /* Reassert ownership of the CLIPBOARD */
+ iReturn = XSetSelectionOwner (pDisplay,
+ atomClipboard, iWindow, CurrentTime);
+
+ if (iReturn == BadAtom || iReturn == BadWindow ||
+ XGetSelectionOwner (pDisplay, atomClipboard) != iWindow) {
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Could not reassert ownership of CLIPBOARD\n");
+ }
+ else {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Reasserted ownership of CLIPBOARD\n");
+ }
+
+ /* Flush the pending SetSelectionOwner event now */
+ XFlush (pDisplay);
}
- /* Flush the pending SetSelectionOwner event now */
- XFlush(pDisplay);
-
s_fProcessingDrawClipboard = FALSE;
- }
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);
return 0;
+ }
case WM_DESTROYCLIPBOARD:
/*
* NOTE: Intentionally do nothing.
@@ -438,10 +427,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
XInternAtom(pDisplay,
"COMPOUND_TEXT", False),
XInternAtom(pDisplay,
- "CYGX_CUT_BUFFER", False),
+ WIN_LOCAL_PROPERTY, False),
iWindow, CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow) {
- winErrorFVerb(1, "winClipboardWindowProc - WM_RENDER*FORMAT - "
+ ErrorF ("winClipboardWindowProc - WM_RENDER*FORMAT - "
"XConvertSelection () failed\n");
break;
}
@@ -449,23 +438,18 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
/* Special handling for WM_RENDERALLFORMATS */
if (message == WM_RENDERALLFORMATS) {
/* We must open and empty the clipboard */
-
- /* Close clipboard if we have it open already */
- if (GetOpenClipboardWindow() == hwnd) {
- CloseClipboard();
- }
-
if (!OpenClipboard(hwnd)) {
- winErrorFVerb(1, "winClipboardWindowProc - WM_RENDER*FORMATS - "
+ ErrorF ("winClipboardWindowProc - WM_RENDER*FORMATS - "
"OpenClipboard () failed: %08x\n",
GetLastError());
break;
}
if (!EmptyClipboard()) {
- winErrorFVerb(1, "winClipboardWindowProc - WM_RENDER*FORMATS - "
+ ErrorF ("winClipboardWindowProc - WM_RENDER*FORMATS - "
"EmptyClipboard () failed: %08x\n",
GetLastError());
+ CloseClipboard ();
break;
}
}
@@ -484,6 +468,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
* satisfy the requirement that we write something to it.
*/
if (WIN_XEVENTS_NOTIFY != iReturn) {
+ ErrorF("winClipboardWindowProc - winProcessXEventsTimeout should have returned WIN_XEVENTS_NOTIFY was %d\n",iReturn);
/* Paste no data, to satisfy required call to SetClipboardData */
SetClipboardData(CF_UNICODETEXT, NULL);
SetClipboardData(CF_TEXT, NULL);
@@ -497,7 +482,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
/* We must close the clipboard */
if (!CloseClipboard()) {
- winErrorFVerb(1,
+ ErrorF (
"winClipboardWindowProc - WM_RENDERALLFORMATS - "
"CloseClipboard () failed: %08x\n",
GetLastError());