xserver: Branch 'master' - 9 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Apr 15 15:00:16 UTC 2020


 .appveyor.yml                       |    2 
 configure.ac                        |    2 
 hw/xwin/InitOutput.c                |   13 
 hw/xwin/man/XWin.man                |    3 
 hw/xwin/meson.build                 |    1 
 hw/xwin/win.h                       |    8 
 hw/xwin/winauth.c                   |   29 -
 hw/xwin/winauth.h                   |   26 +
 hw/xwin/winclipboard/internal.h     |   46 -
 hw/xwin/winclipboard/meson.build    |    7 
 hw/xwin/winclipboard/textconv.c     |    9 
 hw/xwin/winclipboard/thread.c       |  286 ++++-------
 hw/xwin/winclipboard/winclipboard.h |    7 
 hw/xwin/winclipboard/wndproc.c      |  331 +++---------
 hw/xwin/winclipboard/xevents.c      |  930 +++++++++++++++++-------------------
 hw/xwin/winclipboard/xwinclip.c     |   53 --
 hw/xwin/winclipboard/xwinclip.man   |   10 
 hw/xwin/winclipboardinit.c          |   10 
 hw/xwin/winglobals.c                |    1 
 hw/xwin/winglobals.h                |    1 
 hw/xwin/winmultiwindowicons.c       |    3 
 hw/xwin/winmultiwindowicons.h       |    2 
 hw/xwin/winmultiwindowwm.c          |    4 
 hw/xwin/winprocarg.c                |    9 
 hw/xwin/winwndproc.c                |    3 
 25 files changed, 716 insertions(+), 1080 deletions(-)

New commits:
commit 2fe13a1f448ff27925f92a557f145bab9ab91a0e
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Fri Feb 11 16:10:36 2011 +0000

    hw/xwin: Drop call to setlocale()
    
    Since we now only work with UTF-8 (or ISO8859-1) text in the clipboard,
    we don't need to setlocale().

diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index d04b47cdc..9f4a2f807 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -35,7 +35,6 @@ from The Open Group.
 #include "winmsg.h"
 #include "winconfig.h"
 #include "winprefs.h"
-#include "X11/Xlocale.h"
 #ifdef DPMSExtension
 #include "dpmsproc.h"
 #endif
@@ -1018,14 +1017,6 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
     if (g_fXdmcpEnabled || g_fAuthEnabled)
         winGenerateAuthorization();
 
-    /* Perform some one time initialization */
-    if (1 == serverGeneration) {
-        /*
-         * setlocale applies to all threads in the current process.
-         * Apply locale specified in LANG environment variable.
-         */
-        setlocale(LC_ALL, "");
-    }
 
 #if CYGDEBUG || YES
     winDebug("InitOutput - Returning.\n");
commit f269e01e1a783227c88b395cf6f55dcadeb751c9
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Mon Jul 2 17:25:53 2018 +0100

    hw/xwin: Consistently use BOOL type from Xmd.h
    
    This avoids including Xdefs.h, which means we avoid all the issues with
    _XSERVER64 effecting how types are defined by that.

diff --git a/hw/xwin/winauth.c b/hw/xwin/winauth.c
index 8d3bcb447..4e1b26d13 100644
--- a/hw/xwin/winauth.c
+++ b/hw/xwin/winauth.c
@@ -77,7 +77,7 @@ GenerateAuthorization(unsigned name_length,
  * Generate authorization cookie for internal server clients
  */
 
-Bool
+BOOL
 winGenerateAuthorization(void)
 {
 #ifdef XCSECURITY
diff --git a/hw/xwin/winauth.h b/hw/xwin/winauth.h
index 68d3ac0cb..97cfe52a1 100644
--- a/hw/xwin/winauth.h
+++ b/hw/xwin/winauth.h
@@ -20,7 +20,7 @@
  */
 
 #include <xcb/xcb.h>
-#include <X11/Xdefs.h> // for Bool
+#include <X11/Xmd.h> // for BOOL
 
-Bool winGenerateAuthorization(void);
+BOOL winGenerateAuthorization(void);
 xcb_auth_info_t * winGetXcbAuthInfo(void);
diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h
index bb862a258..368fa7057 100644
--- a/hw/xwin/winclipboard/internal.h
+++ b/hw/xwin/winclipboard/internal.h
@@ -33,7 +33,7 @@
 
 #include <xcb/xproto.h>
 #include <X11/Xfuncproto.h> // for _X_ATTRIBUTE_PRINTF
-#include <X11/Xdefs.h> // for Bool type
+#include <X11/Xmd.h> // for BOOL
 
 /* Windows headers */
 #include <X11/Xwindows.h>
@@ -82,7 +82,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 7e47f7e08..0e60c1b24 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -103,7 +103,7 @@ intern_atom(xcb_connection_t *conn, const char *atomName)
  * returns TRUE if shutdown was signalled to loop, FALSE if some error occurred
  */
 
-Bool
+BOOL
 winClipboardProc(char *szDisplay, xcb_auth_info_t *auth_info)
 {
     ClipboardAtoms atoms;
@@ -120,7 +120,7 @@ winClipboardProc(char *szDisplay, xcb_auth_info_t *auth_info)
     xcb_connection_t *conn;
     xcb_window_t iWindow = XCB_NONE;
     int iSelectError;
-    Bool fShutdown = FALSE;
+    BOOL fShutdown = FALSE;
     ClipboardConversionData data;
     int screen;
 
diff --git a/hw/xwin/winclipboard/winclipboard.h b/hw/xwin/winclipboard/winclipboard.h
index 5b25e6e42..243aa24dc 100644
--- a/hw/xwin/winclipboard/winclipboard.h
+++ b/hw/xwin/winclipboard/winclipboard.h
@@ -27,15 +27,15 @@
 #ifndef WINCLIPBOARD_H
 #define WINCLIPBOARD_H
 
-#include <X11/Xdefs.h> // for Bool type
 #include <xcb/xcb.h>
+#include <X11/Xmd.h> // for BOOL type
 
-Bool winClipboardProc(char *szDisplay, xcb_auth_info_t *auth_info);
+BOOL winClipboardProc(char *szDisplay, xcb_auth_info_t *auth_info);
 
 void winFixClipboardChain(void);
 
 void winClipboardWindowDestroy(void);
 
-extern Bool fPrimarySelection;
+extern BOOL fPrimarySelection;
 
 #endif
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index ecbeabd75..10824a3ae 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -131,7 +131,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     static xcb_connection_t *conn;
     static xcb_window_t iWindow;
     static ClipboardAtoms *atoms;
-    static Bool fRunning;
+    static BOOL fRunning;
 
     /* Branch on message type */
     switch (message) {
@@ -310,7 +310,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     case WM_RENDERFORMAT:
     {
         int iReturn;
-        Bool pasted = FALSE;
+        BOOL pasted = FALSE;
         xcb_atom_t selection;
         ClipboardConversionData data;
         int best_target = 0;
@@ -440,7 +440,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 8e8f34095..cac17153f 100644
--- a/hw/xwin/winclipboard/xevents.c
+++ b/hw/xwin/winclipboard/xevents.c
@@ -59,7 +59,7 @@
  */
 
 extern int xfixes_event_base;
-Bool fPrimarySelection = TRUE;
+BOOL fPrimarySelection = TRUE;
 
 /*
  * Local variables
@@ -198,7 +198,7 @@ winClipboardSelectionNotifyData(HWND hwnd, xcb_window_t iWindow, xcb_connection_
     xcb_atom_t xtpText_encoding;
     int xtpText_nitems;
 
-    Bool fSetClipboardData = TRUE;
+    BOOL fSetClipboardData = TRUE;
     char *pszReturnData = NULL;
     UINT codepage;
     wchar_t *pwszUnicodeStr = NULL;
@@ -403,8 +403,8 @@ winClipboardFlushXEvents(HWND hwnd,
         const char *pszGlobalData = NULL;
         HGLOBAL hGlobal = NULL;
         char *pszConvertData = NULL;
-        Bool fAbort = FALSE;
-        Bool fCloseClipboard = FALSE;
+        BOOL fAbort = FALSE;
+        BOOL fCloseClipboard = FALSE;
 
         /* Branch on the event type */
         switch (event->response_type & ~0x80) {
commit 4055fed1e7933c05afe143cbd18743c1ff1c7fee
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Sun Jul 1 15:53:42 2018 +0100

    hw/xwin: Remove XSetAuthorization() for helper clients
    
    All helper client code now uses xcb, so calling XSetAuthorization() is
    no longer needed.
    
    This is the last reference to libX11 from helper clients, so linking
    with x11-xcb and libX11 is no longer required.
    
    Also drop (unneeded?) linking with libXau.
    
    Also drop installing these prerequistes on AppvVeyor.
    
    Also move prototypes for functions in winauth.c from win.h into a new
    header, winauth.h, and include that where needed.

diff --git a/.appveyor.yml b/.appveyor.yml
index b86e33ed4..b243ff43b 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -37,9 +37,7 @@ libGL-devel,\
 libnettle-devel,\
 libpixman1-devel,\
 libtirpc-devel,\
-libX11-devel,\
 libXRes-devel,\
-libXau-devel,\
 libXaw-devel,\
 libXdmcp-devel,\
 libXext-devel,\
diff --git a/configure.ac b/configure.ac
index add563c8b..af5df61dc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2081,7 +2081,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 xau xdmcp x11-xcb xcb-aux xcb-composite xcb-image xcb-ewmh xcb-icccm xcb-xfixes])
+	PKG_CHECK_MODULES([XWINMODULES],[xcb-aux xcb-composite xcb-image xcb-ewmh xcb-icccm xcb-xfixes])
 
 	if test "x$WINDOWSDRI" = xauto; then
 		PKG_CHECK_EXISTS([windowsdriproto], [WINDOWSDRI=yes], [WINDOWSDRI=no])
diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 872a1fdcd..d04b47cdc 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -66,6 +66,7 @@ typedef WINAPI HRESULT(*SHGETFOLDERPATHPROC) (HWND hwndOwner,
 #include "glx/glwindows.h"
 #include "dri/windowsdri.h"
 #endif
+#include "winauth.h"
 
 /*
  * References to external symbols
diff --git a/hw/xwin/meson.build b/hw/xwin/meson.build
index c1a2917b8..62d9ba782 100644
--- a/hw/xwin/meson.build
+++ b/hw/xwin/meson.build
@@ -132,7 +132,6 @@ srcs_windows += pfiles
 
 xwin_dep = [
     common_dep,
-    dependency('x11-xcb'),
     dependency('xcb-aux'),
     dependency('xcb-image'),
     dependency('xcb-ewmh'),
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 6f3437284..50554e7dd 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -669,14 +669,6 @@ Bool
 Bool
  winAllocateCmapPrivates(ColormapPtr pCmap);
 
-/*
- * winauth.c
- */
-
-Bool
- winGenerateAuthorization(void);
-void winSetAuthorization(void);
-
 /*
  * winblock.c
  */
diff --git a/hw/xwin/winauth.c b/hw/xwin/winauth.c
index 14278390f..8d3bcb447 100644
--- a/hw/xwin/winauth.c
+++ b/hw/xwin/winauth.c
@@ -32,7 +32,8 @@
 #include <xwin-config.h>
 #endif
 
-#include "win.h"
+#include "winauth.h"
+#include "winmsg.h"
 
 /* Includes for authorization */
 #include "securitysrv.h"
@@ -40,14 +41,6 @@
 
 #include <xcb/xcb.h>
 
-/* Need to get this from Xlib.h */
-extern void XSetAuthorization(
-    const char *                /* name */,
-    int                         /* namelen */,
-    const char *                /* data */,
-    int                         /* datalen */
-);
-
 /*
  * Constants
  */
@@ -68,9 +61,7 @@ static xcb_auth_info_t auth_info;
  */
 
 #ifndef XCSECURITY
-
-static
-    XID
+static XID
 GenerateAuthorization(unsigned name_length,
                       const char *name,
                       unsigned data_length,
@@ -89,7 +80,9 @@ GenerateAuthorization(unsigned name_length,
 Bool
 winGenerateAuthorization(void)
 {
+#ifdef XCSECURITY
     SecurityAuthorizationPtr pAuth = NULL;
+#endif
 
     /* Call OS layer to generate authorization key */
     g_authId = GenerateAuthorization(strlen(AUTH_NAME),
@@ -106,7 +99,7 @@ winGenerateAuthorization(void)
                  g_uiAuthDataLen, g_pAuthData);
     }
 
-    auth_info.name = AUTH_NAME;
+    auth_info.name = strdup(AUTH_NAME);
     auth_info.namelen = strlen(AUTH_NAME);
     auth_info.data = g_pAuthData;
     auth_info.datalen = g_uiAuthDataLen;
@@ -141,14 +134,6 @@ winGenerateAuthorization(void)
     return TRUE;
 }
 
-/* Use our generated cookie for authentication */
-void
-winSetAuthorization(void)
-{
-    XSetAuthorization(AUTH_NAME,
-                      strlen(AUTH_NAME), g_pAuthData, g_uiAuthDataLen);
-}
-
 xcb_auth_info_t *
 winGetXcbAuthInfo(void)
 {
diff --git a/hw/xwin/winauth.h b/hw/xwin/winauth.h
new file mode 100644
index 000000000..68d3ac0cb
--- /dev/null
+++ b/hw/xwin/winauth.h
@@ -0,0 +1,26 @@
+/*
+ * 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 <xcb/xcb.h>
+#include <X11/Xdefs.h> // for Bool
+
+Bool winGenerateAuthorization(void);
+xcb_auth_info_t * winGetXcbAuthInfo(void);
diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c
index 1e920f51f..814899f8e 100644
--- a/hw/xwin/winclipboardinit.c
+++ b/hw/xwin/winclipboardinit.c
@@ -38,12 +38,11 @@
 #include "win.h"
 #include "winclipboard/winclipboard.h"
 #include "windisplay.h"
+#include "winauth.h"
 
 #define WIN_CLIPBOARD_RETRIES			40
 #define WIN_CLIPBOARD_DELAY			1
 
-extern xcb_auth_info_t *winGetXcbAuthInfo(void);
-
 /*
  * Local variables
  */
@@ -66,9 +65,6 @@ winClipboardThreadProc(void *arg)
 
       ++clipboardRestarts;
 
-      /* Use our generated cookie for authentication */
-      winSetAuthorization();
-
       /* Setup the display connection string */
       /*
        * NOTE: Always connect to screen 0 since we require that screen
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index fa339a9fb..9801b14c9 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -63,6 +63,7 @@
 #include "winglobals.h"
 #include "windisplay.h"
 #include "winmultiwindowicons.h"
+#include "winauth.h"
 
 /* We need the native HWND atom for intWM, so for consistency use the
    same name as extWM does */
@@ -75,7 +76,6 @@
 extern void winDebug(const char *format, ...);
 extern void winReshapeMultiWindow(WindowPtr pWin);
 extern void winUpdateRgnMultiWindow(WindowPtr pWin);
-extern xcb_auth_info_t *winGetXcbAuthInfo(void);
 
 #ifndef CYGDEBUG
 #define CYGDEBUG NO
commit 9e02e023b08e24d4213ca14d99612e4cf5ef2f1e
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Sat Jun 30 16:00:16 2018 +0100

    hw/xwin: xcbify clipboard integration
    
    Convert clipboard integration code from libX11 to xcb
    
    This drops support for COMPOUND_TEXT.  Presumably some ancient
    (pre-2000) clients exist which support that, but not UTF8_STRING, but we
    don't have an example to test with. (Given the nature of the thing, the
    users of those clients probably work in CJK languages)
    
    Supporting COMPOUND_TEXT would also involve writing (or extracting from
    Xlib) support for the ISO 2022 encoding.
    
    v2:
    Fix the length of text property set by a SelectionRequest
    
    The length of the text property is not neccessarily the same as the
    length of the clipboard text before it is d2u converted (specifically,
    if that contains any '\r\n' sequences, it will be shorter as they are
    now just '\n')

diff --git a/configure.ac b/configure.ac
index c789c6a49..add563c8b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2081,7 +2081,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 xau xdmcp xfixes x11-xcb xcb-aux xcb-composite xcb-image xcb-ewmh xcb-icccm])
+	PKG_CHECK_MODULES([XWINMODULES],[x11 xau xdmcp x11-xcb xcb-aux xcb-composite xcb-image xcb-ewmh xcb-icccm xcb-xfixes])
 
 	if test "x$WINDOWSDRI" = xauto; then
 		PKG_CHECK_EXISTS([windowsdriproto], [WINDOWSDRI=yes], [WINDOWSDRI=no])
diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h
index 2c4a20426..bb862a258 100644
--- a/hw/xwin/winclipboard/internal.h
+++ b/hw/xwin/winclipboard/internal.h
@@ -31,8 +31,9 @@
 #ifndef WINCLIPBOARD_INTERNAL_H
 #define WINCLIPBOARD_INTERNAL_H
 
-/* X headers */
-#include <X11/Xlib.h>
+#include <xcb/xproto.h>
+#include <X11/Xfuncproto.h> // for _X_ATTRIBUTE_PRINTF
+#include <X11/Xdefs.h> // for Bool type
 
 /* Windows headers */
 #include <X11/Xwindows.h>
@@ -67,15 +68,14 @@ void
  * winclipboardthread.c
  */
 
-
 typedef struct
 {
-    Atom atomClipboard;
-    Atom atomLocalProperty;
-    Atom atomUTF8String;
-    Atom atomCompoundText;
-    Atom atomTargets;
-    Atom atomIncr;
+    xcb_atom_t atomClipboard;
+    xcb_atom_t atomLocalProperty;
+    xcb_atom_t atomUTF8String;
+    xcb_atom_t atomCompoundText;
+    xcb_atom_t atomTargets;
+    xcb_atom_t atomIncr;
 } ClipboardAtoms;
 
 /*
@@ -89,8 +89,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
 
 typedef struct
 {
-  Display *pClipboardDisplay;
-  Window iClipboardWindow;
+  xcb_connection_t *pClipboardDisplay;
+  xcb_window_t iClipboardWindow;
   ClipboardAtoms *atoms;
 } ClipboardWindowCreationParams;
 
@@ -100,17 +100,17 @@ typedef struct
 
 typedef struct
 {
-  Atom *targetList;
+  xcb_atom_t *targetList;
   unsigned char *incr;
   unsigned long int incrsize;
 } ClipboardConversionData;
 
 int
 winClipboardFlushXEvents(HWND hwnd,
-                         Window iWindow, Display * pDisplay, ClipboardConversionData *data, ClipboardAtoms *atom);
-
+                         xcb_window_t iWindow, xcb_connection_t * pDisplay,
+                         ClipboardConversionData *data, ClipboardAtoms *atoms);
 
-Atom
+xcb_atom_t
 winClipboardGetLastOwnedSelectionAtom(ClipboardAtoms *atoms);
 
 void
diff --git a/hw/xwin/winclipboard/meson.build b/hw/xwin/winclipboard/meson.build
index 71518a7d9..2a46c670e 100644
--- a/hw/xwin/winclipboard/meson.build
+++ b/hw/xwin/winclipboard/meson.build
@@ -12,8 +12,10 @@ xwin_clipboard = static_library(
     include_directories: inc,
     c_args: '-DHAVE_XWIN_CONFIG_H',
     dependencies: [
-        dependency('x11'),
-        dependency('xfixes'),
+        dependency('xcb'),
+        dependency('xcb-aux'),
+        dependency('xcb-icccm'),
+        dependency('xcb-xfixes'),
         socket_dep,
     ],
 )
@@ -28,7 +30,6 @@ executable(
     srcs_xwinclip,
     link_with: xwin_clipboard,
     link_args: ['-lgdi32', '-lpthread'],
-    dependencies: [dependency('x11')],
     install: true,
 )
 
diff --git a/hw/xwin/winclipboard/textconv.c b/hw/xwin/winclipboard/textconv.c
index 9c9cb3529..651ccc666 100644
--- a/hw/xwin/winclipboard/textconv.c
+++ b/hw/xwin/winclipboard/textconv.c
@@ -32,15 +32,6 @@
 #include <xwin-config.h>
 #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 <stdlib.h>
 #include "internal.h"
 
diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c
index 8949e7235..7e47f7e08 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -36,19 +36,9 @@
 #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 <assert.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <setjmp.h>
 #include <pthread.h>
 #include <sys/param.h> // for MAX() macro
 
@@ -58,8 +48,11 @@
 #include <errno.h>
 #endif
 
-#include <X11/Xatom.h>
-#include <X11/extensions/Xfixes.h>
+#include <xcb/xcb.h>
+#include <xcb/xcb_aux.h>
+#include <xcb/xcb_icccm.h>
+#include <xcb/xfixes.h>
+
 #include "winclipboard.h"
 #include "internal.h"
 
@@ -77,9 +70,6 @@
  */
 
 static HWND g_hwndClipboard = NULL;
-static jmp_buf g_jmpEntry;
-static XIOErrorHandler g_winClipboardOldIOErrorHandler;
-static pthread_t g_winClipboardProcThread;
 
 int xfixes_event_base;
 int xfixes_error_base;
@@ -89,13 +79,23 @@ int xfixes_error_base;
  */
 
 static HWND
-winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAtoms *atoms);
-
-static int
- winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr);
+winClipboardCreateMessagingWindow(xcb_connection_t *conn, xcb_window_t iWindow, ClipboardAtoms *atoms);
 
-static int
- winClipboardIOErrorHandler(Display * pDisplay);
+static xcb_atom_t
+intern_atom(xcb_connection_t *conn, const char *atomName)
+{
+  xcb_intern_atom_reply_t *atom_reply;
+  xcb_intern_atom_cookie_t atom_cookie;
+  xcb_atom_t atom = XCB_ATOM_NONE;
+
+  atom_cookie = xcb_intern_atom(conn, 0, strlen(atomName), atomName);
+  atom_reply = xcb_intern_atom_reply(conn, atom_cookie, NULL);
+  if (atom_reply) {
+    atom = atom_reply->atom;
+    free(atom_reply);
+  }
+  return atom;
+}
 
 /*
  * Create X11 and Win32 messaging windows, and run message processing loop
@@ -104,13 +104,12 @@ static int
  */
 
 Bool
-winClipboardProc(char *szDisplay)
+winClipboardProc(char *szDisplay, xcb_auth_info_t *auth_info)
 {
     ClipboardAtoms atoms;
     int iReturn;
     HWND hwnd = NULL;
     int iConnectionNumber = 0;
-
 #ifdef HAS_DEVWINDOWS
     int fdMessageQueue = 0;
 #else
@@ -118,54 +117,27 @@ winClipboardProc(char *szDisplay)
 #endif
     fd_set fdsRead;
     int iMaxDescriptor;
-    Display *pDisplay = NULL;
-    Window iWindow = None;
+    xcb_connection_t *conn;
+    xcb_window_t iWindow = XCB_NONE;
     int iSelectError;
     Bool fShutdown = FALSE;
-    static Bool fErrorHandlerSet = FALSE;
     ClipboardConversionData data;
+    int screen;
 
     winDebug("winClipboardProc - Hello\n");
 
-    /* Allow multiple threads to access Xlib */
-    if (XInitThreads() == 0) {
-        ErrorF("winClipboardProc - XInitThreads failed.\n");
-        goto winClipboardProc_Exit;
-    }
-
-    /* See if X supports the current locale */
-    if (XSupportsLocale() == False) {
-        ErrorF("winClipboardProc - Warning: Locale not supported by X.\n");
-    }
-
-    g_winClipboardProcThread = pthread_self();
-
-    /* Set error handler */
-    if (!fErrorHandlerSet) {
-      XSetErrorHandler(winClipboardErrorHandler);
-      g_winClipboardOldIOErrorHandler =
-         XSetIOErrorHandler(winClipboardIOErrorHandler);
-      fErrorHandlerSet = TRUE;
-    }
-
-    /* Set jump point for Error exits */
-    if (setjmp(g_jmpEntry)) {
-        ErrorF("winClipboardProc - setjmp returned for IO Error Handler.\n");
-        goto winClipboardProc_Done;
-    }
-
     /* Make sure that the display opened */
-    pDisplay = XOpenDisplay(szDisplay);
-    if (pDisplay == NULL) {
+    conn = xcb_connect_to_display_with_auth_info(szDisplay, auth_info, &screen);
+    if (xcb_connection_has_error(conn)) {
         ErrorF("winClipboardProc - Failed opening the display, giving up\n");
         goto winClipboardProc_Done;
     }
 
-    ErrorF("winClipboardProc - XOpenDisplay () returned and "
+    ErrorF("winClipboardProc - xcb_connect () returned and "
            "successfully opened the display.\n");
 
     /* Get our connection number */
-    iConnectionNumber = ConnectionNumber(pDisplay);
+    iConnectionNumber = xcb_get_file_descriptor(conn);
 
 #ifdef HAS_DEVWINDOWS
     /* Open a file descriptor for the windows message queue */
@@ -181,56 +153,75 @@ winClipboardProc(char *szDisplay)
     iMaxDescriptor = iConnectionNumber + 1;
 #endif
 
-    if (!XFixesQueryExtension(pDisplay, &xfixes_event_base, &xfixes_error_base))
+    const xcb_query_extension_reply_t *xfixes_query;
+    xfixes_query = xcb_get_extension_data(conn, &xcb_xfixes_id);
+    if (!xfixes_query->present)
       ErrorF ("winClipboardProc - XFixes extension not present\n");
+    xfixes_event_base = xfixes_query->first_event;
+    xfixes_error_base = xfixes_query->first_error;
+    /* Must advise server of XFIXES version we require */
+    xcb_xfixes_query_version_unchecked(conn, 1, 0);
 
     /* 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);
-    atoms.atomIncr = XInternAtom (pDisplay, "INCR", False);
+    atoms.atomClipboard = intern_atom(conn, "CLIPBOARD");
+    atoms.atomLocalProperty = intern_atom(conn, "CYGX_CUT_BUFFER");
+    atoms.atomUTF8String = intern_atom(conn, "UTF8_STRING");
+    atoms.atomCompoundText = intern_atom(conn, "COMPOUND_TEXT");
+    atoms.atomTargets = intern_atom(conn, "TARGETS");
+    atoms.atomIncr = intern_atom(conn, "INCR");
+
+    xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screen);
+    xcb_window_t root_window_id = root_screen->root;
 
     /* Create a messaging window */
-    iWindow = XCreateSimpleWindow(pDisplay,
-                                  DefaultRootWindow(pDisplay),
-                                  1, 1,
-                                  500, 500,
-                                  0,
-                                  BlackPixel(pDisplay, 0),
-                                  BlackPixel(pDisplay, 0));
-    if (iWindow == 0) {
+    iWindow = xcb_generate_id(conn);
+    xcb_void_cookie_t cookie = xcb_create_window_checked(conn,
+                                                         XCB_COPY_FROM_PARENT,
+                                                         iWindow,
+                                                         root_window_id,
+                                                         1, 1,
+                                                         500, 500,
+                                                         0,
+                                                         XCB_WINDOW_CLASS_INPUT_ONLY,
+                                                         XCB_COPY_FROM_PARENT,
+                                                         0,
+                                                         NULL);
+
+    xcb_generic_error_t *error;
+    if ((error = xcb_request_check(conn, cookie))) {
         ErrorF("winClipboardProc - Could not create an X window.\n");
+        free(error);
         goto winClipboardProc_Done;
     }
 
-    XStoreName(pDisplay, iWindow, "xwinclip");
+    xcb_icccm_set_wm_name(conn, iWindow, XCB_ATOM_STRING, 8, strlen("xwinclip"), "xwinclip");
 
     /* Select event types to watch */
-    if (XSelectInput(pDisplay, iWindow, PropertyChangeMask) == BadWindow)
-        ErrorF("winClipboardProc - XSelectInput generated BadWindow "
-               "on messaging window\n");
-
-    XFixesSelectSelectionInput (pDisplay,
-                                iWindow,
-                                XA_PRIMARY,
-                                XFixesSetSelectionOwnerNotifyMask |
-                                XFixesSelectionWindowDestroyNotifyMask |
-                                XFixesSelectionClientCloseNotifyMask);
+    const static uint32_t values[] = { XCB_EVENT_MASK_PROPERTY_CHANGE };
+    cookie = xcb_change_window_attributes_checked(conn, iWindow, XCB_CW_EVENT_MASK, values);
+    if ((error = xcb_request_check(conn, cookie))) {
+        ErrorF("winClipboardProc - Could not set event mask on messaging window\n");
+        free(error);
+    }
 
-    XFixesSelectSelectionInput (pDisplay,
-                                iWindow,
-                                atoms.atomClipboard,
-                                XFixesSetSelectionOwnerNotifyMask |
-                                XFixesSelectionWindowDestroyNotifyMask |
-                                XFixesSelectionClientCloseNotifyMask);
+    xcb_xfixes_select_selection_input(conn,
+                                      iWindow,
+                                      XCB_ATOM_PRIMARY,
+                                      XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
+                                      XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
+                                      XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE);
 
+    xcb_xfixes_select_selection_input(conn,
+                                      iWindow,
+                                      atoms.atomClipboard,
+                                      XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
+                                      XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
+                                      XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE);
 
     /* Initialize monitored selection state */
     winClipboardInitMonitoredSelections();
     /* Create Windows messaging window */
-    hwnd = winClipboardCreateMessagingWindow(pDisplay, iWindow, &atoms);
+    hwnd = winClipboardCreateMessagingWindow(conn, iWindow, &atoms);
 
     /* Save copy of HWND */
     g_hwndClipboard = hwnd;
@@ -238,20 +229,18 @@ winClipboardProc(char *szDisplay)
     /* Assert ownership of selections if Win32 clipboard is owned */
     if (NULL != GetClipboardOwner()) {
         /* PRIMARY */
-        iReturn = XSetSelectionOwner(pDisplay, XA_PRIMARY,
-                                     iWindow, CurrentTime);
-        if (iReturn == BadAtom || iReturn == BadWindow ||
-            XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) {
+        cookie = xcb_set_selection_owner_checked(conn, iWindow, XCB_ATOM_PRIMARY, XCB_CURRENT_TIME);
+        if ((error = xcb_request_check(conn, cookie))) {
             ErrorF("winClipboardProc - Could not set PRIMARY owner\n");
+            free(error);
             goto winClipboardProc_Done;
         }
 
         /* CLIPBOARD */
-        iReturn = XSetSelectionOwner(pDisplay, atoms.atomClipboard,
-                                     iWindow, CurrentTime);
-        if (iReturn == BadAtom || iReturn == BadWindow ||
-            XGetSelectionOwner(pDisplay, atoms.atomClipboard) != iWindow) {
+        cookie = xcb_set_selection_owner_checked(conn, iWindow, atoms.atomClipboard, XCB_CURRENT_TIME);
+        if ((error = xcb_request_check(conn, cookie))) {
             ErrorF("winClipboardProc - Could not set CLIPBOARD owner\n");
+            free(error);
             goto winClipboardProc_Done;
         }
     }
@@ -263,8 +252,7 @@ winClipboardProc(char *szDisplay)
     while (1) {
 
         /* Process X events */
-        winClipboardFlushXEvents(hwnd,
-                                 iWindow, pDisplay, &data, &atoms);
+        winClipboardFlushXEvents(hwnd, iWindow, conn, &data, &atoms);
 
         /* Process Windows messages */
         if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
@@ -274,7 +262,7 @@ winClipboardProc(char *szDisplay)
         }
 
         /* We need to ensure that all pending requests are sent */
-        XFlush(pDisplay);
+        xcb_flush(conn);
 
         /* Setup the file descriptor set */
         /*
@@ -346,7 +334,6 @@ winClipboardProc(char *szDisplay)
 #endif
     }
 
- winClipboardProc_Exit:
     /* broke out of while loop on a shutdown message */
     fShutdown = TRUE;
 
@@ -357,12 +344,13 @@ winClipboardProc(char *szDisplay)
     }
 
     /* Close our X window */
-    if (pDisplay && iWindow) {
-        iReturn = XDestroyWindow(pDisplay, iWindow);
-        if (iReturn == BadWindow)
-            ErrorF("winClipboardProc - XDestroyWindow returned BadWindow.\n");
+    if (!xcb_connection_has_error(conn) && iWindow) {
+        cookie = xcb_destroy_window_checked(conn, iWindow);
+        if ((error = xcb_request_check(conn, cookie)))
+            ErrorF("winClipboardProc - XDestroyWindow failed.\n");
         else
             ErrorF("winClipboardProc - XDestroyWindow succeeded.\n");
+        free(error);
     }
 
 #ifdef HAS_DEVWINDOWS
@@ -371,26 +359,15 @@ winClipboardProc(char *szDisplay)
         close(fdMessageQueue);
 #endif
 
-#if 0
     /*
-     * 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.
+     * xcb_disconnect() does not sync, so is safe to call even when we are built
+     * into the server.  Unlike XCloseDisplay() there will be no deadlock if the
+     * server is in the process of exiting and waiting for this thread to exit.
      */
-
-    /* Discard any remaining events */
-    XSync(pDisplay, TRUE);
-
-    /* Select event types to watch */
-    XSelectInput(pDisplay, DefaultRootWindow(pDisplay), None);
-
-    /* Close our X display */
-    if (pDisplay) {
-        XCloseDisplay(pDisplay);
+    if (!xcb_connection_has_error(conn)) {
+        /* Close our X display */
+        xcb_disconnect(conn);
     }
-#endif
 
     /* global clipboard variable reset */
     g_hwndClipboard = NULL;
@@ -403,7 +380,7 @@ winClipboardProc(char *szDisplay)
  */
 
 static HWND
-winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAtoms *atoms)
+winClipboardCreateMessagingWindow(xcb_connection_t *conn, xcb_window_t iWindow, ClipboardAtoms *atoms)
 {
     WNDCLASSEX wc;
     ClipboardWindowCreationParams cwcp;
@@ -425,7 +402,7 @@ winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAt
     RegisterClassEx(&wc);
 
     /* Information to be passed to WM_CREATE */
-    cwcp.pClipboardDisplay = pDisplay;
+    cwcp.pClipboardDisplay = conn;
     cwcp.iClipboardWindow = iWindow;
     cwcp.atoms = atoms;
 
@@ -453,42 +430,6 @@ winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAt
     return hwnd;
 }
 
-/*
- * winClipboardErrorHandler - Our application specific error handler
- */
-
-static int
-winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr)
-{
-    char pszErrorMsg[100];
-
-    XGetErrorText(pDisplay, pErr->error_code, pszErrorMsg, sizeof(pszErrorMsg));
-    ErrorF("winClipboardErrorHandler - ERROR: \n\t%s\n"
-           "\tSerial: %lu, Request Code: %d, Minor Code: %d\n",
-           pszErrorMsg, pErr->serial, pErr->request_code, pErr->minor_code);
-    return 0;
-}
-
-/*
- * winClipboardIOErrorHandler - Our application specific IO error handler
- */
-
-static int
-winClipboardIOErrorHandler(Display * pDisplay)
-{
-    ErrorF("winClipboardIOErrorHandler!\n");
-
-    if (pthread_equal(pthread_self(), g_winClipboardProcThread)) {
-        /* Restart at the main entry point */
-        longjmp(g_jmpEntry, 2);
-    }
-
-    if (g_winClipboardOldIOErrorHandler)
-        g_winClipboardOldIOErrorHandler(pDisplay);
-
-    return 0;
-}
-
 void
 winClipboardWindowDestroy(void)
 {
diff --git a/hw/xwin/winclipboard/winclipboard.h b/hw/xwin/winclipboard/winclipboard.h
index 2ae27fd2b..5b25e6e42 100644
--- a/hw/xwin/winclipboard/winclipboard.h
+++ b/hw/xwin/winclipboard/winclipboard.h
@@ -27,7 +27,10 @@
 #ifndef WINCLIPBOARD_H
 #define WINCLIPBOARD_H
 
-Bool winClipboardProc(char *szDisplay);
+#include <X11/Xdefs.h> // for Bool type
+#include <xcb/xcb.h>
+
+Bool winClipboardProc(char *szDisplay, xcb_auth_info_t *auth_info);
 
 void winFixClipboardChain(void);
 
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index ee2266a3d..ecbeabd75 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -36,20 +36,12 @@
 #include <xwin-config.h>
 #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 <sys/types.h>
 #include <sys/time.h>
 #include <limits.h>
 
-#include <X11/Xatom.h>
+#include <xcb/xproto.h>
+#include <xcb/xcb_aux.h>
 
 #include "internal.h"
 #include "winclipboard.h"
@@ -65,7 +57,7 @@
  */
 
 static int
-winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
+winProcessXEventsTimeout(HWND hwnd, xcb_window_t iWindow, xcb_connection_t *conn,
                          ClipboardConversionData *data, ClipboardAtoms *atoms, int iTimeoutSec)
 {
     int iConnNumber;
@@ -76,7 +68,7 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
              iTimeoutSec);
 
     /* Get our connection number */
-    iConnNumber = ConnectionNumber(pDisplay);
+    iConnNumber = xcb_get_file_descriptor(conn);
 
     /* Loop for X events */
     while (1) {
@@ -84,7 +76,7 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
         long remainingTime;
 
         /* Process X events */
-        iReturn = winClipboardFlushXEvents(hwnd, iWindow, pDisplay, data, atoms);
+        iReturn = winClipboardFlushXEvents(hwnd, iWindow, conn, data, atoms);
 
         winDebug("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n", iReturn);
 
@@ -94,7 +86,7 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
         }
 
         /* We need to ensure that all pending requests are sent */
-        XFlush(pDisplay);
+        xcb_flush(conn);
 
         /* Setup the file descriptor set */
         FD_ZERO(&fdsRead);
@@ -136,8 +128,8 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
 LRESULT CALLBACK
 winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
-    static Display *pDisplay;
-    static Window iWindow;
+    static xcb_connection_t *conn;
+    static xcb_window_t iWindow;
     static ClipboardAtoms *atoms;
     static Bool fRunning;
 
@@ -166,7 +158,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         winDebug("winClipboardWindowProc - WM_CREATE\n");
 
-        pDisplay = cwcp->pClipboardDisplay;
+        conn = cwcp->pClipboardDisplay;
         iWindow = cwcp->iClipboardWindow;
         atoms = cwcp->atoms;
         fRunning = TRUE;
@@ -177,7 +169,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
     case WM_CLIPBOARDUPDATE:
     {
-        int iReturn;
+        xcb_generic_error_t *error;
+        xcb_void_cookie_t cookie_set;
 
         winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Enter\n");
 
@@ -211,6 +204,9 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         if (!IsClipboardFormatAvailable(CF_TEXT)
             && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
 
+            xcb_get_selection_owner_cookie_t cookie_get;
+            xcb_get_selection_owner_reply_t *reply;
+
             winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                      "Clipboard does not contain CF_TEXT nor "
                      "CF_UNICODETEXT.\n");
@@ -219,33 +215,33 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
              * We need to make sure that the X Server has processed
              * previous XSetSelectionOwner messages.
              */
-            XSync(pDisplay, FALSE);
+            xcb_aux_sync(conn);
 
             winDebug("winClipboardWindowProc - XSync done.\n");
 
             /* Release PRIMARY selection if owned */
-            iReturn = XGetSelectionOwner(pDisplay, XA_PRIMARY);
-            if (iReturn == iWindow) {
-                winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
-                         "PRIMARY selection is owned by us.\n");
-                XSetSelectionOwner(pDisplay, XA_PRIMARY, None, CurrentTime);
+            cookie_get = xcb_get_selection_owner(conn, XCB_ATOM_PRIMARY);
+            reply = xcb_get_selection_owner_reply(conn, cookie_get, NULL);
+            if (reply) {
+                if (reply->owner == iWindow) {
+                    winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
+                             "PRIMARY selection is owned by us, releasing.\n");
+                    xcb_set_selection_owner(conn, XCB_NONE, XCB_ATOM_PRIMARY, XCB_CURRENT_TIME);
+                }
+                free(reply);
             }
-            else if (BadWindow == iReturn || BadAtom == iReturn)
-                ErrorF("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
-                       "XGetSelectionOwner failed for PRIMARY: %d\n",
-                       iReturn);
 
             /* Release CLIPBOARD selection if owned */
-            iReturn = XGetSelectionOwner(pDisplay, atoms->atomClipboard);
-            if (iReturn == iWindow) {
-                winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
-                         "CLIPBOARD selection is owned by us, releasing\n");
-                XSetSelectionOwner(pDisplay, atoms->atomClipboard, None, CurrentTime);
+            cookie_get = xcb_get_selection_owner(conn, atoms->atomClipboard);
+            reply = xcb_get_selection_owner_reply(conn, cookie_get, NULL);
+            if (reply) {
+                if (reply->owner == iWindow) {
+                    winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
+                             "CLIPBOARD selection is owned by us, releasing\n");
+                    xcb_set_selection_owner(conn, XCB_NONE, atoms->atomClipboard, XCB_CURRENT_TIME);
+                }
+                free(reply);
             }
-            else if (BadWindow == iReturn || BadAtom == iReturn)
-                ErrorF("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
-                       "XGetSelectionOwner failed for CLIPBOARD: %d\n",
-                       iReturn);
 
             winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Exit\n");
 
@@ -253,26 +249,24 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         }
 
         /* Reassert ownership of PRIMARY */
-        iReturn = XSetSelectionOwner(pDisplay,
-                                     XA_PRIMARY, iWindow, CurrentTime);
-        if (iReturn == BadAtom || iReturn == BadWindow ||
-            XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) {
+        cookie_set = xcb_set_selection_owner_checked(conn, iWindow, XCB_ATOM_PRIMARY, XCB_CURRENT_TIME);
+        error = xcb_request_check(conn, cookie_set);
+        if (error) {
             ErrorF("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                    "Could not reassert ownership of PRIMARY\n");
-        }
-        else {
+            free(error);
+        } else {
             winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                      "Reasserted ownership of PRIMARY\n");
         }
 
         /* Reassert ownership of the CLIPBOARD */
-        iReturn = XSetSelectionOwner(pDisplay,
-                                     atoms->atomClipboard, iWindow, CurrentTime);
-
-        if (iReturn == BadAtom || iReturn == BadWindow ||
-            XGetSelectionOwner(pDisplay, atoms->atomClipboard) != iWindow) {
+        cookie_set = xcb_set_selection_owner_checked(conn, iWindow, atoms->atomClipboard, XCB_CURRENT_TIME);
+        error = xcb_request_check(conn, cookie_set);
+        if (error) {
             ErrorF("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                     "Could not reassert ownership of CLIPBOARD\n");
+            free(error);
         }
         else {
             winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
@@ -280,7 +274,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         }
 
         /* Flush the pending SetSelectionOwner event now */
-        XFlush(pDisplay);
+        xcb_flush(conn);
     }
         winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Exit\n");
         return 0;
@@ -317,7 +311,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     {
         int iReturn;
         Bool pasted = FALSE;
-        Atom selection;
+        xcb_atom_t selection;
         ClipboardConversionData data;
         int best_target = 0;
 
@@ -325,7 +319,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                  (int)wParam);
 
         selection = winClipboardGetLastOwnedSelectionAtom(atoms);
-        if (selection == None) {
+        if (selection == XCB_NONE) {
             ErrorF("winClipboardWindowProc - no monitored selection is owned\n");
             goto fake_paste;
         }
@@ -333,11 +327,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         winDebug("winClipboardWindowProc - requesting targets for selection from owner\n");
 
         /* Request the selection's supported conversion targets */
-        XConvertSelection(pDisplay,
-                          selection,
-                          atoms->atomTargets,
-                          atoms->atomLocalProperty,
-                          iWindow, CurrentTime);
+        xcb_convert_selection(conn, iWindow, selection, atoms->atomTargets,
+                              atoms->atomLocalProperty, XCB_CURRENT_TIME);
 
         /* Process X events */
         data.incr = NULL;
@@ -345,7 +336,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         iReturn = winProcessXEventsTimeout(hwnd,
                                            iWindow,
-                                           pDisplay,
+                                           conn,
                                            &data,
                                            atoms,
                                            WIN_POLL_TIMEOUT);
@@ -360,17 +351,15 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         {
             struct target_priority
             {
-                Atom target;
+                xcb_atom_t target;
                 unsigned int priority;
             };
 
             struct target_priority target_priority_table[] =
                 {
-#ifdef X_HAVE_UTF8_STRING
                     { atoms->atomUTF8String,   0 },
-#endif
-                    { atoms->atomCompoundText, 1 },
-                    { XA_STRING,               2 },
+                    // { atoms->atomCompoundText, 1 }, not implemented (yet?)
+                    { XCB_ATOM_STRING,         2 },
                 };
 
             int best_priority = INT_MAX;
@@ -402,16 +391,13 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         winDebug("winClipboardWindowProc - requesting selection from owner\n");
 
         /* Request the selection contents */
-        XConvertSelection(pDisplay,
-                          selection,
-                          best_target,
-                          atoms->atomLocalProperty,
-                          iWindow, CurrentTime);
+        xcb_convert_selection(conn, iWindow, selection, best_target,
+                              atoms->atomLocalProperty, XCB_CURRENT_TIME);
 
         /* Process X events */
         iReturn = winProcessXEventsTimeout(hwnd,
                                            iWindow,
-                                           pDisplay,
+                                           conn,
                                            &data,
                                            atoms,
                                            WIN_POLL_TIMEOUT);
diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c
index 36e136148..8e8f34095 100644
--- a/hw/xwin/winclipboard/xevents.c
+++ b/hw/xwin/winclipboard/xevents.c
@@ -34,20 +34,11 @@
 #include <xwin-config.h>
 #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 <limits.h>
 #include <wchar.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/Xfixes.h>
+
+#include <xcb/xcb.h>
+#include <xcb/xfixes.h>
 
 #include "winclipboard.h"
 #include "internal.h"
@@ -57,10 +48,12 @@
  */
 
 #define CLIP_NUM_SELECTIONS		2
-#define CLIP_OWN_NONE     		-1
+#define CLIP_OWN_NONE			-1
 #define CLIP_OWN_PRIMARY		0
 #define CLIP_OWN_CLIPBOARD		1
 
+#define CP_ISO_8559_1 28591
+
 /*
  * Global variables
  */
@@ -72,17 +65,17 @@ Bool fPrimarySelection = TRUE;
  * Local variables
  */
 
-static Window s_iOwners[CLIP_NUM_SELECTIONS] = { None, None };
+static xcb_window_t s_iOwners[CLIP_NUM_SELECTIONS] = { XCB_NONE, XCB_NONE };
 static const char *szSelectionNames[CLIP_NUM_SELECTIONS] =
     { "PRIMARY", "CLIPBOARD" };
 
 static unsigned int lastOwnedSelectionIndex = CLIP_OWN_NONE;
 
 static void
-MonitorSelection(XFixesSelectionNotifyEvent * e, unsigned int i)
+MonitorSelection(xcb_xfixes_selection_notify_event_t * e, unsigned int i)
 {
     /* Look for owned -> not owned transition */
-    if (None == e->owner && None != s_iOwners[i]) {
+    if ((XCB_NONE == e->owner) && (XCB_NONE != s_iOwners[i])) {
         unsigned int other_index;
 
         winDebug("MonitorSelection - %s - Going from owned to not owned.\n",
@@ -94,36 +87,36 @@ MonitorSelection(XFixesSelectionNotifyEvent * e, unsigned int i)
             other_index = CLIP_OWN_CLIPBOARD;
         if (i == CLIP_OWN_CLIPBOARD)
             other_index = CLIP_OWN_PRIMARY;
-        if (None != s_iOwners[other_index])
+        if (XCB_NONE != s_iOwners[other_index])
             lastOwnedSelectionIndex = other_index;
         else
             lastOwnedSelectionIndex = CLIP_OWN_NONE;
     }
 
     /* Save last owned selection */
-    if (None != e->owner) {
+    if (XCB_NONE != e->owner) {
         lastOwnedSelectionIndex = i;
     }
 
     /* Save new selection owner or None */
     s_iOwners[i] = e->owner;
-    winDebug("MonitorSelection - %s - Now owned by XID %lx\n",
+    winDebug("MonitorSelection - %s - Now owned by XID %x\n",
              szSelectionNames[i], e->owner);
 }
 
-Atom
+xcb_atom_t
 winClipboardGetLastOwnedSelectionAtom(ClipboardAtoms *atoms)
 {
     if (lastOwnedSelectionIndex == CLIP_OWN_NONE)
-        return None;
+        return XCB_NONE;
 
     if (lastOwnedSelectionIndex == CLIP_OWN_PRIMARY)
-        return XA_PRIMARY;
+        return XCB_ATOM_PRIMARY;
 
     if (lastOwnedSelectionIndex == CLIP_OWN_CLIPBOARD)
         return atoms->atomClipboard;
 
-    return None;
+    return XCB_NONE;
 }
 
 
@@ -133,102 +126,116 @@ winClipboardInitMonitoredSelections(void)
     /* Initialize static variables */
     int i;
     for (i = 0; i < CLIP_NUM_SELECTIONS; ++i)
-      s_iOwners[i] = None;
+      s_iOwners[i] = XCB_NONE;
 
     lastOwnedSelectionIndex = CLIP_OWN_NONE;
 }
 
-static int
-winClipboardSelectionNotifyTargets(HWND hwnd, Window iWindow, Display *pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
+static char *get_atom_name(xcb_connection_t *conn, xcb_atom_t atom)
 {
-  Atom type;
-  int format;
-  unsigned long nitems;
-  unsigned long after;
-  Atom *prop;
+    char *ret;
+    xcb_get_atom_name_cookie_t cookie = xcb_get_atom_name(conn, atom);
+    xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(conn, cookie, NULL);
+    if (!reply)
+        return NULL;
+    ret = malloc(xcb_get_atom_name_name_length(reply) + 1);
+    if (ret) {
+        memcpy(ret, xcb_get_atom_name_name(reply), xcb_get_atom_name_name_length(reply));
+        ret[xcb_get_atom_name_name_length(reply)] = '\0';
+    }
+    free(reply);
+    return ret;
+}
 
+static int
+winClipboardSelectionNotifyTargets(HWND hwnd, xcb_window_t iWindow, xcb_connection_t *conn, ClipboardConversionData *data, ClipboardAtoms *atoms)
+{
   /* Retrieve the selection data and delete the property */
-  int iReturn = XGetWindowProperty(pDisplay,
-                                   iWindow,
-                                   atoms->atomLocalProperty,
-                                   0,
-                                   INT_MAX,
-                                   True,
-                                   AnyPropertyType,
-                                   &type,
-                                   &format,
-                                   &nitems,
-                                   &after,
-                                   (unsigned char **)&prop);
-  if (iReturn != Success) {
-    ErrorF("winClipboardFlushXEvents - SelectionNotify - "
-           "XGetWindowProperty () failed, aborting: %d\n", iReturn);
+  xcb_get_property_cookie_t cookie = xcb_get_property(conn,
+                                                      TRUE,
+                                                      iWindow,
+                                                      atoms->atomLocalProperty,
+                                                      XCB_GET_PROPERTY_TYPE_ANY,
+                                                      0,
+                                                      INT_MAX);
+  xcb_get_property_reply_t *reply = xcb_get_property_reply(conn, cookie, NULL);
+  if (!reply) {
+      ErrorF("winClipboardFlushXEvents - SelectionNotify - "
+             "XGetWindowProperty () failed\n");
   } else {
-    int i;
-    data->targetList = malloc((nitems+1)*sizeof(Atom));
-
-    for (i = 0; i < nitems; i++)
-      {
-        Atom atom = prop[i];
-        char *pszAtomName = XGetAtomName(pDisplay, atom);
-        data->targetList[i] = atom;
-        winDebug("winClipboardFlushXEvents - SelectionNotify - target[%d] %ld = %s\n", i, atom, pszAtomName);
-        XFree(pszAtomName);
+      xcb_atom_t *prop = xcb_get_property_value(reply);
+      int nitems = xcb_get_property_value_length(reply)/sizeof(xcb_atom_t);
+      int i;
+      data->targetList = malloc((nitems+1)*sizeof(xcb_atom_t));
+
+      for (i = 0; i < nitems; i++)
+          {
+              xcb_atom_t atom = prop[i];
+              char *pszAtomName = get_atom_name(conn, atom);
+              data->targetList[i] = atom;
+              winDebug("winClipboardFlushXEvents - SelectionNotify - target[%d] %d = %s\n", i, atom, pszAtomName);
+              free(pszAtomName);
       }
 
     data->targetList[nitems] = 0;
 
-    XFree(prop);
+    free(reply);
   }
 
   return WIN_XEVENTS_NOTIFY_TARGETS;
 }
 
 static int
-winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
+winClipboardSelectionNotifyData(HWND hwnd, xcb_window_t iWindow, xcb_connection_t *conn, ClipboardConversionData *data, ClipboardAtoms *atoms)
 {
-    Atom encoding;
+    xcb_atom_t encoding;
     int format;
     unsigned long int nitems;
     unsigned long int after;
     unsigned char *value;
-    XTextProperty xtpText = { 0 };
+
+    unsigned char *xtpText_value;
+    xcb_atom_t xtpText_encoding;
+    int xtpText_nitems;
+
     Bool fSetClipboardData = TRUE;
-    int iReturn;
-    char **ppszTextList = NULL;
-    int iCount;
     char *pszReturnData = NULL;
+    UINT codepage;
     wchar_t *pwszUnicodeStr = NULL;
     HGLOBAL hGlobal = NULL;
     char *pszGlobalData = NULL;
 
     /* Retrieve the selection data and delete the property */
-    iReturn = XGetWindowProperty(pDisplay,
-                                 iWindow,
-                                 atoms->atomLocalProperty,
-                                 0,
-                                 INT_MAX,
-                                 True,
-                                 AnyPropertyType,
-                                 &encoding,
-                                 &format,
-                                 &nitems,
-                                 &after,
-                                 &value);
-    if (iReturn != Success) {
+    xcb_get_property_cookie_t cookie = xcb_get_property(conn,
+                                                        TRUE,
+                                                        iWindow,
+                                                        atoms->atomLocalProperty,
+                                                        XCB_GET_PROPERTY_TYPE_ANY,
+                                                        0,
+                                                        INT_MAX);
+    xcb_get_property_reply_t *reply = xcb_get_property_reply(conn, cookie, NULL);
+    if (!reply) {
         ErrorF("winClipboardFlushXEvents - SelectionNotify - "
-               "XGetWindowProperty () failed, aborting: %d\n", iReturn);
+               "XGetWindowProperty () failed\n");
         goto winClipboardFlushXEvents_SelectionNotify_Done;
+    } else {
+        nitems = xcb_get_property_value_length(reply);
+        value =  xcb_get_property_value(reply);
+        after = reply->bytes_after;
+        encoding = reply->type;
+        format = reply->format;
+        // We assume format == 8 (i.e. data is a sequence of bytes).  It's not
+        // clear how anything else should be handled.
+        if (format != 8)
+            ErrorF("SelectionNotify: format is %d, proceeding as if it was 8\n", format);
     }
 
     {
-        char *pszAtomName = NULL;
-
+        char *pszAtomName;
         winDebug("SelectionNotify - returned data %lu left %lu\n", nitems, after);
-        pszAtomName = XGetAtomName(pDisplay, encoding);
+        pszAtomName = get_atom_name(conn, encoding);
         winDebug("Notify atom name %s\n", pszAtomName);
-        XFree(pszAtomName);
-        pszAtomName = NULL;
+        free(pszAtomName);
     }
 
     /* INCR reply indicates the start of a incremental transfer */
@@ -244,10 +251,12 @@ winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, Cl
         if (nitems == 0) {
             winDebug("winClipboardSelectionNotifyData: ending INCR, actual size %ld\n", data->incrsize);
             /* a zero-length property indicates the end of the data */
-            xtpText.value = data->incr;
-            xtpText.encoding = encoding;
-            xtpText.format = format; // XXX: The type of the converted selection is the type of the first partial property. The remaining partial properties must have the same type.
-            xtpText.nitems = data->incrsize;
+            xtpText_value = data->incr;
+            xtpText_encoding = encoding;
+            // XXX: The type of the converted selection is the type of the first
+            // partial property. The remaining partial properties must have the
+            // same type.
+            xtpText_nitems = data->incrsize;
         }
         else {
             /* Otherwise, continue appending the INCR data */
@@ -261,70 +270,34 @@ winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, Cl
     else {
         /* Otherwise, the data is just contained in the property */
         winDebug("winClipboardSelectionNotifyData: non-INCR, %ld bytes\n", nitems);
-        xtpText.value = value;
-        xtpText.encoding = encoding;
-        xtpText.format = format;
-        xtpText.nitems = nitems;
+        xtpText_value = value;
+        xtpText_encoding = encoding;
+        xtpText_nitems = nitems;
     }
 
-#ifdef X_HAVE_UTF8_STRING
-    /* Convert the text property to a text list */
-    iReturn = Xutf8TextPropertyToTextList(pDisplay,
-                                          &xtpText,
-                                          &ppszTextList, &iCount);
-#endif
-
-    if (iReturn == Success || iReturn > 0) {
-        /* Conversion succeeded or some unconvertible characters */
-        if (ppszTextList != NULL) {
-            int i;
-            int iReturnDataLen = 0;
-            for (i = 0; i < iCount; i++) {
-                iReturnDataLen += strlen(ppszTextList[i]);
-            }
-            pszReturnData = malloc(iReturnDataLen + 1);
-            pszReturnData[0] = '\0';
-            for (i = 0; i < iCount; i++) {
-                strcat(pszReturnData, ppszTextList[i]);
-            }
-        }
-        else {
-            ErrorF("winClipboardFlushXEvents - SelectionNotify - "
-                   "X*TextPropertyToTextList list_return is NULL.\n");
-            pszReturnData = malloc(1);
-            pszReturnData[0] = '\0';
-        }
-    }
-    else {
-        ErrorF("winClipboardFlushXEvents - SelectionNotify - "
-               "X*TextPropertyToTextList returned: ");
-        switch (iReturn) {
-        case XNoMemory:
-            ErrorF("XNoMemory\n");
-            break;
-        case XLocaleNotSupported:
-            ErrorF("XLocaleNotSupported\n");
-            break;
-        case XConverterNotFound:
-            ErrorF("XConverterNotFound\n");
-            break;
-        default:
-            ErrorF("%d\n", iReturn);
-            break;
-        }
+    if (xtpText_encoding == atoms->atomUTF8String) {
+        pszReturnData = malloc(xtpText_nitems + 1);
+        memcpy(pszReturnData, xtpText_value, xtpText_nitems);
+        pszReturnData[xtpText_nitems] = 0;
+        codepage = CP_UTF8; // code page identifier for utf8
+    } else if (xtpText_encoding == XCB_ATOM_STRING) {
+        // STRING encoding is Latin1 (ISO8859-1) plus tab and newline
+        pszReturnData = malloc(xtpText_nitems + 1);
+        memcpy(pszReturnData, xtpText_value, xtpText_nitems);
+        pszReturnData[xtpText_nitems] = 0;
+        codepage = CP_ISO_8559_1; // code page identifier for iso-8559-1
+    } else if (xtpText_encoding == atoms->atomCompoundText) {
+        // COMPOUND_TEXT is complex, based on ISO 2022
+        ErrorF("SelectionNotify: data in COMPOUND_TEXT encoding which is not implemented, discarding\n");
+        pszReturnData = malloc(1);
+        pszReturnData[0] = '\0';
+    } else { // shouldn't happen as we accept no other encodings
         pszReturnData = malloc(1);
         pszReturnData[0] = '\0';
     }
 
-
-    if (ppszTextList)
-        XFreeStringList(ppszTextList);
-    ppszTextList = NULL;
-
-    /* Free the data returned from XGetWindowProperty */
-    XFree(value);
-    value = NULL;
-    nitems = 0;
+    /* Free the data returned from xcb_get_property */
+    free(reply);
 
     /* Free any INCR data */
     if (data->incr) {
@@ -336,9 +309,8 @@ winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, Cl
     /* Convert the X clipboard string to DOS format */
     winClipboardUNIXtoDOS(&pszReturnData, strlen(pszReturnData));
 
-    /* Find out how much space needed to convert MBCS to Unicode */
-    int iUnicodeLen = MultiByteToWideChar(CP_UTF8,
-                                          0,
+    /* Find out how much space needed when converted to UTF-16 */
+    int iUnicodeLen = MultiByteToWideChar(codepage, 0,
                                           pszReturnData, -1, NULL, 0);
 
     /* NOTE: iUnicodeLen includes space for null terminator */
@@ -352,15 +324,12 @@ winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, Cl
     }
 
     /* Do the actual conversion */
-    MultiByteToWideChar(CP_UTF8,
-                        0,
-                        pszReturnData,
-                        -1, pwszUnicodeStr, iUnicodeLen);
+    MultiByteToWideChar(codepage, 0,
+                        pszReturnData, -1, pwszUnicodeStr, iUnicodeLen);
 
     /* Allocate global memory for the X clipboard data */
     hGlobal = GlobalAlloc(GMEM_MOVEABLE, sizeof(wchar_t) * iUnicodeLen);
 
-
     free(pszReturnData);
 
     /* Check that global memory was allocated */
@@ -404,13 +373,6 @@ winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, Cl
 
  winClipboardFlushXEvents_SelectionNotify_Done:
     /* Free allocated resources */
-    if (ppszTextList)
-        XFreeStringList(ppszTextList);
-    if (value) {
-        XFree(value);
-        value = NULL;
-        nitems = 0;
-    }
     free(pwszUnicodeStr);
     if (hGlobal && pszGlobalData)
         GlobalUnlock(hGlobal);
@@ -427,105 +389,97 @@ winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, Cl
 
 int
 winClipboardFlushXEvents(HWND hwnd,
-                         Window iWindow, Display * pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
+                         xcb_window_t iWindow, xcb_connection_t *conn,
+                         ClipboardConversionData *data, ClipboardAtoms *atoms)
 {
-    Atom atomClipboard = atoms->atomClipboard;
-    Atom atomUTF8String = atoms->atomUTF8String;
-    Atom atomCompoundText = atoms->atomCompoundText;
-    Atom atomTargets = atoms->atomTargets;
+    xcb_atom_t atomClipboard = atoms->atomClipboard;
+    xcb_atom_t atomUTF8String = atoms->atomUTF8String;
+    xcb_atom_t atomCompoundText = atoms->atomCompoundText;
+    xcb_atom_t atomTargets = atoms->atomTargets;
 
     /* Process all pending events */
-    while (XPending(pDisplay)) {
-        XTextProperty xtpText = { 0 };
-        XEvent event;
-        XSelectionEvent eventSelection;
-        char *pszGlobalData = NULL;
-        int iReturn;
+    xcb_generic_event_t *event;
+    while ((event = xcb_poll_for_event(conn))) {
+        const char *pszGlobalData = NULL;
         HGLOBAL hGlobal = NULL;
-        XICCEncodingStyle xiccesStyle;
         char *pszConvertData = NULL;
-        char *pszTextList[2] = { NULL };
         Bool fAbort = FALSE;
         Bool fCloseClipboard = FALSE;
 
-        /* Get the next event - will not block because one is ready */
-        XNextEvent(pDisplay, &event);
-
         /* Branch on the event type */
-        switch (event.type) {
-            /*
-             * SelectionRequest
-             */
+        switch (event->response_type & ~0x80) {
+        case XCB_SELECTION_REQUEST:
+        {
+            char *xtpText_value = NULL;
+            int xtpText_nitems;
+            UINT codepage;
 
-        case SelectionRequest:
+            xcb_selection_request_event_t *selection_request =  (xcb_selection_request_event_t *)event;
         {
             char *pszAtomName = NULL;
 
-            winDebug("SelectionRequest - target %ld\n",
-                     event.xselectionrequest.target);
+            winDebug("SelectionRequest - target %d\n", selection_request->target);
 
-            pszAtomName = XGetAtomName(pDisplay,
-                                       event.xselectionrequest.target);
+            pszAtomName = get_atom_name(conn, selection_request->target);
             winDebug("SelectionRequest - Target atom name %s\n", pszAtomName);
-            XFree(pszAtomName);
-            pszAtomName = NULL;
+            free(pszAtomName);
         }
 
             /* Abort if invalid target type */
-            if (event.xselectionrequest.target != XA_STRING
-                && event.xselectionrequest.target != atomUTF8String
-                && event.xselectionrequest.target != atomCompoundText
-                && event.xselectionrequest.target != atomTargets) {
+            if (selection_request->target != XCB_ATOM_STRING
+                && selection_request->target != atomUTF8String
+                && selection_request->target != atomCompoundText
+                && selection_request->target != atomTargets) {
                 /* Abort */
                 fAbort = TRUE;
                 goto winClipboardFlushXEvents_SelectionRequest_Done;
             }
 
             /* Handle targets type of request */
-            if (event.xselectionrequest.target == atomTargets) {
-                Atom atomTargetArr[] = { atomTargets,
-                    atomCompoundText,
-                    atomUTF8String,
-                    XA_STRING
-                };
+            if (selection_request->target == atomTargets) {
+                xcb_atom_t atomTargetArr[] =
+                    {
+                     atomTargets,
+                     atomUTF8String,
+                     XCB_ATOM_STRING,
+                     // atomCompoundText, not implemented (yet?)
+                    };
 
                 /* Try to change the property */
-                iReturn = XChangeProperty(pDisplay,
-                                          event.xselectionrequest.requestor,
-                                          event.xselectionrequest.property,
-                                          XA_ATOM,
+                xcb_void_cookie_t cookie = xcb_change_property_checked(conn,
+                                          XCB_PROP_MODE_REPLACE,
+                                          selection_request->requestor,
+                                          selection_request->property,
+                                          XCB_ATOM_ATOM,
                                           32,
-                                          PropModeReplace,
-                                          (unsigned char *) atomTargetArr,
-                                          ARRAY_SIZE(atomTargetArr));
-                if (iReturn == BadAlloc
-                    || iReturn == BadAtom
-                    || iReturn == BadMatch
-                    || iReturn == BadValue || iReturn == BadWindow) {
+                                          ARRAY_SIZE(atomTargetArr),
+                                          (unsigned char *) atomTargetArr);
+                xcb_generic_error_t *error;
+                if ((error = xcb_request_check(conn, cookie))) {
                     ErrorF("winClipboardFlushXEvents - SelectionRequest - "
-                           "XChangeProperty failed: %d\n", iReturn);
+                           "xcb_change_property failed");
+                    free(error);
                 }
 
                 /* Setup selection notify xevent */
-                eventSelection.type = SelectionNotify;
-                eventSelection.send_event = True;
-                eventSelection.display = pDisplay;
-                eventSelection.requestor = event.xselectionrequest.requestor;
-                eventSelection.selection = event.xselectionrequest.selection;
-                eventSelection.target = event.xselectionrequest.target;
-                eventSelection.property = event.xselectionrequest.property;
-                eventSelection.time = event.xselectionrequest.time;
+                xcb_selection_notify_event_t eventSelection;
+                eventSelection.response_type = XCB_SELECTION_NOTIFY;
+                eventSelection.requestor = selection_request->requestor;
+                eventSelection.selection = selection_request->selection;
+                eventSelection.target = selection_request->target;
+                eventSelection.property = selection_request->property;
+                eventSelection.time = selection_request->time;
 
                 /*
                  * Notify the requesting window that
                  * the operation has completed
                  */
-                iReturn = XSendEvent(pDisplay,
-                                     eventSelection.requestor,
-                                     False, 0L, (XEvent *) &eventSelection);
-                if (iReturn == BadValue || iReturn == BadWindow) {
+                cookie = xcb_send_event_checked(conn, FALSE,
+                                                eventSelection.requestor,
+                                                0, (char *) &eventSelection);
+                if ((error = xcb_request_check(conn, cookie))) {
                     ErrorF("winClipboardFlushXEvents - SelectionRequest - "
-                           "XSendEvent () failed\n");
+                           "xcb_send_event() failed\n");
                 }
                 break;
             }
@@ -567,18 +521,6 @@ winClipboardFlushXEvents(HWND hwnd,
                 goto winClipboardFlushXEvents_SelectionRequest_Done;
             }
 
-            /* Setup the string style */
-            if (event.xselectionrequest.target == XA_STRING)
-                xiccesStyle = XStringStyle;
-#ifdef X_HAVE_UTF8_STRING
-            else if (event.xselectionrequest.target == atomUTF8String)
-                xiccesStyle = XUTF8StringStyle;
-#endif
-            else if (event.xselectionrequest.target == atomCompoundText)
-                xiccesStyle = XCompoundTextStyle;
-            else
-                xiccesStyle = XStringStyle;
-
             /* Get a pointer to the clipboard text, in desired format */
             /* Retrieve clipboard data */
             hGlobal = GetClipboardData(CF_UNICODETEXT);
@@ -593,62 +535,42 @@ winClipboardFlushXEvents(HWND hwnd,
             }
             pszGlobalData = (char *) GlobalLock(hGlobal);
 
-            /* Convert the Unicode string to UTF8 (MBCS) */
-            int iConvertDataLen = WideCharToMultiByte(CP_UTF8,
-                                                      0,
-                                                      (LPCWSTR) pszGlobalData,
-                                                      -1, NULL, 0, NULL, NULL);
+            /* Convert to target string style */
+            if (selection_request->target == XCB_ATOM_STRING) {
+                codepage = CP_ISO_8559_1; // code page identifier for iso-8559-1
+            } else if (selection_request->target == atomUTF8String) {
+                codepage = CP_UTF8; // code page identifier for utf8
+            } else if (selection_request->target == atomCompoundText) {
+                // COMPOUND_TEXT is complex, not (yet) implemented
+                pszGlobalData = "COMPOUND_TEXT not implemented";
+                codepage = CP_UTF8; // code page identifier for utf8
+            }
+
+            /* Convert the UTF16 string to required encoding */
+            int iConvertDataLen = WideCharToMultiByte(codepage, 0,
+                                                      (LPCWSTR) pszGlobalData, -1,
+                                                      NULL, 0, NULL, NULL);
             /* NOTE: iConvertDataLen includes space for null terminator */
             pszConvertData = malloc(iConvertDataLen);
-            WideCharToMultiByte(CP_UTF8,
-                                0,
-                                (LPCWSTR) pszGlobalData,
-                                -1,
-                                pszConvertData,
-                                iConvertDataLen, NULL, NULL);
+            WideCharToMultiByte(codepage, 0,
+                                (LPCWSTR) pszGlobalData, -1,
+                                pszConvertData, iConvertDataLen, NULL, NULL);
 
             /* Convert DOS string to UNIX string */
             winClipboardDOStoUNIX(pszConvertData, strlen(pszConvertData));
 
-            /* Setup our text list */
-            pszTextList[0] = pszConvertData;
-            pszTextList[1] = NULL;
-
-            /* Initialize the text property */
-            xtpText.value = NULL;
-            xtpText.nitems = 0;
-
-            /* Create the text property from the text list */
-#ifdef X_HAVE_UTF8_STRING
-            iReturn = Xutf8TextListToTextProperty(pDisplay,
-                                                  pszTextList,
-                                                  1, xiccesStyle, &xtpText);
-#endif
-
-            if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) {
-                ErrorF("winClipboardFlushXEvents - SelectionRequest - "
-                       "X*TextListToTextProperty failed: %d\n", iReturn);
-
-                /* Abort */
-                fAbort = TRUE;
-                goto winClipboardFlushXEvents_SelectionRequest_Done;
-            }
-
-            /* Free the converted string */
-            free(pszConvertData);
-            pszConvertData = NULL;
+            xtpText_value = strdup(pszConvertData);
+            xtpText_nitems = strlen(pszConvertData);
 
-            /* data will fit into a single X request (INCR not yet supported) */
+            /* data will fit into a single X request? (INCR not yet supported) */
             {
-                long unsigned int maxreqsize = XExtendedMaxRequestSize(pDisplay);
-                if (maxreqsize == 0)
-                    maxreqsize = XMaxRequestSize(pDisplay);
+                uint32_t maxreqsize = xcb_get_maximum_request_length(conn);
 
                 /* covert to bytes and allow for allow for X_ChangeProperty request */
                 maxreqsize = maxreqsize*4 - 24;
 
-                if (xtpText.nitems > maxreqsize) {
-                    ErrorF("winClipboardFlushXEvents - clipboard data size %lu greater than maximum %lu\n", xtpText.nitems, maxreqsize);
+                if (xtpText_nitems > maxreqsize) {
+                    ErrorF("winClipboardFlushXEvents - clipboard data size %d greater than maximum %u\n", xtpText_nitems, maxreqsize);
 
                     /* Abort */
                     fAbort = TRUE;
@@ -657,24 +579,27 @@ winClipboardFlushXEvents(HWND hwnd,
             }
 
             /* Copy the clipboard text to the requesting window */
-            iReturn = XChangeProperty(pDisplay,
-                                      event.xselectionrequest.requestor,
-                                      event.xselectionrequest.property,
-                                      event.xselectionrequest.target,
+            xcb_void_cookie_t cookie = xcb_change_property_checked(conn,
+                                      XCB_PROP_MODE_REPLACE,
+                                      selection_request->requestor,
+                                      selection_request->property,
+                                      selection_request->target,
                                       8,
-                                      PropModeReplace,
-                                      xtpText.value, xtpText.nitems);
-            if (iReturn == BadAlloc || iReturn == BadAtom
-                || iReturn == BadMatch || iReturn == BadValue
-                || iReturn == BadWindow) {
+                                      xtpText_nitems, xtpText_value);
+            xcb_generic_error_t *error;
+            if ((error = xcb_request_check(conn, cookie))) {
                 ErrorF("winClipboardFlushXEvents - SelectionRequest - "
-                       "XChangeProperty failed: %d\n", iReturn);
+                       "xcb_change_property failed\n");
 
                 /* Abort */
                 fAbort = TRUE;
                 goto winClipboardFlushXEvents_SelectionRequest_Done;
             }
 
+            /* Free the converted string */
+            free(pszConvertData);
+            pszConvertData = NULL;
+
             /* Release the clipboard data */
             GlobalUnlock(hGlobal);
             pszGlobalData = NULL;
@@ -682,27 +607,25 @@ winClipboardFlushXEvents(HWND hwnd,
             CloseClipboard();
 
             /* Clean up */
-            XFree(xtpText.value);
-            xtpText.value = NULL;
-            xtpText.nitems = 0;
+            free(xtpText_value);
+            xtpText_value = NULL;
 
             /* Setup selection notify event */
-            eventSelection.type = SelectionNotify;
-            eventSelection.send_event = True;
-            eventSelection.display = pDisplay;
-            eventSelection.requestor = event.xselectionrequest.requestor;
-            eventSelection.selection = event.xselectionrequest.selection;
-            eventSelection.target = event.xselectionrequest.target;
-            eventSelection.property = event.xselectionrequest.property;
-            eventSelection.time = event.xselectionrequest.time;
+            xcb_selection_notify_event_t eventSelection;
+            eventSelection.response_type = XCB_SELECTION_NOTIFY;
+            eventSelection.requestor = selection_request->requestor;
+            eventSelection.selection = selection_request->selection;
+            eventSelection.target = selection_request->target;
+            eventSelection.property = selection_request->property;
+            eventSelection.time = selection_request->time;
 
             /* Notify the requesting window that the operation has completed */
-            iReturn = XSendEvent(pDisplay,
-                                 eventSelection.requestor,
-                                 False, 0L, (XEvent *) &eventSelection);
-            if (iReturn == BadValue || iReturn == BadWindow) {
+            cookie = xcb_send_event_checked(conn, FALSE,
+                                            eventSelection.requestor,
+                                            0, (char *) &eventSelection);
+            if ((error = xcb_request_check(conn, cookie))) {
                 ErrorF("winClipboardFlushXEvents - SelectionRequest - "
-                       "XSendEvent () failed\n");
+                       "xcb_send_event() failed\n");
 
                 /* Abort */
                 fAbort = TRUE;
@@ -711,12 +634,11 @@ winClipboardFlushXEvents(HWND hwnd,
 
  winClipboardFlushXEvents_SelectionRequest_Done:
             /* Free allocated resources */
-            if (xtpText.value) {
-                XFree(xtpText.value);
-                xtpText.value = NULL;
-                xtpText.nitems = 0;
+            if (xtpText_value) {
+                free(xtpText_value);
             }
-            free(pszConvertData);
+            if (pszConvertData)
+                free(pszConvertData);
             if (hGlobal && pszGlobalData)
                 GlobalUnlock(hGlobal);
 
@@ -726,26 +648,24 @@ winClipboardFlushXEvents(HWND hwnd,
              */
             if (fAbort) {
                 /* Setup selection notify event */
-                eventSelection.type = SelectionNotify;
-                eventSelection.send_event = True;
-                eventSelection.display = pDisplay;
-                eventSelection.requestor = event.xselectionrequest.requestor;
-                eventSelection.selection = event.xselectionrequest.selection;
-                eventSelection.target = event.xselectionrequest.target;
-                eventSelection.property = None;
-                eventSelection.time = event.xselectionrequest.time;
+                eventSelection.response_type = XCB_SELECTION_NOTIFY;
+                eventSelection.requestor = selection_request->requestor;
+                eventSelection.selection = selection_request->selection;
+                eventSelection.target = selection_request->target;
+                eventSelection.property = XCB_NONE;
+                eventSelection.time = selection_request->time;
 
                 /* Notify the requesting window that the operation is complete */
-                iReturn = XSendEvent(pDisplay,
-                                     eventSelection.requestor,
-                                     False, 0L, (XEvent *) &eventSelection);
-                if (iReturn == BadValue || iReturn == BadWindow) {
+                cookie = xcb_send_event_checked(conn, FALSE,
+                                                eventSelection.requestor,
+                                                0, (char *) &eventSelection);
+                if ((error = xcb_request_check(conn, cookie))) {
                     /*
                      * Should not be a problem if XSendEvent fails because
                      * the client may simply have exited.
                      */
                     ErrorF("winClipboardFlushXEvents - SelectionRequest - "
-                           "XSendEvent () failed for abort event.\n");
+                           "xcb_send_event() failed for abort event.\n");
                 }
             }
 
@@ -755,71 +675,79 @@ winClipboardFlushXEvents(HWND hwnd,
                 CloseClipboard();
             }
             break;
+        }
 
-            /*
-             * SelectionNotify
-             */
-
-        case SelectionNotify:
+        case XCB_SELECTION_NOTIFY:
+        {
+            xcb_selection_notify_event_t *selection_notify =  (xcb_selection_notify_event_t *)event;
             winDebug("winClipboardFlushXEvents - SelectionNotify\n");
             {
                 char *pszAtomName;
-
-                pszAtomName = XGetAtomName(pDisplay,
-                                           event.xselection.selection);
-
-                winDebug
-                    ("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n",
-                     pszAtomName);
-                XFree(pszAtomName);
+                pszAtomName = get_atom_name(conn, selection_notify->selection);
+                winDebug("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n", pszAtomName);
+                free(pszAtomName);
             }
 
             /*
-              SelectionNotify with property of None indicates either:
+              SelectionNotify with property of XCB_NONE indicates either:
 
               (i) Generated by the X server if no owner for the specified selection exists
                   (perhaps it's disappeared on us mid-transaction), or
               (ii) Sent by the selection owner when the requested selection conversion could
                    not be performed or server errors prevented the conversion data being returned
             */
-            if (event.xselection.property == None) {
+            if (selection_notify->property == XCB_NONE) {
                     ErrorF("winClipboardFlushXEvents - SelectionNotify - "
-                           "Conversion to format %ld refused.\n",
-                           event.xselection.target);
+                           "Conversion to format %d refused.\n",
+                           selection_notify->target);
                     return WIN_XEVENTS_FAILED;
                 }
 
-            if (event.xselection.target == atomTargets) {
-              return winClipboardSelectionNotifyTargets(hwnd, iWindow, pDisplay, data, atoms);
+            if (selection_notify->target == atomTargets) {
+              return winClipboardSelectionNotifyTargets(hwnd, iWindow, conn, data, atoms);
             }
 
-            return winClipboardSelectionNotifyData(hwnd, iWindow, pDisplay, data, atoms);
+            return winClipboardSelectionNotifyData(hwnd, iWindow, conn, data, atoms);
+        }
 
-        case SelectionClear:
+        case XCB_SELECTION_CLEAR:
             winDebug("SelectionClear - doing nothing\n");
             break;
 
-        case PropertyNotify:
+        case XCB_PROPERTY_NOTIFY:
+        {
+            xcb_property_notify_event_t *property_notify = (xcb_property_notify_event_t *)event;
+
             /* If INCR is in progress, collect the data */
             if (data->incr &&
-                (event.xproperty.atom == atoms->atomLocalProperty) &&
-                (event.xproperty.state == PropertyNewValue))
-                return winClipboardSelectionNotifyData(hwnd, iWindow, pDisplay, data, atoms);
+                (property_notify->atom == atoms->atomLocalProperty) &&
+                (property_notify->state == XCB_PROPERTY_NEW_VALUE))
+                return winClipboardSelectionNotifyData(hwnd, iWindow, conn, data, atoms);
+
+            break;
+        }
 
+        case XCB_MAPPING_NOTIFY:
             break;
 
-        case MappingNotify:
+        case 0:
+            /* This is just laziness rather than making sure we used _checked everywhere */
+            {
+                xcb_generic_error_t *err = (xcb_generic_error_t *)event;
+                ErrorF("winClipboardFlushXEvents - Error code: %i, ID: 0x%08x, "
+                       "Major opcode: %i, Minor opcode: %i\n",
+                       err->error_code, err->resource_id,
+                       err->major_code, err->minor_code);
+            }
             break;
 
         default:
-            if (event.type == XFixesSetSelectionOwnerNotify + xfixes_event_base) {
-                XFixesSelectionNotifyEvent *e =
-                    (XFixesSelectionNotifyEvent *) & event;
-
+            if ((event->response_type & ~0x80) == XCB_XFIXES_SELECTION_EVENT_SET_SELECTION_OWNER + xfixes_event_base) {
+                xcb_xfixes_selection_notify_event_t *e = (xcb_xfixes_selection_notify_event_t *)event;
                 winDebug("winClipboardFlushXEvents - XFixesSetSelectionOwnerNotify\n");
 
                 /* Save selection owners for monitored selections, ignore other selections */
-                if ((e->selection == XA_PRIMARY) && fPrimarySelection) {
+                if ((e->selection == XCB_ATOM_PRIMARY) && fPrimarySelection) {
                     MonitorSelection(e, CLIP_OWN_PRIMARY);
                 }
                 else if (e->selection == atomClipboard) {
@@ -829,9 +757,8 @@ winClipboardFlushXEvents(HWND hwnd,
                     break;
 
                 /* Selection is being disowned */
-                if (e->owner == None) {
-                    winDebug
-                        ("winClipboardFlushXEvents - No window, returning.\n");
+                if (e->owner == XCB_NONE) {
+                    winDebug("winClipboardFlushXEvents - No window, returning.\n");
                     break;
                 }
 
@@ -878,15 +805,25 @@ winClipboardFlushXEvents(HWND hwnd,
                     break;
                 }
             }
-            /* XFixesSelectionWindowDestroyNotifyMask */
-            /* XFixesSelectionClientCloseNotifyMask */
+            /* XCB_XFIXES_SELECTION_EVENT_SELECTION_WINDOW_DESTROY */
+            /* XCB_XFIXES_SELECTION_EVENT_SELECTION_CLIENT_CLOSE */
             else {
                 ErrorF("winClipboardFlushXEvents - unexpected event type %d\n",
-                       event.type);
+                       event->response_type);
             }
             break;
         }
+
+        /* I/O errors etc. */
+        {
+            int e = xcb_connection_has_error(conn);
+            if (e) {
+                ErrorF("winClipboardFlushXEvents - Fatal error %d on xcb connection\n", e);
+                break;
+            }
+        }
     }
 
     return WIN_XEVENTS_SUCCESS;
+
 }
diff --git a/hw/xwin/winclipboard/xwinclip.c b/hw/xwin/winclipboard/xwinclip.c
index 6fd1c7598..4df8cd4af 100644
--- a/hw/xwin/winclipboard/xwinclip.c
+++ b/hw/xwin/winclipboard/xwinclip.c
@@ -35,27 +35,10 @@
 #include <xwin-config.h>
 #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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-/* X headers */
-#include <X11/Xlib.h>
-#ifdef X_LOCALE
-#include <X11/Xlocale.h>
-#else /* X_LOCALE */
-#include <locale.h>
-#endif /* X_LOCALE */
-
 #include "winclipboard.h"
 
 /*
@@ -87,7 +70,7 @@ main (int argc, char *argv[])
       /* Look for -noprimary */
       if (!strcmp (argv[i], "-noprimary"))
 	{
-	  fPrimarySelection = False;
+	  fPrimarySelection = 0;
 	  continue;
 	}
 
@@ -96,21 +79,7 @@ main (int argc, char *argv[])
       exit (1);
     }
 
-  /* 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(pszDisplay);
+  winClipboardProc(pszDisplay, NULL /* Use XAUTHORITY for auth data */);
 
   return 0;
 }
diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c
index 3324661df..1e920f51f 100644
--- a/hw/xwin/winclipboardinit.c
+++ b/hw/xwin/winclipboardinit.c
@@ -42,6 +42,8 @@
 #define WIN_CLIPBOARD_RETRIES			40
 #define WIN_CLIPBOARD_DELAY			1
 
+extern xcb_auth_info_t *winGetXcbAuthInfo(void);
+
 /*
  * Local variables
  */
@@ -55,6 +57,7 @@ static void *
 winClipboardThreadProc(void *arg)
 {
   char szDisplay[512];
+  xcb_auth_info_t *auth_info;
   int clipboardRestarts = 0;
 
   while (1)
@@ -82,7 +85,10 @@ winClipboardThreadProc(void *arg)
       /* Flag that clipboard client has been launched */
       g_fClipboardStarted = TRUE;
 
-      fShutdown = winClipboardProc(szDisplay);
+      /* Use our generated cookie for authentication */
+      auth_info = winGetXcbAuthInfo();
+
+      fShutdown = winClipboardProc(szDisplay, auth_info);
 
       /* Flag that clipboard client has stopped */
       g_fClipboardStarted = FALSE;
commit f4936de73c094e35eb293f32ab470347741a4fa0
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Sun Jul 1 12:11:19 2018 +0100

    hw/xwin: Remove nounicodeclipboard option
    
    Always use CF_UNICODETEXT clipboard format.  Windows will automatically
    down-convert to CF_TEXT for clients which request that.
    
    This is subtly different in one way: if CF_TEXT is requested, we now
    post CF_UNICODETEXT and it is converted to CF_TEXT *in the locale of the
    requesting process*.  Previously, we would convert to CF_TEXT *in our
    locale* and post that.
    
    It looks like the code in the !X_HAVE_UTF8_STRING case didn't actually
    work correctly, but fortunately that has never been true...

diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 2e07464ff..872a1fdcd 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -796,9 +796,6 @@ winUseMsg(void)
            "\tDo not draw a window border, title bar, etc.  Windowed\n"
            "\tmode only.\n");
 
-    ErrorF("-nounicodeclipboard\n"
-           "\tDo not use Unicode clipboard even if on a NT-based platform.\n");
-
     ErrorF("-[no]primary\n"
            "\tWhen clipboard integration is enabled, map the X11 PRIMARY selection\n"
            "\tto the Windows clipboard. Default is enabled.\n");
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index 56bea1c12..296ce4c9f 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -233,9 +233,6 @@ icon per screen.  You can globally disable tray icons with
 \fB\-notrayicon\fP, then enable it for specific screens with
 \fB\-trayicon\fP for those screens.
 .TP 8
-.B \-nounicodeclipboard
-Do not use Unicode clipboard even if on a NT-based platform.
-.TP 8
 .B \-[no]unixkill
 Enable or disable the \fICtrl-Alt-Backspace\fP key combination as a
 signal to exit the X Server.  The \fICtrl-Alt-Backspace\fP key combination
diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h
index 6dc2fb660..2c4a20426 100644
--- a/hw/xwin/winclipboard/internal.h
+++ b/hw/xwin/winclipboard/internal.h
@@ -100,7 +100,6 @@ typedef struct
 
 typedef struct
 {
-  Bool fUseUnicode;
   Atom *targetList;
   unsigned char *incr;
   unsigned long int incrsize;
diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c
index 5669a2626..8949e7235 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -104,7 +104,7 @@ static int
  */
 
 Bool
-winClipboardProc(Bool fUseUnicode, char *szDisplay)
+winClipboardProc(char *szDisplay)
 {
     ClipboardAtoms atoms;
     int iReturn;
@@ -256,7 +256,6 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
         }
     }
 
-    data.fUseUnicode = fUseUnicode;
     data.incr = NULL;
     data.incrsize = 0;
 
diff --git a/hw/xwin/winclipboard/winclipboard.h b/hw/xwin/winclipboard/winclipboard.h
index 9c5c568a7..2ae27fd2b 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(Bool fUseUnicode, char *szDisplay);
+Bool winClipboardProc(char *szDisplay);
 
 void winFixClipboardChain(void);
 
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index b6d92f6d8..ee2266a3d 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -316,7 +316,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     case WM_RENDERFORMAT:
     {
         int iReturn;
-        Bool fConvertToUnicode;
         Bool pasted = FALSE;
         Atom selection;
         ClipboardConversionData data;
@@ -325,9 +324,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         winDebug("winClipboardWindowProc - WM_RENDERFORMAT %d - Hello.\n",
                  (int)wParam);
 
-        /* Flag whether to convert to Unicode or not */
-        fConvertToUnicode = (CF_UNICODETEXT == wParam);
-
         selection = winClipboardGetLastOwnedSelectionAtom(atoms);
         if (selection == None) {
             ErrorF("winClipboardWindowProc - no monitored selection is owned\n");
@@ -344,7 +340,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                           iWindow, CurrentTime);
 
         /* Process X events */
-        data.fUseUnicode = fConvertToUnicode;
         data.incr = NULL;
         data.incrsize = 0;
 
diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c
index 7d55f3d92..36e136148 100644
--- a/hw/xwin/winclipboard/xevents.c
+++ b/hw/xwin/winclipboard/xevents.c
@@ -200,7 +200,6 @@ winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, Cl
     char *pszReturnData = NULL;
     wchar_t *pwszUnicodeStr = NULL;
     HGLOBAL hGlobal = NULL;
-    char *pszConvertData = NULL;
     char *pszGlobalData = NULL;
 
     /* Retrieve the selection data and delete the property */
@@ -268,19 +267,13 @@ winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, Cl
         xtpText.nitems = nitems;
     }
 
-    if (data->fUseUnicode) {
 #ifdef X_HAVE_UTF8_STRING
-        /* Convert the text property to a text list */
-        iReturn = Xutf8TextPropertyToTextList(pDisplay,
-                                              &xtpText,
-                                              &ppszTextList, &iCount);
+    /* Convert the text property to a text list */
+    iReturn = Xutf8TextPropertyToTextList(pDisplay,
+                                          &xtpText,
+                                          &ppszTextList, &iCount);
 #endif
-    }
-    else {
-        iReturn = XmbTextPropertyToTextList(pDisplay,
-                                            &xtpText,
-                                            &ppszTextList, &iCount);
-    }
+
     if (iReturn == Success || iReturn > 0) {
         /* Conversion succeeded or some unconvertible characters */
         if (ppszTextList != NULL) {
@@ -343,40 +336,30 @@ winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, Cl
     /* Convert the X clipboard string to DOS format */
     winClipboardUNIXtoDOS(&pszReturnData, strlen(pszReturnData));
 
-    if (data->fUseUnicode) {
-        /* Find out how much space needed to convert MBCS to Unicode */
-        int iUnicodeLen = MultiByteToWideChar(CP_UTF8,
-                                              0,
-                                              pszReturnData, -1, NULL, 0);
+    /* Find out how much space needed to convert MBCS to Unicode */
+    int iUnicodeLen = MultiByteToWideChar(CP_UTF8,
+                                          0,
+                                          pszReturnData, -1, NULL, 0);
 
-        /* NOTE: iUnicodeLen includes space for null terminator */
-        pwszUnicodeStr = malloc(sizeof(wchar_t) * iUnicodeLen);
-        if (!pwszUnicodeStr) {
-            ErrorF("winClipboardFlushXEvents - SelectionNotify "
-                   "malloc failed for pwszUnicodeStr, aborting.\n");
+    /* NOTE: iUnicodeLen includes space for null terminator */
+    pwszUnicodeStr = malloc(sizeof(wchar_t) * iUnicodeLen);
+    if (!pwszUnicodeStr) {
+        ErrorF("winClipboardFlushXEvents - SelectionNotify "
+               "malloc failed for pwszUnicodeStr, aborting.\n");
 
-            /* Abort */
-            goto winClipboardFlushXEvents_SelectionNotify_Done;
-        }
+        /* Abort */
+        goto winClipboardFlushXEvents_SelectionNotify_Done;
+    }
 
-        /* Do the actual conversion */
-        MultiByteToWideChar(CP_UTF8,
-                            0,
-                            pszReturnData,
-                            -1, pwszUnicodeStr, iUnicodeLen);
+    /* Do the actual conversion */
+    MultiByteToWideChar(CP_UTF8,
+                        0,
+                        pszReturnData,
+                        -1, pwszUnicodeStr, iUnicodeLen);
 
-        /* Allocate global memory for the X clipboard data */
-        hGlobal = GlobalAlloc(GMEM_MOVEABLE,
-                              sizeof(wchar_t) * iUnicodeLen);
-    }
-    else {
-        int iConvertDataLen = 0;
-        pszConvertData = strdup(pszReturnData);
-        iConvertDataLen = strlen(pszConvertData) + 1;
+    /* Allocate global memory for the X clipboard data */
+    hGlobal = GlobalAlloc(GMEM_MOVEABLE, sizeof(wchar_t) * iUnicodeLen);
 
-        /* Allocate global memory for the X clipboard data */
-        hGlobal = GlobalAlloc(GMEM_MOVEABLE, iConvertDataLen);
-    }
 
     free(pszReturnData);
 
@@ -400,26 +383,16 @@ winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, Cl
     }
 
     /* Copy the returned string into the global memory */
-    if (data->fUseUnicode) {
-        wcscpy((wchar_t *)pszGlobalData, pwszUnicodeStr);
-        free(pwszUnicodeStr);
-        pwszUnicodeStr = NULL;
-    }
-    else {
-        strcpy(pszGlobalData, pszConvertData);
-        free(pszConvertData);
-        pszConvertData = NULL;
-    }
+    wcscpy((wchar_t *)pszGlobalData, pwszUnicodeStr);
+    free(pwszUnicodeStr);
+    pwszUnicodeStr = NULL;
 
     /* Release the pointer to the global memory */
     GlobalUnlock(hGlobal);
     pszGlobalData = NULL;
 
     /* Push the selection data to the Windows clipboard */
-    if (data->fUseUnicode)
-        SetClipboardData(CF_UNICODETEXT, hGlobal);
-    else
-        SetClipboardData(CF_TEXT, hGlobal);
+    SetClipboardData(CF_UNICODETEXT, hGlobal);
 
     /* Flag that SetClipboardData has been called */
     fSetClipboardData = FALSE;
@@ -438,7 +411,6 @@ winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, Cl
         value = NULL;
         nitems = 0;
     }
-    free(pszConvertData);
     free(pwszUnicodeStr);
     if (hGlobal && pszGlobalData)
         GlobalUnlock(hGlobal);
@@ -577,7 +549,7 @@ winClipboardFlushXEvents(HWND hwnd,
             fCloseClipboard = TRUE;
 
             /* Check that clipboard format is available */
-            if (data->fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+            if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) {
                 static int count;       /* Hack to stop acroread spamming the log */
                 static HWND lasthwnd;   /* I've not seen any other client get here repeatedly? */
 
@@ -594,14 +566,6 @@ winClipboardFlushXEvents(HWND hwnd,
                 fAbort = TRUE;
                 goto winClipboardFlushXEvents_SelectionRequest_Done;
             }
-            else if (!data->fUseUnicode && !IsClipboardFormatAvailable(CF_TEXT)) {
-                ErrorF("winClipboardFlushXEvents - CF_TEXT is not "
-                       "available from Win32 clipboard.  Aborting.\n");
-
-                /* Abort */
-                fAbort = TRUE;
-                goto winClipboardFlushXEvents_SelectionRequest_Done;
-            }
 
             /* Setup the string style */
             if (event.xselectionrequest.target == XA_STRING)
@@ -616,14 +580,9 @@ winClipboardFlushXEvents(HWND hwnd,
                 xiccesStyle = XStringStyle;
 
             /* Get a pointer to the clipboard text, in desired format */
-            if (data->fUseUnicode) {
-                /* Retrieve clipboard data */
-                hGlobal = GetClipboardData(CF_UNICODETEXT);
-            }
-            else {
-                /* Retrieve clipboard data */
-                hGlobal = GetClipboardData(CF_TEXT);
-            }
+            /* Retrieve clipboard data */
+            hGlobal = GetClipboardData(CF_UNICODETEXT);
+
             if (!hGlobal) {
                 ErrorF("winClipboardFlushXEvents - SelectionRequest - "
                        "GetClipboardData () failed: %08x\n", (unsigned int)GetLastError());
@@ -635,23 +594,18 @@ winClipboardFlushXEvents(HWND hwnd,
             pszGlobalData = (char *) GlobalLock(hGlobal);
 
             /* Convert the Unicode string to UTF8 (MBCS) */
-            if (data->fUseUnicode) {
-                int iConvertDataLen = WideCharToMultiByte(CP_UTF8,
+            int iConvertDataLen = WideCharToMultiByte(CP_UTF8,
                                                       0,
                                                       (LPCWSTR) pszGlobalData,
                                                       -1, NULL, 0, NULL, NULL);
-                /* NOTE: iConvertDataLen includes space for null terminator */
-                pszConvertData = malloc(iConvertDataLen);
-                WideCharToMultiByte(CP_UTF8,
-                                    0,
-                                    (LPCWSTR) pszGlobalData,
-                                    -1,
-                                    pszConvertData,
-                                    iConvertDataLen, NULL, NULL);
-            }
-            else {
-                pszConvertData = strdup(pszGlobalData);
-            }
+            /* NOTE: iConvertDataLen includes space for null terminator */
+            pszConvertData = malloc(iConvertDataLen);
+            WideCharToMultiByte(CP_UTF8,
+                                0,
+                                (LPCWSTR) pszGlobalData,
+                                -1,
+                                pszConvertData,
+                                iConvertDataLen, NULL, NULL);
 
             /* Convert DOS string to UNIX string */
             winClipboardDOStoUNIX(pszConvertData, strlen(pszConvertData));
@@ -665,18 +619,12 @@ winClipboardFlushXEvents(HWND hwnd,
             xtpText.nitems = 0;
 
             /* Create the text property from the text list */
-            if (data->fUseUnicode) {
 #ifdef X_HAVE_UTF8_STRING
-                iReturn = Xutf8TextListToTextProperty(pDisplay,
-                                                      pszTextList,
-                                                      1, xiccesStyle, &xtpText);
+            iReturn = Xutf8TextListToTextProperty(pDisplay,
+                                                  pszTextList,
+                                                  1, xiccesStyle, &xtpText);
 #endif
-            }
-            else {
-                iReturn = XmbTextListToTextProperty(pDisplay,
-                                                    pszTextList,
-                                                    1, xiccesStyle, &xtpText);
-            }
+
             if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) {
                 ErrorF("winClipboardFlushXEvents - SelectionRequest - "
                        "X*TextListToTextProperty failed: %d\n", iReturn);
diff --git a/hw/xwin/winclipboard/xwinclip.c b/hw/xwin/winclipboard/xwinclip.c
index 856c4dd54..6fd1c7598 100644
--- a/hw/xwin/winclipboard/xwinclip.c
+++ b/hw/xwin/winclipboard/xwinclip.c
@@ -67,7 +67,6 @@ main (int argc, char *argv[])
 {
   int			i;
   char			*pszDisplay = NULL;
-  int			fUnicodeClipboard = 1;
 
   /* Parse command-line parameters */
   for (i = 1; i < argc; ++i)
@@ -85,13 +84,6 @@ main (int argc, char *argv[])
 	  continue;
 	}
 
-      /* Look for -nounicodeclipboard */
-      if (!strcmp (argv[i], "-nounicodeclipboard"))
-	{
-	  fUnicodeClipboard = 0;
-	  continue;
-	}
-
       /* Look for -noprimary */
       if (!strcmp (argv[i], "-noprimary"))
 	{
@@ -104,16 +96,6 @@ main (int argc, char *argv[])
       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, ""))
     {
@@ -128,7 +110,7 @@ main (int argc, char *argv[])
       setlocale(LC_ALL, "C");
     }
 
-  winClipboardProc(fUnicodeClipboard, pszDisplay);
+  winClipboardProc(pszDisplay);
 
   return 0;
 }
diff --git a/hw/xwin/winclipboard/xwinclip.man b/hw/xwin/winclipboard/xwinclip.man
index f9e0d3bfb..e3db50177 100644
--- a/hw/xwin/winclipboard/xwinclip.man
+++ b/hw/xwin/winclipboard/xwinclip.man
@@ -27,9 +27,6 @@ Do \fINOT\fP run \fIxwinclip\fP unless \fIXWin(1)\fP has been started with the -
 .B \-display [display]
 Specifies the X server display to connect to.
 .TP 8
-.B \-nounicodeclipboard
-Do not use unicode text on the clipboard.
-.TP 8
 .B \-noprimary
 Do not monitor the PRIMARY selection.
 
diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c
index 8aef8fe02..3324661df 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(g_fUnicodeClipboard, szDisplay);
+      fShutdown = winClipboardProc(szDisplay);
 
       /* Flag that clipboard client has stopped */
       g_fClipboardStarted = FALSE;
diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c
index 3212c6beb..29abe1970 100644
--- a/hw/xwin/winglobals.c
+++ b/hw/xwin/winglobals.c
@@ -90,7 +90,6 @@ winDispatchProcPtr winProcEstablishConnectionOrig = NULL;
  * Clipboard variables
  */
 
-Bool g_fUnicodeClipboard = TRUE;
 Bool g_fClipboard = TRUE;
 Bool g_fClipboardStarted = FALSE;
 
diff --git a/hw/xwin/winglobals.h b/hw/xwin/winglobals.h
index 77af6125a..29535f05a 100644
--- a/hw/xwin/winglobals.h
+++ b/hw/xwin/winglobals.h
@@ -70,7 +70,6 @@ typedef int (*winDispatchProcPtr) (ClientPtr);
  * Wrapped DIX functions
  */
 extern winDispatchProcPtr winProcEstablishConnectionOrig;
-extern Bool g_fUnicodeClipboard;
 extern Bool g_fClipboard;
 extern Bool g_fClipboardStarted;
 
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index b5c2643be..50b1f6c38 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -1004,15 +1004,6 @@ ddxProcessArgument(int argc, char *argv[], int i)
         return 2;
     }
 
-    /*
-     * Look for the '-nounicodeclipboard' argument
-     */
-    if (IS_OPTION("-nounicodeclipboard")) {
-        g_fUnicodeClipboard = FALSE;
-        /* Indicate that we have processed the argument */
-        return 1;
-    }
-
     if (IS_OPTION("-xkbrules")) {
         CHECK_ARGS(1);
         g_cmdline.xkbRules = argv[++i];
commit 9f51dfdec37c991173c7a580fd1c279cfe09142e
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Sat Jun 30 16:15:52 2018 +0100

    hw/xwin: Remove support for pre-Vista Win32 clipboard API
    
    The original Win32 clipboard API is widely regarded as terrible, since
    it relies on clients co-operatively managing the clipboard viewer chain,
    and a single buggy client can break it for all other clients.
    
    The last Windows version only supporting that API was Windows XP (5.1),
    EOLed in 2014.
    
    (This requires MinGW-w64 w32api 6.0.0 or later for
    Add/RemoveClipboardListener correctly exported by the x86_64 user32
    implib)

diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h
index 766a836ae..6dc2fb660 100644
--- a/hw/xwin/winclipboard/internal.h
+++ b/hw/xwin/winclipboard/internal.h
@@ -42,7 +42,6 @@
 #define WIN_XEVENTS_NOTIFY_DATA			3
 #define WIN_XEVENTS_NOTIFY_TARGETS		4
 
-#define WM_WM_REINIT                           (WM_USER + 1)
 #define WM_WM_QUIT                             (WM_USER + 2)
 
 #define ARRAY_SIZE(a)  (sizeof((a)) / sizeof((a)[0]))
@@ -79,14 +78,6 @@ typedef struct
     Atom atomIncr;
 } ClipboardAtoms;
 
-/* Modern clipboard API functions */
-typedef wBOOL WINAPI (*ADDCLIPBOARDFORMATLISTENERPROC)(HWND hwnd);
-typedef wBOOL WINAPI (*REMOVECLIPBOARDFORMATLISTENERPROC)(HWND hwnd);
-
-extern Bool g_fHasModernClipboardApi;
-extern ADDCLIPBOARDFORMATLISTENERPROC g_fpAddClipboardFormatListener;
-extern REMOVECLIPBOARDFORMATLISTENERPROC g_fpRemoveClipboardFormatListener;
-
 /*
  * winclipboardwndproc.c
  */
diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c
index 8be6991cc..5669a2626 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -84,10 +84,6 @@ static pthread_t g_winClipboardProcThread;
 int xfixes_event_base;
 int xfixes_error_base;
 
-Bool g_fHasModernClipboardApi = FALSE;
-ADDCLIPBOARDFORMATLISTENERPROC g_fpAddClipboardFormatListener;
-REMOVECLIPBOARDFORMATLISTENERPROC g_fpRemoveClipboardFormatListener;
-
 /*
  * Local function prototypes
  */
@@ -142,11 +138,6 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
         ErrorF("winClipboardProc - Warning: Locale not supported by X.\n");
     }
 
-    g_fpAddClipboardFormatListener = (ADDCLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"AddClipboardFormatListener");
-    g_fpRemoveClipboardFormatListener = (REMOVECLIPBOARDFORMATLISTENERPROC)GetProcAddress(GetModuleHandle("user32"),"RemoveClipboardFormatListener");
-    g_fHasModernClipboardApi = g_fpAddClipboardFormatListener && g_fpRemoveClipboardFormatListener;
-    ErrorF("OS maintains clipboard viewer chain: %s\n", g_fHasModernClipboardApi ? "yes" : "no");
-
     g_winClipboardProcThread = pthread_self();
 
     /* Set error handler */
@@ -506,11 +497,3 @@ winClipboardWindowDestroy(void)
     SendMessage(g_hwndClipboard, WM_WM_QUIT, 0, 0);
   }
 }
-
-void
-winFixClipboardChain(void)
-{
-  if (g_hwndClipboard) {
-    PostMessage(g_hwndClipboard, WM_WM_REINIT, 0, 0);
-  }
-}
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index 990febced..b6d92f6d8 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -30,6 +30,8 @@
  *              Colin Harrison
  */
 
+#define WINVER 0x0600
+
 #ifdef HAVE_XWIN_CONFIG_H
 #include <xwin-config.h>
 #endif
@@ -58,10 +60,6 @@
 
 #define WIN_POLL_TIMEOUT	1
 
-#ifndef WM_CLIPBOARDUPDATE
-#define WM_CLIPBOARDUPDATE 0x031D
-#endif
-
 /*
  * Process X events up to specified timeout
  */
@@ -138,8 +136,6 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
 LRESULT CALLBACK
 winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
-    static HWND s_hwndNextViewer;
-    static Bool s_fCBCInitialized;
     static Display *pDisplay;
     static Window iWindow;
     static ClipboardAtoms *atoms;
@@ -151,18 +147,8 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     {
         winDebug("winClipboardWindowProc - WM_DESTROY\n");
 
-        if (g_fHasModernClipboardApi)
-            {
-                /* Remove clipboard listener */
-                g_fpRemoveClipboardFormatListener(hwnd);
-            }
-        else
-            {
-                /* Remove ourselves from the clipboard chain */
-                ChangeClipboardChain(hwnd, s_hwndNextViewer);
-            }
-
-        s_hwndNextViewer = NULL;
+        /* Remove clipboard listener */
+        RemoveClipboardFormatListener(hwnd);
     }
         return 0;
 
@@ -185,138 +171,15 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         atoms = cwcp->atoms;
         fRunning = TRUE;
 
-        if (g_fHasModernClipboardApi)
-            {
-                g_fpAddClipboardFormatListener(hwnd);
-            }
-        else
-            {
-                HWND first, next;
-                DWORD error_code = 0;
-
-                first = GetClipboardViewer();   /* Get handle to first viewer in chain. */
-                if (first == hwnd)
-                    return 0;           /* Make sure it's not us! */
-                /* Add ourselves to the clipboard viewer chain */
-                next = SetClipboardViewer(hwnd);
-                error_code = GetLastError();
-                if (SUCCEEDED(error_code) && (next == first))   /* SetClipboardViewer must have succeeded, and the handle */
-                    s_hwndNextViewer = next;    /* it returned must have been the first window in the chain */
-                else
-                    s_fCBCInitialized = FALSE;
-            }
-    }
-        return 0;
-
-    case WM_CHANGECBCHAIN:
-    {
-        winDebug("winClipboardWindowProc - WM_CHANGECBCHAIN: wParam(%p) "
-                 "lParam(%p) s_hwndNextViewer(%p)\n",
-                 (HWND)wParam, (HWND)lParam, s_hwndNextViewer);
-
-        if ((HWND) wParam == s_hwndNextViewer) {
-            s_hwndNextViewer = (HWND) lParam;
-            if (s_hwndNextViewer == hwnd) {
-                s_hwndNextViewer = NULL;
-                ErrorF("winClipboardWindowProc - WM_CHANGECBCHAIN: "
-                       "attempted to set next window to ourselves.");
-            }
-        }
-        else if (s_hwndNextViewer)
-            SendMessage(s_hwndNextViewer, message, wParam, lParam);
-
-    }
-        winDebug("winClipboardWindowProc - WM_CHANGECBCHAIN: Exit\n");
-        return 0;
-
-    case WM_WM_REINIT:
-    {
-        /* Ensure that we're in the clipboard chain.  Some apps,
-         * WinXP's remote desktop for one, don't play nice with the
-         * chain.  This message is called whenever we receive a
-         * WM_ACTIVATEAPP message to ensure that we continue to
-         * receive clipboard messages.
-         *
-         * It might be possible to detect if we're still in the chain
-         * by calling SendMessage (GetClipboardViewer(),
-         * WM_DRAWCLIPBOARD, 0, 0); and then seeing if we get the
-         * WM_DRAWCLIPBOARD message.  That, however, might be more
-         * expensive than just putting ourselves back into the chain.
-         */
-
-        HWND first, next;
-        DWORD error_code = 0;
-
-        winDebug("winClipboardWindowProc - WM_WM_REINIT: Enter\n");
-
-        if (g_fHasModernClipboardApi)
-            {
-                return 0;
-            }
-
-        first = GetClipboardViewer();   /* Get handle to first viewer in chain. */
-        if (first == hwnd)
-            return 0;           /* Make sure it's not us! */
-        winDebug("  WM_WM_REINIT: Replacing us(%p) with %p at head "
-                 "of chain\n", hwnd, s_hwndNextViewer);
-        s_fCBCInitialized = FALSE;
-        ChangeClipboardChain(hwnd, s_hwndNextViewer);
-        s_hwndNextViewer = NULL;
-        s_fCBCInitialized = FALSE;
-        winDebug("  WM_WM_REINIT: Putting us back at head of chain.\n");
-        first = GetClipboardViewer();   /* Get handle to first viewer in chain. */
-        if (first == hwnd)
-            return 0;           /* Make sure it's not us! */
-        next = SetClipboardViewer(hwnd);
-        error_code = GetLastError();
-        if (SUCCEEDED(error_code) && (next == first))   /* SetClipboardViewer must have succeeded, and the handle */
-            s_hwndNextViewer = next;    /* it returned must have been the first window in the chain */
-        else
-            s_fCBCInitialized = FALSE;
+        AddClipboardFormatListener(hwnd);
     }
-        winDebug("winClipboardWindowProc - WM_WM_REINIT: Exit\n");
         return 0;
 
-    case WM_DRAWCLIPBOARD:
     case WM_CLIPBOARDUPDATE:
     {
-        static Bool s_fProcessingDrawClipboard = FALSE;
         int iReturn;
 
-        if (message == WM_DRAWCLIPBOARD)
-            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n");
-        else
-            winDebug("winClipboardWindowProc -  WM_CLIPBOARDUPDATE: Enter\n");
-
-        if (!g_fHasModernClipboardApi)
-            {
-                /*
-                 * We've occasionally seen a loop in the clipboard chain.
-                 * Try and fix it on the first hint of recursion.
-                 */
-                if (!s_fProcessingDrawClipboard) {
-                    s_fProcessingDrawClipboard = TRUE;
-                }
-                else {
-                    /* Attempt to break the nesting by getting out of the chain, twice?, and then fix and bail */
-                    s_fCBCInitialized = FALSE;
-                    ChangeClipboardChain(hwnd, s_hwndNextViewer);
-                    winFixClipboardChain();
-                    ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
-                           "Nested calls detected.  Re-initing.\n");
-                    winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
-                    s_fProcessingDrawClipboard = FALSE;
-                    return 0;
-                }
-
-                /* Bail on first message */
-                if (!s_fCBCInitialized) {
-                    s_fCBCInitialized = TRUE;
-                    s_fProcessingDrawClipboard = FALSE;
-                    winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
-                    return 0;
-                }
-            }
+        winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Enter\n");
 
         /*
          * NOTE: We cannot bail out when NULL == GetClipboardOwner ()
@@ -329,12 +192,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         /* Bail when we still own the clipboard */
         if (hwnd == GetClipboardOwner()) {
 
-            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+            winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                      "We own the clipboard, returning.\n");
-            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
-            s_fProcessingDrawClipboard = FALSE;
-            if (s_hwndNextViewer)
-                SendMessage(s_hwndNextViewer, message, wParam, lParam);
+            winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Exit\n");
+
             return 0;
         }
 
@@ -350,7 +211,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         if (!IsClipboardFormatAvailable(CF_TEXT)
             && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
 
-            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+            winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                      "Clipboard does not contain CF_TEXT nor "
                      "CF_UNICODETEXT.\n");
 
@@ -365,31 +226,29 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             /* Release PRIMARY selection if owned */
             iReturn = XGetSelectionOwner(pDisplay, XA_PRIMARY);
             if (iReturn == iWindow) {
-                winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+                winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                          "PRIMARY selection is owned by us.\n");
                 XSetSelectionOwner(pDisplay, XA_PRIMARY, None, CurrentTime);
             }
             else if (BadWindow == iReturn || BadAtom == iReturn)
-                ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+                ErrorF("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                        "XGetSelectionOwner failed for PRIMARY: %d\n",
                        iReturn);
 
             /* Release CLIPBOARD selection if owned */
             iReturn = XGetSelectionOwner(pDisplay, atoms->atomClipboard);
             if (iReturn == iWindow) {
-                winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+                winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                          "CLIPBOARD selection is owned by us, releasing\n");
                 XSetSelectionOwner(pDisplay, atoms->atomClipboard, None, CurrentTime);
             }
             else if (BadWindow == iReturn || BadAtom == iReturn)
-                ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+                ErrorF("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                        "XGetSelectionOwner failed for CLIPBOARD: %d\n",
                        iReturn);
 
-            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
-            s_fProcessingDrawClipboard = FALSE;
-            if (s_hwndNextViewer)
-                SendMessage(s_hwndNextViewer, message, wParam, lParam);
+            winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Exit\n");
+
             return 0;
         }
 
@@ -398,11 +257,11 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                                      XA_PRIMARY, iWindow, CurrentTime);
         if (iReturn == BadAtom || iReturn == BadWindow ||
             XGetSelectionOwner(pDisplay, XA_PRIMARY) != iWindow) {
-            ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+            ErrorF("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                    "Could not reassert ownership of PRIMARY\n");
         }
         else {
-            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+            winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                      "Reasserted ownership of PRIMARY\n");
         }
 
@@ -412,33 +271,28 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         if (iReturn == BadAtom || iReturn == BadWindow ||
             XGetSelectionOwner(pDisplay, atoms->atomClipboard) != iWindow) {
-            ErrorF("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+            ErrorF("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                     "Could not reassert ownership of CLIPBOARD\n");
         }
         else {
-            winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+            winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE - "
                      "Reasserted ownership of CLIPBOARD\n");
         }
 
         /* Flush the pending SetSelectionOwner event now */
         XFlush(pDisplay);
-
-        s_fProcessingDrawClipboard = FALSE;
     }
-        winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
-        /* Pass the message on the next window in the clipboard viewer chain */
-        if (s_hwndNextViewer)
-            SendMessage(s_hwndNextViewer, message, wParam, lParam);
+        winDebug("winClipboardWindowProc - WM_CLIPBOARDUPDATE: Exit\n");
         return 0;
 
     case WM_DESTROYCLIPBOARD:
         /*
          * NOTE: Intentionally do nothing.
-         * Changes in the Win32 clipboard are handled by WM_DRAWCLIPBOARD
+         * Changes in the Win32 clipboard are handled by WM_CLIPBOARDUPDATE
          * above.  We only process this message to conform to the specs
          * for delayed clipboard rendering in Win32.  You might think
          * that we need to release ownership of the X11 selections, but
-         * we do not, because a WM_DRAWCLIPBOARD message will closely
+         * we do not, because a WM_CLIPBOARDUPDATE message will closely
          * follow this message and reassert ownership of the X11
          * selections, handling the issue for us.
          */
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 224bfba79..456213bc3 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -1113,9 +1113,6 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             ShowCursor(TRUE);
         }
 
-        /* Make sure the clipboard chain is ok. */
-        winFixClipboardChain();
-
         /* Call engine specific screen activation/deactivation function */
         (*s_pScreenPriv->pwinActivateApp) (s_pScreen);
 
commit 9a4b62798bf4bcc2828a2a485e878e7d4447d03d
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Fri Apr 26 02:26:44 2019 +0100

    hw/xwin: Fix lingering uses of libX11 types and values

diff --git a/hw/xwin/winmultiwindowicons.c b/hw/xwin/winmultiwindowicons.c
index c43c29887..f39f842db 100644
--- a/hw/xwin/winmultiwindowicons.c
+++ b/hw/xwin/winmultiwindowicons.c
@@ -40,7 +40,6 @@
 #include <stdbool.h>
 
 #include <X11/Xwindows.h>
-#include <X11/Xlib.h>
 #include <xcb/xcb.h>
 #include <xcb/xcb_icccm.h>
 #include <xcb/xcb_image.h>
@@ -582,7 +581,7 @@ winXIconToHICON(xcb_connection_t *conn, xcb_window_t id, int iconSize)
  */
 
 void
-winUpdateIcon(HWND hWnd, xcb_connection_t *conn, Window id, HICON hIconNew)
+winUpdateIcon(HWND hWnd, xcb_connection_t *conn, xcb_window_t id, HICON hIconNew)
 {
     HICON hIcon, hIconSmall = NULL, hIconOld;
 
diff --git a/hw/xwin/winmultiwindowicons.h b/hw/xwin/winmultiwindowicons.h
index 87ba8d1cf..8b077ab80 100644
--- a/hw/xwin/winmultiwindowicons.h
+++ b/hw/xwin/winmultiwindowicons.h
@@ -30,7 +30,7 @@
 #include <xcb/xcb.h>
 
 void
- winUpdateIcon(HWND hWnd, xcb_connection_t *conn, Window id, HICON hIconNew);
+ winUpdateIcon(HWND hWnd, xcb_connection_t *conn, xcb_window_t id, HICON hIconNew);
 
 void
  winInitGlobalIcons(void);
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index aa83c2c41..fa339a9fb 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -1275,7 +1275,7 @@ winMultiWindowXMsgProc(void *pArg)
                 if ((reply->root == reply_qt->parent) && !notify->override_redirect) {
                     xcb_reparent_notify_event_t event_send;
 
-                    event_send.response_type = ReparentNotify;
+                    event_send.response_type = XCB_REPARENT_NOTIFY;
                     event_send.event = notify->window;
                     event_send.window = notify->window;
                     event_send.parent = reply_qt->parent;
commit d7010cd93a381f1fc0cc681ddb70df9371370644
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Thu Nov 19 18:06:28 2015 +0000

    hw/xwin: Warn about too large Windows -> X clipboard pastes
    
    XChangeProperty() requests larger than the ~16MB permitted even with
    BigReq will fail BadLength

diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c
index 61d805011..7d55f3d92 100644
--- a/hw/xwin/winclipboard/xevents.c
+++ b/hw/xwin/winclipboard/xevents.c
@@ -690,6 +690,24 @@ winClipboardFlushXEvents(HWND hwnd,
             free(pszConvertData);
             pszConvertData = NULL;
 
+            /* data will fit into a single X request (INCR not yet supported) */
+            {
+                long unsigned int maxreqsize = XExtendedMaxRequestSize(pDisplay);
+                if (maxreqsize == 0)
+                    maxreqsize = XMaxRequestSize(pDisplay);
+
+                /* covert to bytes and allow for allow for X_ChangeProperty request */
+                maxreqsize = maxreqsize*4 - 24;
+
+                if (xtpText.nitems > maxreqsize) {
+                    ErrorF("winClipboardFlushXEvents - clipboard data size %lu greater than maximum %lu\n", xtpText.nitems, maxreqsize);
+
+                    /* Abort */
+                    fAbort = TRUE;
+                    goto winClipboardFlushXEvents_SelectionRequest_Done;
+                }
+            }
+
             /* Copy the clipboard text to the requesting window */
             iReturn = XChangeProperty(pDisplay,
                                       event.xselectionrequest.requestor,
commit 56a91f20671402a8c6f60c40e5e4e18f7978c740
Author: Jon Turney <jon.turney at dronecode.org.uk>
Date:   Wed Nov 18 21:27:23 2015 +0000

    hw/xwin: Implement INCR protocol for X clipboard -> Windows clipboard
    
    Also, relax the timeout mechanism so it allows 1 second between events,
    rather than 1 second for the entire transfer, as transfers of large
    pastes can take more than 1 second.
    
    Also, prefer UTF8_STRING encoding to COMPOUND_TEXT encoding

diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h
index 2e6b22db3..766a836ae 100644
--- a/hw/xwin/winclipboard/internal.h
+++ b/hw/xwin/winclipboard/internal.h
@@ -1,4 +1,3 @@
-
 /*
  *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
  *
@@ -38,7 +37,7 @@
 /* Windows headers */
 #include <X11/Xwindows.h>
 
-#define WIN_XEVENTS_SUCCESS			0
+#define WIN_XEVENTS_SUCCESS			0  // more like 'CONTINUE'
 #define WIN_XEVENTS_FAILED			1
 #define WIN_XEVENTS_NOTIFY_DATA			3
 #define WIN_XEVENTS_NOTIFY_TARGETS		4
@@ -77,6 +76,7 @@ typedef struct
     Atom atomUTF8String;
     Atom atomCompoundText;
     Atom atomTargets;
+    Atom atomIncr;
 } ClipboardAtoms;
 
 /* Modern clipboard API functions */
@@ -111,6 +111,8 @@ typedef struct
 {
   Bool fUseUnicode;
   Atom *targetList;
+  unsigned char *incr;
+  unsigned long int incrsize;
 } ClipboardConversionData;
 
 int
diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c
index fa57ada80..8be6991cc 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -199,6 +199,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
     atoms.atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False);
     atoms.atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False);
     atoms.atomTargets = XInternAtom (pDisplay, "TARGETS", False);
+    atoms.atomIncr = XInternAtom (pDisplay, "INCR", False);
 
     /* Create a messaging window */
     iWindow = XCreateSimpleWindow(pDisplay,
@@ -265,6 +266,8 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
     }
 
     data.fUseUnicode = fUseUnicode;
+    data.incr = NULL;
+    data.incrsize = 0;
 
     /* Loop for events */
     while (1) {
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index c8d0064bd..990febced 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -73,9 +73,8 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
     int iConnNumber;
     struct timeval tv;
     int iReturn;
-    DWORD dwStopTime = GetTickCount() + iTimeoutSec * 1000;
 
-    winDebug("winProcessXEventsTimeout () - pumping X events for %d seconds\n",
+    winDebug("winProcessXEventsTimeout () - pumping X events, timeout %d seconds\n",
              iTimeoutSec);
 
     /* Get our connection number */
@@ -104,11 +103,9 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
         FD_SET(iConnNumber, &fdsRead);
 
         /* Adjust timeout */
-        remainingTime = dwStopTime - GetTickCount();
+        remainingTime = iTimeoutSec * 1000;
         tv.tv_sec = remainingTime / 1000;
         tv.tv_usec = (remainingTime % 1000) * 1000;
-        winDebug("winProcessXEventsTimeout () - %ld milliseconds left\n",
-                 remainingTime);
 
         /* Break out if no time left */
         if (remainingTime <= 0)
@@ -494,6 +491,9 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         /* Process X events */
         data.fUseUnicode = fConvertToUnicode;
+        data.incr = NULL;
+        data.incrsize = 0;
+
         iReturn = winProcessXEventsTimeout(hwnd,
                                            iWindow,
                                            pDisplay,
@@ -517,10 +517,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
             struct target_priority target_priority_table[] =
                 {
-                    { atoms->atomCompoundText, 0 },
 #ifdef X_HAVE_UTF8_STRING
-                    { atoms->atomUTF8String,   1 },
+                    { atoms->atomUTF8String,   0 },
 #endif
+                    { atoms->atomCompoundText, 1 },
                     { XA_STRING,               2 },
                 };
 
diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c
index d4ea97fc3..61d805011 100644
--- a/hw/xwin/winclipboard/xevents.c
+++ b/hw/xwin/winclipboard/xevents.c
@@ -184,6 +184,271 @@ winClipboardSelectionNotifyTargets(HWND hwnd, Window iWindow, Display *pDisplay,
   return WIN_XEVENTS_NOTIFY_TARGETS;
 }
 
+static int
+winClipboardSelectionNotifyData(HWND hwnd, Window iWindow, Display *pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
+{
+    Atom encoding;
+    int format;
+    unsigned long int nitems;
+    unsigned long int after;
+    unsigned char *value;
+    XTextProperty xtpText = { 0 };
+    Bool fSetClipboardData = TRUE;
+    int iReturn;
+    char **ppszTextList = NULL;
+    int iCount;
+    char *pszReturnData = NULL;
+    wchar_t *pwszUnicodeStr = NULL;
+    HGLOBAL hGlobal = NULL;
+    char *pszConvertData = NULL;
+    char *pszGlobalData = NULL;
+
+    /* Retrieve the selection data and delete the property */
+    iReturn = XGetWindowProperty(pDisplay,
+                                 iWindow,
+                                 atoms->atomLocalProperty,
+                                 0,
+                                 INT_MAX,
+                                 True,
+                                 AnyPropertyType,
+                                 &encoding,
+                                 &format,
+                                 &nitems,
+                                 &after,
+                                 &value);
+    if (iReturn != Success) {
+        ErrorF("winClipboardFlushXEvents - SelectionNotify - "
+               "XGetWindowProperty () failed, aborting: %d\n", iReturn);
+        goto winClipboardFlushXEvents_SelectionNotify_Done;
+    }
+
+    {
+        char *pszAtomName = NULL;
+
+        winDebug("SelectionNotify - returned data %lu left %lu\n", nitems, after);
+        pszAtomName = XGetAtomName(pDisplay, encoding);
+        winDebug("Notify atom name %s\n", pszAtomName);
+        XFree(pszAtomName);
+        pszAtomName = NULL;
+    }
+
+    /* INCR reply indicates the start of a incremental transfer */
+    if (encoding == atoms->atomIncr) {
+        winDebug("winClipboardSelectionNotifyData: starting INCR, anticipated size %d\n", *(int *)value);
+        data->incrsize = 0;
+        data->incr = malloc(*(int *)value);
+        // XXX: if malloc failed, we have an error
+        return WIN_XEVENTS_SUCCESS;
+    }
+    else if (data->incr) {
+        /* If an INCR transfer is in progress ... */
+        if (nitems == 0) {
+            winDebug("winClipboardSelectionNotifyData: ending INCR, actual size %ld\n", data->incrsize);
+            /* a zero-length property indicates the end of the data */
+            xtpText.value = data->incr;
+            xtpText.encoding = encoding;
+            xtpText.format = format; // XXX: The type of the converted selection is the type of the first partial property. The remaining partial properties must have the same type.
+            xtpText.nitems = data->incrsize;
+        }
+        else {
+            /* Otherwise, continue appending the INCR data */
+            winDebug("winClipboardSelectionNotifyData: INCR, %ld bytes\n", nitems);
+            data->incr = realloc(data->incr, data->incrsize + nitems);
+            memcpy(data->incr + data->incrsize, value, nitems);
+            data->incrsize = data->incrsize + nitems;
+            return WIN_XEVENTS_SUCCESS;
+        }
+    }
+    else {
+        /* Otherwise, the data is just contained in the property */
+        winDebug("winClipboardSelectionNotifyData: non-INCR, %ld bytes\n", nitems);
+        xtpText.value = value;
+        xtpText.encoding = encoding;
+        xtpText.format = format;
+        xtpText.nitems = nitems;
+    }
+
+    if (data->fUseUnicode) {
+#ifdef X_HAVE_UTF8_STRING
+        /* Convert the text property to a text list */
+        iReturn = Xutf8TextPropertyToTextList(pDisplay,
+                                              &xtpText,
+                                              &ppszTextList, &iCount);
+#endif
+    }
+    else {
+        iReturn = XmbTextPropertyToTextList(pDisplay,
+                                            &xtpText,
+                                            &ppszTextList, &iCount);
+    }
+    if (iReturn == Success || iReturn > 0) {
+        /* Conversion succeeded or some unconvertible characters */
+        if (ppszTextList != NULL) {
+            int i;
+            int iReturnDataLen = 0;
+            for (i = 0; i < iCount; i++) {
+                iReturnDataLen += strlen(ppszTextList[i]);
+            }
+            pszReturnData = malloc(iReturnDataLen + 1);
+            pszReturnData[0] = '\0';
+            for (i = 0; i < iCount; i++) {
+                strcat(pszReturnData, ppszTextList[i]);
+            }
+        }
+        else {
+            ErrorF("winClipboardFlushXEvents - SelectionNotify - "
+                   "X*TextPropertyToTextList list_return is NULL.\n");
+            pszReturnData = malloc(1);
+            pszReturnData[0] = '\0';
+        }
+    }
+    else {
+        ErrorF("winClipboardFlushXEvents - SelectionNotify - "
+               "X*TextPropertyToTextList returned: ");
+        switch (iReturn) {
+        case XNoMemory:
+            ErrorF("XNoMemory\n");
+            break;
+        case XLocaleNotSupported:
+            ErrorF("XLocaleNotSupported\n");
+            break;
+        case XConverterNotFound:
+            ErrorF("XConverterNotFound\n");
+            break;
+        default:
+            ErrorF("%d\n", iReturn);
+            break;
+        }
+        pszReturnData = malloc(1);
+        pszReturnData[0] = '\0';
+    }
+
+
+    if (ppszTextList)
+        XFreeStringList(ppszTextList);
+    ppszTextList = NULL;
+
+    /* Free the data returned from XGetWindowProperty */
+    XFree(value);
+    value = NULL;
+    nitems = 0;
+
+    /* Free any INCR data */
+    if (data->incr) {
+        free(data->incr);
+        data->incr = NULL;
+        data->incrsize = 0;
+    }
+
+    /* Convert the X clipboard string to DOS format */
+    winClipboardUNIXtoDOS(&pszReturnData, strlen(pszReturnData));
+
+    if (data->fUseUnicode) {
+        /* Find out how much space needed to convert MBCS to Unicode */
+        int iUnicodeLen = MultiByteToWideChar(CP_UTF8,
+                                              0,
+                                              pszReturnData, -1, NULL, 0);
+
+        /* NOTE: iUnicodeLen includes space for null terminator */
+        pwszUnicodeStr = malloc(sizeof(wchar_t) * iUnicodeLen);
+        if (!pwszUnicodeStr) {
+            ErrorF("winClipboardFlushXEvents - SelectionNotify "
+                   "malloc failed for pwszUnicodeStr, aborting.\n");
+
+            /* Abort */
+            goto winClipboardFlushXEvents_SelectionNotify_Done;
+        }
+
+        /* Do the actual conversion */
+        MultiByteToWideChar(CP_UTF8,
+                            0,
+                            pszReturnData,
+                            -1, pwszUnicodeStr, iUnicodeLen);
+
+        /* Allocate global memory for the X clipboard data */
+        hGlobal = GlobalAlloc(GMEM_MOVEABLE,
+                              sizeof(wchar_t) * iUnicodeLen);
+    }
+    else {
+        int iConvertDataLen = 0;
+        pszConvertData = strdup(pszReturnData);
+        iConvertDataLen = strlen(pszConvertData) + 1;
+
+        /* Allocate global memory for the X clipboard data */
+        hGlobal = GlobalAlloc(GMEM_MOVEABLE, iConvertDataLen);
+    }
+
+    free(pszReturnData);
+
+    /* Check that global memory was allocated */
+    if (!hGlobal) {
+        ErrorF("winClipboardFlushXEvents - SelectionNotify "
+               "GlobalAlloc failed, aborting: %08x\n", (unsigned int)GetLastError());
+
+        /* Abort */
+        goto winClipboardFlushXEvents_SelectionNotify_Done;
+    }
+
+    /* Obtain a pointer to the global memory */
+    pszGlobalData = GlobalLock(hGlobal);
+    if (pszGlobalData == NULL) {
+        ErrorF("winClipboardFlushXEvents - Could not lock global "
+               "memory for clipboard transfer\n");
+
+        /* Abort */
+        goto winClipboardFlushXEvents_SelectionNotify_Done;
+    }
+
+    /* Copy the returned string into the global memory */
+    if (data->fUseUnicode) {
+        wcscpy((wchar_t *)pszGlobalData, pwszUnicodeStr);
+        free(pwszUnicodeStr);
+        pwszUnicodeStr = NULL;
+    }
+    else {
+        strcpy(pszGlobalData, pszConvertData);
+        free(pszConvertData);
+        pszConvertData = NULL;
+    }
+
+    /* Release the pointer to the global memory */
+    GlobalUnlock(hGlobal);
+    pszGlobalData = NULL;
+
+    /* Push the selection data to the Windows clipboard */
+    if (data->fUseUnicode)
+        SetClipboardData(CF_UNICODETEXT, hGlobal);
+    else
+        SetClipboardData(CF_TEXT, hGlobal);
+
+    /* Flag that SetClipboardData has been called */
+    fSetClipboardData = FALSE;
+
+    /*
+     * NOTE: Do not try to free pszGlobalData, it is owned by
+     * Windows after the call to SetClipboardData ().
+     */
+
+ winClipboardFlushXEvents_SelectionNotify_Done:
+    /* Free allocated resources */
+    if (ppszTextList)
+        XFreeStringList(ppszTextList);
+    if (value) {
+        XFree(value);
+        value = NULL;
+        nitems = 0;
+    }
+    free(pszConvertData);
+    free(pwszUnicodeStr);
+    if (hGlobal && pszGlobalData)
+        GlobalUnlock(hGlobal);
+    if (fSetClipboardData) {
+        SetClipboardData(CF_UNICODETEXT, NULL);
+        SetClipboardData(CF_TEXT, NULL);
+    }
+    return WIN_XEVENTS_NOTIFY_DATA;
+}
+
 /*
  * Process any pending X events
  */
@@ -193,7 +458,6 @@ winClipboardFlushXEvents(HWND hwnd,
                          Window iWindow, Display * pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
 {
     Atom atomClipboard = atoms->atomClipboard;
-    Atom atomLocalProperty = atoms->atomLocalProperty;
     Atom atomUTF8String = atoms->atomUTF8String;
     Atom atomCompoundText = atoms->atomCompoundText;
     Atom atomTargets = atoms->atomTargets;
@@ -203,20 +467,14 @@ winClipboardFlushXEvents(HWND hwnd,
         XTextProperty xtpText = { 0 };
         XEvent event;
         XSelectionEvent eventSelection;
-        unsigned long ulReturnBytesLeft;
-        char *pszReturnData = NULL;
         char *pszGlobalData = NULL;
         int iReturn;
         HGLOBAL hGlobal = NULL;
         XICCEncodingStyle xiccesStyle;
         char *pszConvertData = NULL;
         char *pszTextList[2] = { NULL };
-        int iCount;
-        char **ppszTextList = NULL;
-        wchar_t *pwszUnicodeStr = NULL;
         Bool fAbort = FALSE;
         Bool fCloseClipboard = FALSE;
-        Bool fSetClipboardData = TRUE;
 
         /* Get the next event - will not block because one is ready */
         XNextEvent(pDisplay, &event);
@@ -569,214 +827,19 @@ winClipboardFlushXEvents(HWND hwnd,
               return winClipboardSelectionNotifyTargets(hwnd, iWindow, pDisplay, data, atoms);
             }
 
-            /* Retrieve the selection data and delete the property */
-            iReturn = XGetWindowProperty(pDisplay,
-                                         iWindow,
-                                         atomLocalProperty,
-                                         0,
-                                         INT_MAX,
-                                         True,
-                                         AnyPropertyType,
-                                         &xtpText.encoding,
-                                         &xtpText.format,
-                                         &xtpText.nitems,
-                                         &ulReturnBytesLeft, &xtpText.value);
-            if (iReturn != Success) {
-                ErrorF("winClipboardFlushXEvents - SelectionNotify - "
-                       "XGetWindowProperty () failed, aborting: %d\n", iReturn);
-                goto winClipboardFlushXEvents_SelectionNotify_Done;
-            }
-
-            {
-                char *pszAtomName = NULL;
-
-                winDebug("SelectionNotify - returned data %lu left %lu\n",
-                         xtpText.nitems, ulReturnBytesLeft);
-                pszAtomName = XGetAtomName(pDisplay, xtpText.encoding);
-                winDebug("Notify atom name %s\n", pszAtomName);
-                XFree(pszAtomName);
-                pszAtomName = NULL;
-            }
-
-            if (data->fUseUnicode) {
-#ifdef X_HAVE_UTF8_STRING
-                /* Convert the text property to a text list */
-                iReturn = Xutf8TextPropertyToTextList(pDisplay,
-                                                      &xtpText,
-                                                      &ppszTextList, &iCount);
-#endif
-            }
-            else {
-                iReturn = XmbTextPropertyToTextList(pDisplay,
-                                                    &xtpText,
-                                                    &ppszTextList, &iCount);
-            }
-            if (iReturn == Success || iReturn > 0) {
-                /* Conversion succeeded or some unconvertible characters */
-                if (ppszTextList != NULL) {
-                    int i;
-                    int iReturnDataLen = 0;
-                    for (i = 0; i < iCount; i++) {
-                        iReturnDataLen += strlen(ppszTextList[i]);
-                    }
-                    pszReturnData = malloc(iReturnDataLen + 1);
-                    pszReturnData[0] = '\0';
-                    for (i = 0; i < iCount; i++) {
-                        strcat(pszReturnData, ppszTextList[i]);
-                    }
-                }
-                else {
-                    ErrorF("winClipboardFlushXEvents - SelectionNotify - "
-                           "X*TextPropertyToTextList list_return is NULL.\n");
-                    pszReturnData = malloc(1);
-                    pszReturnData[0] = '\0';
-                }
-            }
-            else {
-                ErrorF("winClipboardFlushXEvents - SelectionNotify - "
-                       "X*TextPropertyToTextList returned: ");
-                switch (iReturn) {
-                case XNoMemory:
-                    ErrorF("XNoMemory\n");
-                    break;
-                case XLocaleNotSupported:
-                    ErrorF("XLocaleNotSupported\n");
-                    break;
-                case XConverterNotFound:
-                    ErrorF("XConverterNotFound\n");
-                    break;
-                default:
-                    ErrorF("%d\n", iReturn);
-                    break;
-                }
-                pszReturnData = malloc(1);
-                pszReturnData[0] = '\0';
-            }
-
-            /* Free the data returned from XGetWindowProperty */
-            if (ppszTextList)
-                XFreeStringList(ppszTextList);
-            ppszTextList = NULL;
-            XFree(xtpText.value);
-            xtpText.value = NULL;
-            xtpText.nitems = 0;
-
-            /* Convert the X clipboard string to DOS format */
-            winClipboardUNIXtoDOS(&pszReturnData, strlen(pszReturnData));
-
-            if (data->fUseUnicode) {
-                /* Find out how much space needed to convert MBCS to Unicode */
-                int iUnicodeLen = MultiByteToWideChar(CP_UTF8,
-                                                  0,
-                                                  pszReturnData, -1, NULL, 0);
-
-                /* NOTE: iUnicodeLen includes space for null terminator */
-                pwszUnicodeStr = malloc(sizeof(wchar_t) * iUnicodeLen);
-                if (!pwszUnicodeStr) {
-                    ErrorF("winClipboardFlushXEvents - SelectionNotify "
-                           "malloc failed for pwszUnicodeStr, aborting.\n");
-
-                    /* Abort */
-                    fAbort = TRUE;
-                    goto winClipboardFlushXEvents_SelectionNotify_Done;
-                }
-
-                /* Do the actual conversion */
-                MultiByteToWideChar(CP_UTF8,
-                                    0,
-                                    pszReturnData,
-                                    -1, pwszUnicodeStr, iUnicodeLen);
-
-                /* Allocate global memory for the X clipboard data */
-                hGlobal = GlobalAlloc(GMEM_MOVEABLE,
-                                      sizeof(wchar_t) * iUnicodeLen);
-            }
-            else {
-                int iConvertDataLen = 0;
-                pszConvertData = strdup(pszReturnData);
-                iConvertDataLen = strlen(pszConvertData) + 1;
-
-                /* Allocate global memory for the X clipboard data */
-                hGlobal = GlobalAlloc(GMEM_MOVEABLE, iConvertDataLen);
-            }
-
-            free(pszReturnData);
-
-            /* Check that global memory was allocated */
-            if (!hGlobal) {
-                ErrorF("winClipboardFlushXEvents - SelectionNotify "
-                       "GlobalAlloc failed, aborting: %08x\n", (unsigned int)GetLastError());
-
-                /* Abort */
-                fAbort = TRUE;
-                goto winClipboardFlushXEvents_SelectionNotify_Done;
-            }
-
-            /* Obtain a pointer to the global memory */
-            pszGlobalData = GlobalLock(hGlobal);
-            if (pszGlobalData == NULL) {
-                ErrorF("winClipboardFlushXEvents - Could not lock global "
-                       "memory for clipboard transfer\n");
-
-                /* Abort */
-                fAbort = TRUE;
-                goto winClipboardFlushXEvents_SelectionNotify_Done;
-            }
-
-            /* Copy the returned string into the global memory */
-            if (data->fUseUnicode) {
-                wcscpy((wchar_t *)pszGlobalData, pwszUnicodeStr);
-                free(pwszUnicodeStr);
-                pwszUnicodeStr = NULL;
-            }
-            else {
-                strcpy(pszGlobalData, pszConvertData);
-                free(pszConvertData);
-                pszConvertData = NULL;
-            }
-
-            /* Release the pointer to the global memory */
-            GlobalUnlock(hGlobal);
-            pszGlobalData = NULL;
-
-            /* Push the selection data to the Windows clipboard */
-            if (data->fUseUnicode)
-                SetClipboardData(CF_UNICODETEXT, hGlobal);
-            else
-                SetClipboardData(CF_TEXT, hGlobal);
-
-            /* Flag that SetClipboardData has been called */
-            fSetClipboardData = FALSE;
-
-            /*
-             * NOTE: Do not try to free pszGlobalData, it is owned by
-             * Windows after the call to SetClipboardData ().
-             */
-
- winClipboardFlushXEvents_SelectionNotify_Done:
-            /* Free allocated resources */
-            if (ppszTextList)
-                XFreeStringList(ppszTextList);
-            if (xtpText.value) {
-                XFree(xtpText.value);
-                xtpText.value = NULL;
-                xtpText.nitems = 0;
-            }
-            free(pszConvertData);
-            free(pwszUnicodeStr);
-            if (hGlobal && pszGlobalData)
-                GlobalUnlock(hGlobal);
-            if (fSetClipboardData) {
-                SetClipboardData(CF_UNICODETEXT, NULL);
-                SetClipboardData(CF_TEXT, NULL);
-            }
-            return WIN_XEVENTS_NOTIFY_DATA;
+            return winClipboardSelectionNotifyData(hwnd, iWindow, pDisplay, data, atoms);
 
         case SelectionClear:
             winDebug("SelectionClear - doing nothing\n");
             break;
 
         case PropertyNotify:
+            /* If INCR is in progress, collect the data */
+            if (data->incr &&
+                (event.xproperty.atom == atoms->atomLocalProperty) &&
+                (event.xproperty.state == PropertyNewValue))
+                return winClipboardSelectionNotifyData(hwnd, iWindow, pDisplay, data, atoms);
+
             break;
 
         case MappingNotify:
diff --git a/hw/xwin/winclipboard/xwinclip.man b/hw/xwin/winclipboard/xwinclip.man
index 73dfc8a94..f9e0d3bfb 100644
--- a/hw/xwin/winclipboard/xwinclip.man
+++ b/hw/xwin/winclipboard/xwinclip.man
@@ -39,8 +39,8 @@ 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.
+The INCR (Incremental transfer) clipboard protocol for clipboard contents larger than the maximum size of an X
+request (approximately 256K) is only supported for X -> Windows clipboard transfers.
 
 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
@@ -49,7 +49,8 @@ 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.
+using a fixed timeout.  After requesting conversion of the selection, if no events are received from the X
+client which owns the selection for one second, the conversion is assumed to have failed.
 
 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.


More information about the xorg-commit mailing list