diff options
Diffstat (limited to 'xorg-server/hw/xwin/winclipboardwndproc.c')
-rw-r--r-- | xorg-server/hw/xwin/winclipboardwndproc.c | 251 |
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()); |