diff options
Diffstat (limited to 'xorg-server/hw/xwin/winclipboardthread.c')
-rw-r--r-- | xorg-server/hw/xwin/winclipboardthread.c | 183 |
1 files changed, 123 insertions, 60 deletions
diff --git a/xorg-server/hw/xwin/winclipboardthread.c b/xorg-server/hw/xwin/winclipboardthread.c index 908dfcea2..c160453c8 100644 --- a/xorg-server/hw/xwin/winclipboardthread.c +++ b/xorg-server/hw/xwin/winclipboardthread.c @@ -41,7 +41,11 @@ #include <errno.h> #endif #include "misc.h" +#include "winmsg.h" +#ifdef _MSC_VER +#define snprintf _snprintf +#endif /* * References to external symbols @@ -49,10 +53,12 @@ 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; +extern Bool g_fClipboardPrimary; /* @@ -60,6 +66,9 @@ extern Window g_iClipboardWindow; */ static jmp_buf g_jmpEntry; +static XIOErrorHandler g_winClipboardOldIOErrorHandler; +static pthread_t g_winClipboardProcThread; + Bool g_fUnicodeSupport = FALSE; Bool g_fUseUnicode = FALSE; @@ -74,6 +83,8 @@ winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr); static int winClipboardIOErrorHandler (Display *pDisplay); +static void +winClipboardThreadExit(void *arg); /* * Main thread function @@ -100,7 +111,9 @@ winClipboardProc (void *pvNotUsed) char szDisplay[512]; int iSelectError; - ErrorF ("winClipboardProc - Hello\n"); + pthread_cleanup_push(&winClipboardThreadExit, NULL); + + winDebug ("winClipboardProc - Hello\n"); /* Do we have Unicode support? */ g_fUnicodeSupport = winClipboardDetectUnicodeSupport (); @@ -111,18 +124,16 @@ 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"); - pthread_exit (NULL); - } + /* Create Windows messaging window */ + hwnd = winClipboardCreateMessagingWindow (); + + /* Save copy of HWND in screen privates */ + g_hwndClipboard = hwnd; - /* See if X supports the current locale */ - if (XSupportsLocale () == False) - { - ErrorF ("winClipboardProc - Warning: Locale not supported by X.\n"); - } + /* Set error handler */ + XSetErrorHandler (winClipboardErrorHandler); + g_winClipboardProcThread = pthread_self(); + g_winClipboardOldIOErrorHandler = XSetIOErrorHandler (winClipboardIOErrorHandler); /* Set jump point for Error exits */ iReturn = setjmp (g_jmpEntry); @@ -134,22 +145,18 @@ winClipboardProc (void *pvNotUsed) /* setjmp returned an unknown value, exit */ ErrorF ("winClipboardProc - setjmp returned: %d exiting\n", iReturn); - pthread_exit (NULL); + 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); + //goto thread_errorexit; } /* Use our generated cookie for authentication */ winSetAuthorization(); - /* Set error handler */ - XSetErrorHandler (winClipboardErrorHandler); - XSetIOErrorHandler (winClipboardIOErrorHandler); - /* Initialize retry count */ iRetries = 0; @@ -161,13 +168,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 @@ -191,25 +195,27 @@ winClipboardProc (void *pvNotUsed) if (pDisplay == NULL) { ErrorF ("winClipboardProc - Failed opening the display, giving up\n"); - pthread_exit (NULL); + 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); - pthread_exit (NULL); + goto thread_errorexit; } /* Find max of our file descriptors */ @@ -221,6 +227,10 @@ winClipboardProc (void *pvNotUsed) /* 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, @@ -233,9 +243,11 @@ winClipboardProc (void *pvNotUsed) if (iWindow == 0) { ErrorF ("winClipboardProc - Could not create an X window.\n"); - pthread_exit (NULL); + goto thread_errorexit; } + XStoreName(pDisplay, iWindow, "xwinclip"); + /* Select event types to watch */ if (XSelectInput (pDisplay, iWindow, @@ -246,33 +258,31 @@ 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) + 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"); - pthread_exit (NULL); + goto thread_errorexit; } + } /* CLIPBOARD */ iReturn = XSetSelectionOwner (pDisplay, atomClipboard, iWindow, CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner (pDisplay, atomClipboard) != iWindow) + if (iReturn == BadAtom || iReturn == BadWindow /*|| + XGetSelectionOwner (pDisplay, atomClipboard) != iWindow*/) { ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n"); - pthread_exit (NULL); + goto thread_errorexit; } } @@ -282,15 +292,20 @@ winClipboardProc (void *pvNotUsed) * because there may be events in local data structures * already. */ - winClipboardFlushXEvents (hwnd, + /*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; @@ -345,21 +360,24 @@ 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 */ /* Exit when we see that server is shutting down */ iReturn = winClipboardFlushXEvents (hwnd, iWindow, pDisplay, - fUseUnicode); + 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 */ @@ -385,8 +403,10 @@ winClipboardProc (void *pvNotUsed) 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 } @@ -417,9 +437,28 @@ winClipboardProc (void *pvNotUsed) } #endif + 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"); + +commonexit: g_iClipboardWindow = None; g_pClipboardDisplay = NULL; - g_hwndClipboard = NULL; + g_fClipboardLaunched = FALSE; + g_fClipboardStarted = FALSE; + + pthread_cleanup_pop(0); return NULL; } @@ -439,11 +478,17 @@ winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr) 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; } @@ -457,8 +502,26 @@ winClipboardIOErrorHandler (Display *pDisplay) { ErrorF ("winClipboardIOErrorHandler!\n\n"); - /* Restart at the main entry point */ - longjmp (g_jmpEntry, WIN_JMP_ERROR_IO); - + 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 */ + AbortDDX(EXIT_ERR_ABORT); + TerminateProcess(GetCurrentProcess(),1); +} |