diff options
Diffstat (limited to 'xorg-server/hw/xwin/winclipboard')
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/xwin/winclipboard/internal.h | 66 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winclipboard/makefile | 18 | ||||
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/xwin/winclipboard/thread.c | 314 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winclipboard/winclipboard.h | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/xwin/winclipboard/wndproc.c | 323 | ||||
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/xwin/winclipboard/xevents.c | 286 |
6 files changed, 466 insertions, 547 deletions
diff --git a/xorg-server/hw/xwin/winclipboard/internal.h b/xorg-server/hw/xwin/winclipboard/internal.h index 94956f80d..55c7771af 100644..100755 --- a/xorg-server/hw/xwin/winclipboard/internal.h +++ b/xorg-server/hw/xwin/winclipboard/internal.h @@ -1,4 +1,3 @@ - /* *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. * @@ -32,24 +31,54 @@ #ifndef WINCLIPBOARD_INTERNAL_H #define WINCLIPBOARD_INTERNAL_H +/* Standard library headers */ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#ifndef _MSC_VER +#include <unistd.h> +#endif +#ifdef __CYGWIN__ +#include <sys/select.h> +#else +#include <X11/Xwinsock.h> +#endif +#include <fcntl.h> +#include <setjmp.h> +#ifdef _MSC_VER +typedef int pid_t; +#endif +#include <pthread.h> + /* X headers */ -#include <X11/Xlib.h> +#include <X11/X.h> +#include <X11/Xatom.h> +#include <X11/Xproto.h> +#include <X11/Xutil.h> /* Windows headers */ #include <X11/Xwindows.h> +#include "winmsg.h" + #define WIN_XEVENTS_SUCCESS 0 #define WIN_XEVENTS_CONVERT 2 #define WIN_XEVENTS_NOTIFY 3 +#define WIN_LOCAL_PROPERTY "CYGX_CUT_BUFFER" -#define WM_WM_REINIT (WM_USER + 1) +#define WM_WM_REINIT (WM_USER + 200) /* * References to external symbols */ -extern void winDebug(const char *format, ...); -extern void ErrorF(const char *format, ...); +extern char *display; +/* + * winclipboardinit.c + */ + +Bool + winInitClipboard(void); /* * winclipboardtextconv.c @@ -66,15 +95,6 @@ void */ -typedef struct -{ - Atom atomClipboard; - Atom atomLocalProperty; - Atom atomUTF8String; - Atom atomCompoundText; - Atom atomTargets; -} ClipboardAtoms; - /* * winclipboardwndproc.c */ @@ -84,26 +104,12 @@ Bool winClipboardFlushWindowsMessageQueue(HWND hwnd); LRESULT CALLBACK winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -typedef struct -{ - Display *pClipboardDisplay; - Window iClipboardWindow; - ClipboardAtoms *atoms; -} ClipboardWindowCreationParams; - /* * winclipboardxevents.c */ int -winClipboardFlushXEvents(HWND hwnd, - Window iWindow, Display * pDisplay, Bool fUnicodeSupport, ClipboardAtoms *atom); - - -Atom -winClipboardGetLastOwnedSelectionAtom(ClipboardAtoms *atoms); - -void -winClipboardInitMonitoredSelections(void); +winClipboardFlushXEvents(HWND hwnd, + int iWindow, Display * pDisplay, Bool fUnicodeSupport, Bool ClipboardOpened); #endif diff --git a/xorg-server/hw/xwin/winclipboard/makefile b/xorg-server/hw/xwin/winclipboard/makefile new file mode 100644 index 000000000..f49117b3e --- /dev/null +++ b/xorg-server/hw/xwin/winclipboard/makefile @@ -0,0 +1,18 @@ +LIBRARY = libXWinclipboard + +CSRCS = \ + textconv.c \ + thread.c \ + wndproc.c \ + xevents.c + +INCLUDES += .. + +DEFINES += HAVE_XWIN_CONFIG_H +DEFINES += XWIN_CLIPBOARD +DEFINES += XWIN_MULTIWINDOW +DEFINES += XWIN_GLX_WINDOWS +DEFINES += XWIN_RANDR +DEFINES += RELOCATE_PROJECTROOT +DEFINES += PTW32_STATIC_LIB + diff --git a/xorg-server/hw/xwin/winclipboard/thread.c b/xorg-server/hw/xwin/winclipboard/thread.c index c179e3f83..5dee3040e 100644..100755 --- a/xorg-server/hw/xwin/winclipboard/thread.c +++ b/xorg-server/hw/xwin/winclipboard/thread.c @@ -35,61 +35,62 @@ #else #define HAS_WINSOCK 1 #endif - -/* - * Including any server header might define the macro _XSERVER64 on 64 bit machines. - * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen. - * So let's undef that macro if necessary. - */ -#ifdef _XSERVER64 -#undef _XSERVER64 -#endif - -#include <assert.h> -#include <unistd.h> -#include <fcntl.h> -#include <setjmp.h> +#include <sys/types.h> +#include <signal.h> #include <pthread.h> -#include <sys/param.h> // for MAX() macro - -#ifdef HAS_WINSOCK -#include <X11/Xwinsock.h> -#else +#include "winclipboard.h" +#include "windisplay.h" +#ifdef __CYGWIN__ #include <errno.h> #endif - -#include <X11/Xatom.h> -#include <X11/extensions/Xfixes.h> -#include "winclipboard.h" +#include "misc.h" +#include "winmsg.h" #include "internal.h" +/* Clipboard module constants */ #define WIN_CONNECT_RETRIES 40 #define WIN_CONNECT_DELAY 4 +#define WIN_JMP_OKAY 0 +#define WIN_JMP_ERROR_IO 2 #define WIN_CLIPBOARD_WINDOW_CLASS "xwinclip" #define WIN_CLIPBOARD_WINDOW_TITLE "xwinclip" #ifdef HAS_DEVWINDOWS -#define WIN_MSG_QUEUE_FNAME "/dev/windows" +#define WIN_MSG_QUEUE_FNAME "/dev/windows" +#endif + +#ifdef _MSC_VER +#define snprintf _snprintf #endif +/* + * References to external symbols + */ + +extern Bool g_fUnicodeClipboard; +extern Bool g_fClipboard; +extern Bool g_fClipboardStarted; +extern Bool g_fClipboardLaunched; +extern HWND g_hwndClipboard; +extern void *g_pClipboardDisplay; +extern Window g_iClipboardWindow; +extern Bool g_fClipboardPrimary; /* * Global variables */ -static HWND g_hwndClipboard = NULL; static jmp_buf g_jmpEntry; static XIOErrorHandler g_winClipboardOldIOErrorHandler; static pthread_t g_winClipboardProcThread; -int xfixes_event_base; -int xfixes_error_base; +Bool g_fUseUnicode = FALSE; /* * Local function prototypes */ static HWND -winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAtoms *atoms); +winClipboardCreateMessagingWindow(void); static int winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr); @@ -97,19 +98,20 @@ static int static int winClipboardIOErrorHandler(Display * pDisplay); +static void +winClipboardThreadExit(void *arg); /* - * Create X11 and Win32 messaging windows, and run message processing loop - * - * returns TRUE if shutdown was signalled to loop, FALSE if some error occurred + * Main thread function */ Bool winClipboardProc(Bool fUseUnicode, char *szDisplay) { - ClipboardAtoms atoms; + Atom atomClipboard; int iReturn; HWND hwnd = NULL; int iConnectionNumber = 0; + Bool bShutDown = TRUE; #ifdef HAS_DEVWINDOWS int fdMessageQueue = 0; @@ -121,74 +123,80 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) Display *pDisplay = NULL; Window iWindow = None; int iSelectError; - Bool fShutdown = FALSE; - static Bool fErrorHandlerSet = FALSE; - winDebug("winClipboardProc - Hello\n"); + pthread_cleanup_push(&winClipboardThreadExit, NULL); - /* Allow multiple threads to access Xlib */ - if (XInitThreads() == 0) { - ErrorF("winClipboardProc - XInitThreads failed.\n"); - goto winClipboardProc_Exit; - } + winDebug ("winClipboardProc - Hello\n"); - /* See if X supports the current locale */ - if (XSupportsLocale() == False) { - ErrorF("winClipboardProc - Warning: Locale not supported by X.\n"); - } + /* Save the Unicode support flag in a global */ + g_fUseUnicode = fUseUnicode; + + /* Create Windows messaging window */ + hwnd = winClipboardCreateMessagingWindow (); + + /* Save copy of HWND in screen privates */ + g_hwndClipboard = hwnd; g_winClipboardProcThread = pthread_self(); /* Set error handler */ - if (!fErrorHandlerSet) { - XSetErrorHandler(winClipboardErrorHandler); - g_winClipboardOldIOErrorHandler = - XSetIOErrorHandler(winClipboardIOErrorHandler); - fErrorHandlerSet = TRUE; - } + XSetErrorHandler(winClipboardErrorHandler); + g_winClipboardOldIOErrorHandler = + XSetIOErrorHandler(winClipboardIOErrorHandler); /* Set jump point for Error exits */ - if (setjmp(g_jmpEntry)) { + iReturn = setjmp(g_jmpEntry); + + /* Check if we should continue operations */ + if (iReturn != WIN_JMP_ERROR_IO && iReturn != WIN_JMP_OKAY) { + /* setjmp returned an unknown value, exit */ + ErrorF("winClipboardProc - setjmp returned: %d exiting\n", iReturn); + goto thread_errorexit; + } + else if (iReturn == WIN_JMP_ERROR_IO) { + /* TODO: Cleanup the Win32 window and free any allocated memory */ ErrorF("winClipboardProc - setjmp returned for IO Error Handler.\n"); - goto winClipboardProc_Done; } /* Make sure that the display opened */ pDisplay = XOpenDisplay(szDisplay); if (pDisplay == NULL) { ErrorF("winClipboardProc - Failed opening the display, giving up\n"); - goto winClipboardProc_Done; + bShutDown = FALSE; + goto thread_errorexit; } - ErrorF("winClipboardProc - XOpenDisplay () returned and " + /* Save the display in the screen privates */ + g_pClipboardDisplay = pDisplay; + + winDebug ("winClipboardProc - XOpenDisplay () returned and " "successfully opened the display.\n"); /* Get our connection number */ iConnectionNumber = ConnectionNumber(pDisplay); + winDebug("Clipboard is using socket %d\n",iConnectionNumber); + #ifdef HAS_DEVWINDOWS /* Open a file descriptor for the windows message queue */ - fdMessageQueue = open(WIN_MSG_QUEUE_FNAME, O_RDONLY); + fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, _O_RDONLY); if (fdMessageQueue == -1) { ErrorF("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME); - goto winClipboardProc_Done; + goto thread_errorexit; } /* Find max of our file descriptors */ - iMaxDescriptor = MAX(fdMessageQueue, iConnectionNumber) + 1; + iMaxDescriptor = max(fdMessageQueue, iConnectionNumber) + 1; #else iMaxDescriptor = iConnectionNumber + 1; #endif - if (!XFixesQueryExtension(pDisplay, &xfixes_event_base, &xfixes_error_base)) - ErrorF ("winClipboardProc - XFixes extension not present\n"); - - /* Create atoms */ - atoms.atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False); - atoms.atomLocalProperty = XInternAtom (pDisplay, "CYGX_CUT_BUFFER", False); - atoms.atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False); - atoms.atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False); - atoms.atomTargets = XInternAtom (pDisplay, "TARGETS", False); + /* Create atom */ + atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False); + XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False); + XInternAtom (pDisplay, "UTF8_STRING", False); + XInternAtom (pDisplay, "COMPOUND_TEXT", False); + XInternAtom (pDisplay, "TARGETS", False); /* Create a messaging window */ iWindow = XCreateSimpleWindow(pDisplay, @@ -200,7 +208,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) BlackPixel(pDisplay, 0)); if (iWindow == 0) { ErrorF("winClipboardProc - Could not create an X window.\n"); - goto winClipboardProc_Done; + goto thread_errorexit; } XStoreName(pDisplay, iWindow, "xwinclip"); @@ -210,47 +218,33 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) ErrorF("winClipboardProc - XSelectInput generated BadWindow " "on messaging window\n"); - XFixesSelectSelectionInput (pDisplay, - iWindow, - XA_PRIMARY, - XFixesSetSelectionOwnerNotifyMask | - XFixesSelectionWindowDestroyNotifyMask | - XFixesSelectionClientCloseNotifyMask); - - XFixesSelectSelectionInput (pDisplay, - iWindow, - atoms.atomClipboard, - XFixesSetSelectionOwnerNotifyMask | - XFixesSelectionWindowDestroyNotifyMask | - XFixesSelectionClientCloseNotifyMask); - - - /* Initialize monitored selection state */ - winClipboardInitMonitoredSelections(); - /* Create Windows messaging window */ - hwnd = winClipboardCreateMessagingWindow(pDisplay, iWindow, &atoms); - - /* Save copy of HWND */ - g_hwndClipboard = hwnd; + /* Save the window in the screen privates */ + g_iClipboardWindow = iWindow; /* Assert ownership of selections if Win32 clipboard is owned */ if (NULL != GetClipboardOwner()) { - /* PRIMARY */ - iReturn = XSetSelectionOwner(pDisplay, XA_PRIMARY, - iWindow, CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) { - ErrorF("winClipboardProc - Could not set PRIMARY owner\n"); - goto winClipboardProc_Done; + if (g_fClipboardPrimary) + { + /* PRIMARY */ + winDebug("winClipboardProc - asserted ownership.\n"); + iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow /*|| + XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow*/) + { + ErrorF ("winClipboardProc - Could not set PRIMARY owner\n"); + goto thread_errorexit; + } } /* CLIPBOARD */ - iReturn = XSetSelectionOwner(pDisplay, atoms.atomClipboard, + iReturn = XSetSelectionOwner(pDisplay, atomClipboard, iWindow, CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner(pDisplay, atoms.atomClipboard) != iWindow) { - ErrorF("winClipboardProc - Could not set CLIPBOARD owner\n"); - goto winClipboardProc_Done; + if (iReturn == BadAtom || iReturn == BadWindow /*|| + XGetSelectionOwner (pDisplay, atomClipboard) != iWindow*/) + { + ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n"); + goto thread_errorexit; } } @@ -260,13 +254,20 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) * because there may be events in local data structures * already. */ - winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms); + //winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode); /* Pre-flush Windows messages */ - if (!winClipboardFlushWindowsMessageQueue(hwnd)) { - ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n"); + winDebug ("Start flushing \n"); + if (!winClipboardFlushWindowsMessageQueue(hwnd)) + { + ErrorF ("winClipboardFlushWindowsMessageQueue - returned 0\n"); + goto thread_errorexit; } + winDebug ("winClipboardProc - Started\n"); + /* Signal that the clipboard client has started */ + g_fClipboardStarted = TRUE; + /* Loop for X events */ while (1) { /* Setup the file descriptor set */ @@ -316,10 +317,12 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) } /* Branch on which descriptor became active */ - if (FD_ISSET(iConnectionNumber, &fdsRead)) { +// if (FD_ISSET (iConnectionNumber, &fdsRead)) { +// Also do it when no read since winClipboardFlushXEvents +// is sending the output. /* Process X events */ - winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms); - } + winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, FALSE); +// } #ifdef HAS_DEVWINDOWS /* Check for Windows event ready */ @@ -338,23 +341,15 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) } } - winClipboardProc_Exit: - /* broke out of while loop on a shutdown message */ - fShutdown = TRUE; - - winClipboardProc_Done: - /* Close our Windows window */ - if (g_hwndClipboard) { - winClipboardWindowDestroy(); - } - /* Close our X window */ if (pDisplay && iWindow) { iReturn = XDestroyWindow(pDisplay, iWindow); if (iReturn == BadWindow) ErrorF("winClipboardProc - XDestroyWindow returned BadWindow.\n"); +#ifdef WINDBG else - ErrorF("winClipboardProc - XDestroyWindow succeeded.\n"); + winDebug("winClipboardProc - XDestroyWindow succeeded.\n"); +#endif } #ifdef HAS_DEVWINDOWS @@ -365,11 +360,8 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) #if 0 /* - * FIXME: XCloseDisplay hangs if we call it - * - * XCloseDisplay() calls XSync(), so any outstanding errors are reported. - * If we are built into the server, this can deadlock if the server is - * in the process of exiting and waiting for this thread to exit. + * FIXME: XCloseDisplay hangs if we call it, as of 2004/03/26. The + * XSync and XSelectInput calls did not help. */ /* Discard any remaining events */ @@ -384,21 +376,40 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) } #endif - /* global clipboard variable reset */ - g_hwndClipboard = NULL; + goto commonexit; - return fShutdown; +thread_errorexit: + if (g_pClipboardDisplay && g_iClipboardWindow) + { + iReturn = XDestroyWindow (g_pClipboardDisplay, g_iClipboardWindow); + if (iReturn == BadWindow) + ErrorF ("winClipboardProc - XDestroyWindow returned BadWindow.\n"); +#ifdef WINDBG + else + winDebug ("winClipboardProc - XDestroyWindow succeeded.\n"); +#endif + } + winDebug ("Clipboard thread died.\n"); + +commonexit: + g_iClipboardWindow = None; + g_pClipboardDisplay = NULL; + g_fClipboardLaunched = FALSE; + g_fClipboardStarted = FALSE; + + pthread_cleanup_pop(0); + + return bShutDown; } /* * Create the Windows window that we use to receive Windows messages */ -static HWND -winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAtoms *atoms) +HWND +winClipboardCreateMessagingWindow(void) { WNDCLASSEX wc; - ClipboardWindowCreationParams cwcp; HWND hwnd; /* Setup our window class */ @@ -416,11 +427,6 @@ winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAt wc.hIconSm = 0; RegisterClassEx(&wc); - /* Information to be passed to WM_CREATE */ - cwcp.pClipboardDisplay = pDisplay; - cwcp.iClipboardWindow = iWindow; - cwcp.atoms = atoms; - /* Create the window */ hwnd = CreateWindowExA(0, /* Extended styles */ WIN_CLIPBOARD_WINDOW_CLASS, /* Class name */ @@ -433,7 +439,7 @@ winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAt (HWND) NULL, /* No parent or owner window */ (HMENU) NULL, /* No menu */ GetModuleHandle(NULL), /* Instance handle */ - &cwcp); /* Creation data */ + NULL); /* Creation data */ assert(hwnd != NULL); /* I'm not sure, but we may need to call this to start message processing */ @@ -456,8 +462,17 @@ winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr) XGetErrorText(pDisplay, pErr->error_code, pszErrorMsg, sizeof(pszErrorMsg)); ErrorF("winClipboardErrorHandler - ERROR: \n\t%s\n" - "\tSerial: %lu, Request Code: %d, Minor Code: %d\n", - pszErrorMsg, pErr->serial, pErr->request_code, pErr->minor_code); + " errorCode %d\n" + " serial %lu\n" + " resourceID 0x%x\n" + " majorCode %d\n" + " minorCode %d\n" + , pszErrorMsg + , pErr->error_code + , pErr->serial + , pErr->resourceid + , pErr->request_code + , pErr->minor_code); return 0; } @@ -472,7 +487,7 @@ winClipboardIOErrorHandler(Display * pDisplay) if (pthread_equal(pthread_self(), g_winClipboardProcThread)) { /* Restart at the main entry point */ - longjmp(g_jmpEntry, 2); + longjmp(g_jmpEntry, WIN_JMP_ERROR_IO); } if (g_winClipboardOldIOErrorHandler) @@ -481,18 +496,23 @@ winClipboardIOErrorHandler(Display * pDisplay) return 0; } -void -winClipboardWindowDestroy(void) +/* + * winClipboardThreadExit - Thread exit handler + */ + +static void +winClipboardThreadExit(void *arg) { - if (g_hwndClipboard) { - SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0); - } + /* clipboard thread has exited, stop server as well */ + AbortDDX(EXIT_ERR_ABORT); + TerminateProcess(GetCurrentProcess(),1); } + void -winFixClipboardChain(void) +winFixClipboardChain(int Removed) { - if (g_hwndClipboard) { - PostMessage(g_hwndClipboard, WM_WM_REINIT, 0, 0); - } + if (g_fClipboard && g_hwndClipboard) { + PostMessage (g_hwndClipboard, WM_WM_REINIT, Removed, 0); + } } diff --git a/xorg-server/hw/xwin/winclipboard/winclipboard.h b/xorg-server/hw/xwin/winclipboard/winclipboard.h index 52481301b..7b172739a 100644 --- a/xorg-server/hw/xwin/winclipboard/winclipboard.h +++ b/xorg-server/hw/xwin/winclipboard/winclipboard.h @@ -27,10 +27,6 @@ #ifndef WINCLIPBOARD_H #define WINCLIPBOARD_H -Bool winClipboardProc(Bool fUseUnicode, char *szDisplay); - -void winFixClipboardChain(void); - -void winClipboardWindowDestroy(void); +void winFixClipboardChain (int Removed); #endif 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; } } diff --git a/xorg-server/hw/xwin/winclipboard/xevents.c b/xorg-server/hw/xwin/winclipboard/xevents.c index 33d52aafd..cfbf0121e 100644..100755 --- a/xorg-server/hw/xwin/winclipboard/xevents.c +++ b/xorg-server/hw/xwin/winclipboard/xevents.c @@ -33,105 +33,13 @@ #ifdef HAVE_XWIN_CONFIG_H #include <xwin-config.h> #endif - -/* - * Including any server header might define the macro _XSERVER64 on 64 bit machines. - * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen. - * So let's undef that macro if necessary. - */ -#ifdef _XSERVER64 -#undef _XSERVER64 -#endif - +#include "winclipboard.h" +#include "misc.h" +#include "winmsg.h" #include "internal.h" -#include <X11/Xutil.h> -#include <X11/Xatom.h> -#include <X11/extensions/Xfixes.h> - -/* - * Constants - */ - -#define CLIP_NUM_SELECTIONS 2 -#define CLIP_OWN_NONE -1 -#define CLIP_OWN_PRIMARY 0 -#define CLIP_OWN_CLIPBOARD 1 - -/* - * Global variables - */ +#include <unistd.h> -extern int xfixes_event_base; - -/* - * Local variables - */ - -static Window s_iOwners[CLIP_NUM_SELECTIONS] = { None, None }; -static const char *szSelectionNames[CLIP_NUM_SELECTIONS] = - { "PRIMARY", "CLIPBOARD" }; - -static unsigned int lastOwnedSelectionIndex = CLIP_OWN_NONE; - -static void -MonitorSelection(XFixesSelectionNotifyEvent * e, unsigned int i) -{ - /* Look for owned -> not owned transition */ - if (None == e->owner && None != s_iOwners[i]) { - unsigned int other_index; - - winDebug("MonitorSelection - %s - Going from owned to not owned.\n", - szSelectionNames[i]); - - /* If this selection is not owned, the other monitored selection must be the most - recently owned, if it is owned at all */ - if (i == CLIP_OWN_PRIMARY) - other_index = CLIP_OWN_CLIPBOARD; - if (i == CLIP_OWN_CLIPBOARD) - other_index = CLIP_OWN_PRIMARY; - if (None != s_iOwners[other_index]) - lastOwnedSelectionIndex = other_index; - else - lastOwnedSelectionIndex = CLIP_OWN_NONE; - } - - /* Save last owned selection */ - if (None != e->owner) { - lastOwnedSelectionIndex = i; - } - - /* Save new selection owner or None */ - s_iOwners[i] = e->owner; - winDebug("MonitorSelection - %s - Now owned by XID %x\n", - szSelectionNames[i], e->owner); -} - -Atom -winClipboardGetLastOwnedSelectionAtom(ClipboardAtoms *atoms) -{ - if (lastOwnedSelectionIndex == CLIP_OWN_NONE) - return None; - - if (lastOwnedSelectionIndex == CLIP_OWN_PRIMARY) - return XA_PRIMARY; - - if (lastOwnedSelectionIndex == CLIP_OWN_CLIPBOARD) - return atoms->atomClipboard; - - return None; -} - - -void -winClipboardInitMonitoredSelections(void) -{ - /* Initialize static variables */ - int i; - for (i = 0; i < CLIP_NUM_SELECTIONS; ++i) - s_iOwners[i] = None; - - lastOwnedSelectionIndex = CLIP_OWN_NONE; -} +extern Bool g_fClipboardPrimary; /* * Process any pending X events @@ -139,13 +47,21 @@ winClipboardInitMonitoredSelections(void) int winClipboardFlushXEvents(HWND hwnd, - Window iWindow, Display * pDisplay, Bool fUseUnicode, ClipboardAtoms *atoms) + int iWindow, Display * pDisplay, Bool fUseUnicode, Bool ClipboardOpened) { - Atom atomClipboard = atoms->atomClipboard; - Atom atomLocalProperty = atoms->atomLocalProperty; - Atom atomUTF8String = atoms->atomUTF8String; - Atom atomCompoundText = atoms->atomCompoundText; - Atom atomTargets = atoms->atomTargets; + static Atom atomLocalProperty; + static Atom atomCompoundText; + static Atom atomUTF8String; + static Atom atomTargets; + static int generation; + + if (generation != serverGeneration) { + generation = serverGeneration; + atomLocalProperty = XInternAtom(pDisplay, WIN_LOCAL_PROPERTY, False); + atomUTF8String = XInternAtom(pDisplay, "UTF8_STRING", False); + atomCompoundText = XInternAtom(pDisplay, "COMPOUND_TEXT", False); + atomTargets = XInternAtom(pDisplay, "TARGETS", False); + } /* Process all pending events */ while (XPending(pDisplay)) { @@ -166,6 +82,7 @@ winClipboardFlushXEvents(HWND hwnd, wchar_t *pwszUnicodeStr = NULL; int iUnicodeLen = 0; int iReturnDataLen = 0; + int i; Bool fAbort = FALSE; Bool fCloseClipboard = FALSE; Bool fSetClipboardData = TRUE; @@ -173,6 +90,8 @@ winClipboardFlushXEvents(HWND hwnd, /* Get the next event - will not block because one is ready */ XNextEvent(pDisplay, &event); + winDebug ("Received event type %d\n",event.type); + /* Branch on the event type */ switch (event.type) { /* @@ -180,6 +99,7 @@ winClipboardFlushXEvents(HWND hwnd, */ case SelectionRequest: +#ifdef _DEBUG { char *pszAtomName = NULL; @@ -191,7 +111,10 @@ winClipboardFlushXEvents(HWND hwnd, winDebug("SelectionRequest - Target atom name %s\n", pszAtomName); XFree(pszAtomName); pszAtomName = NULL; + winDebug ("SelectionRequest - owner %d\n", event.xselectionrequest.owner); + winDebug ("SelectionRequest - requestor %d\n", event.xselectionrequest.requestor); } +#endif /* Abort if invalid target type */ if (event.xselectionrequest.target != XA_STRING @@ -253,24 +176,24 @@ winClipboardFlushXEvents(HWND hwnd, break; } - /* Close clipboard if we have it open already */ - if (GetOpenClipboardWindow() == hwnd) { - CloseClipboard(); - } - - /* Access the clipboard */ - if (!OpenClipboard(hwnd)) { - ErrorF("winClipboardFlushXEvents - SelectionRequest - " - "OpenClipboard () failed: %08lx\n", GetLastError()); + /* Access the clipboard */ + if (!ClipboardOpened) + { + if (!OpenClipboard (hwnd)) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "OpenClipboard () failed: %08lx\n", + GetLastError ()); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Indicate that clipboard was opened */ + fCloseClipboard = TRUE; } - /* Indicate that clipboard was opened */ - fCloseClipboard = TRUE; - /* Check that clipboard format is available */ if (fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) { static int count; /* Hack to stop acroread spamming the log */ @@ -320,7 +243,16 @@ winClipboardFlushXEvents(HWND hwnd, hGlobal = GetClipboardData(CF_TEXT); } if (!hGlobal) { - ErrorF("winClipboardFlushXEvents - SelectionRequest - " + if (GetLastError()==ERROR_CLIPBOARD_NOT_OPEN && ClipboardOpened) + { + ErrorF("We should not have received a SelectionRequest????\n" + "The owner is the clipboard, but in reality it was" + "an X window\n"); + /* Set the owner to None */ + if (g_fClipboardPrimary) XSetSelectionOwner (pDisplay, XA_PRIMARY, None, CurrentTime); + XSetSelectionOwner (pDisplay, XInternAtom (pDisplay, "CLIPBOARD", False), None, CurrentTime); + } + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " "GetClipboardData () failed: %08lx\n", GetLastError()); /* Abort */ @@ -408,9 +340,11 @@ winClipboardFlushXEvents(HWND hwnd, /* Release the clipboard data */ GlobalUnlock(hGlobal); pszGlobalData = NULL; - fCloseClipboard = FALSE; - CloseClipboard(); - + if (fCloseClipboard) + { + fCloseClipboard = FALSE; + CloseClipboard (); + } /* Clean up */ XFree(xtpText.value); xtpText.value = NULL; @@ -489,9 +423,8 @@ winClipboardFlushXEvents(HWND hwnd, /* * SelectionNotify */ - case SelectionNotify: - +#ifdef _DEBUG winDebug("winClipboardFlushXEvents - SelectionNotify\n"); { char *pszAtomName; @@ -502,8 +435,11 @@ winClipboardFlushXEvents(HWND hwnd, winDebug ("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n", pszAtomName); + winDebug ("SelectionNotify - requestor %d\n", event.xselectionrequest.requestor); XFree(pszAtomName); } +#endif + /* * Request conversion of UTF8 and CompoundText targets. @@ -586,6 +522,7 @@ winClipboardFlushXEvents(HWND hwnd, break; } +#ifdef WINDBG { char *pszAtomName = NULL; @@ -596,6 +533,7 @@ winClipboardFlushXEvents(HWND hwnd, XFree(pszAtomName); pszAtomName = NULL; } +#endif if (fUseUnicode) { #ifdef X_HAVE_UTF8_STRING @@ -613,13 +551,11 @@ winClipboardFlushXEvents(HWND hwnd, if (iReturn == Success || iReturn > 0) { /* Conversion succeeded or some unconvertible characters */ if (ppszTextList != NULL) { - int i; - iReturnDataLen = 0; for (i = 0; i < iCount; i++) { iReturnDataLen += strlen(ppszTextList[i]); } - pszReturnData = malloc(iReturnDataLen + 1); + pszReturnData = (char *) malloc(iReturnDataLen + 1); pszReturnData[0] = '\0'; for (i = 0; i < iCount; i++) { strcat(pszReturnData, ppszTextList[i]); @@ -628,7 +564,7 @@ winClipboardFlushXEvents(HWND hwnd, else { ErrorF("winClipboardFlushXEvents - SelectionNotify - " "X*TextPropertyToTextList list_return is NULL.\n"); - pszReturnData = malloc(1); + pszReturnData = (char *) malloc(1); pszReturnData[0] = '\0'; } } @@ -649,7 +585,7 @@ winClipboardFlushXEvents(HWND hwnd, ErrorF("%d\n", iReturn); break; } - pszReturnData = malloc(1); + pszReturnData = (char *) malloc(1); pszReturnData[0] = '\0'; } @@ -662,7 +598,7 @@ winClipboardFlushXEvents(HWND hwnd, xtpText.nitems = 0; /* Convert the X clipboard string to DOS format */ - winClipboardUNIXtoDOS(&pszReturnData, strlen(pszReturnData)); + winClipboardUNIXtoDOS((unsigned char **)&pszReturnData, strlen(pszReturnData)); if (fUseUnicode) { /* Find out how much space needed to convert MBCS to Unicode */ @@ -772,89 +708,37 @@ winClipboardFlushXEvents(HWND hwnd, } return WIN_XEVENTS_NOTIFY; - case SelectionClear: + /* + * SelectionClear + */ + case SelectionClear: +#ifdef _DEBUG winDebug("SelectionClear - doing nothing\n"); + { + char *pszAtomName; + + pszAtomName = XGetAtomName (pDisplay, + event.xselection.selection); + + winDebug ("SelectionClear - ATOM: %s\n", + pszAtomName); + winDebug ("SelectionClear - owner %d\n", event.xselectionrequest.owner); + + XFree (pszAtomName); + } +#endif break; case PropertyNotify: break; - + case MappingNotify: + XRefreshKeyboardMapping((XMappingEvent *)&event); break; default: - if (event.type == XFixesSetSelectionOwnerNotify + xfixes_event_base) { - XFixesSelectionNotifyEvent *e = - (XFixesSelectionNotifyEvent *) & event; - - winDebug("winClipboardFlushXEvents - XFixesSetSelectionOwnerNotify\n"); - - /* Save selection owners for monitored selections, ignore other selections */ - if (e->selection == XA_PRIMARY) { - MonitorSelection(e, CLIP_OWN_PRIMARY); - } - else if (e->selection == atomClipboard) { - MonitorSelection(e, CLIP_OWN_CLIPBOARD); - } - else - break; - - /* Selection is being disowned */ - if (e->owner == None) { - winDebug - ("winClipboardFlushXEvents - No window, returning.\n"); - break; - } - - /* - XXX: there are all kinds of wacky edge cases we might need here: - - we own windows clipboard, but neither PRIMARY nor CLIPBOARD have an owner, so we should disown it? - - root window is taking ownership? - */ - - /* If we are the owner of the most recently owned selection, don't go all recursive :) */ - if ((lastOwnedSelectionIndex != CLIP_OWN_NONE) && - (s_iOwners[lastOwnedSelectionIndex] == iWindow)) { - winDebug("winClipboardFlushXEvents - Ownership changed to us, aborting.\n"); - break; - } - - /* Close clipboard if we have it open already (possible? correct??) */ - if (GetOpenClipboardWindow() == hwnd) { - CloseClipboard(); - } - - /* Access the Windows clipboard */ - if (!OpenClipboard(hwnd)) { - ErrorF("winClipboardFlushXEvents - OpenClipboard () failed: %08x\n", - (int) GetLastError()); - break; - } - - /* Take ownership of the Windows clipboard */ - if (!EmptyClipboard()) { - ErrorF("winClipboardFlushXEvents - EmptyClipboard () failed: %08x\n", - (int) GetLastError()); - break; - } - - /* Advertise regular text and unicode */ - SetClipboardData(CF_UNICODETEXT, NULL); - SetClipboardData(CF_TEXT, NULL); - - /* Release the clipboard */ - if (!CloseClipboard()) { - ErrorF("winClipboardFlushXEvents - CloseClipboard () failed: %08x\n", - (int) GetLastError()); - break; - } - } - /* XFixesSelectionWindowDestroyNotifyMask */ - /* XFixesSelectionClientCloseNotifyMask */ - else { - ErrorF("winClipboardFlushXEvents - unexpected event type %d\n", - event.type); - } + ErrorF("winClipboardFlushXEvents - unexpected event type %d\n", + event.type); break; } } |