diff options
Diffstat (limited to 'xorg-server/hw/xwin/winclipboard/wndproc.c')
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/xwin/winclipboard/wndproc.c | 323 |
1 files changed, 159 insertions, 164 deletions
diff --git a/xorg-server/hw/xwin/winclipboard/wndproc.c b/xorg-server/hw/xwin/winclipboard/wndproc.c index 165ff558a..f5f931f74 100644..100755 --- a/xorg-server/hw/xwin/winclipboard/wndproc.c +++ b/xorg-server/hw/xwin/winclipboard/wndproc.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 */ @@ -45,34 +45,55 @@ #include <sys/types.h> #include <sys/time.h> - -#include <X11/Xatom.h> - -#include "internal.h" #include "winclipboard.h" +#include "misc.h" +#include "winmsg.h" +#include "objbase.h" +#include "ddraw.h" +#include "winwindow.h" +#include "internal.h" /* * Constants */ -#define WIN_POLL_TIMEOUT 1 +#define WIN_POLL_TIMEOUT 1 +/* + * References to external symbols + */ + +extern void *g_pClipboardDisplay; +extern Window g_iClipboardWindow; +extern Atom g_atomLastOwnedSelection; +extern Bool g_fClipboardStarted; +extern HWND g_hwndClipboard; +extern Bool g_fClipboardPrimary; /* * Process X events up to specified timeout */ static int -winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay, - Bool fUseUnicode, ClipboardAtoms *atoms, int iTimeoutSec) +winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay, + Bool fUseUnicode, int iTimeoutSec) { int iConnNumber; struct timeval tv; 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); @@ -82,9 +103,6 @@ winProcessXEventsTimeout(HWND hwnd, Window 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); @@ -107,8 +125,8 @@ winProcessXEventsTimeout(HWND hwnd, Window 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; } @@ -117,7 +135,7 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay, /* Process X events */ /* Exit when we see that server is shutting down */ iReturn = winClipboardFlushXEvents(hwnd, - iWindow, pDisplay, fUseUnicode, atoms); + iWindow, pDisplay, fUseUnicode, TRUE); winDebug ("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n", @@ -144,10 +162,6 @@ 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 ClipboardAtoms *atoms; /* Branch on message type */ switch (message) { @@ -159,7 +173,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ChangeClipboardChain(hwnd, s_hwndNextViewer); s_hwndNextViewer = NULL; - + g_hwndClipboard = NULL; PostQuitMessage(0); } return 0; @@ -168,24 +182,19 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HWND first, next; DWORD error_code = 0; - ClipboardWindowCreationParams *cwcp = (ClipboardWindowCreationParams *)((CREATESTRUCT *)lParam)->lpCreateParams; winDebug("winClipboardWindowProc - WM_CREATE\n"); - pDisplay = cwcp->pClipboardDisplay; - iWindow = cwcp->iClipboardWindow; - atoms = cwcp->atoms; - - 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; @@ -198,9 +207,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; - ErrorF("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) @@ -227,38 +235,52 @@ 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: { + static Atom atomClipboard; + static int generation; static Bool s_fProcessingDrawClipboard = FALSE; + Display *pDisplay = g_pClipboardDisplay; + 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; + atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False); + } /* * We've occasionally seen a loop in the clipboard chain. @@ -269,41 +291,12 @@ 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(); - 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"); + winFixClipboardChain(1); + ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "Nested calls detected. Re-initing.\n"); winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); s_fProcessingDrawClipboard = FALSE; - if (s_hwndNextViewer) - SendMessage(s_hwndNextViewer, message, wParam, lParam); return 0; } @@ -325,31 +318,31 @@ 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 == iWindow) { - 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) - ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "XGetSelectionOwner failed for PRIMARY: %d\n", - iReturn); - /* Release CLIPBOARD selection if owned */ - iReturn = XGetSelectionOwner(pDisplay, atoms->atomClipboard); - if (iReturn == iWindow) { + iReturn = XGetSelectionOwner(pDisplay, atomClipboard); + if (iReturn == g_iClipboardWindow) { winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "CLIPBOARD selection is owned by us, releasing\n"); - XSetSelectionOwner(pDisplay, atoms->atomClipboard, None, CurrentTime); + "CLIPBOARD selection is owned by us.\n"); + XSetSelectionOwner(pDisplay, atomClipboard, None, CurrentTime); } else if (BadWindow == iReturn || BadAtom == iReturn) - ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "XGetSelectionOwner failed for CLIPBOARD: %d\n", - iReturn); + ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "XGetSelection failed for CLIPBOARD: %d\n", + iReturn); winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); s_fProcessingDrawClipboard = FALSE; @@ -357,45 +350,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) { - 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, - atoms->atomClipboard, iWindow, CurrentTime); - - if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner(pDisplay, atoms->atomClipboard) != iWindow) { - ErrorF("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. @@ -414,6 +410,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_RENDERALLFORMATS: { int iReturn; + Display *pDisplay = g_pClipboardDisplay; + Window iWindow = g_iClipboardWindow; Bool fConvertToUnicode; winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Hello.\n"); @@ -426,36 +424,33 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* Request the selection contents */ iReturn = XConvertSelection(pDisplay, - winClipboardGetLastOwnedSelectionAtom(atoms), - atoms->atomCompoundText, - atoms->atomLocalProperty, + g_atomLastOwnedSelection, + XInternAtom(pDisplay, + "COMPOUND_TEXT", False), + XInternAtom(pDisplay, + WIN_LOCAL_PROPERTY, False), iWindow, CurrentTime); if (iReturn == BadAtom || iReturn == BadWindow) { - ErrorF("winClipboardWindowProc - WM_RENDER*FORMAT - " - "XConvertSelection () failed\n"); + ErrorF ("winClipboardWindowProc - WM_RENDER*FORMAT - " + "XConvertSelection () failed\n"); break; } /* 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)) { - ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - " - "OpenClipboard () failed: %08x\n", - GetLastError()); + ErrorF ("winClipboardWindowProc - WM_RENDER*FORMATS - " + "OpenClipboard () failed: %08x\n", + GetLastError()); break; } if (!EmptyClipboard()) { - ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - " - "EmptyClipboard () failed: %08x\n", - GetLastError()); + ErrorF ("winClipboardWindowProc - WM_RENDER*FORMATS - " + "EmptyClipboard () failed: %08x\n", + GetLastError()); + CloseClipboard (); break; } } @@ -464,9 +459,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) iReturn = winProcessXEventsTimeout(hwnd, iWindow, pDisplay, - fConvertToUnicode, - atoms, - WIN_POLL_TIMEOUT); + fConvertToUnicode, WIN_POLL_TIMEOUT); /* * The last call to winProcessXEventsTimeout @@ -476,6 +469,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); @@ -489,9 +483,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* We must close the clipboard */ if (!CloseClipboard()) { - ErrorF("winClipboardWindowProc - WM_RENDERALLFORMATS - " - "CloseClipboard () failed: %08x\n", - GetLastError()); + ErrorF ( + "winClipboardWindowProc - WM_RENDERALLFORMATS - " + "CloseClipboard () failed: %08x\n", + GetLastError()); break; } } |