diff options
Diffstat (limited to 'xorg-server/hw/xwin/winclipboard/thread.c')
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/xwin/winclipboard/thread.c | 185 |
1 files changed, 114 insertions, 71 deletions
diff --git a/xorg-server/hw/xwin/winclipboard/thread.c b/xorg-server/hw/xwin/winclipboard/thread.c index 50e1e8cb5..bb7418992 100644..100755 --- a/xorg-server/hw/xwin/winclipboard/thread.c +++ b/xorg-server/hw/xwin/winclipboard/thread.c @@ -45,38 +45,52 @@ #undef _XSERVER64 #endif -#include <assert.h> -#include <unistd.h> -#include <fcntl.h> -#include <setjmp.h> +#include <sys/types.h> +#include <signal.h> #include <pthread.h> -#include <sys/param.h> // for MAX() macro - -#ifdef HAS_WINSOCK -#include <X11/Xwinsock.h> -#else +#include "windisplay.h" +#ifdef __CYGWIN__ #include <errno.h> #endif +#include "misc.h" +#include "winmsg.h" #include <X11/Xatom.h> #include <X11/extensions/Xfixes.h> #include "winclipboard.h" #include "internal.h" +/* Clipboard module constants */ #define WIN_CONNECT_RETRIES 40 #define WIN_CONNECT_DELAY 4 +#define WIN_JMP_OKAY 0 +#define WIN_JMP_ERROR_IO 2 #define WIN_CLIPBOARD_WINDOW_CLASS "xwinclip" #define WIN_CLIPBOARD_WINDOW_TITLE "xwinclip" #ifdef HAS_DEVWINDOWS -#define WIN_MSG_QUEUE_FNAME "/dev/windows" +#define WIN_MSG_QUEUE_FNAME "/dev/windows" #endif +#ifdef _MSC_VER +#define snprintf _snprintf +#endif +/* + * References to external symbols + */ + +extern Bool g_fUnicodeClipboard; +extern Bool g_fClipboard; +extern Bool g_fClipboardStarted; +extern Bool g_fClipboardLaunched; +extern HWND g_hwndClipboard; +extern void *g_pClipboardDisplay; +extern Window g_iClipboardWindow; + /* * Global variables */ -static HWND g_hwndClipboard = NULL; static jmp_buf g_jmpEntry; static XIOErrorHandler g_winClipboardOldIOErrorHandler; static pthread_t g_winClipboardProcThread; @@ -84,6 +98,8 @@ static pthread_t g_winClipboardProcThread; int xfixes_event_base; int xfixes_error_base; +Bool g_fUseUnicode = FALSE; + /* * Local function prototypes */ @@ -97,6 +113,9 @@ static int static int winClipboardIOErrorHandler(Display * pDisplay); +static void +winClipboardThreadExit(void *arg); + /* * Create X11 and Win32 messaging windows, and run message processing loop * @@ -121,16 +140,21 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) Display *pDisplay = NULL; Window iWindow = None; int iSelectError; - Bool fShutdown = FALSE; + Bool fShutDown = TRUE; static Bool fErrorHandlerSet = FALSE; + + pthread_cleanup_push(&winClipboardThreadExit, NULL); ClipboardConversionData data; winDebug("winClipboardProc - Hello\n"); + /* 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"); - goto winClipboardProc_Exit; + goto thread_errorexit; } /* See if X supports the current locale */ @@ -149,19 +173,31 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) } /* Set jump point for Error exits */ - if (setjmp(g_jmpEntry)) { + iReturn = setjmp(g_jmpEntry); + + /* Check if we should continue operations */ + if (iReturn != WIN_JMP_ERROR_IO && iReturn != WIN_JMP_OKAY) { + /* setjmp returned an unknown value, exit */ + ErrorF("winClipboardProc - setjmp returned: %d exiting\n", iReturn); + goto thread_errorexit; + } + else if (iReturn == WIN_JMP_ERROR_IO) { + /* TODO: Cleanup the Win32 window and free any allocated memory */ ErrorF("winClipboardProc - setjmp returned for IO Error Handler.\n"); - goto winClipboardProc_Done; } /* Make sure that the display opened */ pDisplay = XOpenDisplay(szDisplay); if (pDisplay == NULL) { ErrorF("winClipboardProc - Failed opening the display, giving up\n"); - goto winClipboardProc_Done; + fShutDown = FALSE; + goto thread_errorexit; } - ErrorF("winClipboardProc - XOpenDisplay () returned and " + /* Save the display in the screen privates */ + g_pClipboardDisplay = pDisplay; + + winDebug ("winClipboardProc - XOpenDisplay () returned and " "successfully opened the display.\n"); /* Get our connection number */ @@ -172,7 +208,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) fdMessageQueue = open(WIN_MSG_QUEUE_FNAME, O_RDONLY); if (fdMessageQueue == -1) { ErrorF("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME); - goto winClipboardProc_Done; + goto thread_errorexit; } /* Find max of our file descriptors */ @@ -201,7 +237,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) BlackPixel(pDisplay, 0)); if (iWindow == 0) { ErrorF("winClipboardProc - Could not create an X window.\n"); - goto winClipboardProc_Done; + goto thread_errorexit; } XStoreName(pDisplay, iWindow, "xwinclip"); @@ -225,7 +261,8 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) XFixesSelectionWindowDestroyNotifyMask | XFixesSelectionClientCloseNotifyMask); - + /* Save the window in the screen privates */ + g_iClipboardWindow = iWindow; /* Initialize monitored selection state */ winClipboardInitMonitoredSelections(); /* Create Windows messaging window */ @@ -242,7 +279,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) if (iReturn == BadAtom || iReturn == BadWindow || XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) { ErrorF("winClipboardProc - Could not set PRIMARY owner\n"); - goto winClipboardProc_Done; + goto thread_errorexit; } /* CLIPBOARD */ @@ -251,11 +288,14 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) if (iReturn == BadAtom || iReturn == BadWindow || XGetSelectionOwner(pDisplay, atoms.atomClipboard) != iWindow) { ErrorF("winClipboardProc - Could not set CLIPBOARD owner\n"); - goto winClipboardProc_Done; + goto thread_errorexit; } } data.fUseUnicode = fUseUnicode; + winDebug ("winClipboardProc - Started\n"); + /* Signal that the clipboard client has started */ + g_fClipboardStarted = TRUE; /* Loop for events */ while (1) { @@ -319,39 +359,6 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) "Bailing.\n", iReturn); break; } - - if (FD_ISSET(iConnectionNumber, &fdsRead)) { - winDebug - ("winClipboardProc - X connection ready, pumping X event queue\n"); - } - -#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"); - } - -#ifdef HAS_DEVWINDOWS - if (!(FD_ISSET(iConnectionNumber, &fdsRead)) && - !(FD_ISSET(fdMessageQueue, &fdsRead))) { - winDebug("winClipboardProc - Spurious wake, select() returned %d\n", iReturn); - } -#endif - } - - winClipboardProc_Exit: - /* broke out of while loop on a shutdown message */ - fShutdown = TRUE; - - winClipboardProc_Done: - /* Close our Windows window */ - if (g_hwndClipboard) { - DestroyWindow(g_hwndClipboard); } /* Close our X window */ @@ -359,8 +366,10 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) iReturn = XDestroyWindow(pDisplay, iWindow); if (iReturn == BadWindow) ErrorF("winClipboardProc - XDestroyWindow returned BadWindow.\n"); +#ifdef WINDBG else - ErrorF("winClipboardProc - XDestroyWindow succeeded.\n"); + winDebug("winClipboardProc - XDestroyWindow succeeded.\n"); +#endif } #ifdef HAS_DEVWINDOWS @@ -390,10 +399,30 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) } #endif - /* global clipboard variable reset */ - g_hwndClipboard = NULL; + goto commonexit; - return fShutdown; +thread_errorexit: + if (g_pClipboardDisplay && g_iClipboardWindow) + { + iReturn = XDestroyWindow (g_pClipboardDisplay, g_iClipboardWindow); + if (iReturn == BadWindow) + ErrorF ("winClipboardProc - XDestroyWindow returned BadWindow.\n"); +#ifdef WINDBG + else + winDebug ("winClipboardProc - XDestroyWindow succeeded.\n"); +#endif + } + winDebug ("Clipboard thread died.\n"); + +commonexit: + g_iClipboardWindow = None; + g_pClipboardDisplay = NULL; + g_fClipboardLaunched = FALSE; + g_fClipboardStarted = FALSE; + + pthread_cleanup_pop(0); + + return fShutDown; } /* @@ -462,8 +491,17 @@ winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr) XGetErrorText(pDisplay, pErr->error_code, pszErrorMsg, sizeof(pszErrorMsg)); ErrorF("winClipboardErrorHandler - ERROR: \n\t%s\n" - "\tSerial: %lu, Request Code: %d, Minor Code: %d\n", - pszErrorMsg, pErr->serial, pErr->request_code, pErr->minor_code); + " errorCode %d\n" + " serial %lu\n" + " resourceID 0x%x\n" + " majorCode %d\n" + " minorCode %d\n" + , pszErrorMsg + , pErr->error_code + , pErr->serial + , pErr->resourceid + , pErr->request_code + , pErr->minor_code); return 0; } @@ -478,7 +516,7 @@ winClipboardIOErrorHandler(Display * pDisplay) if (pthread_equal(pthread_self(), g_winClipboardProcThread)) { /* Restart at the main entry point */ - longjmp(g_jmpEntry, 2); + longjmp(g_jmpEntry, WIN_JMP_ERROR_IO); } if (g_winClipboardOldIOErrorHandler) @@ -487,18 +525,23 @@ winClipboardIOErrorHandler(Display * pDisplay) return 0; } -void -winClipboardWindowDestroy(void) +/* + * winClipboardThreadExit - Thread exit handler + */ + +static void +winClipboardThreadExit(void *arg) { - if (g_hwndClipboard) { - SendMessage(g_hwndClipboard, WM_WM_QUIT, 0, 0); - } + /* clipboard thread has exited, stop server as well */ + AbortDDX(EXIT_ERR_ABORT); + TerminateProcess(GetCurrentProcess(),1); } + void -winFixClipboardChain(void) +winFixClipboardChain(int Removed) { - if (g_hwndClipboard) { - PostMessage(g_hwndClipboard, WM_WM_REINIT, 0, 0); - } + if (g_fClipboard && g_hwndClipboard) { + PostMessage (g_hwndClipboard, WM_WM_REINIT, Removed, 0); + } } |