diff options
Diffstat (limited to 'xorg-server/hw/xwin/winclipboardthread.c')
-rw-r--r-- | xorg-server/hw/xwin/winclipboardthread.c | 196 |
1 files changed, 103 insertions, 93 deletions
diff --git a/xorg-server/hw/xwin/winclipboardthread.c b/xorg-server/hw/xwin/winclipboardthread.c index 33595be7f..488a00fcc 100644 --- a/xorg-server/hw/xwin/winclipboardthread.c +++ b/xorg-server/hw/xwin/winclipboardthread.c @@ -42,7 +42,11 @@ #include <errno.h> #endif #include "misc.h" +#include "winmsg.h" +#ifdef _MSC_VER +#define snprintf _snprintf +#endif /* * References to external symbols */ @@ -50,17 +54,16 @@ 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; +extern Bool g_fClipboardPrimary; /* * Global variables */ static jmp_buf g_jmpEntry; -static int clipboardRestarts = 0; static XIOErrorHandler g_winClipboardOldIOErrorHandler; static pthread_t g_winClipboardProcThread; @@ -76,6 +79,8 @@ static int static int winClipboardIOErrorHandler(Display * pDisplay); +static void +winClipboardThreadExit(void *arg); /* * Main thread function */ @@ -102,8 +107,9 @@ winClipboardProc(void *pvNotUsed) char szDisplay[512]; int iSelectError; - winDebug("winClipboardProc - Hello\n"); - ++clipboardRestarts; + pthread_cleanup_push(&winClipboardThreadExit, NULL); + + winDebug ("winClipboardProc - Hello\n"); /* Do we use Unicode clipboard? */ fUseUnicode = g_fUnicodeClipboard; @@ -111,16 +117,11 @@ winClipboardProc(void *pvNotUsed) /* 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; - } - - /* 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 error handler */ XSetErrorHandler(winClipboardErrorHandler); @@ -135,12 +136,11 @@ winClipboardProc(void *pvNotUsed) 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; + 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"); - pthread_exit(NULL); } /* Use our generated cookie for authentication */ @@ -157,10 +157,10 @@ winClipboardProc(void *pvNotUsed) * 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); + winGetDisplayName(szDisplay,0); /* Print the display connection string */ - ErrorF("winClipboardProc - DISPLAY=%s\n", szDisplay); + winDebug ("winClipboardProc - DISPLAY=%s\n", szDisplay); /* Open the X display */ do { @@ -180,24 +180,26 @@ winClipboardProc(void *pvNotUsed) /* Make sure that the display opened */ if (pDisplay == NULL) { ErrorF("winClipboardProc - Failed opening the display, giving up\n"); - goto winClipboardProc_Done; + goto thread_errorexit; } /* Save the display in the screen privates */ g_pClipboardDisplay = pDisplay; - ErrorF("winClipboardProc - XOpenDisplay () returned and " + winDebug ("winClipboardProc - XOpenDisplay () returned and " "successfully opened the display.\n"); /* Get our connection number */ iConnectionNumber = ConnectionNumber(pDisplay); + winDebug("Clipboard is using socket %d\n",iConnectionNumber); + #ifdef HAS_DEVWINDOWS /* Open a file descriptor for the windows message queue */ - fdMessageQueue = open(WIN_MSG_QUEUE_FNAME, O_RDONLY); + fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, _O_RDONLY); if (fdMessageQueue == -1) { ErrorF("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME); - goto winClipboardProc_Done; + goto thread_errorexit; } /* Find max of our file descriptors */ @@ -208,6 +210,10 @@ winClipboardProc(void *pvNotUsed) /* Create atom */ atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False); + XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False); + XInternAtom (pDisplay, "UTF8_STRING", False); + XInternAtom (pDisplay, "COMPOUND_TEXT", False); + XInternAtom (pDisplay, "TARGETS", False); /* Create a messaging window */ iWindow = XCreateSimpleWindow(pDisplay, @@ -219,7 +225,7 @@ winClipboardProc(void *pvNotUsed) 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"); @@ -232,30 +238,30 @@ winClipboardProc(void *pvNotUsed) /* 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; + if (g_fClipboardPrimary) + { + /* PRIMARY */ + winDebug("winClipboardProc - asserted ownership.\n"); + iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow /*|| + XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow*/) + { + ErrorF ("winClipboardProc - Could not set PRIMARY owner\n"); + goto thread_errorexit; + } } /* CLIPBOARD */ iReturn = XSetSelectionOwner(pDisplay, atomClipboard, iWindow, CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner(pDisplay, atomClipboard) != iWindow) { - ErrorF("winClipboardProc - Could not set CLIPBOARD owner\n"); - goto winClipboardProc_Done; + if (iReturn == BadAtom || iReturn == BadWindow /*|| + XGetSelectionOwner (pDisplay, atomClipboard) != iWindow*/) + { + ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n"); + goto thread_errorexit; } } @@ -265,12 +271,17 @@ winClipboardProc(void *pvNotUsed) * because there may be events in local data structures * already. */ - winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode); + //winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode); /* Pre-flush Windows messages */ + winDebug ("Start flushing \n"); if (!winClipboardFlushWindowsMessageQueue(hwnd)) - return 0; + { + ErrorF ("winClipboardFlushWindowsMessageQueue - returned 0\n"); + goto thread_errorexit; + } + winDebug ("winClipboardProc - Started\n"); /* Signal that the clipboard client has started */ g_fClipboardStarted = TRUE; @@ -323,10 +334,12 @@ winClipboardProc(void *pvNotUsed) } /* Branch on which descriptor became active */ - if (FD_ISSET(iConnectionNumber, &fdsRead)) { +// if (FD_ISSET (iConnectionNumber, &fdsRead)) { +// Also do it when no read since winClipboardFlushXEvents +// is sending the output. /* Process X events */ - winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode); - } + winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, FALSE); +// } #ifdef HAS_DEVWINDOWS /* Check for Windows event ready */ @@ -345,26 +358,15 @@ winClipboardProc(void *pvNotUsed) } } - 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"); +#ifdef WINDBG else - ErrorF("winClipboardProc - XDestroyWindow succeeded.\n"); + winDebug("winClipboardProc - XDestroyWindow succeeded.\n"); +#endif } #ifdef HAS_DEVWINDOWS @@ -391,41 +393,28 @@ winClipboardProc(void *pvNotUsed) } #endif - /* global clipboard variable reset */ - g_fClipboardLaunched = FALSE; - g_fClipboardStarted = FALSE; - g_iClipboardWindow = None; - g_pClipboardDisplay = NULL; - g_hwndClipboard = NULL; - - /* checking if we need to restart */ - if (clipboardRestarts >= WIN_CLIPBOARD_RETRIES) { - /* terminates clipboard thread but the main server still lives */ - ErrorF - ("winClipboardProc - the clipboard thread has restarted %d times and seems to be unstable, disabling clipboard integration\n", - clipboardRestarts); - g_fClipboard = FALSE; - return NULL; + goto commonexit; + +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"); - if (g_fClipboard) { - sleep(WIN_CLIPBOARD_DELAY); - ErrorF("winClipboardProc - trying to restart clipboard thread \n"); - /* Create the clipboard client thread */ - if (!winInitClipboard()) { - ErrorF("winClipboardProc - winClipboardInit failed.\n"); - return NULL; - } +commonexit: + g_iClipboardWindow = None; + g_pClipboardDisplay = NULL; + g_fClipboardLaunched = FALSE; + g_fClipboardStarted = FALSE; - winDebug("winClipboardProc - winInitClipboard returned.\n"); - /* Flag that clipboard client has been launched */ - g_fClipboardLaunched = TRUE; - } - else { - ErrorF("winClipboardProc - Clipboard disabled - Exit from server \n"); - /* clipboard thread has exited, stop server as well */ - raise(SIGTERM); - } + pthread_cleanup_pop(0); return NULL; } @@ -441,8 +430,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; } @@ -465,3 +463,15 @@ winClipboardIOErrorHandler(Display * pDisplay) return 0; } + +/* + * winClipboardThreadExit - Thread exit handler + */ + +static void +winClipboardThreadExit(void *arg) +{ + /* clipboard thread has exited, stop server as well */ + AbortDDX(EXIT_ERR_ABORT); + TerminateProcess(GetCurrentProcess(),1); +} |