diff options
Diffstat (limited to 'xorg-server/hw/xwin/winclipboardthread.c')
-rw-r--r-- | xorg-server/hw/xwin/winclipboardthread.c | 963 |
1 files changed, 501 insertions, 462 deletions
diff --git a/xorg-server/hw/xwin/winclipboardthread.c b/xorg-server/hw/xwin/winclipboardthread.c index a3809034e..e08e7acd0 100644 --- a/xorg-server/hw/xwin/winclipboardthread.c +++ b/xorg-server/hw/xwin/winclipboardthread.c @@ -1,462 +1,501 @@ -/* - *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 "winclipboard.h" -#ifdef __CYGWIN__ -#include <errno.h> -#endif -#include "misc.h" - - -/* - * References to external symbols - */ - -extern Bool g_fUnicodeClipboard; -extern unsigned long serverGeneration; -extern Bool g_fClipboardStarted; -extern HWND g_hwndClipboard; -extern void *g_pClipboardDisplay; -extern Window g_iClipboardWindow; - - -/* - * Global variables - */ - -static jmp_buf g_jmpEntry; -Bool g_fUnicodeSupport = FALSE; -Bool g_fUseUnicode = FALSE; - - -/* - * Local function prototypes - */ - -static int -winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr); - -static int -winClipboardIOErrorHandler (Display *pDisplay); - - -/* - * 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; - - ErrorF ("winClipboardProc - Hello\n"); - - /* Do we have Unicode support? */ - g_fUnicodeSupport = winClipboardDetectUnicodeSupport (); - - /* Do we use Unicode clipboard? */ - fUseUnicode = g_fUnicodeClipboard && g_fUnicodeSupport; - - /* Save the Unicode support flag in a global */ - g_fUseUnicode = fUseUnicode; - - /* Allow multiple threads to access Xlib */ - if (XInitThreads () == 0) - { - ErrorF ("winClipboardProc - XInitThreads failed.\n"); - pthread_exit (NULL); - } - - /* See if X supports the current locale */ - if (XSupportsLocale () == False) - { - ErrorF ("winClipboardProc - Warning: Locale not supported by X.\n"); - } - - /* 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); - pthread_exit (NULL); - } - 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"); - pthread_exit (NULL); - } - - /* Use our generated cookie for authentication */ - winSetAuthorization(); - - /* Set error handler */ - XSetErrorHandler (winClipboardErrorHandler); - XSetIOErrorHandler (winClipboardIOErrorHandler); - - /* 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. - */ - snprintf (szDisplay, - 512, - "127.0.0.1:%s.0", - display); - - /* 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"); - pthread_exit (NULL); - } - - /* Save the display in the screen privates */ - g_pClipboardDisplay = pDisplay; - - ErrorF ("winClipboardProc - XOpenDisplay () returned and " - "successfully opened the display.\n"); - - /* Get our connection number */ - iConnectionNumber = ConnectionNumber (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); - pthread_exit (NULL); - } - - /* 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, - DefaultRootWindow (pDisplay), - 1, 1, - 500, 500, - 0, - BlackPixel (pDisplay, 0), - BlackPixel (pDisplay, 0)); - if (iWindow == 0) - { - ErrorF ("winClipboardProc - Could not create an X window.\n"); - pthread_exit (NULL); - } - - /* 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"); - pthread_exit (NULL); - } - - /* CLIPBOARD */ - iReturn = XSetSelectionOwner (pDisplay, atomClipboard, - iWindow, CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner (pDisplay, atomClipboard) != iWindow) - { - ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n"); - pthread_exit (NULL); - } - } - - /* 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)) - return 0; - - /* 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 - - /* 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; - } - - /* Branch on which descriptor became active */ - if (FD_ISSET (iConnectionNumber, &fdsRead)) - { - /* 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 - { - /* Process Windows messages */ - if (!winClipboardFlushWindowsMessageQueue (hwnd)) - { - ErrorF ("winClipboardProc - " - "winClipboardFlushWindowsMessageQueue trapped " - "WM_QUIT message, exiting main loop.\n"); - break; - } - } - } - - /* 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, - DefaultRootWindow (pDisplay), - None); - - /* Close our X display */ - if (pDisplay) - { - XCloseDisplay (pDisplay); - } -#endif - - g_iClipboardWindow = None; - g_pClipboardDisplay = NULL; - g_hwndClipboard = NULL; - - 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: %d, 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 ("\nwinClipboardIOErrorHandler!\n\n"); - - /* Restart at the main entry point */ - longjmp (g_jmpEntry, WIN_JMP_ERROR_IO); - - return 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 "winclipboard.h"
+#ifdef __CYGWIN__
+#include <errno.h>
+#endif
+#include "misc.h"
+#include "winmsg.h"
+
+#ifdef _MSC_VER
+#define snprintf _snprintf
+#endif
+
+/*
+ * References to external symbols
+ */
+
+extern Bool g_fUnicodeClipboard;
+extern unsigned long serverGeneration;
+extern Bool g_fClipboardLaunched;
+extern Bool g_fClipboardStarted;
+extern HWND g_hwndClipboard;
+extern void *g_pClipboardDisplay;
+extern Window g_iClipboardWindow;
+
+
+/*
+ * Global variables
+ */
+
+static jmp_buf g_jmpEntry;
+Bool g_fUnicodeSupport = FALSE;
+Bool g_fUseUnicode = FALSE;
+
+
+/*
+ * Local function prototypes
+ */
+
+static int
+winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr);
+
+static int
+winClipboardIOErrorHandler (Display *pDisplay);
+
+
+/*
+ * 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;
+
+ winDebug ("winClipboardProc - Hello\n");
+
+ /* Do we have Unicode support? */
+ g_fUnicodeSupport = winClipboardDetectUnicodeSupport ();
+
+ /* Do we use Unicode clipboard? */
+ fUseUnicode = g_fUnicodeClipboard && g_fUnicodeSupport;
+
+ /* Save the Unicode support flag in a global */
+ g_fUseUnicode = fUseUnicode;
+
+ /* See if X supports the current locale */
+ if (XSupportsLocale () == False)
+ {
+ ErrorF ("winClipboardProc - Warning: Locale not supported by X.\n");
+ }
+
+ /* Create Windows messaging window */
+ hwnd = winClipboardCreateMessagingWindow ();
+
+ /* Save copy of HWND in screen privates */
+ g_hwndClipboard = hwnd;
+
+ /* 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 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 thread_errorexit;
+ }
+
+ /* Use our generated cookie for authentication */
+ winSetAuthorization();
+
+ /* Set error handler */
+ XSetErrorHandler (winClipboardErrorHandler);
+ XSetIOErrorHandler (winClipboardIOErrorHandler);
+
+ /* 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.
+ */
+ snprintf (szDisplay,
+ 512,
+ "127.0.0.1:%s.0",
+ display);
+
+ /* Print the display connection string */
+ winDebug ("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 thread_errorexit;
+ }
+
+ /* 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);
+ if (fdMessageQueue == -1)
+ {
+ ErrorF ("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME);
+ goto thread_errorexit;
+ }
+
+ /* 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);
+ 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,
+ DefaultRootWindow (pDisplay),
+ 1, 1,
+ 500, 500,
+ 0,
+ BlackPixel (pDisplay, 0),
+ BlackPixel (pDisplay, 0));
+ if (iWindow == 0)
+ {
+ ErrorF ("winClipboardProc - Could not create an X window.\n");
+ goto thread_errorexit;
+ }
+
+ /* 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;
+
+ /* Assert ownership of selections if Win32 clipboard is owned */
+ if (NULL != GetClipboardOwner ())
+ {
+ /* 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, atomClipboard,
+ iWindow, CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow /*||
+ XGetSelectionOwner (pDisplay, atomClipboard) != iWindow*/)
+ {
+ ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n");
+ goto thread_errorexit;
+ }
+ }
+ /* 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 */
+ 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 */
+ /*
+ * 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
+
+ /* 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;
+ }
+
+ /* Branch on which descriptor became active */
+// if (FD_ISSET (iConnectionNumber, &fdsRead))
+// { Also do it when no read since winClipboardFlushXEvents
+// is sending the output.
+ /* Process X events */
+ /* Exit when we see that server is shutting down */
+ iReturn = winClipboardFlushXEvents (hwnd,
+ iWindow,
+ pDisplay,
+ fUseUnicode,
+ FALSE
+ );
+ 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
+ {
+ /* Process Windows messages */
+ if (!winClipboardFlushWindowsMessageQueue (hwnd))
+ {
+ ErrorF ("winClipboardProc - "
+ "winClipboardFlushWindowsMessageQueue trapped "
+ "WM_QUIT message, exiting main loop.\n");
+ break;
+ }
+ }
+ }
+
+ /* Close our X window */
+ if (pDisplay && iWindow)
+ {
+ iReturn = XDestroyWindow (pDisplay, iWindow);
+ if (iReturn == BadWindow)
+ ErrorF ("winClipboardProc - XDestroyWindow returned BadWindow.\n");
+#ifdef WINDBG
+ else
+ winDebug ("winClipboardProc - XDestroyWindow succeeded.\n");
+#endif
+ }
+
+
+#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,
+ DefaultRootWindow (pDisplay),
+ None);
+
+ /* Close our X display */
+ if (pDisplay)
+ {
+ XCloseDisplay (pDisplay);
+ }
+#endif
+
+ g_iClipboardWindow = None;
+ g_pClipboardDisplay = NULL;
+ g_fClipboardLaunched = FALSE;
+ g_fClipboardStarted = FALSE;
+
+ return NULL;
+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
+ }
+ g_iClipboardWindow = None;
+ g_pClipboardDisplay = NULL;
+ g_fClipboardLaunched = FALSE;
+ g_fClipboardStarted = FALSE;
+ //pthread_exit (NULL);
+ winDebug ("Clipboard thread died.\n");
+ 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"
+ " errorCode %d\n"
+ " serial %d\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;
+}
+
+
+/*
+ * winClipboardIOErrorHandler - Our application specific IO error handler
+ */
+
+static int
+winClipboardIOErrorHandler (Display *pDisplay)
+{
+ ErrorF ("\nwinClipboardIOErrorHandler!\n\n");
+
+ /* Restart at the main entry point */
+ longjmp (g_jmpEntry, WIN_JMP_ERROR_IO);
+
+ return 0;
+}
|