diff options
Diffstat (limited to 'xorg-server/hw/xwin/winclipboardwndproc.c')
-rw-r--r-- | xorg-server/hw/xwin/winclipboardwndproc.c | 275 |
1 files changed, 133 insertions, 142 deletions
diff --git a/xorg-server/hw/xwin/winclipboardwndproc.c b/xorg-server/hw/xwin/winclipboardwndproc.c index 02347ff43..50a63001f 100644 --- a/xorg-server/hw/xwin/winclipboardwndproc.c +++ b/xorg-server/hw/xwin/winclipboardwndproc.c @@ -37,6 +37,10 @@ #include <sys/time.h> #include "winclipboard.h" #include "misc.h" +#include "winmsg.h" +#include "objbase.h" +#include "ddraw.h" +#include "winwindow.h" /* * Constants @@ -44,7 +48,6 @@ #define WIN_POLL_TIMEOUT 1 - /* * References to external symbols */ @@ -54,7 +57,9 @@ extern Bool g_fUnicodeSupport; 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 @@ -78,8 +83,17 @@ winProcessXEventsTimeout (HWND hwnd, int iWindow, Display *pDisplay, int iReturn; DWORD dwStopTime = (GetTickCount () / 1000) + iTimeoutSec; - /* We need to ensure that all pending events are processed */ - XSync (pDisplay, FALSE); + /* 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); @@ -109,8 +123,8 @@ winProcessXEventsTimeout (HWND hwnd, int iWindow, Display *pDisplay, &tv); /* No 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 +136,8 @@ winProcessXEventsTimeout (HWND hwnd, int iWindow, Display *pDisplay, iReturn = winClipboardFlushXEvents (hwnd, iWindow, pDisplay, - fUseUnicode); + fUseUnicode, + TRUE); if (WIN_XEVENTS_NOTIFY == iReturn) { /* Bail out if notify processed */ @@ -134,7 +149,6 @@ winProcessXEventsTimeout (HWND hwnd, int iWindow, Display *pDisplay, return WIN_XEVENTS_SUCCESS; } - /* * Process a given Windows message */ @@ -144,7 +158,6 @@ winClipboardWindowProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND s_hwndNextViewer; - static Bool s_fCBCInitialized; /* Branch on message type */ switch (message) @@ -157,7 +170,7 @@ winClipboardWindowProc (HWND hwnd, UINT message, ChangeClipboardChain (hwnd, s_hwndNextViewer); s_hwndNextViewer = NULL; - + g_hwndClipboard = NULL; PostQuitMessage (0); } return 0; @@ -169,15 +182,16 @@ winClipboardWindowProc (HWND hwnd, UINT message, DWORD error_code = 0; 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; @@ -192,11 +206,10 @@ winClipboardWindowProc (HWND hwnd, UINT message, { 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) SendMessage (s_hwndNextViewer, message, @@ -223,27 +236,28 @@ winClipboardWindowProc (HWND hwnd, UINT message, 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; @@ -256,7 +270,15 @@ winClipboardWindowProc (HWND hwnd, UINT message, 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) { @@ -275,46 +297,15 @@ winClipboardWindowProc (HWND hwnd, UINT message, 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 @@ -333,24 +324,24 @@ winClipboardWindowProc (HWND hwnd, UINT message, * previous XSetSelectionOwner messages. */ 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); - } - else if (BadWindow == iReturn || BadAtom == iReturn) - winErrorFVerb (1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "XGetSelection failed for PRIMARY: %d\n", iReturn); - + 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); + } /* Release CLIPBOARD selection if owned */ iReturn = XGetSelectionOwner (pDisplay, atomClipboard); @@ -364,7 +355,7 @@ winClipboardWindowProc (HWND hwnd, UINT message, CurrentTime); } else if (BadWindow == iReturn || BadAtom == iReturn) - winErrorFVerb (1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " + ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " "XGetSelection failed for CLIPBOARD: %d\n", iReturn); winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); @@ -373,53 +364,58 @@ winClipboardWindowProc (HWND hwnd, UINT message, 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 + /* Only reassert ownership when we did not change the clipboard ourselves */ + if (hwnd!=(HWND)wParam) + { + if (g_fClipboardPrimary) { - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "Reasserted ownership of CLIPBOARD\n"); + /* 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); - - s_fProcessingDrawClipboard = FALSE; - } + /* 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: /* @@ -457,12 +453,12 @@ winClipboardWindowProc (HWND hwnd, UINT message, 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; } @@ -471,16 +467,9 @@ winClipboardWindowProc (HWND hwnd, UINT message, 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; @@ -488,9 +477,10 @@ winClipboardWindowProc (HWND hwnd, UINT message, if (!EmptyClipboard ()) { - winErrorFVerb (1, "winClipboardWindowProc - WM_RENDER*FORMATS - " + ErrorF ("winClipboardWindowProc - WM_RENDER*FORMATS - " "EmptyClipboard () failed: %08x\n", GetLastError ()); + CloseClipboard (); break; } } @@ -511,6 +501,7 @@ winClipboardWindowProc (HWND hwnd, UINT message, */ 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 */ if (g_fUnicodeSupport) SetClipboardData (CF_UNICODETEXT, NULL); @@ -526,7 +517,7 @@ winClipboardWindowProc (HWND hwnd, UINT message, if (!CloseClipboard ()) { - winErrorFVerb (1, "winClipboardWindowProc - WM_RENDERALLFORMATS - " + ErrorF ("winClipboardWindowProc - WM_RENDERALLFORMATS - " "CloseClipboard () failed: %08x\n", GetLastError ()); break; |