diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2010-11-03 13:52:47 +0000 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2010-11-03 13:52:47 +0000 |
commit | eb4deaf9bfbab02302d4afaf76be26b5ffaaf884 (patch) | |
tree | 9d2d478c34bf5886d6eb792295d7e9668585af17 | |
parent | 89912be98de63c48e8e950d227f81ef518839465 (diff) | |
parent | 1920e08443b16298bbe45418382f8c1da3753fd0 (diff) |
Merge branch 'mhummel-clipboard-thread-improvements' into cygwin-release-1.9xserver-cygwin-1.9.2-1
-rw-r--r-- | hw/xwin/InitInput.c | 8 | ||||
-rw-r--r-- | hw/xwin/winclipboard.h | 2 | ||||
-rw-r--r-- | hw/xwin/winclipboardthread.c | 85 | ||||
-rwxr-xr-x | hw/xwin/winclipboardwrappers.c | 121 | ||||
-rw-r--r-- | hw/xwin/winclipboardxevents.c | 3 |
5 files changed, 66 insertions, 153 deletions
diff --git a/hw/xwin/InitInput.c b/hw/xwin/InitInput.c index 705e618de..f17a905f1 100644 --- a/hw/xwin/InitInput.c +++ b/hw/xwin/InitInput.c @@ -60,10 +60,8 @@ DeviceIntPtr g_pwinKeyboard; #ifdef HAS_DEVWINDOWS extern int g_fdMessageQueue; #endif -extern Bool g_fXdmcpEnabled; #ifdef XWIN_CLIPBOARD extern winDispatchProcPtr winProcEstablishConnectionOrig; -extern winDispatchProcPtr winProcQueryTreeOrig; #endif @@ -127,12 +125,6 @@ InitInput (int argc, char *argv[]) winProcEstablishConnectionOrig = InitialVector[2]; InitialVector[2] = winProcEstablishConnection; } - if (g_fXdmcpEnabled - && ProcVector[X_QueryTree] != winProcQueryTree) - { - winProcQueryTreeOrig = ProcVector[X_QueryTree]; - ProcVector[X_QueryTree] = winProcQueryTree; - } #endif g_pwinPointer = AddInputDevice (serverClient, winMouseProc, TRUE); diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h index 089c2913b..3285702ac 100644 --- a/hw/xwin/winclipboard.h +++ b/hw/xwin/winclipboard.h @@ -71,6 +71,8 @@ #define WIN_XEVENTS_SHUTDOWN 1 #define WIN_XEVENTS_CONVERT 2 #define WIN_XEVENTS_NOTIFY 3 +#define WIN_CLIPBOARD_RETRIES 40 +#define WIN_CLIPBOARD_DELAY 1 #define WM_WM_REINIT (WM_USER + 1) diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c index ea9459910..ae7036ce2 100644 --- a/hw/xwin/winclipboardthread.c +++ b/hw/xwin/winclipboardthread.c @@ -48,6 +48,8 @@ extern Bool g_fUnicodeClipboard; extern unsigned long serverGeneration; extern Bool g_fClipboardStarted; +extern Bool g_fClipboardLaunched; +extern Bool g_fClipboard; extern HWND g_hwndClipboard; extern void *g_pClipboardDisplay; extern Window g_iClipboardWindow; @@ -60,6 +62,7 @@ extern Window g_iClipboardWindow; static jmp_buf g_jmpEntry; static XIOErrorHandler g_winClipboardOldIOErrorHandler; static pthread_t g_winClipboardProcThread; +static int clipboardRestarts = 0; Bool g_fUnicodeSupport = FALSE; Bool g_fUseUnicode = FALSE; @@ -75,9 +78,6 @@ winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr); static int winClipboardIOErrorHandler (Display *pDisplay); -static void -winClipboardThreadExit(void *arg); - /* * Main thread function */ @@ -103,9 +103,8 @@ winClipboardProc (void *pvNotUsed) char szDisplay[512]; int iSelectError; - pthread_cleanup_push(&winClipboardThreadExit, NULL); - ErrorF ("winClipboardProc - Hello\n"); + ++clipboardRestarts; /* Do we have Unicode support? */ g_fUnicodeSupport = winClipboardDetectUnicodeSupport (); @@ -120,7 +119,7 @@ winClipboardProc (void *pvNotUsed) if (XInitThreads () == 0) { ErrorF ("winClipboardProc - XInitThreads failed.\n"); - pthread_exit (NULL); + goto winClipboardProc_Exit; } /* See if X supports the current locale */ @@ -144,7 +143,7 @@ winClipboardProc (void *pvNotUsed) /* setjmp returned an unknown value, exit */ ErrorF ("winClipboardProc - setjmp returned: %d exiting\n", iReturn); - pthread_exit (NULL); + goto winClipboardProc_Exit; } else if (iReturn == WIN_JMP_ERROR_IO) { @@ -194,7 +193,7 @@ winClipboardProc (void *pvNotUsed) if (pDisplay == NULL) { ErrorF ("winClipboardProc - Failed opening the display, giving up\n"); - pthread_exit (NULL); + goto winClipboardProc_Done; } /* Save the display in a global used by the wndproc */ @@ -212,7 +211,7 @@ winClipboardProc (void *pvNotUsed) if (fdMessageQueue == -1) { ErrorF ("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME); - pthread_exit (NULL); + goto winClipboardProc_Done; } /* Find max of our file descriptors */ @@ -236,9 +235,11 @@ winClipboardProc (void *pvNotUsed) if (iWindow == 0) { ErrorF ("winClipboardProc - Could not create an X window.\n"); - pthread_exit (NULL); + goto winClipboardProc_Done; } + XStoreName(pDisplay, iWindow, "xwinclip"); + /* Select event types to watch */ if (XSelectInput (pDisplay, iWindow, @@ -265,7 +266,7 @@ winClipboardProc (void *pvNotUsed) XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow) { ErrorF ("winClipboardProc - Could not set PRIMARY owner\n"); - pthread_exit (NULL); + goto winClipboardProc_Done; } /* CLIPBOARD */ @@ -275,7 +276,7 @@ winClipboardProc (void *pvNotUsed) XGetSelectionOwner (pDisplay, atomClipboard) != iWindow) { ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n"); - pthread_exit (NULL); + goto winClipboardProc_Done; } } @@ -294,7 +295,7 @@ winClipboardProc (void *pvNotUsed) if (!winClipboardFlushWindowsMessageQueue (hwnd)) { ErrorF ("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n"); - pthread_exit (NULL); + goto winClipboardProc_Done; } /* Signal that the clipboard client has started */ @@ -385,7 +386,20 @@ 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) { @@ -424,11 +438,43 @@ winClipboardProc_Done: } #endif + /* global clipboard variable reset */ + g_fClipboardLaunched = FALSE; + g_fClipboardStarted = FALSE; g_iClipboardWindow = None; g_pClipboardDisplay = NULL; g_hwndClipboard = NULL; - pthread_cleanup_pop(0); + /* 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; + } + + 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; + } + + 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 */ + kill(getpid(), SIGTERM); + } return NULL; } @@ -477,14 +523,3 @@ winClipboardIOErrorHandler (Display *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/winclipboardwrappers.c b/hw/xwin/winclipboardwrappers.c index 658d050d2..d8c013c66 100755 --- a/hw/xwin/winclipboardwrappers.c +++ b/hw/xwin/winclipboardwrappers.c @@ -42,7 +42,6 @@ * Constants */ -#define CLIP_NUM_CALLS 4 #define CLIP_NUM_SELECTIONS 2 #define CLIP_OWN_PRIMARY 0 #define CLIP_OWN_CLIPBOARD 1 @@ -53,7 +52,6 @@ */ DISPATCH_PROC(winProcEstablishConnection); -DISPATCH_PROC(winProcQueryTree); DISPATCH_PROC(winProcSetSelectionOwner); @@ -79,104 +77,6 @@ extern winDispatchProcPtr winProcSetSelectionOwnerOrig; /* - * Wrapper for internal QueryTree function. - * Hides the clipboard client when it is the only client remaining. - */ - -int -winProcQueryTree (ClientPtr client) -{ - int iReturn; - - ErrorF ("winProcQueryTree - Hello\n"); - - /* - * This procedure is only used for initialization. - * We can unwrap the original procedure at this point - * so that this function is no longer called until the - * server resets and the function is wrapped again. - */ - ProcVector[X_QueryTree] = winProcQueryTreeOrig; - - /* - * Call original function and bail if it fails. - * NOTE: We must do this first, since we need XdmcpOpenDisplay - * to be called before we initialize our clipboard client. - */ - iReturn = (*winProcQueryTreeOrig) (client); - if (iReturn != 0) - { - ErrorF ("winProcQueryTree - ProcQueryTree failed, bailing.\n"); - return iReturn; - } - - /* Make errors more obvious */ - winProcQueryTreeOrig = NULL; - - /* Do nothing if clipboard is not enabled */ - if (!g_fClipboard) - { - ErrorF ("winProcQueryTree - Clipboard is not enabled, " - "returning.\n"); - return iReturn; - } - - /* If the clipboard client has already been started, abort */ - if (g_fClipboardLaunched) - { - ErrorF ("winProcQueryTree - Clipboard client already " - "launched, returning.\n"); - return iReturn; - } - - /* Startup the clipboard client if clipboard mode is being used */ - if (g_fXdmcpEnabled && g_fClipboard) - { - /* - * NOTE: The clipboard client is started here for a reason: - * 1) Assume you are using XDMCP (e.g. XWin -query %hostname%) - * 2) If the clipboard client attaches during X Server startup, - * then it becomes the "magic client" that causes the X Server - * to reset if it exits. - * 3) XDMCP calls KillAllClients when it starts up. - * 4) The clipboard client is a client, so it is killed. - * 5) The clipboard client is the "magic client", so the X Server - * resets itself. - * 6) This repeats ad infinitum. - * 7) We avoid this by waiting until at least one client (could - * be XDM, could be another client) connects, which makes it - * almost certain that the clipboard client will not connect - * until after XDM when using XDMCP. - * 8) Unfortunately, there is another problem. - * 9) XDM walks the list of windows with XQueryTree, - * killing any client it finds with a window. - * 10)Thus, when using XDMCP we wait until the first call - * to ProcQueryTree before we startup the clipboard client. - * This should prevent XDM from finding the clipboard client, - * since it has not yet created a window. - * 11)Startup when not using XDMCP is handled in - * winProcEstablishConnection. - */ - - /* Create the clipboard client thread */ - if (!winInitClipboard ()) - { - ErrorF ("winProcQueryTree - winClipboardInit " - "failed.\n"); - return iReturn; - } - - ErrorF ("winProcQueryTree - winInitClipboard returned.\n"); - } - - /* Flag that clipboard client has been launched */ - g_fClipboardLaunched = TRUE; - - return iReturn; -} - - -/* * Wrapper for internal EstablishConnection function. * Initializes internal clients that must not be started until * an external client has connected. @@ -189,7 +89,7 @@ winProcEstablishConnection (ClientPtr client) static int s_iCallCount = 0; static unsigned long s_ulServerGeneration = 0; - if (s_iCallCount == 0 || s_iCallCount == CLIP_NUM_CALLS) ErrorF ("winProcEstablishConnection - Hello\n"); + if (s_iCallCount == 0) ErrorF ("winProcEstablishConnection - Hello\n"); /* Do nothing if clipboard is not enabled */ if (!g_fClipboard) @@ -217,18 +117,6 @@ winProcEstablishConnection (ClientPtr client) /* Increment call count */ ++s_iCallCount; - /* Wait for CLIP_NUM_CALLS when Xdmcp is enabled */ - if (g_fXdmcpEnabled - && !g_fClipboardLaunched - && s_iCallCount < CLIP_NUM_CALLS) - { - if (s_iCallCount == 1) ErrorF ("winProcEstablishConnection - Xdmcp, waiting to " - "start clipboard client until %dth call", CLIP_NUM_CALLS); - if (s_iCallCount == CLIP_NUM_CALLS - 1) ErrorF (".\n"); - else ErrorF ("."); - return (*winProcEstablishConnectionOrig) (client); - } - /* * This procedure is only used for initialization. * We can unwrap the original procedure at this point @@ -279,13 +167,6 @@ winProcEstablishConnection (ClientPtr client) * be XDM, could be another client) connects, which makes it * almost certain that the clipboard client will not connect * until after XDM when using XDMCP. - * 8) Unfortunately, there is another problem. - * 9) XDM walks the list of windows with XQueryTree, - * killing any client it finds with a window. - * 10)Thus, when using XDMCP we wait until CLIP_NUM_CALLS - * to ProcEstablishCeonnection before we startup the clipboard - * client. This should prevent XDM from finding the clipboard - * client, since it has not yet created a window. */ /* Create the clipboard client thread */ diff --git a/hw/xwin/winclipboardxevents.c b/hw/xwin/winclipboardxevents.c index edb6ac4bd..42b9977a5 100644 --- a/hw/xwin/winclipboardxevents.c +++ b/hw/xwin/winclipboardxevents.c @@ -789,6 +789,9 @@ winClipboardFlushXEvents (HWND hwnd, case PropertyNotify: break; + case MappingNotify: + break; + default: ErrorF ("winClipboardFlushXEvents - unexpected event type %d\n", event.type); break; |