From 6343b531d786dd4a9bb52050c9ef267a04374b57 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Wed, 1 Jan 2014 17:54:48 +0000 Subject: [PATCH 01/30] hw/xwin: Remove left-over pthread_exit() in clipboard code Commit c1bf3baa44fbd8af33a2b3ce045324485b85a7a7 removed all but one of the pthread_exit() calls which used to call winClipboardThreadExit() Fix the final remaining one to exit via done label on IOError instead. Also fix a comment and report pre-flush failure to log, but do not exit Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboardthread.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c index e70896081..4a9eb4c32 100644 --- a/hw/xwin/winclipboardthread.c +++ b/hw/xwin/winclipboardthread.c @@ -141,7 +141,7 @@ winClipboardProc(void *pvNotUsed) 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 winClipboardProc_Done; } /* Use our generated cookie for authentication */ @@ -184,7 +184,7 @@ winClipboardProc(void *pvNotUsed) goto winClipboardProc_Done; } - /* Save the display in the screen privates */ + /* Save the display in a global used by the wndproc */ g_pClipboardDisplay = pDisplay; ErrorF("winClipboardProc - XOpenDisplay () returned and " @@ -269,8 +269,9 @@ winClipboardProc(void *pvNotUsed) winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode); /* Pre-flush Windows messages */ - if (!winClipboardFlushWindowsMessageQueue(hwnd)) - return 0; + if (!winClipboardFlushWindowsMessageQueue(hwnd)) { + ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n"); + } /* Signal that the clipboard client has started */ g_fClipboardStarted = TRUE; From 0bb6eae4e34634abb2679004ace94504a4d65964 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 00:07:01 +0100 Subject: [PATCH 02/30] hw/xwin: Push winClipboardShutdown() into winclipboardinit.c Push winClipboardShutdown() into winclipboardinit.c This lets us make g_ptClipboardProc static Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/InitOutput.c | 38 -------------------------------------- hw/xwin/win.h | 3 +++ hw/xwin/winclipboardinit.c | 32 +++++++++++++++++++++++++++++++- hw/xwin/winglobals.c | 1 - 4 files changed, 34 insertions(+), 40 deletions(-) diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c index 6b5c38d92..88bc85a44 100644 --- a/hw/xwin/InitOutput.c +++ b/hw/xwin/InitOutput.c @@ -66,24 +66,11 @@ typedef WINAPI HRESULT(*SHGETFOLDERPATHPROC) (HWND hwndOwner, /* * References to external symbols */ -#ifdef XWIN_CLIPBOARD -extern Bool g_fUnicodeClipboard; -extern Bool g_fClipboardLaunched; -extern Bool g_fClipboardStarted; -extern pthread_t g_ptClipboardProc; -extern HWND g_hwndClipboard; -extern Bool g_fClipboard; -#endif /* * Function prototypes */ -#ifdef XWIN_CLIPBOARD -static void - winClipboardShutdown(void); -#endif - static Bool winCheckDisplayNumber(void); @@ -125,31 +112,6 @@ static PixmapFormatRec g_PixmapFormats[] = { const int NUMFORMATS = sizeof(g_PixmapFormats) / sizeof(g_PixmapFormats[0]); -#ifdef XWIN_CLIPBOARD -static void -winClipboardShutdown(void) -{ - /* Close down clipboard resources */ - if (g_fClipboard && g_fClipboardLaunched && g_fClipboardStarted) { - /* Synchronously destroy the clipboard window */ - if (g_hwndClipboard != NULL) { - SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0); - /* NOTE: g_hwndClipboard is set to NULL in winclipboardthread.c */ - } - else - return; - - /* Wait for the clipboard thread to exit */ - pthread_join(g_ptClipboardProc, NULL); - - g_fClipboardLaunched = FALSE; - g_fClipboardStarted = FALSE; - - winDebug("winClipboardShutdown - Clipboard thread has exited.\n"); - } -} -#endif - static const ExtensionModule xwinExtensions[] = { #ifdef GLXEXT { GlxExtensionInit, "GLX", &noGlxExtension }, diff --git a/hw/xwin/win.h b/hw/xwin/win.h index a738a5940..1a882f4aa 100644 --- a/hw/xwin/win.h +++ b/hw/xwin/win.h @@ -794,6 +794,9 @@ Bool void winFixClipboardChain(void); + +void + winClipboardShutdown(void); #endif /* diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index 157006dab..e6bbf17e2 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -46,10 +46,17 @@ int winProcSetSelectionOwner(ClientPtr /* client */ ); * References to external symbols */ -extern pthread_t g_ptClipboardProc; extern winDispatchProcPtr winProcSetSelectionOwnerOrig; extern Bool g_fClipboard; extern HWND g_hwndClipboard; +extern Bool g_fClipboardLaunched; +extern Bool g_fClipboardStarted; + +/* + * Local variables + */ + +static pthread_t g_ptClipboardProc; /* * Intialize the Clipboard module @@ -76,6 +83,29 @@ winInitClipboard(void) return TRUE; } +void +winClipboardShutdown(void) +{ + /* Close down clipboard resources */ + if (g_fClipboard && g_fClipboardLaunched && g_fClipboardStarted) { + /* Synchronously destroy the clipboard window */ + if (g_hwndClipboard != NULL) { + SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0); + /* NOTE: g_hwndClipboard is set to NULL in winclipboardthread.c */ + } + else + return; + + /* Wait for the clipboard thread to exit */ + pthread_join(g_ptClipboardProc, NULL); + + g_fClipboardLaunched = FALSE; + g_fClipboardStarted = FALSE; + + winDebug("winClipboardShutdown - Clipboard thread has exited.\n"); + } +} + /* * Create the Windows window that we use to receive Windows messages */ diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c index b9ad294d5..b0d6ffc3c 100644 --- a/hw/xwin/winglobals.c +++ b/hw/xwin/winglobals.c @@ -96,7 +96,6 @@ Bool g_fUnicodeClipboard = TRUE; Bool g_fClipboard = TRUE; Bool g_fClipboardLaunched = FALSE; Bool g_fClipboardStarted = FALSE; -pthread_t g_ptClipboardProc; HWND g_hwndClipboard = NULL; void *g_pClipboardDisplay = NULL; Window g_iClipboardWindow = None; From 91e55691ef07735bb866c0f4d3c1a6e2ca167992 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Sun, 16 Jun 2013 23:57:17 +0100 Subject: [PATCH 03/30] hw/xwin: Hoist clipboard thread restart up one level Hoist clipboard thread restart up one level. Note that currently g_fClipboardLaunched is set the first time in the winProcEstablishConnection wrapper, and subsequent times when the clipboard thread restarts itself. Try to clarify this and just set g_fClipboardLaunched before starting the thread. Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard.h | 4 ---- hw/xwin/winclipboardinit.c | 41 +++++++++++++++++++++++++++++++++- hw/xwin/winclipboardthread.c | 34 +++------------------------- hw/xwin/winclipboardwrappers.c | 3 --- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h index cb7769510..63dce733d 100644 --- a/hw/xwin/winclipboard.h +++ b/hw/xwin/winclipboard.h @@ -60,16 +60,12 @@ #ifdef HAS_DEVWINDOWS #define WIN_MSG_QUEUE_FNAME "/dev/windows" #endif -#define WIN_CONNECT_RETRIES 40 -#define WIN_CONNECT_DELAY 4 #define WIN_JMP_OKAY 0 #define WIN_JMP_ERROR_IO 2 #define WIN_LOCAL_PROPERTY "CYGX_CUT_BUFFER" #define WIN_XEVENTS_SUCCESS 0 #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/winclipboardinit.c b/hw/xwin/winclipboardinit.c index e6bbf17e2..a3c1261d7 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -31,9 +31,16 @@ #ifdef HAVE_XWIN_CONFIG_H #include #endif + +#include +#include + #include "dixstruct.h" #include "winclipboard.h" +#define WIN_CLIPBOARD_RETRIES 40 +#define WIN_CLIPBOARD_DELAY 1 + /* * Local typedefs */ @@ -58,6 +65,38 @@ extern Bool g_fClipboardStarted; static pthread_t g_ptClipboardProc; +/* + * + */ +static void * +winClipboardThreadProc(void *arg) +{ + int clipboardRestarts = 0; + + while (1) + { + ++clipboardRestarts; + + /* Flag that clipboard client has been launched */ + g_fClipboardLaunched = TRUE; + + winClipboardProc(arg); + + /* 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; + break; + } + + sleep(WIN_CLIPBOARD_DELAY); + ErrorF("winClipboardProc - trying to restart clipboard thread \n"); + } + + return NULL; +} + /* * Intialize the Clipboard module */ @@ -74,7 +113,7 @@ winInitClipboard(void) } /* Spawn a thread for the Clipboard module */ - if (pthread_create(&g_ptClipboardProc, NULL, winClipboardProc, NULL)) { + if (pthread_create(&g_ptClipboardProc, NULL, winClipboardThreadProc, NULL)) { /* Bail if thread creation failed */ ErrorF("winInitClipboard - pthread_create failed.\n"); return FALSE; diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c index 4a9eb4c32..fd1fc0731 100644 --- a/hw/xwin/winclipboardthread.c +++ b/hw/xwin/winclipboardthread.c @@ -44,6 +44,9 @@ #endif #include "misc.h" +#define WIN_CONNECT_RETRIES 40 +#define WIN_CONNECT_DELAY 4 + /* * References to external symbols */ @@ -61,7 +64,6 @@ extern Window g_iClipboardWindow; */ static jmp_buf g_jmpEntry; -static int clipboardRestarts = 0; static XIOErrorHandler g_winClipboardOldIOErrorHandler; static pthread_t g_winClipboardProcThread; @@ -104,7 +106,6 @@ winClipboardProc(void *pvNotUsed) int iSelectError; winDebug("winClipboardProc - Hello\n"); - ++clipboardRestarts; /* Do we use Unicode clipboard? */ fUseUnicode = g_fUnicodeClipboard; @@ -400,35 +401,6 @@ winClipboardProc(void *pvNotUsed) 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; - } - - 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; - } - - 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); - } - return NULL; } diff --git a/hw/xwin/winclipboardwrappers.c b/hw/xwin/winclipboardwrappers.c index bfd6bff8b..05a8a2820 100644 --- a/hw/xwin/winclipboardwrappers.c +++ b/hw/xwin/winclipboardwrappers.c @@ -163,9 +163,6 @@ winProcEstablishConnection(ClientPtr client) ErrorF("winProcEstablishConnection - winInitClipboard returned.\n"); } - /* Flag that clipboard client has been launched */ - g_fClipboardLaunched = TRUE; - return iReturn; } From 290dbff0753ddf60f04da92d5a408c567a2ee3e0 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 01:55:03 +0100 Subject: [PATCH 04/30] hw/xwin: winProcEstablishConnection doesn't need to check if clipboard started winProcEstablishConnection doesn't need to check if clipboard has already been started. It should be clear that we start the thread only once when the wrapper tells us to, as the wrapper unhooks itself thereafter. Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboardwrappers.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/hw/xwin/winclipboardwrappers.c b/hw/xwin/winclipboardwrappers.c index 05a8a2820..99dfc5b47 100644 --- a/hw/xwin/winclipboardwrappers.c +++ b/hw/xwin/winclipboardwrappers.c @@ -56,7 +56,6 @@ DISPATCH_PROC(winProcSetSelectionOwner); * References to external symbols */ -extern Bool g_fClipboardLaunched; extern Bool g_fClipboardStarted; extern Bool g_fClipboard; extern Window g_iClipboardWindow; @@ -127,13 +126,6 @@ winProcEstablishConnection(ClientPtr client) /* Clear original function pointer */ winProcEstablishConnectionOrig = NULL; - /* If the clipboard client has already been started, abort */ - if (g_fClipboardLaunched) { - ErrorF("winProcEstablishConnection - Clipboard client already " - "launched, returning.\n"); - return iReturn; - } - /* Startup the clipboard client if clipboard mode is being used */ if (g_fClipboard) { /* From 42d13810822f6b48771d77b09c0ef7cc2356ede5 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 01:30:09 +0100 Subject: [PATCH 05/30] hw/xwin: Hoist setting of g_fClipboardStarted flag up one level Hoist the setting of g_fClipboardStarted flag up one level. Also move up the clearing of the g_fClipboardLaunched at the end of clipboard function. Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboardinit.c | 5 +++++ hw/xwin/winclipboardthread.c | 7 ------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index a3c1261d7..0b895cb8c 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -79,9 +79,14 @@ winClipboardThreadProc(void *arg) /* Flag that clipboard client has been launched */ g_fClipboardLaunched = TRUE; + g_fClipboardStarted = TRUE; winClipboardProc(arg); + /* Flag that clipboard client has stopped */ + g_fClipboardLaunched = FALSE; + g_fClipboardStarted = FALSE; + /* checking if we need to restart */ if (clipboardRestarts >= WIN_CLIPBOARD_RETRIES) { /* terminates clipboard thread but the main server still lives */ diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c index fd1fc0731..2ef73bde9 100644 --- a/hw/xwin/winclipboardthread.c +++ b/hw/xwin/winclipboardthread.c @@ -52,8 +52,6 @@ */ extern Bool g_fUnicodeClipboard; -extern Bool g_fClipboardStarted; -extern Bool g_fClipboardLaunched; extern Bool g_fClipboard; extern HWND g_hwndClipboard; extern void *g_pClipboardDisplay; @@ -274,9 +272,6 @@ winClipboardProc(void *pvNotUsed) ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n"); } - /* Signal that the clipboard client has started */ - g_fClipboardStarted = TRUE; - /* Loop for X events */ while (1) { /* Setup the file descriptor set */ @@ -395,8 +390,6 @@ winClipboardProc(void *pvNotUsed) #endif /* global clipboard variable reset */ - g_fClipboardLaunched = FALSE; - g_fClipboardStarted = FALSE; g_iClipboardWindow = None; g_pClipboardDisplay = NULL; g_hwndClipboard = NULL; From ab55746c1b179172a82b7a89ec6429b268a1f166 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 01:55:46 +0100 Subject: [PATCH 06/30] hw/xwin: Remove g_fClipboardLaunched, it's value is identical to g_fClipboardStarted Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboardinit.c | 6 +----- hw/xwin/winglobals.c | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index 0b895cb8c..4912b2e7d 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -56,7 +56,6 @@ int winProcSetSelectionOwner(ClientPtr /* client */ ); extern winDispatchProcPtr winProcSetSelectionOwnerOrig; extern Bool g_fClipboard; extern HWND g_hwndClipboard; -extern Bool g_fClipboardLaunched; extern Bool g_fClipboardStarted; /* @@ -78,13 +77,11 @@ winClipboardThreadProc(void *arg) ++clipboardRestarts; /* Flag that clipboard client has been launched */ - g_fClipboardLaunched = TRUE; g_fClipboardStarted = TRUE; winClipboardProc(arg); /* Flag that clipboard client has stopped */ - g_fClipboardLaunched = FALSE; g_fClipboardStarted = FALSE; /* checking if we need to restart */ @@ -131,7 +128,7 @@ void winClipboardShutdown(void) { /* Close down clipboard resources */ - if (g_fClipboard && g_fClipboardLaunched && g_fClipboardStarted) { + if (g_fClipboard && g_fClipboardStarted) { /* Synchronously destroy the clipboard window */ if (g_hwndClipboard != NULL) { SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0); @@ -143,7 +140,6 @@ winClipboardShutdown(void) /* Wait for the clipboard thread to exit */ pthread_join(g_ptClipboardProc, NULL); - g_fClipboardLaunched = FALSE; g_fClipboardStarted = FALSE; winDebug("winClipboardShutdown - Clipboard thread has exited.\n"); diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c index b0d6ffc3c..095ecff67 100644 --- a/hw/xwin/winglobals.c +++ b/hw/xwin/winglobals.c @@ -94,7 +94,6 @@ winDispatchProcPtr winProcSetSelectionOwnerOrig = NULL; Bool g_fUnicodeClipboard = TRUE; Bool g_fClipboard = TRUE; -Bool g_fClipboardLaunched = FALSE; Bool g_fClipboardStarted = FALSE; HWND g_hwndClipboard = NULL; void *g_pClipboardDisplay = NULL; From a70c2384a2689cc0346868bb27366c008c01758d Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 13 Feb 2012 19:58:37 +0000 Subject: [PATCH 07/30] hw/xwin: Remove SetSelectionOwner wrapper, use XFixesSetSelectionOwnerNotify event instead Use the XFixesSetSelectionNotify event instead of a SetSelectionOwner wrapper, the completely equivalent client-side mechanism. Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- configure.ac | 2 +- hw/xwin/InitInput.c | 1 - hw/xwin/winclipboard.h | 9 +- hw/xwin/winclipboardinit.c | 17 +-- hw/xwin/winclipboardthread.c | 23 ++++ hw/xwin/winclipboardwndproc.c | 3 +- hw/xwin/winclipboardwrappers.c | 215 +-------------------------------- hw/xwin/winclipboardxevents.c | 165 ++++++++++++++++++++++++- hw/xwin/winglobals.c | 3 - hw/xwin/winglobals.h | 1 - 10 files changed, 197 insertions(+), 242 deletions(-) diff --git a/configure.ac b/configure.ac index cba7d24ea..8dc719852 100644 --- a/configure.ac +++ b/configure.ac @@ -2143,7 +2143,7 @@ if test "x$XWIN" = xyes; then AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support]) AC_CHECK_TOOL(WINDRES, windres) - PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau]) + PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfixes]) if test "x$WINDOWSWM" = xauto; then PKG_CHECK_EXISTS($WINDOWSWMPROTO, [WINDOWSWM=yes], [WINDOWSWM=no]) diff --git a/hw/xwin/InitInput.c b/hw/xwin/InitInput.c index 38203c906..3e9ee41e6 100644 --- a/hw/xwin/InitInput.c +++ b/hw/xwin/InitInput.c @@ -39,7 +39,6 @@ #ifdef XWIN_CLIPBOARD int winProcEstablishConnection(ClientPtr /* client */ ); -int winProcSetSelectionOwner(ClientPtr /* client */ ); #endif /* diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h index 63dce733d..503d6acfe 100644 --- a/hw/xwin/winclipboard.h +++ b/hw/xwin/winclipboard.h @@ -116,7 +116,14 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); */ int - winClipboardFlushXEvents(HWND hwnd, int iWindow, Display * pDisplay, Bool fUnicodeSupport); + + +Atom +winClipboardGetLastOwnedSelectionAtom(void); + +void +winClipboardInitMonitoredSelections(void); + #endif diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index 4912b2e7d..e74e2b23d 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -35,25 +35,16 @@ #include #include -#include "dixstruct.h" +#include "os.h" #include "winclipboard.h" #define WIN_CLIPBOARD_RETRIES 40 #define WIN_CLIPBOARD_DELAY 1 -/* - * Local typedefs - */ - -typedef int (*winDispatchProcPtr) (ClientPtr); - -int winProcSetSelectionOwner(ClientPtr /* client */ ); - /* * References to external symbols */ -extern winDispatchProcPtr winProcSetSelectionOwnerOrig; extern Bool g_fClipboard; extern HWND g_hwndClipboard; extern Bool g_fClipboardStarted; @@ -108,12 +99,6 @@ winInitClipboard(void) { winDebug("winInitClipboard ()\n"); - /* Wrap some internal server functions */ - if (ProcVector[X_SetSelectionOwner] != winProcSetSelectionOwner) { - winProcSetSelectionOwnerOrig = ProcVector[X_SetSelectionOwner]; - ProcVector[X_SetSelectionOwner] = winProcSetSelectionOwner; - } - /* Spawn a thread for the Clipboard module */ if (pthread_create(&g_ptClipboardProc, NULL, winClipboardThreadProc, NULL)) { /* Bail if thread creation failed */ diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c index 2ef73bde9..04ab24f7f 100644 --- a/hw/xwin/winclipboardthread.c +++ b/hw/xwin/winclipboardthread.c @@ -43,6 +43,7 @@ #include #endif #include "misc.h" +#include #define WIN_CONNECT_RETRIES 40 #define WIN_CONNECT_DELAY 4 @@ -66,6 +67,8 @@ static XIOErrorHandler g_winClipboardOldIOErrorHandler; static pthread_t g_winClipboardProcThread; Bool g_fUseUnicode = FALSE; +int xfixes_event_base; +int xfixes_error_base; /* * Local function prototypes @@ -206,6 +209,9 @@ winClipboardProc(void *pvNotUsed) iMaxDescriptor = iConnectionNumber + 1; #endif + if (!XFixesQueryExtension(pDisplay, &xfixes_event_base, &xfixes_error_base)) + ErrorF ("winClipboardProc - XFixes extension not present\n"); + /* Create atom */ atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False); @@ -229,9 +235,26 @@ winClipboardProc(void *pvNotUsed) ErrorF("winClipboardProc - XSelectInput generated BadWindow " "on messaging window\n"); + XFixesSelectSelectionInput (pDisplay, + iWindow, + XA_PRIMARY, + XFixesSetSelectionOwnerNotifyMask | + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask); + + XFixesSelectSelectionInput (pDisplay, + iWindow, + XInternAtom (pDisplay, "CLIPBOARD", False), + XFixesSetSelectionOwnerNotifyMask | + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask); + /* Save the window in the screen privates */ g_iClipboardWindow = iWindow; + /* Initialize monitored selection state */ + winClipboardInitMonitoredSelections(); + /* Create Windows messaging window */ hwnd = winClipboardCreateMessagingWindow(); diff --git a/hw/xwin/winclipboardwndproc.c b/hw/xwin/winclipboardwndproc.c index 90dc9e0bb..d73c2db40 100644 --- a/hw/xwin/winclipboardwndproc.c +++ b/hw/xwin/winclipboardwndproc.c @@ -50,7 +50,6 @@ extern void *g_pClipboardDisplay; extern Window g_iClipboardWindow; -extern Atom g_atomLastOwnedSelection; /* * Process X events up to specified timeout @@ -423,7 +422,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* Request the selection contents */ iReturn = XConvertSelection(pDisplay, - g_atomLastOwnedSelection, + winClipboardGetLastOwnedSelectionAtom(), XInternAtom(pDisplay, "COMPOUND_TEXT", False), XInternAtom(pDisplay, diff --git a/hw/xwin/winclipboardwrappers.c b/hw/xwin/winclipboardwrappers.c index 99dfc5b47..2679f4f98 100644 --- a/hw/xwin/winclipboardwrappers.c +++ b/hw/xwin/winclipboardwrappers.c @@ -33,35 +33,21 @@ #ifdef HAVE_XWIN_CONFIG_H #include #endif + #include "win.h" #include "dixstruct.h" -#include - -/* - * Constants - */ - -#define CLIP_NUM_SELECTIONS 2 -#define CLIP_OWN_PRIMARY 0 -#define CLIP_OWN_CLIPBOARD 1 /* * Local function prototypes */ DISPATCH_PROC(winProcEstablishConnection); -DISPATCH_PROC(winProcSetSelectionOwner); /* * References to external symbols */ -extern Bool g_fClipboardStarted; extern Bool g_fClipboard; -extern Window g_iClipboardWindow; -extern Atom g_atomLastOwnedSelection; -extern HWND g_hwndClipboard; - /* * Wrapper for internal EstablishConnection function. @@ -157,202 +143,3 @@ winProcEstablishConnection(ClientPtr client) return iReturn; } - -/* - * Wrapper for internal SetSelectionOwner function. - * Grabs ownership of Windows clipboard when X11 clipboard owner changes. - */ - -int -winProcSetSelectionOwner(ClientPtr client) -{ - int i; - DrawablePtr pDrawable; - WindowPtr pWindow = None; - Bool fOwnedToNotOwned = FALSE; - static Window s_iOwners[CLIP_NUM_SELECTIONS] = { None }; - static unsigned long s_ulServerGeneration = 0; - - REQUEST(xSetSelectionOwnerReq); - - REQUEST_SIZE_MATCH(xSetSelectionOwnerReq); - - winDebug("winProcSetSelectionOwner - Hello.\n"); - - /* Watch for server reset */ - if (s_ulServerGeneration != serverGeneration) { - /* Save new generation number */ - s_ulServerGeneration = serverGeneration; - - /* Initialize static variables */ - for (i = 0; i < CLIP_NUM_SELECTIONS; ++i) - s_iOwners[i] = None; - } - - /* Abort if clipboard not completely initialized yet */ - if (!g_fClipboardStarted) { - /* ErrorF ("winProcSetSelectionOwner - Clipboard not yet started, " - "aborting.\n"); */ - goto winProcSetSelectionOwner_Done; - } - - /* Grab window if we have one */ - if (None != stuff->window) { - /* Grab the Window from the request */ - int rc = - dixLookupWindow(&pWindow, stuff->window, client, DixReadAccess); - if (rc != Success) { - ErrorF("winProcSetSelectionOwner - Found BadWindow, aborting.\n"); - goto winProcSetSelectionOwner_Done; - } - } - - /* Now we either have a valid window or None */ - - /* Save selection owners for monitored selections, ignore other selections */ - if (XA_PRIMARY == stuff->selection) { - /* Look for owned -> not owned transition */ - if (None == stuff->window && None != s_iOwners[CLIP_OWN_PRIMARY]) { - fOwnedToNotOwned = TRUE; - - winDebug("winProcSetSelectionOwner - PRIMARY - Going from " - "owned to not owned.\n"); - - /* Adjust last owned selection */ - if (None != s_iOwners[CLIP_OWN_CLIPBOARD]) - g_atomLastOwnedSelection = MakeAtom("CLIPBOARD", 9, TRUE); - else - g_atomLastOwnedSelection = None; - } - - /* Save new selection owner or None */ - s_iOwners[CLIP_OWN_PRIMARY] = stuff->window; - - winDebug("winProcSetSelectionOwner - PRIMARY - Now owned by: %d\n", - stuff->window); - } - else if (MakeAtom("CLIPBOARD", 9, TRUE) == stuff->selection) { - /* Look for owned -> not owned transition */ - if (None == stuff->window && None != s_iOwners[CLIP_OWN_CLIPBOARD]) { - fOwnedToNotOwned = TRUE; - - winDebug("winProcSetSelectionOwner - CLIPBOARD - Going from " - "owned to not owned.\n"); - - /* Adjust last owned selection */ - if (None != s_iOwners[CLIP_OWN_PRIMARY]) - g_atomLastOwnedSelection = XA_PRIMARY; - else - g_atomLastOwnedSelection = None; - } - - /* Save new selection owner or None */ - s_iOwners[CLIP_OWN_CLIPBOARD] = stuff->window; - - winDebug("winProcSetSelectionOwner - CLIPBOARD - Now owned by: %d\n", - stuff->window); - - } - else - goto winProcSetSelectionOwner_Done; - - /* - * At this point, if one of the selections is still owned by the - * clipboard manager then it should be marked as unowned since - * we will be taking ownership of the Win32 clipboard. - */ - if (g_iClipboardWindow == s_iOwners[CLIP_OWN_PRIMARY]) - s_iOwners[CLIP_OWN_PRIMARY] = None; - if (g_iClipboardWindow == s_iOwners[CLIP_OWN_CLIPBOARD]) - s_iOwners[CLIP_OWN_CLIPBOARD] = None; - - /* - * Handle case when selection is being disowned, - * WM_DRAWCLIPBOARD did not do the disowning, - * both monitored selections are no longer owned, - * an owned to not owned transition was detected, - * and we currently own the Win32 clipboard. - */ - if (stuff->window == None - && s_iOwners[CLIP_OWN_PRIMARY] == None - && s_iOwners[CLIP_OWN_CLIPBOARD] == None - && fOwnedToNotOwned - && g_hwndClipboard != NULL && g_hwndClipboard == GetClipboardOwner()) { - winDebug("winProcSetSelectionOwner - We currently own the " - "clipboard and neither the PRIMARY nor the CLIPBOARD " - "selections are owned, releasing ownership of Win32 " - "clipboard.\n"); - - /* Release ownership of the Windows clipboard */ - OpenClipboard(NULL); - EmptyClipboard(); - CloseClipboard(); - - goto winProcSetSelectionOwner_Done; - } - - /* Abort if no window at this point */ - if (None == stuff->window) { - winDebug("winProcSetSelectionOwner - No window, returning.\n"); - goto winProcSetSelectionOwner_Done; - } - - /* Abort if invalid selection */ - if (!ValidAtom(stuff->selection)) { - ErrorF("winProcSetSelectionOwner - Found BadAtom, aborting.\n"); - goto winProcSetSelectionOwner_Done; - } - - /* Cast Window to Drawable */ - pDrawable = (DrawablePtr) pWindow; - - /* Abort if clipboard manager is owning the selection */ - if (pDrawable->id == g_iClipboardWindow) { - winDebug("winProcSetSelectionOwner - We changed ownership, " - "aborting.\n"); - goto winProcSetSelectionOwner_Done; - } - - /* Abort if root window is taking ownership */ - if (pDrawable->id == 0) { - ErrorF("winProcSetSelectionOwner - Root window taking ownership, " - "aborting\n"); - goto winProcSetSelectionOwner_Done; - } - - /* Close clipboard if we have it open already */ - if (GetOpenClipboardWindow() == g_hwndClipboard) { - CloseClipboard(); - } - - /* Access the Windows clipboard */ - if (!OpenClipboard(g_hwndClipboard)) { - ErrorF("winProcSetSelectionOwner - OpenClipboard () failed: %08x\n", - (int) GetLastError()); - goto winProcSetSelectionOwner_Done; - } - - /* Take ownership of the Windows clipboard */ - if (!EmptyClipboard()) { - ErrorF("winProcSetSelectionOwner - EmptyClipboard () failed: %08x\n", - (int) GetLastError()); - goto winProcSetSelectionOwner_Done; - } - - /* Advertise regular text and unicode */ - SetClipboardData(CF_UNICODETEXT, NULL); - SetClipboardData(CF_TEXT, NULL); - - /* Save handle to last owned selection */ - g_atomLastOwnedSelection = stuff->selection; - - /* Release the clipboard */ - if (!CloseClipboard()) { - ErrorF("winProcSetSelectionOwner - CloseClipboard () failed: " - "%08x\n", (int) GetLastError()); - goto winProcSetSelectionOwner_Done; - } - - winProcSetSelectionOwner_Done: - return (*winProcSetSelectionOwnerOrig) (client); -} diff --git a/hw/xwin/winclipboardxevents.c b/hw/xwin/winclipboardxevents.c index 7d3c30e85..a792467f0 100644 --- a/hw/xwin/winclipboardxevents.c +++ b/hw/xwin/winclipboardxevents.c @@ -33,8 +33,95 @@ #ifdef HAVE_XWIN_CONFIG_H #include #endif + #include "winclipboard.h" #include "misc.h" +#include + +/* + * Constants + */ + +#define CLIP_NUM_SELECTIONS 2 +#define CLIP_OWN_NONE -1 +#define CLIP_OWN_PRIMARY 0 +#define CLIP_OWN_CLIPBOARD 1 + +/* + * Global variables + */ + +extern int xfixes_event_base; + +/* + * Local variables + */ + +static Window s_iOwners[CLIP_NUM_SELECTIONS] = { None, None }; +static const char *szSelectionNames[CLIP_NUM_SELECTIONS] = + { "PRIMARY", "CLIPBOARD" }; + +static unsigned int lastOwnedSelectionIndex = CLIP_OWN_NONE; +static Atom atomClipboard = None; + +static void +MonitorSelection(XFixesSelectionNotifyEvent * e, unsigned int i) +{ + /* Look for owned -> not owned transition */ + if (None == e->owner && None != s_iOwners[i]) { + unsigned int other_index; + + winDebug("MonitorSelection - %s - Going from owned to not owned.\n", + szSelectionNames[i]); + + /* If this selection is not owned, the other monitored selection must be the most + recently owned, if it is owned at all */ + if (i == CLIP_OWN_PRIMARY) + other_index = CLIP_OWN_CLIPBOARD; + if (i == CLIP_OWN_CLIPBOARD) + other_index = CLIP_OWN_PRIMARY; + if (None != s_iOwners[other_index]) + lastOwnedSelectionIndex = other_index; + else + lastOwnedSelectionIndex = CLIP_OWN_NONE; + } + + /* Save last owned selection */ + if (None != e->owner) { + lastOwnedSelectionIndex = i; + } + + /* Save new selection owner or None */ + s_iOwners[i] = e->owner; + winDebug("MonitorSelection - %s - Now owned by XID %x\n", + szSelectionNames[i], e->owner); +} + +Atom +winClipboardGetLastOwnedSelectionAtom(void) +{ + if (lastOwnedSelectionIndex == CLIP_OWN_NONE) + return None; + + if (lastOwnedSelectionIndex == CLIP_OWN_PRIMARY) + return XA_PRIMARY; + + if (lastOwnedSelectionIndex == CLIP_OWN_CLIPBOARD) + return atomClipboard; + + return None; +} + + +void +winClipboardInitMonitoredSelections(void) +{ + /* Initialize static variables */ + for (int i = 0; i < CLIP_NUM_SELECTIONS; ++i) + s_iOwners[i] = None; + + lastOwnedSelectionIndex = CLIP_OWN_NONE; +} /* * Process any pending X events @@ -52,6 +139,7 @@ winClipboardFlushXEvents(HWND hwnd, if (generation != serverGeneration) { generation = serverGeneration; + atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False); atomLocalProperty = XInternAtom(pDisplay, WIN_LOCAL_PROPERTY, False); atomUTF8String = XInternAtom(pDisplay, "UTF8_STRING", False); atomCompoundText = XInternAtom(pDisplay, "COMPOUND_TEXT", False); @@ -77,7 +165,6 @@ winClipboardFlushXEvents(HWND hwnd, wchar_t *pwszUnicodeStr = NULL; int iUnicodeLen = 0; int iReturnDataLen = 0; - int i; Bool fAbort = FALSE; Bool fCloseClipboard = FALSE; Bool fSetClipboardData = TRUE; @@ -525,6 +612,8 @@ winClipboardFlushXEvents(HWND hwnd, if (iReturn == Success || iReturn > 0) { /* Conversion succeeded or some unconvertible characters */ if (ppszTextList != NULL) { + int i; + iReturnDataLen = 0; for (i = 0; i < iCount; i++) { iReturnDataLen += strlen(ppszTextList[i]); @@ -693,8 +782,78 @@ winClipboardFlushXEvents(HWND hwnd, break; default: - ErrorF("winClipboardFlushXEvents - unexpected event type %d\n", - event.type); + if (event.type == XFixesSetSelectionOwnerNotify + xfixes_event_base) { + XFixesSelectionNotifyEvent *e = + (XFixesSelectionNotifyEvent *) & event; + + winDebug("winClipboardFlushXEvents - XFixesSetSelectionOwnerNotify\n"); + + /* Save selection owners for monitored selections, ignore other selections */ + if (e->selection == XA_PRIMARY) { + MonitorSelection(e, CLIP_OWN_PRIMARY); + } + else if (e->selection == atomClipboard) { + MonitorSelection(e, CLIP_OWN_CLIPBOARD); + } + else + break; + + /* Selection is being disowned */ + if (e->owner == None) { + winDebug + ("winClipboardFlushXEvents - No window, returning.\n"); + break; + } + + /* + XXX: there are all kinds of wacky edge cases we might need here: + - we own windows clipboard, but neither PRIMARY nor CLIPBOARD have an owner, so we should disown it? + - root window is taking ownership? + */ + + /* If we are the owner of the most recently owned selection, don't go all recursive :) */ + if ((lastOwnedSelectionIndex != CLIP_OWN_NONE) && + (s_iOwners[lastOwnedSelectionIndex] == iWindow)) { + winDebug("winClipboardFlushXEvents - Ownership changed to us, aborting.\n"); + break; + } + + /* Close clipboard if we have it open already (possible? correct??) */ + if (GetOpenClipboardWindow() == hwnd) { + CloseClipboard(); + } + + /* Access the Windows clipboard */ + if (!OpenClipboard(hwnd)) { + ErrorF("winClipboardFlushXEvents - OpenClipboard () failed: %08x\n", + (int) GetLastError()); + break; + } + + /* Take ownership of the Windows clipboard */ + if (!EmptyClipboard()) { + ErrorF("winClipboardFlushXEvents - EmptyClipboard () failed: %08x\n", + (int) GetLastError()); + break; + } + + /* Advertise regular text and unicode */ + SetClipboardData(CF_UNICODETEXT, NULL); + SetClipboardData(CF_TEXT, NULL); + + /* Release the clipboard */ + if (!CloseClipboard()) { + ErrorF("winClipboardFlushXEvents - CloseClipboard () failed: %08x\n", + (int) GetLastError()); + break; + } + } + /* XFixesSelectionWindowDestroyNotifyMask */ + /* XFixesSelectionClientCloseNotifyMask */ + else { + ErrorF("winClipboardFlushXEvents - unexpected event type %d\n", + event.type); + } break; } } diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c index 095ecff67..b3f18ae4b 100644 --- a/hw/xwin/winglobals.c +++ b/hw/xwin/winglobals.c @@ -86,7 +86,6 @@ pthread_mutex_t g_pmTerminating = PTHREAD_MUTEX_INITIALIZER; * Wrapped DIX functions */ winDispatchProcPtr winProcEstablishConnectionOrig = NULL; -winDispatchProcPtr winProcSetSelectionOwnerOrig = NULL; /* * Clipboard variables @@ -98,7 +97,6 @@ Bool g_fClipboardStarted = FALSE; HWND g_hwndClipboard = NULL; void *g_pClipboardDisplay = NULL; Window g_iClipboardWindow = None; -Atom g_atomLastOwnedSelection = None; #endif /* @@ -113,7 +111,6 @@ winInitializeGlobals(void) #ifdef XWIN_CLIPBOARD g_iClipboardWindow = None; g_pClipboardDisplay = NULL; - g_atomLastOwnedSelection = None; g_hwndClipboard = NULL; #endif } diff --git a/hw/xwin/winglobals.h b/hw/xwin/winglobals.h index 60c00da42..5d8e7a075 100644 --- a/hw/xwin/winglobals.h +++ b/hw/xwin/winglobals.h @@ -72,7 +72,6 @@ typedef int (*winDispatchProcPtr) (ClientPtr); * Wrapped DIX functions */ extern winDispatchProcPtr winProcEstablishConnectionOrig; -extern winDispatchProcPtr winProcSetSelectionOwnerOrig; #endif /* The global X default icons */ From 229a0a83a44c94ce76eb937d58dc1773a38baa3e Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Sun, 16 Jun 2013 22:13:26 +0100 Subject: [PATCH 08/30] hw/xwin: Move winClipboardCreateMessagingWindow() to winclipboardthread.c Move winClipboardCreateMessagingWindow() from winclipboardinit.c to winclipboardthread.c, the only place that uses it, and make it static. Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard.h | 4 --- hw/xwin/winclipboardinit.c | 49 -------------------------------- hw/xwin/winclipboardthread.c | 55 ++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 53 deletions(-) diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h index 503d6acfe..2d1b508d9 100644 --- a/hw/xwin/winclipboard.h +++ b/hw/xwin/winclipboard.h @@ -55,8 +55,6 @@ #include /* Clipboard module constants */ -#define WIN_CLIPBOARD_WINDOW_CLASS "xwinclip" -#define WIN_CLIPBOARD_WINDOW_TITLE "xwinclip" #ifdef HAS_DEVWINDOWS #define WIN_MSG_QUEUE_FNAME "/dev/windows" #endif @@ -84,8 +82,6 @@ extern void winErrorFVerb(int verb, const char *format, ...); Bool winInitClipboard(void); -HWND winClipboardCreateMessagingWindow(void); - /* * winclipboardtextconv.c */ diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index e74e2b23d..07e57eebf 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -131,55 +131,6 @@ winClipboardShutdown(void) } } -/* - * Create the Windows window that we use to receive Windows messages - */ - -HWND -winClipboardCreateMessagingWindow(void) -{ - WNDCLASSEX wc; - HWND hwnd; - - /* Setup our window class */ - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = winClipboardWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = GetModuleHandle(NULL); - wc.hIcon = 0; - wc.hCursor = 0; - wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName = WIN_CLIPBOARD_WINDOW_CLASS; - wc.hIconSm = 0; - RegisterClassEx(&wc); - - /* Create the window */ - hwnd = CreateWindowExA(0, /* Extended styles */ - WIN_CLIPBOARD_WINDOW_CLASS, /* Class name */ - WIN_CLIPBOARD_WINDOW_TITLE, /* Window name */ - WS_OVERLAPPED, /* Not visible anyway */ - CW_USEDEFAULT, /* Horizontal position */ - CW_USEDEFAULT, /* Vertical position */ - CW_USEDEFAULT, /* Right edge */ - CW_USEDEFAULT, /* Bottom edge */ - (HWND) NULL, /* No parent or owner window */ - (HMENU) NULL, /* No menu */ - GetModuleHandle(NULL), /* Instance handle */ - NULL); /* Creation data */ - assert(hwnd != NULL); - - /* I'm not sure, but we may need to call this to start message processing */ - ShowWindow(hwnd, SW_HIDE); - - /* Similarly, we may need a call to this even though we don't paint */ - UpdateWindow(hwnd); - - return hwnd; -} - void winFixClipboardChain(void) { diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c index 04ab24f7f..0bffd44d2 100644 --- a/hw/xwin/winclipboardthread.c +++ b/hw/xwin/winclipboardthread.c @@ -48,6 +48,9 @@ #define WIN_CONNECT_RETRIES 40 #define WIN_CONNECT_DELAY 4 +#define WIN_CLIPBOARD_WINDOW_CLASS "xwinclip" +#define WIN_CLIPBOARD_WINDOW_TITLE "xwinclip" + /* * References to external symbols */ @@ -74,6 +77,9 @@ int xfixes_error_base; * Local function prototypes */ +static HWND +winClipboardCreateMessagingWindow(void); + static int winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr); @@ -420,6 +426,55 @@ winClipboardProc(void *pvNotUsed) return NULL; } +/* + * Create the Windows window that we use to receive Windows messages + */ + +static HWND +winClipboardCreateMessagingWindow(void) +{ + WNDCLASSEX wc; + HWND hwnd; + + /* Setup our window class */ + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winClipboardWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetModuleHandle(NULL); + wc.hIcon = 0; + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = WIN_CLIPBOARD_WINDOW_CLASS; + wc.hIconSm = 0; + RegisterClassEx(&wc); + + /* Create the window */ + hwnd = CreateWindowExA(0, /* Extended styles */ + WIN_CLIPBOARD_WINDOW_CLASS, /* Class name */ + WIN_CLIPBOARD_WINDOW_TITLE, /* Window name */ + WS_OVERLAPPED, /* Not visible anyway */ + CW_USEDEFAULT, /* Horizontal position */ + CW_USEDEFAULT, /* Vertical position */ + CW_USEDEFAULT, /* Right edge */ + CW_USEDEFAULT, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle(NULL), /* Instance handle */ + NULL); /* Creation data */ + assert(hwnd != NULL); + + /* I'm not sure, but we may need to call this to start message processing */ + ShowWindow(hwnd, SW_HIDE); + + /* Similarly, we may need a call to this even though we don't paint */ + UpdateWindow(hwnd); + + return hwnd; +} + /* * winClipboardErrorHandler - Our application specific error handler */ From a3c1e405cb78df9ef18a1158dcaed3c27b3cbffe Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Sun, 16 Jun 2013 22:35:22 +0100 Subject: [PATCH 09/30] hw/xwin: Eliminate g_pClipboardDisplay and g_iClipboardWindow globals Eliminate the g_pClipboardDisplay and g_iClipboardWindow globals used to make those values available to the clipboard wndproc, by passing them in via the WM_CREATE message instead. Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard.h | 6 ++++++ hw/xwin/winclipboardthread.c | 23 +++++++++-------------- hw/xwin/winclipboardwndproc.c | 20 ++++++++------------ hw/xwin/winglobals.c | 4 ---- 4 files changed, 23 insertions(+), 30 deletions(-) diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h index 2d1b508d9..fcda6bfa0 100644 --- a/hw/xwin/winclipboard.h +++ b/hw/xwin/winclipboard.h @@ -107,6 +107,12 @@ BOOL winClipboardFlushWindowsMessageQueue(HWND hwnd); LRESULT CALLBACK winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +typedef struct +{ + Display *pClipboardDisplay; + Window iClipboardWindow; +} ClipboardWindowCreationParams; + /* * winclipboardxevents.c */ diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c index 0bffd44d2..f9089ffc0 100644 --- a/hw/xwin/winclipboardthread.c +++ b/hw/xwin/winclipboardthread.c @@ -58,8 +58,6 @@ extern Bool g_fUnicodeClipboard; extern Bool g_fClipboard; extern HWND g_hwndClipboard; -extern void *g_pClipboardDisplay; -extern Window g_iClipboardWindow; /* * Global variables @@ -78,7 +76,7 @@ int xfixes_error_base; */ static HWND -winClipboardCreateMessagingWindow(void); +winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow); static int winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr); @@ -192,9 +190,6 @@ winClipboardProc(void *pvNotUsed) goto winClipboardProc_Done; } - /* Save the display in a global used by the wndproc */ - g_pClipboardDisplay = pDisplay; - ErrorF("winClipboardProc - XOpenDisplay () returned and " "successfully opened the display.\n"); @@ -255,14 +250,11 @@ winClipboardProc(void *pvNotUsed) XFixesSelectionWindowDestroyNotifyMask | XFixesSelectionClientCloseNotifyMask); - /* Save the window in the screen privates */ - g_iClipboardWindow = iWindow; /* Initialize monitored selection state */ winClipboardInitMonitoredSelections(); - /* Create Windows messaging window */ - hwnd = winClipboardCreateMessagingWindow(); + hwnd = winClipboardCreateMessagingWindow(pDisplay, iWindow); /* Save copy of HWND in screen privates */ g_hwndClipboard = hwnd; @@ -419,8 +411,6 @@ winClipboardProc(void *pvNotUsed) #endif /* global clipboard variable reset */ - g_iClipboardWindow = None; - g_pClipboardDisplay = NULL; g_hwndClipboard = NULL; return NULL; @@ -431,9 +421,10 @@ winClipboardProc(void *pvNotUsed) */ static HWND -winClipboardCreateMessagingWindow(void) +winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow) { WNDCLASSEX wc; + ClipboardWindowCreationParams cwcp; HWND hwnd; /* Setup our window class */ @@ -451,6 +442,10 @@ winClipboardCreateMessagingWindow(void) wc.hIconSm = 0; RegisterClassEx(&wc); + /* Information to be passed to WM_CREATE */ + cwcp.pClipboardDisplay = pDisplay; + cwcp.iClipboardWindow = iWindow; + /* Create the window */ hwnd = CreateWindowExA(0, /* Extended styles */ WIN_CLIPBOARD_WINDOW_CLASS, /* Class name */ @@ -463,7 +458,7 @@ winClipboardCreateMessagingWindow(void) (HWND) NULL, /* No parent or owner window */ (HMENU) NULL, /* No menu */ GetModuleHandle(NULL), /* Instance handle */ - NULL); /* Creation data */ + &cwcp); /* Creation data */ assert(hwnd != NULL); /* I'm not sure, but we may need to call this to start message processing */ diff --git a/hw/xwin/winclipboardwndproc.c b/hw/xwin/winclipboardwndproc.c index d73c2db40..459170f2a 100644 --- a/hw/xwin/winclipboardwndproc.c +++ b/hw/xwin/winclipboardwndproc.c @@ -44,12 +44,6 @@ #define WIN_POLL_TIMEOUT 1 -/* - * References to external symbols - */ - -extern void *g_pClipboardDisplay; -extern Window g_iClipboardWindow; /* * Process X events up to specified timeout @@ -138,6 +132,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND s_hwndNextViewer; static Bool s_fCBCInitialized; + static Display *pDisplay; + static Window iWindow; /* Branch on message type */ switch (message) { @@ -158,9 +154,13 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HWND first, next; DWORD error_code = 0; + ClipboardWindowCreationParams *cwcp = (ClipboardWindowCreationParams *)((CREATESTRUCT *)lParam)->lpCreateParams; winDebug("winClipboardWindowProc - WM_CREATE\n"); + pDisplay = cwcp->pClipboardDisplay; + iWindow = cwcp->iClipboardWindow; + first = GetClipboardViewer(); /* Get handle to first viewer in chain. */ if (first == hwnd) return 0; /* Make sure it's not us! */ @@ -243,8 +243,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) static Atom atomClipboard; static int generation; static Bool s_fProcessingDrawClipboard = FALSE; - Display *pDisplay = g_pClipboardDisplay; - Window iWindow = g_iClipboardWindow; int iReturn; winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n"); @@ -323,7 +321,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* Release PRIMARY selection if owned */ iReturn = XGetSelectionOwner(pDisplay, XA_PRIMARY); - if (iReturn == g_iClipboardWindow) { + if (iReturn == iWindow) { winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - " "PRIMARY selection is owned by us.\n"); XSetSelectionOwner(pDisplay, XA_PRIMARY, None, CurrentTime); @@ -335,7 +333,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* Release CLIPBOARD selection if owned */ iReturn = XGetSelectionOwner(pDisplay, atomClipboard); - if (iReturn == g_iClipboardWindow) { + if (iReturn == iWindow) { winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - " "CLIPBOARD selection is owned by us.\n"); XSetSelectionOwner(pDisplay, atomClipboard, None, CurrentTime); @@ -408,8 +406,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_RENDERALLFORMATS: { int iReturn; - Display *pDisplay = g_pClipboardDisplay; - Window iWindow = g_iClipboardWindow; Bool fConvertToUnicode; winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Hello.\n"); diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c index b3f18ae4b..8eaaf385a 100644 --- a/hw/xwin/winglobals.c +++ b/hw/xwin/winglobals.c @@ -95,8 +95,6 @@ Bool g_fUnicodeClipboard = TRUE; Bool g_fClipboard = TRUE; Bool g_fClipboardStarted = FALSE; HWND g_hwndClipboard = NULL; -void *g_pClipboardDisplay = NULL; -Window g_iClipboardWindow = None; #endif /* @@ -109,8 +107,6 @@ winInitializeGlobals(void) { g_dwCurrentThreadID = GetCurrentThreadId(); #ifdef XWIN_CLIPBOARD - g_iClipboardWindow = None; - g_pClipboardDisplay = NULL; g_hwndClipboard = NULL; #endif } From 8f9fba5bc1499804a6c4a3287d99fe7dab8d6b8f Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 02:01:27 +0100 Subject: [PATCH 10/30] hw/xwin: Hoist use of winSetAuthorization() and winGetDisplayName() up one level Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard.h | 3 +-- hw/xwin/winclipboardinit.c | 22 +++++++++++++++++++++- hw/xwin/winclipboardthread.c | 18 +----------------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h index fcda6bfa0..fa32c6253 100644 --- a/hw/xwin/winclipboard.h +++ b/hw/xwin/winclipboard.h @@ -71,7 +71,6 @@ * References to external symbols */ -extern char *display; extern void winDebug(const char *format, ...); extern void winErrorFVerb(int verb, const char *format, ...); @@ -96,7 +95,7 @@ void * winclipboardthread.c */ -void *winClipboardProc(void *); +void *winClipboardProc(char *szDisplay); /* * winclipboardwndproc.c diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index 07e57eebf..335e37920 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -37,10 +37,13 @@ #include "os.h" #include "winclipboard.h" +#include "windisplay.h" #define WIN_CLIPBOARD_RETRIES 40 #define WIN_CLIPBOARD_DELAY 1 +extern void winSetAuthorization(void); + /* * References to external symbols */ @@ -61,16 +64,33 @@ static pthread_t g_ptClipboardProc; static void * winClipboardThreadProc(void *arg) { + char szDisplay[512]; int clipboardRestarts = 0; while (1) { ++clipboardRestarts; + /* Use our generated cookie for authentication */ + winSetAuthorization(); + + /* Setup the display connection string */ + /* + * NOTE: Always connect to screen 0 since we require that screen + * numbers start at 0 and increase without gaps. We only need + * to connect to one screen on the display to get events + * for all screens on the display. That is why there is only + * one clipboard client thread. + */ + winGetDisplayName(szDisplay, 0); + + /* Print the display connection string */ + ErrorF("winClipboardThreadProc - DISPLAY=%s\n", szDisplay); + /* Flag that clipboard client has been launched */ g_fClipboardStarted = TRUE; - winClipboardProc(arg); + winClipboardProc(szDisplay); /* Flag that clipboard client has stopped */ g_fClipboardStarted = FALSE; diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c index f9089ffc0..3d49606ba 100644 --- a/hw/xwin/winclipboardthread.c +++ b/hw/xwin/winclipboardthread.c @@ -89,7 +89,7 @@ static int */ void * -winClipboardProc(void *pvNotUsed) +winClipboardProc(char *szDisplay) { Atom atomClipboard; int iReturn; @@ -107,7 +107,6 @@ winClipboardProc(void *pvNotUsed) Window iWindow = None; int iRetries; Bool fUseUnicode; - char szDisplay[512]; int iSelectError; winDebug("winClipboardProc - Hello\n"); @@ -150,24 +149,9 @@ winClipboardProc(void *pvNotUsed) goto winClipboardProc_Done; } - /* Use our generated cookie for authentication */ - winSetAuthorization(); - /* Initialize retry count */ iRetries = 0; - /* Setup the display connection string x */ - /* - * NOTE: Always connect to screen 0 since we require that screen - * numbers start at 0 and increase without gaps. We only need - * to connect to one screen on the display to get events - * for all screens on the display. That is why there is only - * one clipboard client thread. - */ - winGetDisplayName(szDisplay, 0); - - /* Print the display connection string */ - ErrorF("winClipboardProc - DISPLAY=%s\n", szDisplay); /* Open the X display */ do { From 03a59e7f787a160c6cc07c7a37df64a793242ef2 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 02:01:39 +0100 Subject: [PATCH 11/30] hw/xwin: Add remaining clipboard globals to winglobals.h Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/windialogs.c | 7 ------- hw/xwin/winglobals.h | 3 +++ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/hw/xwin/windialogs.c b/hw/xwin/windialogs.c index c9af0e203..61f7fe0bd 100644 --- a/hw/xwin/windialogs.c +++ b/hw/xwin/windialogs.c @@ -36,13 +36,6 @@ #include #include "winprefs.h" -/* - * References to external globals - */ - -#ifdef XWIN_CLIPBOARD -extern Bool g_fClipboardStarted; -#endif /* * Local function prototypes */ diff --git a/hw/xwin/winglobals.h b/hw/xwin/winglobals.h index 5d8e7a075..d7b813dbb 100644 --- a/hw/xwin/winglobals.h +++ b/hw/xwin/winglobals.h @@ -73,6 +73,9 @@ typedef int (*winDispatchProcPtr) (ClientPtr); */ extern winDispatchProcPtr winProcEstablishConnectionOrig; #endif +extern Bool g_fUnicodeClipboard; +extern Bool g_fClipboard; +extern Bool g_fClipboardStarted; /* The global X default icons */ #if defined(XWIN_MULTIWINDOW) From e965001a732a6b573c374f6a3503e172df01e8ec Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 13:18:16 +0100 Subject: [PATCH 12/30] hw/xwin: Make g_hwndClipboard static Move winFixClipboardChain() into winclipboardthread.c Add winCLipboardWindowDestroy() function to access it for WM_DESTROY Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard.h | 3 +++ hw/xwin/winclipboardinit.c | 16 +--------------- hw/xwin/winclipboardthread.c | 25 +++++++++++++++++++------ hw/xwin/winglobals.c | 4 ---- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h index fa32c6253..41c0a538b 100644 --- a/hw/xwin/winclipboard.h +++ b/hw/xwin/winclipboard.h @@ -97,6 +97,9 @@ void void *winClipboardProc(char *szDisplay); +void +winClipboardWindowDestroy(void); + /* * winclipboardwndproc.c */ diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index 335e37920..d16c121c6 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -49,7 +49,6 @@ extern void winSetAuthorization(void); */ extern Bool g_fClipboard; -extern HWND g_hwndClipboard; extern Bool g_fClipboardStarted; /* @@ -135,12 +134,7 @@ winClipboardShutdown(void) /* Close down clipboard resources */ if (g_fClipboard && g_fClipboardStarted) { /* Synchronously destroy the clipboard window */ - if (g_hwndClipboard != NULL) { - SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0); - /* NOTE: g_hwndClipboard is set to NULL in winclipboardthread.c */ - } - else - return; + winClipboardWindowDestroy(); /* Wait for the clipboard thread to exit */ pthread_join(g_ptClipboardProc, NULL); @@ -150,11 +144,3 @@ winClipboardShutdown(void) winDebug("winClipboardShutdown - Clipboard thread has exited.\n"); } } - -void -winFixClipboardChain(void) -{ - if (g_fClipboard && g_hwndClipboard) { - PostMessage(g_hwndClipboard, WM_WM_REINIT, 0, 0); - } -} diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c index 3d49606ba..2641e2099 100644 --- a/hw/xwin/winclipboardthread.c +++ b/hw/xwin/winclipboardthread.c @@ -57,12 +57,12 @@ extern Bool g_fUnicodeClipboard; extern Bool g_fClipboard; -extern HWND g_hwndClipboard; /* * Global variables */ +static HWND g_hwndClipboard = NULL; static jmp_buf g_jmpEntry; static XIOErrorHandler g_winClipboardOldIOErrorHandler; static pthread_t g_winClipboardProcThread; @@ -240,7 +240,7 @@ winClipboardProc(char *szDisplay) /* Create Windows messaging window */ hwnd = winClipboardCreateMessagingWindow(pDisplay, iWindow); - /* Save copy of HWND in screen privates */ + /* Save copy of HWND */ g_hwndClipboard = hwnd; /* Assert ownership of selections if Win32 clipboard is owned */ @@ -355,10 +355,7 @@ winClipboardProc(char *szDisplay) 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); + winClipboardWindowDestroy(); } /* Close our X window */ @@ -489,3 +486,19 @@ winClipboardIOErrorHandler(Display * pDisplay) return 0; } + +void +winClipboardWindowDestroy(void) +{ + if (g_hwndClipboard) { + SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0); + } +} + +void +winFixClipboardChain(void) +{ + if (g_hwndClipboard) { + PostMessage(g_hwndClipboard, WM_WM_REINIT, 0, 0); + } +} diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c index 8eaaf385a..ad82b83f6 100644 --- a/hw/xwin/winglobals.c +++ b/hw/xwin/winglobals.c @@ -94,7 +94,6 @@ winDispatchProcPtr winProcEstablishConnectionOrig = NULL; Bool g_fUnicodeClipboard = TRUE; Bool g_fClipboard = TRUE; Bool g_fClipboardStarted = FALSE; -HWND g_hwndClipboard = NULL; #endif /* @@ -106,7 +105,4 @@ void winInitializeGlobals(void) { g_dwCurrentThreadID = GetCurrentThreadId(); -#ifdef XWIN_CLIPBOARD - g_hwndClipboard = NULL; -#endif } From 88d44597046086953032fec7e035fc036596e255 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 00:38:47 +0100 Subject: [PATCH 13/30] hw/xwin: Move clipboard integration code down to a subdirectory Move clipboard integration code down to a subdirectory and build as a convenience library Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- configure.ac | 1 + hw/xwin/Makefile.am | 15 +++++++-------- hw/xwin/winclipboard/Makefile.am | 15 +++++++++++++++ .../textconv.c} | 0 .../thread.c} | 2 +- hw/xwin/{ => winclipboard}/winclipboard.h | 5 +++-- .../wndproc.c} | 0 .../xevents.c} | 0 hw/xwin/winclipboardinit.c | 2 +- 9 files changed, 28 insertions(+), 12 deletions(-) create mode 100644 hw/xwin/winclipboard/Makefile.am rename hw/xwin/{winclipboardtextconv.c => winclipboard/textconv.c} (100%) rename hw/xwin/{winclipboardthread.c => winclipboard/thread.c} (99%) rename hw/xwin/{ => winclipboard}/winclipboard.h (99%) rename hw/xwin/{winclipboardwndproc.c => winclipboard/wndproc.c} (100%) rename hw/xwin/{winclipboardxevents.c => winclipboard/xevents.c} (100%) diff --git a/configure.ac b/configure.ac index 8dc719852..93e8895e2 100644 --- a/configure.ac +++ b/configure.ac @@ -2599,6 +2599,7 @@ hw/xnest/man/Makefile hw/xwin/Makefile hw/xwin/glx/Makefile hw/xwin/man/Makefile +hw/xwin/winclipboard/Makefile hw/xquartz/Makefile hw/xquartz/GL/Makefile hw/xquartz/bundle/Makefile diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am index 326ffa03d..2c7fde313 100644 --- a/hw/xwin/Makefile.am +++ b/hw/xwin/Makefile.am @@ -3,12 +3,9 @@ bin_PROGRAMS = XWin if XWIN_CLIPBOARD SRCS_CLIPBOARD = \ winclipboardinit.c \ - winclipboardtextconv.c \ - winclipboardthread.c \ - winclipboardwndproc.c \ - winclipboardwrappers.c \ - winclipboardxevents.c + winclipboardwrappers.c DEFS_CLIPBOARD = -DXWIN_CLIPBOARD +CLIPBOARD_LIBS = $(top_builddir)/hw/xwin/winclipboard/libXWinclipboard.la endif if XWIN_GLX_WINDOWS @@ -110,7 +107,6 @@ SRCS = InitInput.c \ winwindow.c \ winwndproc.c \ ddraw.h \ - winclipboard.h \ winconfig.h \ win.h \ winglobals.h \ @@ -162,12 +158,15 @@ XWin_DEPENDENCIES = \ $(MULTIWINDOWEXTWM_LIBS) \ $(XWIN_GLX_LIBS) \ $(XWIN_LIBS) \ + $(CLIPBOARD_LIBS) \ $(XSERVER_LIBS) + XWin_LDADD = \ $(MULTIWINDOWEXTWM_LIBS) \ $(XWIN_GLX_LIBS) \ $(XWIN_LIBS) \ + $(CLIPBOARD_LIBS) \ $(XSERVER_LIBS) \ $(XWIN_GLX_SYS_LIBS) \ $(XSERVER_SYS_LIBS) \ @@ -210,5 +209,5 @@ EXTRA_DIST = \ relink: $(AM_V_at)rm -f XWin$(EXEEXT) && $(MAKE) XWin$(EXEEXT) -SUBDIRS = man $(GLX_DIR) . -DIST_SUBDIRS = man glx . +SUBDIRS = man $(GLX_DIR) winclipboard . +DIST_SUBDIRS = man glx winclipboard . diff --git a/hw/xwin/winclipboard/Makefile.am b/hw/xwin/winclipboard/Makefile.am new file mode 100644 index 000000000..91cc11607 --- /dev/null +++ b/hw/xwin/winclipboard/Makefile.am @@ -0,0 +1,15 @@ +noinst_LTLIBRARIES = libXWinclipboard.la + +libXWinclipboard_la_SOURCES = \ + winclipboard.h \ + textconv.c \ + thread.c \ + wndproc.c \ + xevents.c + +libXWinclipboard_la_CFLAGS = -DHAVE_XWIN_CONFIG_H \ + $(DIX_CFLAGS) \ + $(XWINMODULES_CFLAGS) \ + -I$(top_srcdir) -I$(top_srcdir)/miext/rootless -I$(srcdir)/.. + +libXWinclipboard_la_LDFLAGS = -static -no-undefined diff --git a/hw/xwin/winclipboardtextconv.c b/hw/xwin/winclipboard/textconv.c similarity index 100% rename from hw/xwin/winclipboardtextconv.c rename to hw/xwin/winclipboard/textconv.c diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboard/thread.c similarity index 99% rename from hw/xwin/winclipboardthread.c rename to hw/xwin/winclipboard/thread.c index 2641e2099..9ec61f8f5 100644 --- a/hw/xwin/winclipboardthread.c +++ b/hw/xwin/winclipboard/thread.c @@ -265,7 +265,7 @@ winClipboardProc(char *szDisplay) } /* Pre-flush X events */ - /* + /* * NOTE: Apparently you'll freeze if you don't do this, * because there may be events in local data structures * already. diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard/winclipboard.h similarity index 99% rename from hw/xwin/winclipboard.h rename to hw/xwin/winclipboard/winclipboard.h index 41c0a538b..58e35dc75 100644 --- a/hw/xwin/winclipboard.h +++ b/hw/xwin/winclipboard/winclipboard.h @@ -1,5 +1,3 @@ -#ifndef _WINCLIPBOARD_H_ -#define _WINCLIPBOARD_H_ /* *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. * @@ -30,6 +28,9 @@ * Authors: Harold L Hunt II */ +#ifndef _WINCLIPBOARD_H_ +#define _WINCLIPBOARD_H_ + /* Standard library headers */ #include #include diff --git a/hw/xwin/winclipboardwndproc.c b/hw/xwin/winclipboard/wndproc.c similarity index 100% rename from hw/xwin/winclipboardwndproc.c rename to hw/xwin/winclipboard/wndproc.c diff --git a/hw/xwin/winclipboardxevents.c b/hw/xwin/winclipboard/xevents.c similarity index 100% rename from hw/xwin/winclipboardxevents.c rename to hw/xwin/winclipboard/xevents.c diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index d16c121c6..2e400f65b 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -36,7 +36,7 @@ #include #include "os.h" -#include "winclipboard.h" +#include "winclipboard/winclipboard.h" #include "windisplay.h" #define WIN_CLIPBOARD_RETRIES 40 From 30c535219ef2c251d90a1a1d3d07c8a7ec936da9 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 18 Jun 2013 00:32:53 +0100 Subject: [PATCH 14/30] hw/xwin: Return a shutdown flag from winClipboardProc() if we should stop trying Return a shutdown flag from winClipboardProc(), and use it in winClipboardThreadProc() to determine if we should stop. Currently this is set if the clipboard messaging window received a WM_QUIT. Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/thread.c | 14 ++++++++------ hw/xwin/winclipboard/winclipboard.h | 2 +- hw/xwin/winclipboardinit.c | 7 ++++++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index 9ec61f8f5..bbb3a2142 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -56,7 +56,6 @@ */ extern Bool g_fUnicodeClipboard; -extern Bool g_fClipboard; /* * Global variables @@ -85,10 +84,12 @@ static int winClipboardIOErrorHandler(Display * pDisplay); /* - * Main thread function + * Create X11 and Win32 messaging windows, and run message processing loop + * + * returns TRUE if shutdown was signalled to loop, FALSE if some error occurred */ -void * +Bool winClipboardProc(char *szDisplay) { Atom atomClipboard; @@ -108,6 +109,7 @@ winClipboardProc(char *szDisplay) int iRetries; Bool fUseUnicode; int iSelectError; + Bool fShutdown = FALSE; winDebug("winClipboardProc - Hello\n"); @@ -349,8 +351,8 @@ winClipboardProc(char *szDisplay) } winClipboardProc_Exit: - /* disable the clipboard, which means the thread will die */ - g_fClipboard = FALSE; + /* broke out of while loop on a shutdown message */ + fShutdown = TRUE; winClipboardProc_Done: /* Close our Windows window */ @@ -394,7 +396,7 @@ winClipboardProc(char *szDisplay) /* global clipboard variable reset */ g_hwndClipboard = NULL; - return NULL; + return fShutdown; } /* diff --git a/hw/xwin/winclipboard/winclipboard.h b/hw/xwin/winclipboard/winclipboard.h index 58e35dc75..95b18a6e8 100644 --- a/hw/xwin/winclipboard/winclipboard.h +++ b/hw/xwin/winclipboard/winclipboard.h @@ -96,7 +96,7 @@ void * winclipboardthread.c */ -void *winClipboardProc(char *szDisplay); +Bool winClipboardProc(char *szDisplay); void winClipboardWindowDestroy(void); diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index 2e400f65b..25790d044 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -68,6 +68,8 @@ winClipboardThreadProc(void *arg) while (1) { + Bool fShutdown; + ++clipboardRestarts; /* Use our generated cookie for authentication */ @@ -89,11 +91,14 @@ winClipboardThreadProc(void *arg) /* Flag that clipboard client has been launched */ g_fClipboardStarted = TRUE; - winClipboardProc(szDisplay); + fShutdown = winClipboardProc(szDisplay); /* Flag that clipboard client has stopped */ g_fClipboardStarted = FALSE; + if (fShutdown) + break; + /* checking if we need to restart */ if (clipboardRestarts >= WIN_CLIPBOARD_RETRIES) { /* terminates clipboard thread but the main server still lives */ From 126c1cfaa5b5978026d44a1f8b044d367056965b Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 18:27:56 +0100 Subject: [PATCH 15/30] hw/xwin: Separate libwinclipboard interface and internal header files Rename the libwinclipboard internal header from winclipboard.h to internal.h Put libwinclipboard's public interface into winclipboard.h This lets winclipboardinit.c partake of that public interface, and all X server headers without clashes winInitClipboard() prototype belongs in a server header v2: Remove duplicate declaration of winClipboardWindowDestroy() Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/win.h | 3 - hw/xwin/winclipboard/internal.h | 123 ++++++++++++++++++++++ hw/xwin/winclipboard/thread.c | 5 +- hw/xwin/winclipboard/winclipboard.h | 156 ++++++---------------------- hw/xwin/winclipboard/wndproc.c | 5 +- hw/xwin/winclipboard/xevents.c | 2 +- hw/xwin/winclipboardinit.c | 11 +- hw/xwin/winwndproc.c | 3 + 8 files changed, 165 insertions(+), 143 deletions(-) create mode 100644 hw/xwin/winclipboard/internal.h diff --git a/hw/xwin/win.h b/hw/xwin/win.h index 1a882f4aa..7af35e71b 100644 --- a/hw/xwin/win.h +++ b/hw/xwin/win.h @@ -792,9 +792,6 @@ RegionPtr Bool winInitClipboard(void); -void - winFixClipboardChain(void); - void winClipboardShutdown(void); #endif diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h new file mode 100644 index 000000000..89f0c39c7 --- /dev/null +++ b/hw/xwin/winclipboard/internal.h @@ -0,0 +1,123 @@ + +/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifndef WINCLIPBOARD_INTERNAL_H +#define WINCLIPBOARD_INTERNAL_H + +/* Standard library headers */ +#include +#include +#include +#include +#ifdef __CYGWIN__ +#include +#else +#include +#endif +#include +#include +#include + +/* X headers */ +#include +#include +#include +#include + +/* Windows headers */ +#include + +/* Clipboard module constants */ +#ifdef HAS_DEVWINDOWS +#define WIN_MSG_QUEUE_FNAME "/dev/windows" +#endif +#define WIN_JMP_OKAY 0 +#define WIN_JMP_ERROR_IO 2 +#define WIN_LOCAL_PROPERTY "CYGX_CUT_BUFFER" +#define WIN_XEVENTS_SUCCESS 0 +#define WIN_XEVENTS_CONVERT 2 +#define WIN_XEVENTS_NOTIFY 3 + +#define WM_WM_REINIT (WM_USER + 1) + +/* + * References to external symbols + */ + +extern void winDebug(const char *format, ...); +extern void winErrorFVerb(int verb, const char *format, ...); + +/* + * winclipboardtextconv.c + */ + +void + winClipboardDOStoUNIX(char *pszData, int iLength); + +void + winClipboardUNIXtoDOS(char **ppszData, int iLength); + +/* + * winclipboardthread.c + */ + + +/* + * winclipboardwndproc.c + */ + +BOOL winClipboardFlushWindowsMessageQueue(HWND hwnd); + +LRESULT CALLBACK +winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +typedef struct +{ + Display *pClipboardDisplay; + Window iClipboardWindow; +} ClipboardWindowCreationParams; + +/* + * winclipboardxevents.c + */ + +int +winClipboardFlushXEvents(HWND hwnd, + int iWindow, Display * pDisplay, Bool fUnicodeSupport); + + +Atom +winClipboardGetLastOwnedSelectionAtom(void); + +void +winClipboardInitMonitoredSelections(void); + +#endif diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index bbb3a2142..36a1b4e45 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -35,15 +35,18 @@ #else #define HAS_WINSOCK 1 #endif + #include #include -#include "winclipboard.h" #include "windisplay.h" #ifdef __CYGWIN__ #include #endif + #include "misc.h" #include +#include "winclipboard.h" +#include "internal.h" #define WIN_CONNECT_RETRIES 40 #define WIN_CONNECT_DELAY 4 diff --git a/hw/xwin/winclipboard/winclipboard.h b/hw/xwin/winclipboard/winclipboard.h index 95b18a6e8..7aaa341d4 100644 --- a/hw/xwin/winclipboard/winclipboard.h +++ b/hw/xwin/winclipboard/winclipboard.h @@ -1,134 +1,36 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - */ +// +// Copyright © Jon TURNEY 2013 +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice (including the next +// paragraph) shall be included in all copies or substantial portions of the +// Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File: winclipboard.h +// Purpose: public interface to winclipboard library +// -#ifndef _WINCLIPBOARD_H_ -#define _WINCLIPBOARD_H_ - -/* Standard library headers */ -#include -#include -#include -#include -#ifdef __CYGWIN__ -#include -#else -#include -#endif -#include -#include -#include - -/* X headers */ -#include -#include -#include -#include -#include - -/* Windows headers */ -#include - -/* Clipboard module constants */ -#ifdef HAS_DEVWINDOWS -#define WIN_MSG_QUEUE_FNAME "/dev/windows" -#endif -#define WIN_JMP_OKAY 0 -#define WIN_JMP_ERROR_IO 2 -#define WIN_LOCAL_PROPERTY "CYGX_CUT_BUFFER" -#define WIN_XEVENTS_SUCCESS 0 -#define WIN_XEVENTS_CONVERT 2 -#define WIN_XEVENTS_NOTIFY 3 - -#define WM_WM_REINIT (WM_USER + 1) - -/* - * References to external symbols - */ - -extern void winDebug(const char *format, ...); -extern void winErrorFVerb(int verb, const char *format, ...); - -/* - * winclipboardinit.c - */ - -Bool - winInitClipboard(void); - -/* - * winclipboardtextconv.c - */ - -void - winClipboardDOStoUNIX(char *pszData, int iLength); - -void - winClipboardUNIXtoDOS(char **ppszData, int iLength); - -/* - * winclipboardthread.c - */ +#ifndef WINCLIPBOARD_H +#define WINCLIPBOARD_H Bool winClipboardProc(char *szDisplay); -void -winClipboardWindowDestroy(void); +void winFixClipboardChain(void); -/* - * winclipboardwndproc.c - */ - -BOOL winClipboardFlushWindowsMessageQueue(HWND hwnd); - -LRESULT CALLBACK -winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); - -typedef struct -{ - Display *pClipboardDisplay; - Window iClipboardWindow; -} ClipboardWindowCreationParams; - -/* - * winclipboardxevents.c - */ - -int -winClipboardFlushXEvents(HWND hwnd, - int iWindow, Display * pDisplay, Bool fUnicodeSupport); - - -Atom -winClipboardGetLastOwnedSelectionAtom(void); - -void -winClipboardInitMonitoredSelections(void); +void winClipboardWindowDestroy(void); #endif diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c index 459170f2a..769422bbc 100644 --- a/hw/xwin/winclipboard/wndproc.c +++ b/hw/xwin/winclipboard/wndproc.c @@ -33,10 +33,13 @@ #ifdef HAVE_XWIN_CONFIG_H #include #endif + #include #include -#include "winclipboard.h" + +#include "internal.h" #include "misc.h" +#include "winclipboard.h" /* * Constants diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c index a792467f0..3fcf6e3b1 100644 --- a/hw/xwin/winclipboard/xevents.c +++ b/hw/xwin/winclipboard/xevents.c @@ -34,7 +34,7 @@ #include #endif -#include "winclipboard.h" +#include "internal.h" #include "misc.h" #include diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index 25790d044..3324661df 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -35,22 +35,13 @@ #include #include -#include "os.h" +#include "win.h" #include "winclipboard/winclipboard.h" #include "windisplay.h" #define WIN_CLIPBOARD_RETRIES 40 #define WIN_CLIPBOARD_DELAY 1 -extern void winSetAuthorization(void); - -/* - * References to external symbols - */ - -extern Bool g_fClipboard; -extern Bool g_fClipboardStarted; - /* * Local variables */ diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c index bee223de7..e3adb5605 100644 --- a/hw/xwin/winwndproc.c +++ b/hw/xwin/winwndproc.c @@ -42,6 +42,9 @@ #include "winmsg.h" #include "winmonitors.h" #include "inputstr.h" +#ifdef XWIN_CLIPBOARD +#include "winclipboard/winclipboard.h" +#endif /* * Global variables From be61a1fc7e25a380f8d506e13b22017492a71913 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 19:07:05 +0100 Subject: [PATCH 16/30] hw/xwin: Add fUseUnicode as parameter to winClipboardProc() Add fUseUnicode as parameter to winClipboardProc() Access g_fUseUnicode global when calling it Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/thread.c | 16 +--------------- hw/xwin/winclipboard/winclipboard.h | 2 +- hw/xwin/winclipboardinit.c | 2 +- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index 36a1b4e45..a9565fe22 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -54,12 +54,6 @@ #define WIN_CLIPBOARD_WINDOW_CLASS "xwinclip" #define WIN_CLIPBOARD_WINDOW_TITLE "xwinclip" -/* - * References to external symbols - */ - -extern Bool g_fUnicodeClipboard; - /* * Global variables */ @@ -69,7 +63,6 @@ static jmp_buf g_jmpEntry; static XIOErrorHandler g_winClipboardOldIOErrorHandler; static pthread_t g_winClipboardProcThread; -Bool g_fUseUnicode = FALSE; int xfixes_event_base; int xfixes_error_base; @@ -93,7 +86,7 @@ static int */ Bool -winClipboardProc(char *szDisplay) +winClipboardProc(Bool fUseUnicode, char *szDisplay) { Atom atomClipboard; int iReturn; @@ -110,18 +103,11 @@ winClipboardProc(char *szDisplay) Display *pDisplay = NULL; Window iWindow = None; int iRetries; - Bool fUseUnicode; int iSelectError; Bool fShutdown = FALSE; winDebug("winClipboardProc - Hello\n"); - /* Do we use Unicode clipboard? */ - fUseUnicode = g_fUnicodeClipboard; - - /* 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"); diff --git a/hw/xwin/winclipboard/winclipboard.h b/hw/xwin/winclipboard/winclipboard.h index 7aaa341d4..52481301b 100644 --- a/hw/xwin/winclipboard/winclipboard.h +++ b/hw/xwin/winclipboard/winclipboard.h @@ -27,7 +27,7 @@ #ifndef WINCLIPBOARD_H #define WINCLIPBOARD_H -Bool winClipboardProc(char *szDisplay); +Bool winClipboardProc(Bool fUseUnicode, char *szDisplay); void winFixClipboardChain(void); diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index 3324661df..8aef8fe02 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -82,7 +82,7 @@ winClipboardThreadProc(void *arg) /* Flag that clipboard client has been launched */ g_fClipboardStarted = TRUE; - fShutdown = winClipboardProc(szDisplay); + fShutdown = winClipboardProc(g_fUnicodeClipboard, szDisplay); /* Flag that clipboard client has stopped */ g_fClipboardStarted = FALSE; From e1cf2b47bea9ff3e64c0ef1e4d0744d9df4bc1b7 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 19:58:20 +0100 Subject: [PATCH 17/30] hw/xwin: Look up atoms in winClipboardProc() Look up all atoms of interest in clipboard code in winClipboardProc() and pass them down. This avoids the need to check serverGeneration to notice when we need to invalidate cached atom values. Also consistently use cached atom values everywhere, rather than sometimes just doing XInternAtom() again. Remove WIN_LOCAL_PROPERTY as unused now, as we only refer to CYGX_CUT_BUFFER once and do that directly. Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/internal.h | 16 ++++++++++++--- hw/xwin/winclipboard/thread.c | 27 ++++++++++++++----------- hw/xwin/winclipboard/wndproc.c | 35 ++++++++++++++------------------- hw/xwin/winclipboard/xevents.c | 26 ++++++++---------------- 4 files changed, 52 insertions(+), 52 deletions(-) diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h index 89f0c39c7..e31db546c 100644 --- a/hw/xwin/winclipboard/internal.h +++ b/hw/xwin/winclipboard/internal.h @@ -61,7 +61,7 @@ #endif #define WIN_JMP_OKAY 0 #define WIN_JMP_ERROR_IO 2 -#define WIN_LOCAL_PROPERTY "CYGX_CUT_BUFFER" + #define WIN_XEVENTS_SUCCESS 0 #define WIN_XEVENTS_CONVERT 2 #define WIN_XEVENTS_NOTIFY 3 @@ -90,6 +90,15 @@ void */ +typedef struct +{ + Atom atomClipboard; + Atom atomLocalProperty; + Atom atomUTF8String; + Atom atomCompoundText; + Atom atomTargets; +} ClipboardAtoms; + /* * winclipboardwndproc.c */ @@ -103,6 +112,7 @@ typedef struct { Display *pClipboardDisplay; Window iClipboardWindow; + ClipboardAtoms *atoms; } ClipboardWindowCreationParams; /* @@ -111,11 +121,11 @@ typedef struct int winClipboardFlushXEvents(HWND hwnd, - int iWindow, Display * pDisplay, Bool fUnicodeSupport); + int iWindow, Display * pDisplay, Bool fUnicodeSupport, ClipboardAtoms *atom); Atom -winClipboardGetLastOwnedSelectionAtom(void); +winClipboardGetLastOwnedSelectionAtom(ClipboardAtoms *atoms); void winClipboardInitMonitoredSelections(void); diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index a9565fe22..0d64cce21 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -71,7 +71,7 @@ int xfixes_error_base; */ static HWND -winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow); +winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAtoms *atoms); static int winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr); @@ -88,7 +88,7 @@ static int Bool winClipboardProc(Bool fUseUnicode, char *szDisplay) { - Atom atomClipboard; + ClipboardAtoms atoms; int iReturn; HWND hwnd = NULL; int iConnectionNumber = 0; @@ -188,8 +188,12 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) if (!XFixesQueryExtension(pDisplay, &xfixes_event_base, &xfixes_error_base)) ErrorF ("winClipboardProc - XFixes extension not present\n"); - /* Create atom */ - atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False); + /* Create atoms */ + atoms.atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False); + atoms.atomLocalProperty = XInternAtom (pDisplay, "CYGX_CUT_BUFFER", False); + atoms.atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False); + atoms.atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False); + atoms.atomTargets = XInternAtom (pDisplay, "TARGETS", False); /* Create a messaging window */ iWindow = XCreateSimpleWindow(pDisplay, @@ -220,7 +224,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) XFixesSelectSelectionInput (pDisplay, iWindow, - XInternAtom (pDisplay, "CLIPBOARD", False), + atoms.atomClipboard, XFixesSetSelectionOwnerNotifyMask | XFixesSelectionWindowDestroyNotifyMask | XFixesSelectionClientCloseNotifyMask); @@ -229,7 +233,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) /* Initialize monitored selection state */ winClipboardInitMonitoredSelections(); /* Create Windows messaging window */ - hwnd = winClipboardCreateMessagingWindow(pDisplay, iWindow); + hwnd = winClipboardCreateMessagingWindow(pDisplay, iWindow, &atoms); /* Save copy of HWND */ g_hwndClipboard = hwnd; @@ -246,10 +250,10 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) } /* CLIPBOARD */ - iReturn = XSetSelectionOwner(pDisplay, atomClipboard, + iReturn = XSetSelectionOwner(pDisplay, atoms.atomClipboard, iWindow, CurrentTime); if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner(pDisplay, atomClipboard) != iWindow) { + XGetSelectionOwner(pDisplay, atoms.atomClipboard) != iWindow) { ErrorF("winClipboardProc - Could not set CLIPBOARD owner\n"); goto winClipboardProc_Done; } @@ -261,7 +265,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) * because there may be events in local data structures * already. */ - winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode); + winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms); /* Pre-flush Windows messages */ if (!winClipboardFlushWindowsMessageQueue(hwnd)) { @@ -319,7 +323,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) /* Branch on which descriptor became active */ if (FD_ISSET(iConnectionNumber, &fdsRead)) { /* Process X events */ - winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode); + winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms); } #ifdef HAS_DEVWINDOWS @@ -393,7 +397,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) */ static HWND -winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow) +winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAtoms *atoms) { WNDCLASSEX wc; ClipboardWindowCreationParams cwcp; @@ -417,6 +421,7 @@ winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow) /* Information to be passed to WM_CREATE */ cwcp.pClipboardDisplay = pDisplay; cwcp.iClipboardWindow = iWindow; + cwcp.atoms = atoms; /* Create the window */ hwnd = CreateWindowExA(0, /* Extended styles */ diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c index 769422bbc..affedf046 100644 --- a/hw/xwin/winclipboard/wndproc.c +++ b/hw/xwin/winclipboard/wndproc.c @@ -54,7 +54,7 @@ static int winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay, - Bool fUseUnicode, int iTimeoutSec) + Bool fUseUnicode, ClipboardAtoms *atoms, int iTimeoutSec) { int iConnNumber; struct timeval tv; @@ -107,7 +107,7 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay, /* Process X events */ /* Exit when we see that server is shutting down */ iReturn = winClipboardFlushXEvents(hwnd, - iWindow, pDisplay, fUseUnicode); + iWindow, pDisplay, fUseUnicode, atoms); winDebug ("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n", @@ -137,6 +137,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) static Bool s_fCBCInitialized; static Display *pDisplay; static Window iWindow; + static ClipboardAtoms *atoms; /* Branch on message type */ switch (message) { @@ -163,6 +164,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) pDisplay = cwcp->pClipboardDisplay; iWindow = cwcp->iClipboardWindow; + atoms = cwcp->atoms; first = GetClipboardViewer(); /* Get handle to first viewer in chain. */ if (first == hwnd) @@ -243,18 +245,11 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_DRAWCLIPBOARD: { - static Atom atomClipboard; - static int generation; static Bool s_fProcessingDrawClipboard = FALSE; int iReturn; winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n"); - if (generation != serverGeneration) { - generation = serverGeneration; - atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False); - } - /* * We've occasionally seen a loop in the clipboard chain. * Try and fix it on the first hint of recursion. @@ -335,11 +330,11 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) iReturn); /* Release CLIPBOARD selection if owned */ - iReturn = XGetSelectionOwner(pDisplay, atomClipboard); + iReturn = XGetSelectionOwner(pDisplay, atoms->atomClipboard); if (iReturn == iWindow) { winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "CLIPBOARD selection is owned by us.\n"); - XSetSelectionOwner(pDisplay, atomClipboard, None, CurrentTime); + "CLIPBOARD selection is owned by us, releasing\n"); + XSetSelectionOwner(pDisplay, atoms->atomClipboard, None, CurrentTime); } else if (BadWindow == iReturn || BadAtom == iReturn) winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " @@ -368,10 +363,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* Reassert ownership of the CLIPBOARD */ iReturn = XSetSelectionOwner(pDisplay, - atomClipboard, iWindow, CurrentTime); + atoms->atomClipboard, iWindow, CurrentTime); if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner(pDisplay, atomClipboard) != iWindow) { + XGetSelectionOwner(pDisplay, atoms->atomClipboard) != iWindow) { winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " "Could not reassert ownership of CLIPBOARD\n"); } @@ -421,11 +416,9 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* Request the selection contents */ iReturn = XConvertSelection(pDisplay, - winClipboardGetLastOwnedSelectionAtom(), - XInternAtom(pDisplay, - "COMPOUND_TEXT", False), - XInternAtom(pDisplay, - "CYGX_CUT_BUFFER", False), + winClipboardGetLastOwnedSelectionAtom(atoms), + atoms->atomCompoundText, + atoms->atomLocalProperty, iWindow, CurrentTime); if (iReturn == BadAtom || iReturn == BadWindow) { winErrorFVerb(1, "winClipboardWindowProc - WM_RENDER*FORMAT - " @@ -461,7 +454,9 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) iReturn = winProcessXEventsTimeout(hwnd, iWindow, pDisplay, - fConvertToUnicode, WIN_POLL_TIMEOUT); + fConvertToUnicode, + atoms, + WIN_POLL_TIMEOUT); /* * The last call to winProcessXEventsTimeout diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c index 3fcf6e3b1..7275552ce 100644 --- a/hw/xwin/winclipboard/xevents.c +++ b/hw/xwin/winclipboard/xevents.c @@ -62,7 +62,6 @@ static const char *szSelectionNames[CLIP_NUM_SELECTIONS] = { "PRIMARY", "CLIPBOARD" }; static unsigned int lastOwnedSelectionIndex = CLIP_OWN_NONE; -static Atom atomClipboard = None; static void MonitorSelection(XFixesSelectionNotifyEvent * e, unsigned int i) @@ -98,7 +97,7 @@ MonitorSelection(XFixesSelectionNotifyEvent * e, unsigned int i) } Atom -winClipboardGetLastOwnedSelectionAtom(void) +winClipboardGetLastOwnedSelectionAtom(ClipboardAtoms *atoms) { if (lastOwnedSelectionIndex == CLIP_OWN_NONE) return None; @@ -107,7 +106,7 @@ winClipboardGetLastOwnedSelectionAtom(void) return XA_PRIMARY; if (lastOwnedSelectionIndex == CLIP_OWN_CLIPBOARD) - return atomClipboard; + return atoms->atomClipboard; return None; } @@ -129,22 +128,13 @@ winClipboardInitMonitoredSelections(void) int winClipboardFlushXEvents(HWND hwnd, - int iWindow, Display * pDisplay, Bool fUseUnicode) + int iWindow, Display * pDisplay, Bool fUseUnicode, ClipboardAtoms *atoms) { - static Atom atomLocalProperty; - static Atom atomCompoundText; - static Atom atomUTF8String; - static Atom atomTargets; - static int generation; - - if (generation != serverGeneration) { - generation = serverGeneration; - atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False); - atomLocalProperty = XInternAtom(pDisplay, WIN_LOCAL_PROPERTY, False); - atomUTF8String = XInternAtom(pDisplay, "UTF8_STRING", False); - atomCompoundText = XInternAtom(pDisplay, "COMPOUND_TEXT", False); - atomTargets = XInternAtom(pDisplay, "TARGETS", False); - } + Atom atomClipboard = atoms->atomClipboard; + Atom atomLocalProperty = atoms->atomLocalProperty; + Atom atomUTF8String = atoms->atomUTF8String; + Atom atomCompoundText = atoms->atomCompoundText; + Atom atomTargets = atoms->atomTargets; /* Process all pending events */ while (XPending(pDisplay)) { From 5ae674ae6d6c0b02fd86c5e7b23b8c38b19f180a Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 20:03:04 +0100 Subject: [PATCH 18/30] hw/xwin: Changes in error logging to make libwinclipboard more useful as a library Consistently use ErrorF() rather than winErrorFVerb() Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/wndproc.c | 51 +++++++++++++++++----------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c index affedf046..28e7ade86 100644 --- a/hw/xwin/winclipboard/wndproc.c +++ b/hw/xwin/winclipboard/wndproc.c @@ -189,8 +189,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) s_hwndNextViewer = (HWND) lParam; if (s_hwndNextViewer == hwnd) { s_hwndNextViewer = NULL; - winErrorFVerb(1, "winClipboardWindowProc - WM_CHANGECBCHAIN: " - "attempted to set next window to ourselves."); + ErrorF("winClipboardWindowProc - WM_CHANGECBCHAIN: " + "attempted to set next window to ourselves."); } } else if (s_hwndNextViewer) @@ -262,8 +262,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) s_fCBCInitialized = FALSE; ChangeClipboardChain(hwnd, s_hwndNextViewer); winFixClipboardChain(); - winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "Nested calls detected. Re-initing.\n"); + ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "Nested calls detected. Re-initing.\n"); winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); s_fProcessingDrawClipboard = FALSE; return 0; @@ -325,9 +325,9 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) XSetSelectionOwner(pDisplay, XA_PRIMARY, None, CurrentTime); } else if (BadWindow == iReturn || BadAtom == iReturn) - winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "XGetSelection failed for PRIMARY: %d\n", - iReturn); + ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "XGetSelectionOwner failed for PRIMARY: %d\n", + iReturn); /* Release CLIPBOARD selection if owned */ iReturn = XGetSelectionOwner(pDisplay, atoms->atomClipboard); @@ -337,9 +337,9 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) XSetSelectionOwner(pDisplay, atoms->atomClipboard, None, CurrentTime); } else if (BadWindow == iReturn || BadAtom == iReturn) - winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "XGetSelection failed for CLIPBOARD: %d\n", - iReturn); + ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "XGetSelectionOwner failed for CLIPBOARD: %d\n", + iReturn); winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); s_fProcessingDrawClipboard = FALSE; @@ -353,8 +353,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) XA_PRIMARY, iWindow, CurrentTime); if (iReturn == BadAtom || iReturn == BadWindow || XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) { - winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "Could not reassert ownership of PRIMARY\n"); + ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "Could not reassert ownership of PRIMARY\n"); } else { winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - " @@ -367,8 +367,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (iReturn == BadAtom || iReturn == BadWindow || XGetSelectionOwner(pDisplay, atoms->atomClipboard) != iWindow) { - winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "Could not reassert ownership of CLIPBOARD\n"); + ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "Could not reassert ownership of CLIPBOARD\n"); } else { winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - " @@ -421,8 +421,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) atoms->atomLocalProperty, iWindow, CurrentTime); if (iReturn == BadAtom || iReturn == BadWindow) { - winErrorFVerb(1, "winClipboardWindowProc - WM_RENDER*FORMAT - " - "XConvertSelection () failed\n"); + ErrorF("winClipboardWindowProc - WM_RENDER*FORMAT - " + "XConvertSelection () failed\n"); break; } @@ -436,16 +436,16 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } if (!OpenClipboard(hwnd)) { - winErrorFVerb(1, "winClipboardWindowProc - WM_RENDER*FORMATS - " - "OpenClipboard () failed: %08x\n", - GetLastError()); + ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - " + "OpenClipboard () failed: %08x\n", + GetLastError()); break; } if (!EmptyClipboard()) { - winErrorFVerb(1, "winClipboardWindowProc - WM_RENDER*FORMATS - " - "EmptyClipboard () failed: %08x\n", - GetLastError()); + ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - " + "EmptyClipboard () failed: %08x\n", + GetLastError()); break; } } @@ -479,10 +479,9 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* We must close the clipboard */ if (!CloseClipboard()) { - winErrorFVerb(1, - "winClipboardWindowProc - WM_RENDERALLFORMATS - " - "CloseClipboard () failed: %08x\n", - GetLastError()); + ErrorF("winClipboardWindowProc - WM_RENDERALLFORMATS - " + "CloseClipboard () failed: %08x\n", + GetLastError()); break; } } From 5992550c4cf8818d1c47c1e474c3d8c3383983fa Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 17 Jun 2013 19:01:19 +0100 Subject: [PATCH 19/30] hw/xwin: Add xwinclip test client Add xwinclip test client, which includes stubs for winDebug(), ErrorF() Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/Makefile.am | 8 +++ hw/xwin/winclipboard/debug.c | 52 ++++++++++++++ hw/xwin/winclipboard/xwinclip.c | 118 +++++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 hw/xwin/winclipboard/debug.c create mode 100644 hw/xwin/winclipboard/xwinclip.c diff --git a/hw/xwin/winclipboard/Makefile.am b/hw/xwin/winclipboard/Makefile.am index 91cc11607..b52e0e701 100644 --- a/hw/xwin/winclipboard/Makefile.am +++ b/hw/xwin/winclipboard/Makefile.am @@ -13,3 +13,11 @@ libXWinclipboard_la_CFLAGS = -DHAVE_XWIN_CONFIG_H \ -I$(top_srcdir) -I$(top_srcdir)/miext/rootless -I$(srcdir)/.. libXWinclipboard_la_LDFLAGS = -static -no-undefined + +bin_PROGRAMS = xwinclip + +xwinclip_SOURCES = xwinclip.c debug.c + +xwinclip_CFLAGS = $(XWINMODULES_CFLAGS) + +xwinclip_LDADD = libXWinclipboard.la $(XWINMODULES_LIBS) -lgdi32 diff --git a/hw/xwin/winclipboard/debug.c b/hw/xwin/winclipboard/debug.c new file mode 100644 index 000000000..78ab6d902 --- /dev/null +++ b/hw/xwin/winclipboard/debug.c @@ -0,0 +1,52 @@ +// +// Copyright © Jon TURNEY 2013 +// +// This file is part of xwinclip. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice (including the next +// paragraph) shall be included in all copies or substantial portions of the +// Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + +#include +#include + +#if 1 +int +winDebug(const char *format, ...) +{ + int count; + va_list ap; + va_start(ap, format); + count = fprintf(stderr, "xwinclip: "); + count += vfprintf(stderr, format, ap); + va_end(ap); + return count; +} +#endif + +int +ErrorF(const char *format, ...) +{ + int count; + va_list ap; + va_start(ap, format); + count = vfprintf(stderr, format, ap); + va_end(ap); + return count; +} diff --git a/hw/xwin/winclipboard/xwinclip.c b/hw/xwin/winclipboard/xwinclip.c new file mode 100644 index 000000000..7b4577036 --- /dev/null +++ b/hw/xwin/winclipboard/xwinclip.c @@ -0,0 +1,118 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + *Copyright (C) Colin Harrison 2005-2008 + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the copyright holder(s) + *and author(s) shall not be used in advertising or otherwise to promote + *the sale, use or other dealings in this Software without prior written + *authorization from the copyright holder(s) and author(s). + * + * Authors: Harold L Hunt II + * Colin Harrison + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif + +#include +#include +#include + +/* X headers */ +#include +#ifdef X_LOCALE +#include +#else /* X_LOCALE */ +#include +#endif /* X_LOCALE */ + +#include "winclipboard.h" + +/* + * Main function + */ + +int +main (int argc, char *argv[]) +{ + int i; + char *pszDisplay = NULL; + int fUnicodeClipboard = 1; + + /* Parse command-line parameters */ + for (i = 1; i < argc; ++i) + { + /* Look for -display "display_name" or --display "display_name" */ + if (i < argc - 1 + && (!strcmp (argv[i], "-display") + || !strcmp (argv[i], "--display"))) + { + /* Grab a pointer to the display parameter */ + pszDisplay = argv[i + 1]; + + /* Skip the display argument */ + i++; + continue; + } + + /* Look for -nounicodeclipboard */ + if (!strcmp (argv[i], "-nounicodeclipboard")) + { + fUnicodeClipboard = 0; + continue; + } + + /* Yack when we find a parameter that we don't know about */ + printf ("Unknown parameter: %s\nExiting.\n", argv[i]); + exit (1); + } + + /* Do we have Unicode support? */ + if (fUnicodeClipboard) + { + printf ("Unicode clipboard I/O\n"); + } + else + { + printf ("Non Unicode clipboard I/O\n"); + } + + /* Apply locale specified in the LANG environment variable */ + if (!setlocale (LC_ALL, "")) + { + printf ("setlocale() error\n"); + exit (1); + } + + /* See if X supports the current locale */ + if (XSupportsLocale () == False) + { + printf ("Locale not supported by X, falling back to 'C' locale.\n"); + setlocale(LC_ALL, "C"); + } + + winClipboardProc(fUnicodeClipboard, pszDisplay); + + return 0; +} From 52f3cf3c612b2f33e39fd6f985b840a0d7192a50 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Wed, 19 Jun 2013 18:09:07 +0100 Subject: [PATCH 20/30] hw/xwin: Remove standard includes from internal.h and add them where needed Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/internal.h | 14 -------------- hw/xwin/winclipboard/thread.c | 13 +++++++++---- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h index e31db546c..0f9a656c1 100644 --- a/hw/xwin/winclipboard/internal.h +++ b/hw/xwin/winclipboard/internal.h @@ -32,20 +32,6 @@ #ifndef WINCLIPBOARD_INTERNAL_H #define WINCLIPBOARD_INTERNAL_H -/* Standard library headers */ -#include -#include -#include -#include -#ifdef __CYGWIN__ -#include -#else -#include -#endif -#include -#include -#include - /* X headers */ #include #include diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index 0d64cce21..ea0ef42a8 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -36,10 +36,15 @@ #define HAS_WINSOCK 1 #endif -#include -#include -#include "windisplay.h" -#ifdef __CYGWIN__ +#include +#include +#include +#include +#include + +#ifdef HAS_WINSOCK +#include +#else #include #endif From cbe133752d1e817246b532a274fda3f7d74ebca1 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Thu, 20 Jun 2013 12:50:18 +0100 Subject: [PATCH 21/30] hw/xwin: Remove unused X includes from internal.h and add them where needed Also removing server headers we might clash with and no longer need. Make a few adjustments to allow for this change: - provide a prototype of ErrorF() - use the MAX() macro provided by sys/param.h, not the max() macro provided by misc.h - use the X 'Bool' type rather than the unwrapped Windows 'BOOL' type Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/internal.h | 9 +++------ hw/xwin/winclipboard/thread.c | 5 +++-- hw/xwin/winclipboard/wndproc.c | 5 +++-- hw/xwin/winclipboard/xevents.c | 3 ++- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h index 0f9a656c1..e51712319 100644 --- a/hw/xwin/winclipboard/internal.h +++ b/hw/xwin/winclipboard/internal.h @@ -33,10 +33,7 @@ #define WINCLIPBOARD_INTERNAL_H /* X headers */ -#include -#include -#include -#include +#include /* Windows headers */ #include @@ -59,7 +56,7 @@ */ extern void winDebug(const char *format, ...); -extern void winErrorFVerb(int verb, const char *format, ...); +extern void ErrorF(const char *format, ...); /* * winclipboardtextconv.c @@ -89,7 +86,7 @@ typedef struct * winclipboardwndproc.c */ -BOOL winClipboardFlushWindowsMessageQueue(HWND hwnd); +Bool winClipboardFlushWindowsMessageQueue(HWND hwnd); LRESULT CALLBACK winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index ea0ef42a8..289bbb333 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -41,6 +41,7 @@ #include #include #include +#include // for MAX() macro #ifdef HAS_WINSOCK #include @@ -48,7 +49,7 @@ #include #endif -#include "misc.h" +#include #include #include "winclipboard.h" #include "internal.h" @@ -185,7 +186,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) } /* Find max of our file descriptors */ - iMaxDescriptor = max(fdMessageQueue, iConnectionNumber) + 1; + iMaxDescriptor = MAX(fdMessageQueue, iConnectionNumber) + 1; #else iMaxDescriptor = iConnectionNumber + 1; #endif diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c index 28e7ade86..fa84894b1 100644 --- a/hw/xwin/winclipboard/wndproc.c +++ b/hw/xwin/winclipboard/wndproc.c @@ -37,8 +37,9 @@ #include #include +#include + #include "internal.h" -#include "misc.h" #include "winclipboard.h" /* @@ -499,7 +500,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) * Process any pending Windows messages */ -BOOL +Bool winClipboardFlushWindowsMessageQueue(HWND hwnd) { MSG msg; diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c index 7275552ce..d1e7df43d 100644 --- a/hw/xwin/winclipboard/xevents.c +++ b/hw/xwin/winclipboard/xevents.c @@ -35,7 +35,8 @@ #endif #include "internal.h" -#include "misc.h" +#include +#include #include /* From fa0da5a020c2ea9366568375b7f35d3f2ddad680 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Thu, 20 Jun 2013 13:04:35 +0100 Subject: [PATCH 22/30] hw/xwin: Use header for prototypes in textconv.c Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/textconv.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/hw/xwin/winclipboard/textconv.c b/hw/xwin/winclipboard/textconv.c index fd405a02e..4262d98b9 100644 --- a/hw/xwin/winclipboard/textconv.c +++ b/hw/xwin/winclipboard/textconv.c @@ -31,14 +31,8 @@ #ifdef HAVE_XWIN_CONFIG_H #include #endif -#include "win.h" -#include #include - -void - winClipboardDOStoUNIX(char *pszSrc, int iLength); -void - winClipboardUNIXtoDOS(char **ppszData, int iLength); +#include "internal.h" /* * Convert \r\n to \n From d0353bbe57aab910a6ef7da8778023a9d39c37df Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Thu, 20 Jun 2013 00:04:16 +0100 Subject: [PATCH 23/30] hw/xwin: Move WIN_MSG_QUEUE_FNAME to where it's used Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/internal.h | 5 ----- hw/xwin/winclipboard/thread.c | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h index e51712319..34563e170 100644 --- a/hw/xwin/winclipboard/internal.h +++ b/hw/xwin/winclipboard/internal.h @@ -38,13 +38,8 @@ /* Windows headers */ #include -/* Clipboard module constants */ -#ifdef HAS_DEVWINDOWS -#define WIN_MSG_QUEUE_FNAME "/dev/windows" -#endif #define WIN_JMP_OKAY 0 #define WIN_JMP_ERROR_IO 2 - #define WIN_XEVENTS_SUCCESS 0 #define WIN_XEVENTS_CONVERT 2 #define WIN_XEVENTS_NOTIFY 3 diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index 289bbb333..72d56d5e1 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -59,6 +59,9 @@ #define WIN_CLIPBOARD_WINDOW_CLASS "xwinclip" #define WIN_CLIPBOARD_WINDOW_TITLE "xwinclip" +#ifdef HAS_DEVWINDOWS +#define WIN_MSG_QUEUE_FNAME "/dev/windows" +#endif /* * Global variables From 89eb7bdcad092821b61a48832e1db82975a2252b Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Wed, 19 Jun 2013 13:59:40 +0100 Subject: [PATCH 24/30] hw/xwin: Remove setjmp()/longjmp() error constants Check specially that setjmp() returned a value which we don't pass to longjmp() seems a bit over-complex. Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/internal.h | 2 -- hw/xwin/winclipboard/thread.c | 13 ++----------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h index 34563e170..4b3531ad6 100644 --- a/hw/xwin/winclipboard/internal.h +++ b/hw/xwin/winclipboard/internal.h @@ -38,8 +38,6 @@ /* Windows headers */ #include -#define WIN_JMP_OKAY 0 -#define WIN_JMP_ERROR_IO 2 #define WIN_XEVENTS_SUCCESS 0 #define WIN_XEVENTS_CONVERT 2 #define WIN_XEVENTS_NOTIFY 3 diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index 72d56d5e1..8f0ede5c8 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -135,16 +135,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) XSetIOErrorHandler(winClipboardIOErrorHandler); /* Set jump point for Error exits */ - 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 winClipboardProc_Exit; - } - else if (iReturn == WIN_JMP_ERROR_IO) { - /* TODO: Cleanup the Win32 window and free any allocated memory */ + if (setjmp(g_jmpEntry)) { ErrorF("winClipboardProc - setjmp returned for IO Error Handler.\n"); goto winClipboardProc_Done; } @@ -483,7 +474,7 @@ winClipboardIOErrorHandler(Display * pDisplay) if (pthread_equal(pthread_self(), g_winClipboardProcThread)) { /* Restart at the main entry point */ - longjmp(g_jmpEntry, WIN_JMP_ERROR_IO); + longjmp(g_jmpEntry, 2); } if (g_winClipboardOldIOErrorHandler) From 4fc62aef8079266f8878cb355e6eb894000d8b8b Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Wed, 19 Jun 2013 14:00:28 +0100 Subject: [PATCH 25/30] hw/xwin: Improve comment about why we can't XCloseDisplay() Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/thread.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index 8f0ede5c8..53e28c47a 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -370,8 +370,11 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) #if 0 /* - * FIXME: XCloseDisplay hangs if we call it, as of 2004/03/26. The - * XSync and XSelectInput calls did not help. + * FIXME: XCloseDisplay hangs if we call it + * + * XCloseDisplay() calls XSync(), so any outstanding errors are reported. + * If we are built into the server, this can deadlock if the server is + * in the process of exiting and waiting for this thread to exit. */ /* Discard any remaining events */ From 4a38c3bda2b0a868d7611f9423d8a0f304b435aa Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 18 Jun 2013 19:18:08 +0100 Subject: [PATCH 26/30] hw/xwin: Remove XOpenDisplay() retry code Remove XOpenDisplay() retry code. This isn't a sensible thing for the application to be doing, and XWin server needs to retry much more than just XOpenDisplay(). Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/thread.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index 53e28c47a..31986f6a0 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -111,7 +111,6 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) int iMaxDescriptor; Display *pDisplay = NULL; Window iWindow = None; - int iRetries; int iSelectError; Bool fShutdown = FALSE; @@ -140,26 +139,8 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) goto winClipboardProc_Done; } - /* Initialize retry count */ - iRetries = 0; - - - /* Open the X display */ - do { - pDisplay = XOpenDisplay(szDisplay); - if (pDisplay == NULL) { - ErrorF("winClipboardProc - Could not open display, " - "try: %d, sleeping: %d\n", iRetries + 1, WIN_CONNECT_DELAY); - ++iRetries; - sleep(WIN_CONNECT_DELAY); - continue; - } - else - break; - } - while (pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); - /* Make sure that the display opened */ + pDisplay = XOpenDisplay(szDisplay); if (pDisplay == NULL) { ErrorF("winClipboardProc - Failed opening the display, giving up\n"); goto winClipboardProc_Done; From 492c924c8531b013d50637e29213da287b9a7fa2 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 18 Jun 2013 19:28:53 +0100 Subject: [PATCH 27/30] hw/xwin: In clipboard function prototypes, use Window type, not int type Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/internal.h | 2 +- hw/xwin/winclipboard/wndproc.c | 2 +- hw/xwin/winclipboard/xevents.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h index 4b3531ad6..94956f80d 100644 --- a/hw/xwin/winclipboard/internal.h +++ b/hw/xwin/winclipboard/internal.h @@ -97,7 +97,7 @@ typedef struct int winClipboardFlushXEvents(HWND hwnd, - int iWindow, Display * pDisplay, Bool fUnicodeSupport, ClipboardAtoms *atom); + Window iWindow, Display * pDisplay, Bool fUnicodeSupport, ClipboardAtoms *atom); Atom diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c index fa84894b1..973f9484e 100644 --- a/hw/xwin/winclipboard/wndproc.c +++ b/hw/xwin/winclipboard/wndproc.c @@ -54,7 +54,7 @@ */ static int -winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay, +winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay, Bool fUseUnicode, ClipboardAtoms *atoms, int iTimeoutSec) { int iConnNumber; diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c index d1e7df43d..8a75bc461 100644 --- a/hw/xwin/winclipboard/xevents.c +++ b/hw/xwin/winclipboard/xevents.c @@ -129,7 +129,7 @@ winClipboardInitMonitoredSelections(void) int winClipboardFlushXEvents(HWND hwnd, - int iWindow, Display * pDisplay, Bool fUseUnicode, ClipboardAtoms *atoms) + Window iWindow, Display * pDisplay, Bool fUseUnicode, ClipboardAtoms *atoms) { Atom atomClipboard = atoms->atomClipboard; Atom atomLocalProperty = atoms->atomLocalProperty; From 5819a02d461349dbfc86317c742406d2217f7f0c Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 18 Jun 2013 19:35:20 +0100 Subject: [PATCH 28/30] hw/xwin: Add a basic manpage for xwinclip Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/Makefile.am | 3 ++ hw/xwin/winclipboard/xwinclip.man | 61 +++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 hw/xwin/winclipboard/xwinclip.man diff --git a/hw/xwin/winclipboard/Makefile.am b/hw/xwin/winclipboard/Makefile.am index b52e0e701..614e7ec9e 100644 --- a/hw/xwin/winclipboard/Makefile.am +++ b/hw/xwin/winclipboard/Makefile.am @@ -21,3 +21,6 @@ xwinclip_SOURCES = xwinclip.c debug.c xwinclip_CFLAGS = $(XWINMODULES_CFLAGS) xwinclip_LDADD = libXWinclipboard.la $(XWINMODULES_LIBS) -lgdi32 + +include $(top_srcdir)/manpages.am +appman_PRE = xwinclip.man diff --git a/hw/xwin/winclipboard/xwinclip.man b/hw/xwin/winclipboard/xwinclip.man new file mode 100644 index 000000000..822db91d4 --- /dev/null +++ b/hw/xwin/winclipboard/xwinclip.man @@ -0,0 +1,61 @@ +.TH xwinclip 1 __xorgversion__ +.SH NAME +xwinclip - An X11 and Windows clipboard integration tool + +.SH SYNOPSIS +.B xwinclip [OPTION]... + +.SH DESCRIPTION +\fIxwinclip\fP is a tool for copying and pasting text between the Windows and X11 clipboard systems. + +\fIxwinclip\fP watches for updates to either clipboard and copies data between them when either one is updated. + +\fIxwinclip\fP monitors the X PRIMARY and CLIBPOARD selections for changes in ownership, and makes +the contents of the most recent one to change available to paste from the Windows clipboard. + +It also monitors the contents of the Windows clipboard for changes, taking ownership of the PRIMARY and +CLIPBOARD selections, and making the contents of the Windows clipboard available in them. + +.B Note well: +The \fIXWin(1)\fP X server has internal clipboard integration that is enabled by default. +Do \fINOT\fP run \fIxwinclip\fP unless \fIXWin(1)\fP has been started with the -noclipboard option. + +.SH OPTIONS +\fIxwinclip\fP accepts the following optional command line switches: + +.TP 8 +.B \-display [display] +Specifies the X server display to connect to. +.TP 8 +.B \-nounicodeclipboard +Do not use unicode text on the clipboard. + +.SH "SEE ALSO" +XWin(1) + +.SH BUGS +Only text clipboard contents are supported. + +The INCR (Incrememntal transfer) clipboard protocol for clipboard contents larger than the maximum size of an +X request is not supported. + +Some X clients, notably ones written in Tcl/Tk, do not re-assert ownership of the PRIMARY selection or update +it's timestamp when it's contents change, which currently prevents \fIxwinclip\fP from correctly noticing that +the PRIMARY selection's contents have changed. + +Windows clipboard rendering is synchronous in the WM_RENDER*FORMAT message (that is, we must have placed the +contents onto the clipboard by the time we return from processing this message), but we must wait for the X +client which owns the selection to convert the selection to our requested format. This is currently achieved +using a fixed timeout of one second. + +The XWin(1) server should indicate somehow (by placing an atom on the root window?) that it is running with it's +internal clipboard integration enabled, and xwinclip should notice this and exit with an appropriate error. + +Probably many other bugs. + +.SH "CONFORMING TO" +ICCCM (Inter-Client Communication Conventions Manual) 2.0 + +.SH AUTHORS +Contributors to xwinclip include Benjamin Riefenstahl, Roland Cassard, Brian Genisio, Colin Harrison, +Harold L Hunt II, Matsuzaki Kensuke, Jon Turney, Chris Twiner and Jeremy Wilkins. From 7ca93301940647219dbed2d14fcd3f37e49fb477 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 18 Jun 2013 19:53:52 +0100 Subject: [PATCH 29/30] hw/xwin: Only add to XSetIOErrorHandler() handler chain once Only use XSetIOErrorHandler() to add to the global XSetIOErrorHandler() chain once. If we do it every restart, then we make a loop in the handler chain, and we end up with a thread spinning in that loop when the server shuts down... Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/thread.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index 31986f6a0..a124e3e90 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -113,6 +113,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) Window iWindow = None; int iSelectError; Bool fShutdown = FALSE; + static Bool fErrorHandlerSet = FALSE; winDebug("winClipboardProc - Hello\n"); @@ -127,11 +128,15 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay) ErrorF("winClipboardProc - Warning: Locale not supported by X.\n"); } - /* Set error handler */ - XSetErrorHandler(winClipboardErrorHandler); g_winClipboardProcThread = pthread_self(); - g_winClipboardOldIOErrorHandler = - XSetIOErrorHandler(winClipboardIOErrorHandler); + + /* Set error handler */ + if (!fErrorHandlerSet) { + XSetErrorHandler(winClipboardErrorHandler); + g_winClipboardOldIOErrorHandler = + XSetIOErrorHandler(winClipboardIOErrorHandler); + fErrorHandlerSet = TRUE; + } /* Set jump point for Error exits */ if (setjmp(g_jmpEntry)) { From 1d6334dd0ca99923b6b55c5c047ef6b5c325f66c Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Wed, 19 Jun 2013 13:09:35 +0100 Subject: [PATCH 30/30] hw/xwin: Undefine _XSERVER64 in hw/xwin/winclipboard Including any server header might define the macro _XSERVER64 on 64 bit machines. That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen. So let's undef that macro if necessary. Remove server directories from include path to ensure no server includes are included Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison --- hw/xwin/winclipboard/Makefile.am | 3 +-- hw/xwin/winclipboard/textconv.c | 10 ++++++++++ hw/xwin/winclipboard/thread.c | 9 +++++++++ hw/xwin/winclipboard/wndproc.c | 9 +++++++++ hw/xwin/winclipboard/xevents.c | 9 +++++++++ hw/xwin/winclipboard/xwinclip.c | 9 +++++++++ 6 files changed, 47 insertions(+), 2 deletions(-) diff --git a/hw/xwin/winclipboard/Makefile.am b/hw/xwin/winclipboard/Makefile.am index 614e7ec9e..b1c95f4ef 100644 --- a/hw/xwin/winclipboard/Makefile.am +++ b/hw/xwin/winclipboard/Makefile.am @@ -9,8 +9,7 @@ libXWinclipboard_la_SOURCES = \ libXWinclipboard_la_CFLAGS = -DHAVE_XWIN_CONFIG_H \ $(DIX_CFLAGS) \ - $(XWINMODULES_CFLAGS) \ - -I$(top_srcdir) -I$(top_srcdir)/miext/rootless -I$(srcdir)/.. + $(XWINMODULES_CFLAGS) libXWinclipboard_la_LDFLAGS = -static -no-undefined diff --git a/hw/xwin/winclipboard/textconv.c b/hw/xwin/winclipboard/textconv.c index 4262d98b9..9c9cb3529 100644 --- a/hw/xwin/winclipboard/textconv.c +++ b/hw/xwin/winclipboard/textconv.c @@ -31,6 +31,16 @@ #ifdef HAVE_XWIN_CONFIG_H #include #endif + +/* + * Including any server header might define the macro _XSERVER64 on 64 bit machines. + * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen. + * So let's undef that macro if necessary. + */ +#ifdef _XSERVER64 +#undef _XSERVER64 +#endif + #include #include "internal.h" diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c index a124e3e90..c179e3f83 100644 --- a/hw/xwin/winclipboard/thread.c +++ b/hw/xwin/winclipboard/thread.c @@ -36,6 +36,15 @@ #define HAS_WINSOCK 1 #endif +/* + * Including any server header might define the macro _XSERVER64 on 64 bit machines. + * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen. + * So let's undef that macro if necessary. + */ +#ifdef _XSERVER64 +#undef _XSERVER64 +#endif + #include #include #include diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c index 973f9484e..165ff558a 100644 --- a/hw/xwin/winclipboard/wndproc.c +++ b/hw/xwin/winclipboard/wndproc.c @@ -34,6 +34,15 @@ #include #endif +/* + * Including any server header might define the macro _XSERVER64 on 64 bit machines. + * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen. + * So let's undef that macro if necessary. + */ +#ifdef _XSERVER64 +#undef _XSERVER64 +#endif + #include #include diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c index 8a75bc461..d0077b846 100644 --- a/hw/xwin/winclipboard/xevents.c +++ b/hw/xwin/winclipboard/xevents.c @@ -34,6 +34,15 @@ #include #endif +/* + * Including any server header might define the macro _XSERVER64 on 64 bit machines. + * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen. + * So let's undef that macro if necessary. + */ +#ifdef _XSERVER64 +#undef _XSERVER64 +#endif + #include "internal.h" #include #include diff --git a/hw/xwin/winclipboard/xwinclip.c b/hw/xwin/winclipboard/xwinclip.c index 7b4577036..3677974c4 100644 --- a/hw/xwin/winclipboard/xwinclip.c +++ b/hw/xwin/winclipboard/xwinclip.c @@ -35,6 +35,15 @@ #include #endif +/* + * Including any server header might define the macro _XSERVER64 on 64 bit machines. + * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen. + * So let's undef that macro if necessary. + */ +#ifdef _XSERVER64 +#undef _XSERVER64 +#endif + #include #include #include