diff options
-rw-r--r-- | hw/xwin/InitInput.c | 6 | ||||
-rw-r--r-- | hw/xwin/winclipboard.h | 2 | ||||
-rw-r--r-- | hw/xwin/winclipboardthread.c | 64 | ||||
-rw-r--r-- | hw/xwin/winclipboardwrappers.c | 123 |
4 files changed, 64 insertions, 131 deletions
diff --git a/hw/xwin/InitInput.c b/hw/xwin/InitInput.c index 70578b16c..3f136fd24 100644 --- a/hw/xwin/InitInput.c +++ b/hw/xwin/InitInput.c @@ -112,12 +112,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 aa9901cd2..b3e8bb06c 100644 --- a/hw/xwin/winclipboard.h +++ b/hw/xwin/winclipboard.h @@ -70,6 +70,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 a66a4a75d..240c0c29f 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; @@ -106,6 +109,7 @@ winClipboardProc (void *pvNotUsed) pthread_cleanup_push(&winClipboardThreadExit, NULL); winDebug ("winClipboardProc - Hello\n"); + ++clipboardRestarts; /* Do we have Unicode support? */ g_fUnicodeSupport = winClipboardDetectUnicodeSupport (); @@ -131,7 +135,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) { @@ -181,7 +185,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 */ @@ -199,7 +203,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 */ @@ -223,9 +227,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, @@ -252,7 +258,7 @@ winClipboardProc (void *pvNotUsed) XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow) { ErrorF ("winClipboardProc - Could not set PRIMARY owner\n"); - pthread_exit (NULL); + goto winClipboardProc_Done; } /* CLIPBOARD */ @@ -262,7 +268,7 @@ winClipboardProc (void *pvNotUsed) XGetSelectionOwner (pDisplay, atomClipboard) != iWindow) { ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n"); - pthread_exit (NULL); + goto winClipboardProc_Done; } } @@ -372,7 +378,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) { @@ -411,11 +430,44 @@ 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; } diff --git a/hw/xwin/winclipboardwrappers.c b/hw/xwin/winclipboardwrappers.c index 0f3dc14ce..529d5ba08 100644 --- 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 @@ -55,6 +54,8 @@ int winProcEstablishConnection(ClientPtr /* client */); int winProcQueryTree(ClientPtr /* client */); int winProcSetSelectionOwner(ClientPtr /* client */); +DISPATCH_PROC(winProcEstablishConnection); +DISPATCH_PROC(winProcSetSelectionOwner); /* @@ -79,104 +80,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 +92,8 @@ winProcEstablishConnection (ClientPtr client) static int s_iCallCount = 0; static unsigned long s_ulServerGeneration = 0; - if (s_iCallCount == 0 || s_iCallCount == CLIP_NUM_CALLS) winDebug ("winProcEstablishConnection - Hello\n"); + + if (s_iCallCount == 0 ) winDebug ("winProcEstablishConnection - Hello\n"); /* Do nothing if clipboard is not enabled */ if (!g_fClipboard) @@ -217,18 +121,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 +171,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 */ |