diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2013-06-12 19:41:21 +0100 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2013-06-15 16:03:06 +0100 |
commit | ffcbe2baeb81ffc1595381aa32b5f807e7a24f9f (patch) | |
tree | 1253cd7c310a0913e27ee8e642160031b691661a | |
parent | c2507b8c3d0ffd6f1bb2aa1b2f3c505d9f78cdfc (diff) |
Move clipboard integration code out to a libraryclipboard-use-libXWinclip
Remove SetSelectionOwner wrapper, the library instead uses the
XFixesSetSelectionOwnerNotify event, the equivalent client-side mechanism.
Clean up the interface between clipboard integration code and the rest of the
code a bit more.
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | hw/xwin/InitInput.c | 1 | ||||
-rw-r--r-- | hw/xwin/Makefile.am | 7 | ||||
-rw-r--r-- | hw/xwin/winclipboard.h | 127 | ||||
-rw-r--r-- | hw/xwin/winclipboardinit.c | 130 | ||||
-rw-r--r-- | hw/xwin/winclipboardtextconv.c | 154 | ||||
-rw-r--r-- | hw/xwin/winclipboardthread.c | 473 | ||||
-rw-r--r-- | hw/xwin/winclipboardwndproc.c | 577 | ||||
-rw-r--r-- | hw/xwin/winclipboardwrappers.c | 240 | ||||
-rw-r--r-- | hw/xwin/winclipboardxevents.c | 716 | ||||
-rw-r--r-- | hw/xwin/windialogs.c | 7 | ||||
-rw-r--r-- | hw/xwin/winglobals.c | 14 | ||||
-rw-r--r-- | hw/xwin/winglobals.h | 4 |
13 files changed, 52 insertions, 2400 deletions
diff --git a/configure.ac b/configure.ac index e9b3b6c8c..19bc239dd 100644 --- a/configure.ac +++ b/configure.ac @@ -1896,7 +1896,7 @@ if test "x$XWIN" = xyes; then AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support]) AC_CHECK_TOOL(WINDRES, windres) - PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau x11-xcb xcb-image xcb-icccm]) + PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau x11-xcb xcb-image xcb-icccm xwinclip]) if test "x$WINDOWSWM" = xauto; then PKG_CHECK_EXISTS($WINDOWSWMPROTO, [WINDOWSWM=yes], [WINDOWSWM=no]) diff --git a/hw/xwin/InitInput.c b/hw/xwin/InitInput.c index 36346b7e1..c42418c23 100644 --- a/hw/xwin/InitInput.c +++ b/hw/xwin/InitInput.c @@ -39,7 +39,6 @@ #ifdef XWIN_CLIPBOARD int winProcEstablishConnection(ClientPtr /* client */ ); -int winProcSetSelectionOwner(ClientPtr /* client */ ); #endif /* diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am index 28abb5345..f0654b273 100644 --- a/hw/xwin/Makefile.am +++ b/hw/xwin/Makefile.am @@ -3,11 +3,7 @@ bin_PROGRAMS = XWin if XWIN_CLIPBOARD SRCS_CLIPBOARD = \ winclipboardinit.c \ - winclipboardtextconv.c \ - winclipboardthread.c \ - winclipboardwndproc.c \ - winclipboardwrappers.c \ - winclipboardxevents.c + winclipboardwrappers.c DEFS_CLIPBOARD = -DXWIN_CLIPBOARD endif @@ -111,7 +107,6 @@ SRCS = InitInput.c \ winwindow.c \ winwndproc.c \ ddraw.h \ - winclipboard.h \ winconfig.h \ win.h \ winglobals.h \ diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h deleted file mode 100644 index b6ae1d5b9..000000000 --- a/hw/xwin/winclipboard.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef _WINCLIPBOARD_H_ -#define _WINCLIPBOARD_H_ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - */ - -/* Standard library headers */ -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#ifdef __CYGWIN__ -#include <sys/select.h> -#else -#include <X11/Xwinsock.h> -#endif -#include <fcntl.h> -#include <setjmp.h> -#include <pthread.h> - -/* X headers */ -#include <X11/X.h> -#include <X11/Xatom.h> -#include <X11/Xproto.h> -#include <X11/Xutil.h> - -/* Windows headers */ -#include <X11/Xwindows.h> - -/* Clipboard module constants */ -#define WIN_CLIPBOARD_WINDOW_CLASS "xwinclip" -#define WIN_CLIPBOARD_WINDOW_TITLE "xwinclip" -#ifdef HAS_DEVWINDOWS -#define WIN_MSG_QUEUE_FNAME "/dev/windows" -#endif -#define WIN_CONNECT_RETRIES 40 -#define WIN_CONNECT_DELAY 4 -#define WIN_JMP_OKAY 0 -#define WIN_JMP_ERROR_IO 2 -#define WIN_LOCAL_PROPERTY "CYGX_CUT_BUFFER" -#define WIN_XEVENTS_SUCCESS 0 -#define WIN_XEVENTS_SHUTDOWN 1 -#define WIN_XEVENTS_CONVERT 2 -#define WIN_XEVENTS_NOTIFY 3 - -#define WM_WM_REINIT (WM_USER + 1) - -/* - * References to external symbols - */ - -extern char *display; -extern void winDebug(const char *format, ...); -extern void winErrorFVerb(int verb, const char *format, ...); - -/* - * winclipboardinit.c - */ - -Bool - winInitClipboard(void); - -HWND winClipboardCreateMessagingWindow(void); - -/* - * winclipboardtextconv.c - */ - -void - winClipboardDOStoUNIX(char *pszData, int iLength); - -void - winClipboardUNIXtoDOS(char **ppszData, int iLength); - -/* - * winclipboardthread.c - */ - -void *winClipboardProc(void *); - -void - winDeinitClipboard(void); - -/* - * winclipboardwndproc.c - */ - -BOOL winClipboardFlushWindowsMessageQueue(HWND hwnd); - -LRESULT CALLBACK -winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); - -/* - * winclipboardxevents.c - */ - -int - -winClipboardFlushXEvents(HWND hwnd, - int iWindow, Display * pDisplay, Bool fUnicodeSupport); -#endif diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index 25b06843b..1eac500be 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -34,31 +34,23 @@ #include <assert.h> #include <unistd.h> +#include <pthread.h> -#include "dixstruct.h" -#include "winclipboard.h" +#include <xwinclip/xwinclip.h> + +#include <X11/Xdefs.h> // for Bool +#include <X11/Xwindows.h> +#include "winmsg.h" +#include "winglobals.h" +#include "win.h" #define WIN_CLIPBOARD_RETRIES 40 #define WIN_CLIPBOARD_DELAY 1 /* - * Local typedefs + * */ - -typedef int (*winDispatchProcPtr) (ClientPtr); - -int winProcSetSelectionOwner(ClientPtr /* client */ ); - -/* - * References to external symbols - */ - -extern pthread_t g_ptClipboardProc; -extern winDispatchProcPtr winProcSetSelectionOwnerOrig; -extern Bool g_fClipboard; -extern HWND g_hwndClipboard; -extern Bool g_fClipboardLaunched; -extern Bool g_fClipboardStarted; +static pthread_t g_ptClipboardProc; /* * @@ -66,16 +58,41 @@ extern Bool g_fClipboardStarted; static void * winClipboardThreadProc(void *arg) { + char szDisplay[512]; int clipboardRestarts = 0; while (1) { + int fShutdown; + ++clipboardRestarts; - /* Flag that clipboard client has been launched */ - g_fClipboardLaunched = TRUE; + /* Use our generated cookie for authentication */ + winSetAuthorization(); + + /* Setup the display connection string */ + /* + * NOTE: Always connect to screen 0 since we require that screen + * numbers start at 0 and increase without gaps. We only need + * to connect to one screen on the display to get events + * for all screens on the display. That is why there is only + * one clipboard client thread. + */ + winGetDisplayName(szDisplay, 0); + + /* Print the display connection string */ + ErrorF("winClipboardProc - DISPLAY=%s\n", szDisplay); + + /* Flag that clipboard client has started */ + g_fClipboardStarted = TRUE; + + fShutdown = ClipboardProc(g_fUnicodeClipboard, szDisplay); - winClipboardProc(arg); + /* Flag that clipboard client has stopped */ + g_fClipboardStarted = FALSE; + + if (fShutdown) + break; /* checking if we need to restart */ if (clipboardRestarts >= WIN_CLIPBOARD_RETRIES) { @@ -101,12 +118,6 @@ winInitClipboard(void) { winDebug("winInitClipboard ()\n"); - /* Wrap some internal server functions */ - if (ProcVector[X_SetSelectionOwner] != winProcSetSelectionOwner) { - winProcSetSelectionOwnerOrig = ProcVector[X_SetSelectionOwner]; - ProcVector[X_SetSelectionOwner] = winProcSetSelectionOwner; - } - /* Spawn a thread for the Clipboard module */ if (pthread_create(&g_ptClipboardProc, NULL, winClipboardThreadProc, NULL)) { /* Bail if thread creation failed */ @@ -121,78 +132,21 @@ void winClipboardShutdown(void) { /* Close down clipboard resources */ - if (g_fClipboard && g_fClipboardLaunched && g_fClipboardStarted) { - /* Synchronously destroy the clipboard window */ - if (g_hwndClipboard != NULL) { - SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0); - /* NOTE: g_hwndClipboard is set to NULL in winclipboardthread.c */ - } - else - return; + if (g_fClipboard && g_fClipboardStarted) { + ClipboardWindowDestroy(); /* Wait for the clipboard thread to exit */ pthread_join(g_ptClipboardProc, NULL); - g_fClipboardLaunched = FALSE; g_fClipboardStarted = FALSE; winDebug("winClipboardShutdown - Clipboard thread has exited.\n"); } } -/* - * Create the Windows window that we use to recieve Windows messages - */ - -HWND -winClipboardCreateMessagingWindow(void) -{ - WNDCLASSEX wc; - HWND hwnd; - - /* Setup our window class */ - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = winClipboardWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = GetModuleHandle(NULL); - wc.hIcon = 0; - wc.hCursor = 0; - wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName = WIN_CLIPBOARD_WINDOW_CLASS; - wc.hIconSm = 0; - RegisterClassEx(&wc); - - /* Create the window */ - hwnd = CreateWindowExA(0, /* Extended styles */ - WIN_CLIPBOARD_WINDOW_CLASS, /* Class name */ - WIN_CLIPBOARD_WINDOW_TITLE, /* Window name */ - WS_OVERLAPPED, /* Not visible anyway */ - CW_USEDEFAULT, /* Horizontal position */ - CW_USEDEFAULT, /* Vertical position */ - CW_USEDEFAULT, /* Right edge */ - CW_USEDEFAULT, /* Bottom edge */ - (HWND) NULL, /* No parent or owner window */ - (HMENU) NULL, /* No menu */ - GetModuleHandle(NULL), /* Instance handle */ - NULL); /* Creation data */ - assert(hwnd != NULL); - - /* I'm not sure, but we may need to call this to start message processing */ - ShowWindow(hwnd, SW_HIDE); - - /* Similarly, we may need a call to this even though we don't paint */ - UpdateWindow(hwnd); - - return hwnd; -} - void winFixClipboardChain(void) { - if (g_fClipboard && g_hwndClipboard) { - PostMessage(g_hwndClipboard, WM_WM_REINIT, 0, 0); - } + if (g_fClipboard) + ClipboardFixClipboardChain(); } diff --git a/hw/xwin/winclipboardtextconv.c b/hw/xwin/winclipboardtextconv.c deleted file mode 100644 index 7b8eb9826..000000000 --- a/hw/xwin/winclipboardtextconv.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include <stdio.h> -#include <stdlib.h> - -void - winClipboardDOStoUNIX(char *pszSrc, int iLength); -void - winClipboardUNIXtoDOS(char **ppszData, int iLength); - -/* - * Convert \r\n to \n - * - * NOTE: This was heavily inspired by, Cygwin's - * winsup/cygwin/fhandler.cc/fhandler_base::read () - */ - -void -winClipboardDOStoUNIX(char *pszData, int iLength) -{ - char *pszSrc = pszData; - char *pszDest = pszSrc; - char *pszEnd = pszSrc + iLength; - - winDebug("DOXtoUNIX() - Original data:'%s'\n", pszData); - - /* Loop until the last character */ - while (pszSrc < pszEnd) { - /* Copy the current source character to current destination character */ - *pszDest = *pszSrc; - - /* Advance to the next source character */ - pszSrc++; - - /* Don't advance the destination character if we need to drop an \r */ - if (*pszDest != '\r' || *pszSrc != '\n') - pszDest++; - } - - /* Move the terminating null */ - *pszDest = '\0'; - - winDebug("DOStoUNIX() - Final string:'%s'\n", pszData); -} - -/* - * Convert \n to \r\n - */ - -void -winClipboardUNIXtoDOS(char **ppszData, int iLength) -{ - int iNewlineCount = 0; - char *pszSrc = *ppszData; - char *pszEnd = pszSrc + iLength; - char *pszDest = NULL, *pszDestBegin = NULL; - - winDebug("UNIXtoDOS () - Original data:'%s'\n", *ppszData); - - /* Count \n characters without leading \r */ - while (pszSrc < pszEnd) { - /* Skip ahead two character if found set of \r\n */ - if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n') { - pszSrc += 2; - continue; - } - - /* Increment the count if found naked \n */ - if (*pszSrc == '\n') { - iNewlineCount++; - } - - pszSrc++; - } - - /* Return if no naked \n's */ - if (iNewlineCount == 0) { - winDebug("UNIXtoDOS () - no conversion necessary\n"); - return; - } - - /* Allocate a new string */ - pszDestBegin = pszDest = malloc(iLength + iNewlineCount + 1); - - /* Set source pointer to beginning of data string */ - pszSrc = *ppszData; - - /* Loop through all characters in source string */ - while (pszSrc < pszEnd) { - /* Copy line endings that are already valid */ - if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n') { - *pszDest = *pszSrc; - *(pszDest + 1) = *(pszSrc + 1); - pszDest += 2; - pszSrc += 2; - continue; - } - - /* Add \r to naked \n's */ - if (*pszSrc == '\n') { - *pszDest = '\r'; - *(pszDest + 1) = *pszSrc; - pszDest += 2; - pszSrc += 1; - continue; - } - - /* Copy normal characters */ - *pszDest = *pszSrc; - pszSrc++; - pszDest++; - } - - /* Put terminating null at end of new string */ - *pszDest = '\0'; - - /* Swap string pointers */ - free(*ppszData); - *ppszData = pszDestBegin; - - winDebug("UNIXtoDOS () - Final string:'%s'\n", pszDestBegin); -} diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c deleted file mode 100644 index 8e6232ba4..000000000 --- a/hw/xwin/winclipboardthread.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2008 - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the copyright holder(s) - *and author(s) shall not be used in advertising or otherwise to promote - *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 - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#else -#define HAS_WINSOCK 1 -#endif -#include <sys/types.h> -#include <signal.h> -#include "winclipboard.h" -#ifdef __CYGWIN__ -#include <errno.h> -#endif -#include "misc.h" - -extern winSetAuthorization(void); -extern void winGetDisplayName(char *szDisplay, unsigned int screen); - -/* - * References to external symbols - */ - -extern Bool g_fUnicodeClipboard; -extern Bool g_fClipboardStarted; -extern Bool g_fClipboardLaunched; -extern Bool g_fClipboard; -extern HWND g_hwndClipboard; -extern void *g_pClipboardDisplay; -extern Window g_iClipboardWindow; - -/* - * Global variables - */ - -static jmp_buf g_jmpEntry; -static XIOErrorHandler g_winClipboardOldIOErrorHandler; -static pthread_t g_winClipboardProcThread; - -Bool g_fUseUnicode = FALSE; - -/* - * Local function prototypes - */ - -static int - winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr); - -static int - winClipboardIOErrorHandler(Display * pDisplay); - -static void -winClipboardThreadExit(void *arg); - -/* - * Main thread function - */ - -void * -winClipboardProc(void *pvNotUsed) -{ - Atom atomClipboard, atomClipboardManager; - int iReturn; - HWND hwnd = NULL; - int iConnectionNumber = 0; - -#ifdef HAS_DEVWINDOWS - int fdMessageQueue = 0; -#else - struct timeval tvTimeout; -#endif - fd_set fdsRead; - int iMaxDescriptor; - Display *pDisplay = NULL; - Window iWindow = None; - int iRetries; - Bool fUseUnicode; - char szDisplay[512]; - int iSelectError; - - pthread_cleanup_push(&winClipboardThreadExit, NULL); - - winDebug("winClipboardProc - Hello\n"); - - /* Do we use Unicode clipboard? */ - fUseUnicode = g_fUnicodeClipboard; - - /* Save the Unicode support flag in a global */ - g_fUseUnicode = fUseUnicode; - - - /* Set error handler */ - XSetErrorHandler(winClipboardErrorHandler); - g_winClipboardProcThread = pthread_self(); - g_winClipboardOldIOErrorHandler = - XSetIOErrorHandler(winClipboardIOErrorHandler); - - /* Set jump point for Error exits */ - 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 winClipboardProc_Exit; - } - 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; - } - - /* Use our generated cookie for authentication */ - winSetAuthorization(); - - /* Initialize retry count */ - iRetries = 0; - - /* Setup the display connection string x */ - /* - * NOTE: Always connect to screen 0 since we require that screen - * numbers start at 0 and increase without gaps. We only need - * to connect to one screen on the display to get events - * for all screens on the display. That is why there is only - * one clipboard client thread. - */ - winGetDisplayName(szDisplay, 0); - - /* Print the display connection string */ - ErrorF("winClipboardProc - DISPLAY=%s\n", szDisplay); - - /* Open the X display */ - do { - pDisplay = XOpenDisplay(szDisplay); - if (pDisplay == NULL) { - ErrorF("winClipboardProc - Could not open display, " - "try: %d, sleeping: %d\n", iRetries + 1, WIN_CONNECT_DELAY); - ++iRetries; - sleep(WIN_CONNECT_DELAY); - continue; - } - else - break; - } - while (pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); - - /* Make sure that the display opened */ - if (pDisplay == NULL) { - ErrorF("winClipboardProc - Failed opening the display, giving up\n"); - goto winClipboardProc_Done; - } - - /* Save the display in a global used by the wndproc */ - g_pClipboardDisplay = pDisplay; - - ErrorF("winClipboardProc - XOpenDisplay () returned and " - "successfully opened the display.\n"); - - /* Get our connection number */ - iConnectionNumber = XConnectionNumber(pDisplay); - -#ifdef HAS_DEVWINDOWS - /* Open a file descriptor for the windows message queue */ - fdMessageQueue = open(WIN_MSG_QUEUE_FNAME, O_RDONLY); - if (fdMessageQueue == -1) { - ErrorF("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME); - goto winClipboardProc_Done; - } - - /* Find max of our file descriptors */ - iMaxDescriptor = max(fdMessageQueue, iConnectionNumber) + 1; -#else - iMaxDescriptor = iConnectionNumber + 1; -#endif - - /* Create atoms */ - atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False); - atomClipboardManager = XInternAtom(pDisplay, "CLIPBOARD_MANAGER", False); - - /* Create a messaging window */ - iWindow = XCreateSimpleWindow(pDisplay, - XDefaultRootWindow(pDisplay), - 1, 1, - 500, 500, - 0, - XBlackPixel(pDisplay, 0), - XBlackPixel(pDisplay, 0)); - if (iWindow == 0) { - ErrorF("winClipboardProc - Could not create an X window.\n"); - goto winClipboardProc_Done; - } - - XStoreName(pDisplay, iWindow, "xwinclip"); - - /* Select event types to watch */ - if (XSelectInput(pDisplay, iWindow, PropertyChangeMask) == BadWindow) - ErrorF("winClipboardProc - XSelectInput generated BadWindow " - "on messaging window\n"); - - /* Save the window in the screen privates */ - g_iClipboardWindow = iWindow; - - /* Create Windows messaging window */ - hwnd = winClipboardCreateMessagingWindow(); - - /* Save copy of HWND in screen privates */ - g_hwndClipboard = hwnd; - - /* 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; - } - - /* CLIPBOARD */ - iReturn = XSetSelectionOwner(pDisplay, atomClipboard, - iWindow, CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner(pDisplay, atomClipboard) != iWindow) { - ErrorF("winClipboardProc - Could not set CLIPBOARD owner\n"); - goto winClipboardProc_Done; - } - } - - /* Pre-flush X events */ - /* - * NOTE: Apparently you'll freeze if you don't do this, - * because there may be events in local data structures - * already. - */ - winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode); - - /* Pre-flush Windows messages */ - if (!winClipboardFlushWindowsMessageQueue(hwnd)) { - ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n"); - pthread_exit(NULL); - } - - /* Signal that the clipboard client has started */ - g_fClipboardStarted = TRUE; - - /* Loop for X events */ - while (1) { - /* Setup the file descriptor set */ - /* - * NOTE: You have to do this before every call to select - * because select modifies the mask to indicate - * which descriptors are ready. - */ - FD_ZERO(&fdsRead); - FD_SET(iConnectionNumber, &fdsRead); -#ifdef HAS_DEVWINDOWS - FD_SET(fdMessageQueue, &fdsRead); -#else - tvTimeout.tv_sec = 0; - tvTimeout.tv_usec = 100; -#endif - - winDebug("winClipboardProc - Waiting in select\n"); - - /* Wait for a Windows event or an X event */ - iReturn = select(iMaxDescriptor, /* Highest fds number */ - &fdsRead, /* Read mask */ - NULL, /* No write mask */ - NULL, /* No exception mask */ -#ifdef HAS_DEVWINDOWS - NULL /* No timeout */ -#else - &tvTimeout /* Set timeout */ -#endif - ); - -#ifndef HAS_WINSOCK - iSelectError = errno; -#else - iSelectError = WSAGetLastError(); -#endif - - if (iReturn < 0) { -#ifndef HAS_WINSOCK - if (iSelectError == EINTR) -#else - if (iSelectError == WSAEINTR) -#endif - continue; - - ErrorF("winClipboardProc - Call to select () failed: %d. " - "Bailing.\n", iReturn); - break; - } - - winDebug("winClipboardProc - select returned %d\n", iReturn); - - /* Branch on which descriptor became active */ - if (FD_ISSET(iConnectionNumber, &fdsRead)) { - winDebug - ("winClipboardProc - X connection ready, pumping X event queue\n"); - - /* Process X events */ - /* Exit when we see that server is shutting down */ - iReturn = winClipboardFlushXEvents(hwnd, - iWindow, pDisplay, fUseUnicode); - if (WIN_XEVENTS_SHUTDOWN == iReturn) { - ErrorF("winClipboardProc - winClipboardFlushXEvents " - "trapped shutdown event, exiting main loop.\n"); - break; - } - } - -#ifdef HAS_DEVWINDOWS - /* Check for Windows event ready */ - if (FD_ISSET(fdMessageQueue, &fdsRead)) -#else - if (1) -#endif - { - winDebug - ("winClipboardProc - /dev/windows ready, pumping Windows message queue\n"); - - /* Process Windows messages */ - if (!winClipboardFlushWindowsMessageQueue(hwnd)) { - ErrorF("winClipboardProc - " - "winClipboardFlushWindowsMessageQueue trapped " - "WM_QUIT message, exiting main loop.\n"); - break; - } - } - -#ifdef HAS_DEVWINDOWS - if (!(FD_ISSET(iConnectionNumber, &fdsRead)) && - !(FD_ISSET(fdMessageQueue, &fdsRead))) { - winDebug("winClipboardProc - Spurious wake\n"); - } -#endif - } - - winClipboardProc_Exit: - /* disable the clipboard, which means the thread will die */ - g_fClipboard = FALSE; - - winClipboardProc_Done: - /* Close our Windows window */ - if (g_hwndClipboard) { - /* Destroy the Window window (hwnd) */ - winDebug("winClipboardProc - Destroy Windows window\n"); - PostMessage(g_hwndClipboard, WM_DESTROY, 0, 0); - winClipboardFlushWindowsMessageQueue(g_hwndClipboard); - } - - /* Close our X window */ - if (pDisplay && iWindow) { - iReturn = XDestroyWindow(pDisplay, iWindow); - if (iReturn == BadWindow) - ErrorF("winClipboardProc - XDestroyWindow returned BadWindow.\n"); - else - ErrorF("winClipboardProc - XDestroyWindow succeeded.\n"); - } - -#ifdef HAS_DEVWINDOWS - /* Close our Win32 message handle */ - if (fdMessageQueue) - close(fdMessageQueue); -#endif - -#if 0 - /* - * FIXME: XCloseDisplay hangs if we call it, as of 2004/03/26. The - * XSync and XSelectInput calls did not help. - */ - - /* Discard any remaining events */ - XSync(pDisplay, TRUE); - - /* Select event types to watch */ - XSelectInput(pDisplay, XDefaultRootWindow(pDisplay), None); - - /* Close our X display */ - if (pDisplay) { - XCloseDisplay(pDisplay); - } -#endif - - /* global clipboard variable reset */ - g_fClipboardLaunched = FALSE; - g_fClipboardStarted = FALSE; - g_iClipboardWindow = None; - g_pClipboardDisplay = NULL; - g_hwndClipboard = NULL; - - pthread_cleanup_pop(0); - return NULL; -} - -/* - * winClipboardErrorHandler - Our application specific error handler - */ - -static int -winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr) -{ - char pszErrorMsg[100]; - - 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); - return 0; -} - -/* - * winClipboardIOErrorHandler - Our application specific IO error handler - */ - -static int -winClipboardIOErrorHandler(Display * pDisplay) -{ - ErrorF("winClipboardIOErrorHandler!\n"); - - if (pthread_equal(pthread_self(), g_winClipboardProcThread)) { - /* Restart at the main entry point */ - longjmp(g_jmpEntry, WIN_JMP_ERROR_IO); - } - - if (g_winClipboardOldIOErrorHandler) - g_winClipboardOldIOErrorHandler(pDisplay); - - return 0; -} - -/* - * winClipboardThreadExit - Thread exit handler - */ - -static void -winClipboardThreadExit(void *arg) -{ - /* clipboard thread has exited, stop server as well */ - kill(getpid(), SIGTERM); -} diff --git a/hw/xwin/winclipboardwndproc.c b/hw/xwin/winclipboardwndproc.c deleted file mode 100644 index 222446b4a..000000000 --- a/hw/xwin/winclipboardwndproc.c +++ /dev/null @@ -1,577 +0,0 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2008 - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the copyright holder(s) - *and author(s) shall not be used in advertising or otherwise to promote - *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 - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include <sys/types.h> -#include <sys/time.h> -#include "winclipboard.h" -#include "misc.h" -#include "winmsg.h" - - -extern void winFixClipboardChain(void); - - -/* - * Constants - */ - -#define WIN_POLL_TIMEOUT 1 - -/* - * References to external symbols - */ - -extern Bool g_fUseUnicode; -extern void *g_pClipboardDisplay; -extern Window g_iClipboardWindow; -extern Atom g_atomLastOwnedSelection; - -/* - * Local function prototypes - */ - -static int - - -winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay, - Bool fUseUnicode, int iTimeoutSec); - -/* - * Process X events up to specified timeout - */ - -static int -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); - - /* Get our connection number */ - iConnNumber = XConnectionNumber(pDisplay); - - /* Loop for X events */ - while (1) { - 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); - - /* Adjust timeout */ - remainingTime = dwStopTime - GetTickCount(); - tv.tv_sec = remainingTime / 1000; - tv.tv_usec = (remainingTime % 1000) * 1000; - winDebug("winProcessXEventsTimeout () - %d milliseconds left\n", - remainingTime); - - /* Break out if no time left */ - if (remainingTime <= 0) - return WIN_XEVENTS_SUCCESS; - - /* Wait for an X event */ - iReturn = select(iConnNumber + 1, /* Highest fds number */ - &fdsRead, /* Read mask */ - NULL, /* No write mask */ - NULL, /* No exception mask */ - &tv); /* Timeout */ - if (iReturn < 0) { - ErrorF("winProcessXEventsTimeout - Call to select () failed: %d. " - "Bailing.\n", iReturn); - break; - } - - /* Branch on which descriptor became active */ - if (FD_ISSET(iConnNumber, &fdsRead)) { - /* Process X events */ - /* Exit when we see that server is shutting down */ - iReturn = winClipboardFlushXEvents(hwnd, - iWindow, pDisplay, fUseUnicode); - - winDebug - ("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n", - iReturn); - - if (WIN_XEVENTS_NOTIFY == iReturn) { - /* Bail out if notify processed */ - return iReturn; - } - } - else { - winDebug("winProcessXEventsTimeout - Spurious wake\n"); - } - } - - return WIN_XEVENTS_SUCCESS; -} - -/* - * Process a given Windows message - */ - -LRESULT CALLBACK -winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - static HWND s_hwndNextViewer; - static Bool s_fCBCInitialized; - -#if CYGDEBUG - winDebugWin32Message("winClipboardWindowProc", hwnd, message, wParam, - lParam); -#endif - - /* Branch on message type */ - switch (message) { - case WM_DESTROY: - { - winDebug("winClipboardWindowProc - WM_DESTROY\n"); - - /* Remove ourselves from the clipboard chain */ - ChangeClipboardChain(hwnd, s_hwndNextViewer); - - s_hwndNextViewer = NULL; - - PostQuitMessage(0); - } - return 0; - - case WM_CREATE: - { - HWND first, next; - 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; - } - return 0; - - case WM_CHANGECBCHAIN: - { - winDebug("winClipboardWindowProc - WM_CHANGECBCHAIN: wParam(%x) " - "lParam(%x) s_hwndNextViewer(%x)\n", - wParam, lParam, s_hwndNextViewer); - - 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."); - } - } - else if (s_hwndNextViewer) - SendMessage(s_hwndNextViewer, message, wParam, lParam); - - } - winDebug("winClipboardWindowProc - WM_CHANGECBCHAIN: Exit\n"); - return 0; - - case WM_WM_REINIT: - { - /* Ensure that we're in the clipboard chain. Some apps, - * WinXP's remote desktop for one, don't play nice with the - * chain. This message is called whenever we receive a - * WM_ACTIVATEAPP message to ensure that we continue to - * receive clipboard messages. - * - * It might be possible to detect if we're still in the chain - * by calling SendMessage (GetClipboardViewer(), - * WM_DRAWCLIPBOARD, 0, 0); and then seeing if we get the - * WM_DRAWCLIPBOARD message. That, however, might be more - * expensive than just putting ourselves back into the chain. - */ - - HWND first, next; - DWORD error_code = 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; - } - 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"); - - if (generation != serverGeneration) { - generation = serverGeneration; - atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False); - } - - /* - * We've occasionally seen a loop in the clipboard chain. - * Try and fix it on the first hint of recursion. - */ - if (!s_fProcessingDrawClipboard) { - s_fProcessingDrawClipboard = TRUE; - } - 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 - " - "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 - * into the Win32 clipboard. - */ - if (!IsClipboardFormatAvailable(CF_TEXT) - && !IsClipboardFormatAvailable(CF_UNICODETEXT)) { - - winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "Clipboard does not contain CF_TEXT nor " - "CF_UNICODETEXT.\n"); - - winDebug("winClipboardWindowProc: %d formats\n", - CountClipboardFormats()); - { - unsigned int format = 0; - - do { - format = EnumClipboardFormats(format); - if (GetLastError() != ERROR_SUCCESS) { - winDebug - ("winClipboardWindowProc: EnumClipboardFormats failed %x\n", - GetLastError()); - } - if (format > 0xc000) { - char buff[256]; - - GetClipboardFormatName(format, buff, 256); - winDebug("winClipboardWindowProc: %d %s\n", format, - buff); - } - else if (format > 0) - winDebug("winClipboardWindowProc: %d\n", format); - } while (format != 0); - } - /* - * We need to make sure that the X Server has processed - * 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, releasing\n"); - XSetSelectionOwner(pDisplay, XA_PRIMARY, None, CurrentTime); - } - else if (BadWindow == iReturn || BadAtom == iReturn) - winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "XGetSelectionOwner failed for PRIMARY: %d\n", - iReturn); - - /* Release CLIPBOARD selection if owned */ - iReturn = XGetSelectionOwner(pDisplay, atomClipboard); - if (iReturn == g_iClipboardWindow) { - winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "CLIPBOARD selection is owned by us, releasing\n"); - XSetSelectionOwner(pDisplay, atomClipboard, None, CurrentTime); - } - else if (BadWindow == iReturn || BadAtom == iReturn) - winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "XGetSelectionOwner failed for CLIPBOARD: %d\n", - iReturn); - - winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); - s_fProcessingDrawClipboard = FALSE; - if (s_hwndNextViewer) - 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"); - } - - /* 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. - * Changes in the Win32 clipboard are handled by WM_DRAWCLIPBOARD - * above. We only process this message to conform to the specs - * for delayed clipboard rendering in Win32. You might think - * that we need to release ownership of the X11 selections, but - * we do not, because a WM_DRAWCLIPBOARD message will closely - * follow this message and reassert ownership of the X11 - * selections, handling the issue for us. - */ - winDebug("winClipboardWindowProc - WM_DESTROYCLIPBOARD - Ignored.\n"); - return 0; - - case WM_RENDERFORMAT: - case WM_RENDERALLFORMATS: - { - int iReturn; - Display *pDisplay = g_pClipboardDisplay; - Window iWindow = g_iClipboardWindow; - Bool fConvertToUnicode; - - if (message == WM_RENDERALLFORMATS) - winDebug("winClipboardWindowProc - WM_RENDERALLFORMATS - Hello.\n"); - else - winDebug("winClipboardWindowProc - WM_RENDERFORMAT %d - Hello.\n", - wParam); - - /* Flag whether to convert to Unicode or not */ - if (message == WM_RENDERALLFORMATS) - fConvertToUnicode = FALSE; - else - fConvertToUnicode = (CF_UNICODETEXT == wParam); - - /* Request the selection contents */ - iReturn = XConvertSelection(pDisplay, - g_atomLastOwnedSelection, - XInternAtom(pDisplay, - "COMPOUND_TEXT", False), - XInternAtom(pDisplay, - "CYGX_CUT_BUFFER", False), - iWindow, CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow) { - winErrorFVerb(1, "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)) { - winErrorFVerb(1, "winClipboardWindowProc - WM_RENDER*FORMATS - " - "OpenClipboard () failed: %08x\n", - GetLastError()); - break; - } - - if (!EmptyClipboard()) { - winErrorFVerb(1, "winClipboardWindowProc - WM_RENDER*FORMATS - " - "EmptyClipboard () failed: %08x\n", - GetLastError()); - break; - } - } - - /* Process the SelectionNotify event */ - iReturn = winProcessXEventsTimeout(hwnd, - iWindow, - pDisplay, - fConvertToUnicode, WIN_POLL_TIMEOUT); - - /* - * The last call to winProcessXEventsTimeout - * from above had better have seen a notify event, or else we - * are dealing with a buggy or old X11 app. In these cases we - * have to paste some fake data to the Win32 clipboard to - * satisfy the requirement that we write something to it. - */ - if (WIN_XEVENTS_NOTIFY != iReturn) { - /* Paste no data, to satisfy required call to SetClipboardData */ - SetClipboardData(CF_UNICODETEXT, NULL); - SetClipboardData(CF_TEXT, NULL); - - ErrorF - ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY\n"); - } - - /* Special handling for WM_RENDERALLFORMATS */ - if (message == WM_RENDERALLFORMATS) { - /* We must close the clipboard */ - - if (!CloseClipboard()) { - winErrorFVerb(1, - "winClipboardWindowProc - WM_RENDERALLFORMATS - " - "CloseClipboard () failed: %08x\n", - GetLastError()); - break; - } - } - - winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Returning.\n"); - return 0; - } - } - - /* Let Windows perform default processing for unhandled messages */ - return DefWindowProc(hwnd, message, wParam, lParam); -} - -/* - * Process any pending Windows messages - */ - -BOOL -winClipboardFlushWindowsMessageQueue(HWND hwnd) -{ - MSG msg; - - /* Flush the messaging window queue */ - /* NOTE: Do not pass the hwnd of our messaging window to PeekMessage, - * as this will filter out many non-window-specific messages that - * are sent to our thread, such as WM_QUIT. - */ - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - /* Dispatch the message if not WM_QUIT */ - if (msg.message == WM_QUIT) - return FALSE; - else - DispatchMessage(&msg); - } - - return TRUE; -} diff --git a/hw/xwin/winclipboardwrappers.c b/hw/xwin/winclipboardwrappers.c index e3ec59ee7..b618176e1 100644 --- a/hw/xwin/winclipboardwrappers.c +++ b/hw/xwin/winclipboardwrappers.c @@ -33,38 +33,18 @@ #ifdef HAVE_XWIN_CONFIG_H #include <xwin-config.h> #endif -#include "win.h" -#include "dixstruct.h" -#include <X11/Xatom.h> - -/* - * Constants - */ -#define CLIP_NUM_SELECTIONS 2 -#define CLIP_OWN_PRIMARY 0 -#define CLIP_OWN_CLIPBOARD 1 +#include <X11/Xwindows.h> +#include "dixstruct.h" +#include "winglobals.h" +#include "winmsg.h" +#include "win.h" /* * Local function prototypes */ DISPATCH_PROC(winProcEstablishConnection); -DISPATCH_PROC(winProcSetSelectionOwner); - -/* - * References to external symbols - */ - -extern unsigned int g_uiAuthDataLen; -extern char *g_pAuthData; -extern Bool g_fClipboardLaunched; -extern Bool g_fClipboardStarted; -extern Bool g_fClipboard; -extern Window g_iClipboardWindow; -extern Atom g_atomLastOwnedSelection; -extern HWND g_hwndClipboard; - /* * Wrapper for internal EstablishConnection function. @@ -129,13 +109,6 @@ winProcEstablishConnection(ClientPtr client) /* Clear original function pointer */ winProcEstablishConnectionOrig = NULL; - /* If the clipboard client has already been started, abort */ - if (g_fClipboardLaunched) { - ErrorF("winProcEstablishConnection - Clipboard client already " - "launched, returning.\n"); - return iReturn; - } - /* Startup the clipboard client if clipboard mode is being used */ if (g_fClipboard) { /* @@ -167,206 +140,3 @@ winProcEstablishConnection(ClientPtr client) return iReturn; } - -/* - * Wrapper for internal SetSelectionOwner function. - * Grabs ownership of Windows clipboard when X11 clipboard owner changes. - */ - -int -winProcSetSelectionOwner(ClientPtr client) -{ - int i; - DrawablePtr pDrawable; - WindowPtr pWindow = None; - Bool fOwnedToNotOwned = FALSE; - static Window s_iOwners[CLIP_NUM_SELECTIONS] = { None }; - static unsigned long s_ulServerGeneration = 0; - - REQUEST(xSetSelectionOwnerReq); - - REQUEST_SIZE_MATCH(xSetSelectionOwnerReq); - - winDebug - ("winProcSetSelectionOwner - Hello. atom 0x%08x window XID 0x%08x \n", - stuff->selection, stuff->window); - - /* Watch for server reset */ - if (s_ulServerGeneration != serverGeneration) { - /* Save new generation number */ - s_ulServerGeneration = serverGeneration; - - /* Initialize static variables */ - for (i = 0; i < CLIP_NUM_SELECTIONS; ++i) - s_iOwners[i] = None; - } - - /* Abort if clipboard not completely initialized yet */ - if (!g_fClipboardStarted) { - /* ErrorF ("winProcSetSelectionOwner - Clipboard not yet started, " - "aborting.\n"); */ - goto winProcSetSelectionOwner_Done; - } - - /* Grab window if we have one */ - if (None != stuff->window) { - /* Grab the Window from the request */ - int rc = - dixLookupWindow(&pWindow, stuff->window, client, DixReadAccess); - if (rc != Success) { - ErrorF("winProcSetSelectionOwner - Found BadWindow, aborting.\n"); - goto winProcSetSelectionOwner_Done; - } - } - - /* Now we either have a valid window or None */ - - /* Save selection owners for monitored selections, ignore other selections */ - if (XA_PRIMARY == stuff->selection) { - /* Look for owned -> not owned transition */ - if (None == stuff->window && None != s_iOwners[CLIP_OWN_PRIMARY]) { - fOwnedToNotOwned = TRUE; - - winDebug("winProcSetSelectionOwner - PRIMARY - Going from " - "owned to not owned.\n"); - - /* Adjust last owned selection */ - if (None != s_iOwners[CLIP_OWN_CLIPBOARD]) - g_atomLastOwnedSelection = MakeAtom("CLIPBOARD", 9, TRUE); - else - g_atomLastOwnedSelection = None; - } - - /* Save new selection owner or None */ - s_iOwners[CLIP_OWN_PRIMARY] = stuff->window; - - winDebug - ("winProcSetSelectionOwner - PRIMARY - Now owned by XID 0x%08x\n", - stuff->window); - } - else if (MakeAtom("CLIPBOARD", 9, TRUE) == stuff->selection) { - /* Look for owned -> not owned transition */ - if (None == stuff->window && None != s_iOwners[CLIP_OWN_CLIPBOARD]) { - fOwnedToNotOwned = TRUE; - - winDebug("winProcSetSelectionOwner - CLIPBOARD - Going from " - "owned to not owned.\n"); - - /* Adjust last owned selection */ - if (None != s_iOwners[CLIP_OWN_PRIMARY]) - g_atomLastOwnedSelection = XA_PRIMARY; - else - g_atomLastOwnedSelection = None; - } - - /* Save new selection owner or None */ - s_iOwners[CLIP_OWN_CLIPBOARD] = stuff->window; - - winDebug - ("winProcSetSelectionOwner - CLIPBOARD - Now owned by XID 0x%08x\n", - stuff->window); - - } - else - goto winProcSetSelectionOwner_Done; - - /* - * At this point, if one of the selections is still owned by the - * clipboard manager then it should be marked as unowned since - * we will be taking ownership of the Win32 clipboard. - */ - if (g_iClipboardWindow == s_iOwners[CLIP_OWN_PRIMARY]) - s_iOwners[CLIP_OWN_PRIMARY] = None; - if (g_iClipboardWindow == s_iOwners[CLIP_OWN_CLIPBOARD]) - s_iOwners[CLIP_OWN_CLIPBOARD] = None; - - /* - * Handle case when selection is being disowned, - * WM_DRAWCLIPBOARD did not do the disowning, - * both monitored selections are no longer owned, - * an owned to not owned transition was detected, - * and we currently own the Win32 clipboard. - */ - if (stuff->window == None - && s_iOwners[CLIP_OWN_PRIMARY] == None - && s_iOwners[CLIP_OWN_CLIPBOARD] == None - && fOwnedToNotOwned - && g_hwndClipboard != NULL && g_hwndClipboard == GetClipboardOwner()) { - winDebug("winProcSetSelectionOwner - We currently own the " - "clipboard and neither the PRIMARY nor the CLIPBOARD " - "selections are owned, releasing ownership of Win32 " - "clipboard.\n"); - - /* Release ownership of the Windows clipboard */ - OpenClipboard(NULL); - EmptyClipboard(); - CloseClipboard(); - - goto winProcSetSelectionOwner_Done; - } - - /* Abort if no window at this point */ - if (None == stuff->window) { - winDebug("winProcSetSelectionOwner - No window, returning.\n"); - goto winProcSetSelectionOwner_Done; - } - - /* Abort if invalid selection */ - if (!ValidAtom(stuff->selection)) { - ErrorF("winProcSetSelectionOwner - Found BadAtom, aborting.\n"); - goto winProcSetSelectionOwner_Done; - } - - /* Cast Window to Drawable */ - pDrawable = (DrawablePtr) pWindow; - - /* Abort if clipboard manager is owning the selection */ - if (pDrawable->id == g_iClipboardWindow) { - winDebug("winProcSetSelectionOwner - We changed ownership, " - "aborting.\n"); - goto winProcSetSelectionOwner_Done; - } - - /* Abort if root window is taking ownership */ - if (pDrawable->id == 0) { - ErrorF("winProcSetSelectionOwner - Root window taking ownership, " - "aborting\n"); - goto winProcSetSelectionOwner_Done; - } - - /* Close clipboard if we have it open already */ - if (GetOpenClipboardWindow() == g_hwndClipboard) { - CloseClipboard(); - } - - /* Access the Windows clipboard */ - if (!OpenClipboard(g_hwndClipboard)) { - ErrorF("winProcSetSelectionOwner - OpenClipboard () failed: %08x\n", - (int) GetLastError()); - goto winProcSetSelectionOwner_Done; - } - - /* Take ownership of the Windows clipboard */ - if (!EmptyClipboard()) { - ErrorF("winProcSetSelectionOwner - EmptyClipboard () failed: %08x\n", - (int) GetLastError()); - goto winProcSetSelectionOwner_Done; - } - - /* Advertise regular text and unicode */ - SetClipboardData(CF_UNICODETEXT, NULL); - SetClipboardData(CF_TEXT, NULL); - - /* Save handle to last owned selection */ - g_atomLastOwnedSelection = stuff->selection; - - /* Release the clipboard */ - if (!CloseClipboard()) { - ErrorF("winProcSetSelectionOwner - CloseClipboard () failed: " - "%08x\n", (int) GetLastError()); - goto winProcSetSelectionOwner_Done; - } - - winProcSetSelectionOwner_Done: - return (*winProcSetSelectionOwnerOrig) (client); -} diff --git a/hw/xwin/winclipboardxevents.c b/hw/xwin/winclipboardxevents.c deleted file mode 100644 index a4d193d93..000000000 --- a/hw/xwin/winclipboardxevents.c +++ /dev/null @@ -1,716 +0,0 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2008 - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the copyright holder(s) - *and author(s) shall not be used in advertising or otherwise to promote - *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 - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "winclipboard.h" -#include "misc.h" - -/* - * Process any pending X events - */ - -int -winClipboardFlushXEvents(HWND hwnd, - int iWindow, Display * pDisplay, Bool fUseUnicode) -{ - 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)) { - XTextProperty xtpText = { 0 }; - XEvent event; - XSelectionEvent eventSelection; - unsigned long ulReturnBytesLeft; - char *pszReturnData = NULL; - char *pszGlobalData = NULL; - int iReturn; - HGLOBAL hGlobal = NULL; - XICCEncodingStyle xiccesStyle; - int iConvertDataLen = 0; - char *pszConvertData = NULL; - char *pszTextList[2] = { NULL }; - int iCount; - char **ppszTextList = NULL; - wchar_t *pwszUnicodeStr = NULL; - int iUnicodeLen = 0; - int iReturnDataLen = 0; - int i; - Bool fAbort = FALSE; - Bool fCloseClipboard = FALSE; - Bool fSetClipboardData = TRUE; - - /* Get the next event - will not block because one is ready */ - XNextEvent(pDisplay, &event); - - /* Branch on the event type */ - switch (event.type) { - /* - * SelectionRequest - */ - - case SelectionRequest: - { - char *pszAtomName = NULL; - - winDebug("SelectionRequest - target %d\n", - event.xselectionrequest.target); - - pszAtomName = XGetAtomName(pDisplay, - event.xselectionrequest.target); - winDebug("SelectionRequest - Target atom name %s\n", pszAtomName); - XFree(pszAtomName); - pszAtomName = NULL; - } - - /* Abort if invalid target type */ - if (event.xselectionrequest.target != XA_STRING - && event.xselectionrequest.target != atomUTF8String - && event.xselectionrequest.target != atomCompoundText - && event.xselectionrequest.target != atomTargets) { - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Handle targets type of request */ - if (event.xselectionrequest.target == atomTargets) { - Atom atomTargetArr[] = { atomTargets, - atomCompoundText, - atomUTF8String, - XA_STRING - }; - winDebug("SelectionRequest - populating targets\n"); - - /* Try to change the property */ - iReturn = XChangeProperty(pDisplay, - event.xselectionrequest.requestor, - event.xselectionrequest.property, - XA_ATOM, - 32, - PropModeReplace, - (unsigned char *) atomTargetArr, - (sizeof(atomTargetArr) - / sizeof(atomTargetArr[0]))); - if (iReturn == BadAlloc - || iReturn == BadAtom - || iReturn == BadMatch - || iReturn == BadValue || iReturn == BadWindow) { - ErrorF("winClipboardFlushXEvents - SelectionRequest - " - "XChangeProperty failed: %d\n", iReturn); - } - - /* Setup selection notify xevent */ - eventSelection.type = SelectionNotify; - eventSelection.send_event = True; - eventSelection.display = pDisplay; - eventSelection.requestor = event.xselectionrequest.requestor; - eventSelection.selection = event.xselectionrequest.selection; - eventSelection.target = event.xselectionrequest.target; - eventSelection.property = event.xselectionrequest.property; - eventSelection.time = event.xselectionrequest.time; - - /* - * Notify the requesting window that - * the operation has completed - */ - iReturn = XSendEvent(pDisplay, - eventSelection.requestor, - False, 0L, (XEvent *) &eventSelection); - if (iReturn == BadValue || iReturn == BadWindow) { - ErrorF("winClipboardFlushXEvents - SelectionRequest - " - "XSendEvent () failed\n"); - } - 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()); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* 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 */ - static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */ - - if (hwnd != lasthwnd) - count = 0; - count++; - if (count < 6) - ErrorF("winClipboardFlushXEvents - CF_UNICODETEXT is not " - "available from Win32 clipboard. Aborting %d.\n", - count); - lasthwnd = hwnd; - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - else if (!fUseUnicode && !IsClipboardFormatAvailable(CF_TEXT)) { - ErrorF("winClipboardFlushXEvents - CF_TEXT is not " - "available from Win32 clipboard. Aborting.\n"); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Setup the string style */ - if (event.xselectionrequest.target == XA_STRING) - xiccesStyle = XStringStyle; -#ifdef X_HAVE_UTF8_STRING - else if (event.xselectionrequest.target == atomUTF8String) - xiccesStyle = XUTF8StringStyle; -#endif - else if (event.xselectionrequest.target == atomCompoundText) - xiccesStyle = XCompoundTextStyle; - else - xiccesStyle = XStringStyle; - - /* Get a pointer to the clipboard text, in desired format */ - if (fUseUnicode) { - /* Retrieve clipboard data */ - hGlobal = GetClipboardData(CF_UNICODETEXT); - } - else { - /* Retrieve clipboard data */ - hGlobal = GetClipboardData(CF_TEXT); - } - if (!hGlobal) { - ErrorF("winClipboardFlushXEvents - SelectionRequest - " - "GetClipboardData () failed: %08lx\n", GetLastError()); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - pszGlobalData = (char *) GlobalLock(hGlobal); - - /* Convert the Unicode string to UTF8 (MBCS) */ - if (fUseUnicode) { - iConvertDataLen = WideCharToMultiByte(CP_UTF8, - 0, - (LPCWSTR) pszGlobalData, - -1, NULL, 0, NULL, NULL); - /* NOTE: iConvertDataLen includes space for null terminator */ - pszConvertData = (char *) malloc(iConvertDataLen); - WideCharToMultiByte(CP_UTF8, - 0, - (LPCWSTR) pszGlobalData, - -1, - pszConvertData, - iConvertDataLen, NULL, NULL); - } - else { - pszConvertData = strdup(pszGlobalData); - iConvertDataLen = strlen(pszConvertData) + 1; - } - - /* Convert DOS string to UNIX string */ - winClipboardDOStoUNIX(pszConvertData, strlen(pszConvertData)); - - /* Setup our text list */ - pszTextList[0] = pszConvertData; - pszTextList[1] = NULL; - - /* Initialize the text property */ - xtpText.value = NULL; - xtpText.nitems = 0; - - /* Create the text property from the text list */ - if (fUseUnicode) { -#ifdef X_HAVE_UTF8_STRING - iReturn = Xutf8TextListToTextProperty(pDisplay, - pszTextList, - 1, xiccesStyle, &xtpText); -#endif - } - else { - iReturn = XmbTextListToTextProperty(pDisplay, - pszTextList, - 1, xiccesStyle, &xtpText); - } - if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) { - ErrorF("winClipboardFlushXEvents - SelectionRequest - " - "X*TextListToTextProperty failed: %d\n", iReturn); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Free the converted string */ - free(pszConvertData); - pszConvertData = NULL; - - /* Copy the clipboard text to the requesting window */ - iReturn = XChangeProperty(pDisplay, - event.xselectionrequest.requestor, - event.xselectionrequest.property, - event.xselectionrequest.target, - 8, - PropModeReplace, - xtpText.value, xtpText.nitems); - if (iReturn == BadAlloc || iReturn == BadAtom - || iReturn == BadMatch || iReturn == BadValue - || iReturn == BadWindow) { - ErrorF("winClipboardFlushXEvents - SelectionRequest - " - "XChangeProperty failed: %d\n", iReturn); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Release the clipboard data */ - GlobalUnlock(hGlobal); - pszGlobalData = NULL; - fCloseClipboard = FALSE; - CloseClipboard(); - - /* Clean up */ - XFree(xtpText.value); - xtpText.value = NULL; - xtpText.nitems = 0; - - /* Setup selection notify event */ - eventSelection.type = SelectionNotify; - eventSelection.send_event = True; - eventSelection.display = pDisplay; - eventSelection.requestor = event.xselectionrequest.requestor; - eventSelection.selection = event.xselectionrequest.selection; - eventSelection.target = event.xselectionrequest.target; - eventSelection.property = event.xselectionrequest.property; - eventSelection.time = event.xselectionrequest.time; - - /* Notify the requesting window that the operation has completed */ - iReturn = XSendEvent(pDisplay, - eventSelection.requestor, - False, 0L, (XEvent *) &eventSelection); - if (iReturn == BadValue || iReturn == BadWindow) { - ErrorF("winClipboardFlushXEvents - SelectionRequest - " - "XSendEvent () failed\n"); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - winClipboardFlushXEvents_SelectionRequest_Done: - /* Free allocated resources */ - if (xtpText.value) { - XFree(xtpText.value); - xtpText.value = NULL; - xtpText.nitems = 0; - } - free(pszConvertData); - if (hGlobal && pszGlobalData) - GlobalUnlock(hGlobal); - - /* - * Send a SelectionNotify event to the requesting - * client when we abort. - */ - if (fAbort) { - winDebug("SelectionRequest - aborting\n"); - /* Setup selection notify event */ - eventSelection.type = SelectionNotify; - eventSelection.send_event = True; - eventSelection.display = pDisplay; - eventSelection.requestor = event.xselectionrequest.requestor; - eventSelection.selection = event.xselectionrequest.selection; - eventSelection.target = event.xselectionrequest.target; - eventSelection.property = None; - eventSelection.time = event.xselectionrequest.time; - - /* Notify the requesting window that the operation is complete */ - iReturn = XSendEvent(pDisplay, - eventSelection.requestor, - False, 0L, (XEvent *) &eventSelection); - if (iReturn == BadValue || iReturn == BadWindow) { - /* - * Should not be a problem if XSendEvent fails because - * the client may simply have exited. - */ - ErrorF("winClipboardFlushXEvents - SelectionRequest - " - "XSendEvent () failed for abort event.\n"); - } - } - - /* Close clipboard if it was opened */ - if (fCloseClipboard) { - fCloseClipboard = FALSE; - CloseClipboard(); - } - break; - - /* - * SelectionNotify - */ - - case SelectionNotify: - - winDebug("winClipboardFlushXEvents - SelectionNotify\n"); - { - char *pszAtomName; - - pszAtomName = XGetAtomName(pDisplay, - event.xselection.selection); - - winDebug - ("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n", - pszAtomName); - XFree(pszAtomName); - } - - /* - * Request conversion of UTF8 and CompoundText targets. - */ - if (event.xselection.property == None) { - if (event.xselection.target == XA_STRING) { - winDebug("winClipboardFlushXEvents - SelectionNotify - " - "XA_STRING\n"); - - return WIN_XEVENTS_CONVERT; - } - else if (event.xselection.target == atomUTF8String) { - winDebug("winClipboardFlushXEvents - SelectionNotify - " - "Requesting conversion of UTF8 target.\n"); - - XConvertSelection(pDisplay, - event.xselection.selection, - XA_STRING, - atomLocalProperty, iWindow, CurrentTime); - - /* Process the ConvertSelection event */ - XFlush(pDisplay); - return WIN_XEVENTS_CONVERT; - } -#ifdef X_HAVE_UTF8_STRING - else if (event.xselection.target == atomCompoundText) { - winDebug("winClipboardFlushXEvents - SelectionNotify - " - "Requesting conversion of CompoundText target.\n"); - - XConvertSelection(pDisplay, - event.xselection.selection, - atomUTF8String, - atomLocalProperty, iWindow, CurrentTime); - - /* Process the ConvertSelection event */ - XFlush(pDisplay); - return WIN_XEVENTS_CONVERT; - } -#endif - else { - ErrorF("winClipboardFlushXEvents - SelectionNotify - " - "Unknown format. Cannot request conversion, " - "aborting.\n"); - break; - } - } - - case SelectionClear: - winDebug("SelectionClear - doing nothing\n"); - break; - - case PropertyNotify: - { - char *pszAtomName; - - pszAtomName = XGetAtomName(pDisplay, event.xproperty.atom); - winDebug("winClipboardFlushXEvents - PropertyNotify - ATOM: %s\n", - pszAtomName); - XFree(pszAtomName); - } - - if (event.xproperty.atom != atomLocalProperty) - break; - - /* Retrieve the size of the stored data */ - iReturn = XGetWindowProperty(pDisplay, iWindow, atomLocalProperty, 0, 0, /* Don't get data, just size */ - False, - AnyPropertyType, - &xtpText.encoding, - &xtpText.format, - &xtpText.nitems, - &ulReturnBytesLeft, &xtpText.value); - if (iReturn != Success) { - ErrorF("winClipboardFlushXEvents - PropertyNotify - " - "XGetWindowProperty () failed, aborting: %d\n", iReturn); - break; - } - - winDebug("PropertyNotify - returned data %d left %d\n", - xtpText.nitems, ulReturnBytesLeft); - - /* Request the selection data */ - iReturn = XGetWindowProperty(pDisplay, - iWindow, - atomLocalProperty, - 0, - ulReturnBytesLeft, - False, - AnyPropertyType, - &xtpText.encoding, - &xtpText.format, - &xtpText.nitems, - &ulReturnBytesLeft, &xtpText.value); - if (iReturn != Success) { - ErrorF("winClipboardFlushXEvents - PropertyNotify - " - "XGetWindowProperty () failed, aborting: %d\n", iReturn); - break; - } - - { - char *pszAtomName = NULL; - - winDebug("PropertyNotify - returned data %d left %d\n", - xtpText.nitems, ulReturnBytesLeft); - pszAtomName = XGetAtomName(pDisplay, xtpText.encoding); - winDebug("PropertyNotify - encoding atom name %s\n", - pszAtomName); - XFree(pszAtomName); - pszAtomName = NULL; - } - - if (fUseUnicode) { -#ifdef X_HAVE_UTF8_STRING - /* Convert the text property to a text list */ - iReturn = Xutf8TextPropertyToTextList(pDisplay, - &xtpText, - &ppszTextList, &iCount); -#endif - } - else { - iReturn = XmbTextPropertyToTextList(pDisplay, - &xtpText, - &ppszTextList, &iCount); - } - if (iReturn == Success || iReturn > 0) { - /* Conversion succeeded or some unconvertible characters */ - if (ppszTextList != NULL) { - iReturnDataLen = 0; - for (i = 0; i < iCount; i++) { - iReturnDataLen += strlen(ppszTextList[i]); - } - pszReturnData = malloc(iReturnDataLen + 1); - pszReturnData[0] = '\0'; - for (i = 0; i < iCount; i++) { - strcat(pszReturnData, ppszTextList[i]); - } - } - else { - ErrorF("winClipboardFlushXEvents - PropertyNotify - " - "X*TextPropertyToTextList list_return is NULL.\n"); - pszReturnData = malloc(1); - pszReturnData[0] = '\0'; - } - } - else { - ErrorF("winClipboardFlushXEvents - PropertyNotify - " - "X*TextPropertyToTextList returned: "); - switch (iReturn) { - case XNoMemory: - ErrorF("XNoMemory\n"); - break; - case XLocaleNotSupported: - ErrorF("XLocaleNotSupported\n"); - break; - case XConverterNotFound: - ErrorF("XConverterNotFound\n"); - break; - default: - ErrorF("%d\n", iReturn); - break; - } - pszReturnData = malloc(1); - pszReturnData[0] = '\0'; - } - - /* Free the data returned from XGetWindowProperty */ - if (ppszTextList) - XFreeStringList(ppszTextList); - ppszTextList = NULL; - XFree(xtpText.value); - xtpText.value = NULL; - xtpText.nitems = 0; - - /* Convert the X clipboard string to DOS format */ - winClipboardUNIXtoDOS(&pszReturnData, strlen(pszReturnData)); - - if (fUseUnicode) { - /* Find out how much space needed to convert MBCS to Unicode */ - iUnicodeLen = MultiByteToWideChar(CP_UTF8, - 0, - pszReturnData, -1, NULL, 0); - - /* Allocate memory for the Unicode string */ - pwszUnicodeStr - = (wchar_t *) malloc(sizeof(wchar_t) * (iUnicodeLen + 1)); - if (!pwszUnicodeStr) { - ErrorF("winClipboardFlushXEvents - PropertyNotify " - "malloc failed for pwszUnicodeStr, aborting.\n"); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_PropertyNotify_Done; - } - - /* Do the actual conversion */ - MultiByteToWideChar(CP_UTF8, - 0, - pszReturnData, - -1, pwszUnicodeStr, iUnicodeLen); - - /* Allocate global memory for the X clipboard data */ - hGlobal = GlobalAlloc(GMEM_MOVEABLE, - sizeof(wchar_t) * (iUnicodeLen + 1)); - } - else { - pszConvertData = strdup(pszReturnData); - iConvertDataLen = strlen(pszConvertData) + 1; - - /* Allocate global memory for the X clipboard data */ - hGlobal = GlobalAlloc(GMEM_MOVEABLE, iConvertDataLen); - } - - free(pszReturnData); - - /* Check that global memory was allocated */ - if (!hGlobal) { - ErrorF("winClipboardFlushXEvents - PropertyNotify " - "GlobalAlloc failed, aborting: %ld\n", GetLastError()); - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_PropertyNotify_Done; - } - - /* Obtain a pointer to the global memory */ - pszGlobalData = GlobalLock(hGlobal); - if (pszGlobalData == NULL) { - ErrorF("winClipboardFlushXEvents - Could not lock global " - "memory for clipboard transfer\n"); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_PropertyNotify_Done; - } - - /* Copy the returned string into the global memory */ - if (fUseUnicode) { - memcpy(pszGlobalData, - pwszUnicodeStr, sizeof(wchar_t) * (iUnicodeLen + 1)); - free(pwszUnicodeStr); - pwszUnicodeStr = NULL; - } - else { - strcpy(pszGlobalData, pszConvertData); - free(pszConvertData); - pszConvertData = NULL; - } - - /* Release the pointer to the global memory */ - GlobalUnlock(hGlobal); - pszGlobalData = NULL; - - /* Push the selection data to the Windows clipboard */ - if (fUseUnicode) - SetClipboardData(CF_UNICODETEXT, hGlobal); - else - SetClipboardData(CF_TEXT, hGlobal); - - /* Flag that SetClipboardData has been called */ - fSetClipboardData = FALSE; - - /* - * NOTE: Do not try to free pszGlobalData, it is owned by - * Windows after the call to SetClipboardData (). - */ - - winClipboardFlushXEvents_PropertyNotify_Done: - /* Free allocated resources */ - if (ppszTextList) - XFreeStringList(ppszTextList); - if (xtpText.value) { - XFree(xtpText.value); - xtpText.value = NULL; - xtpText.nitems = 0; - } - free(pszConvertData); - free(pwszUnicodeStr); - if (hGlobal && pszGlobalData) - GlobalUnlock(hGlobal); - if (fSetClipboardData) { - SetClipboardData(CF_UNICODETEXT, NULL); - SetClipboardData(CF_TEXT, NULL); - } - return WIN_XEVENTS_NOTIFY; - - case MappingNotify: - break; - - default: - ErrorF("winClipboardFlushXEvents - unexpected event type %d\n", - event.type); - break; - } - } - - return WIN_XEVENTS_SUCCESS; -} diff --git a/hw/xwin/windialogs.c b/hw/xwin/windialogs.c index 87d58ae19..725a4619d 100644 --- a/hw/xwin/windialogs.c +++ b/hw/xwin/windialogs.c @@ -37,13 +37,6 @@ #include "winprefs.h" /* - * References to external globals - */ - -#ifdef XWIN_CLIPBOARD -extern Bool g_fClipboardStarted; -#endif -/* * Local function prototypes */ diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c index b9ad294d5..0e9b8b34a 100644 --- a/hw/xwin/winglobals.c +++ b/hw/xwin/winglobals.c @@ -86,21 +86,13 @@ pthread_mutex_t g_pmTerminating = PTHREAD_MUTEX_INITIALIZER; * Wrapped DIX functions */ winDispatchProcPtr winProcEstablishConnectionOrig = NULL; -winDispatchProcPtr winProcSetSelectionOwnerOrig = NULL; /* * Clipboard variables */ - Bool g_fUnicodeClipboard = TRUE; Bool g_fClipboard = TRUE; -Bool g_fClipboardLaunched = FALSE; Bool g_fClipboardStarted = FALSE; -pthread_t g_ptClipboardProc; -HWND g_hwndClipboard = NULL; -void *g_pClipboardDisplay = NULL; -Window g_iClipboardWindow = None; -Atom g_atomLastOwnedSelection = None; #endif /* @@ -112,10 +104,4 @@ void winInitializeGlobals(void) { g_dwCurrentThreadID = GetCurrentThreadId(); -#ifdef XWIN_CLIPBOARD - g_iClipboardWindow = None; - g_pClipboardDisplay = NULL; - g_atomLastOwnedSelection = None; - g_hwndClipboard = NULL; -#endif } diff --git a/hw/xwin/winglobals.h b/hw/xwin/winglobals.h index 869ea67e0..5df4b608e 100644 --- a/hw/xwin/winglobals.h +++ b/hw/xwin/winglobals.h @@ -70,8 +70,10 @@ typedef int (*winDispatchProcPtr) (ClientPtr); * Wrapped DIX functions */ extern winDispatchProcPtr winProcEstablishConnectionOrig; -extern winDispatchProcPtr winProcSetSelectionOwnerOrig; #endif +extern Bool g_fUnicodeClipboard; +extern Bool g_fClipboard; +extern Bool g_fClipboardStarted; /* The global X default icons */ #if defined(XWIN_MULTIWINDOW) |