Create an X connection for each thread, and process X events in the
thread that created the corresponding X window.
Spawn a separate thread to run the desktop message loop in desktop
mode.

diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c
index aece6ca..b0b7f13 100644
--- a/windows/x11drv/clipboard.c
+++ b/windows/x11drv/clipboard.c
@@ -176,7 +176,7 @@
             if (fmtName)
             {
                 strncat(str, fmtName, sizeof(str) - strlen(FMT_PREFIX));
-                prop = TSXInternAtom(display, str, False);
+                prop = TSXInternAtom(thread_display(), str, False);
             }
             break;
         }
@@ -196,7 +196,7 @@
  */
 BOOL X11DRV_CLIPBOARD_IsNativeProperty(Atom prop)
 {
-    char *itemFmtName = TSXGetAtomName(display, prop);
+    char *itemFmtName = TSXGetAtomName(thread_display(), prop);
     BOOL bRet = FALSE;
     
     if ( 0 == strncmp(itemFmtName, FMT_PREFIX, strlen(FMT_PREFIX)) )
@@ -217,6 +217,7 @@
 BOOL X11DRV_CLIPBOARD_LaunchServer()
 {
     int iWndsLocks;
+    char clearSelection[8];
 
     /* If persistant selection has been disabled in the .winerc Clipboard section,
      * don't launch the server
@@ -224,6 +225,9 @@
     if ( !PROFILE_GetWineIniInt("Clipboard", "PersistentSelection", 1) )
         return FALSE;
 
+    /* Get the clear selection preference */
+    sprintf(clearSelection, "%d", PROFILE_GetWineIniInt("Clipboard", "ClearAllSelections", 0));
+
     /*  Start up persistant WINE X clipboard server process which will
      *  take ownership of the X selection and continue to service selection
      *  requests from other apps.
@@ -234,16 +238,8 @@
         /* NOTE: This code only executes in the context of the child process
          * Do note make any Wine specific calls here.
          */
-        
         int dbgClasses = 0;
-        char selMask[8], dbgClassMask[8], clearSelection[8];
-	int i;
-
-	/* Don't inherit wine's X sockets to the wineclipsrv, otherwise
-	 * windows stay around when you have to kill a hanging wine...
-	 */
-	for (i = 3; i < 256; ++i)
-		fcntl(i, F_SETFD, 1);
+        char selMask[8], dbgClassMask[8];
 
         sprintf(selMask, "%d", selectionAcquired);
 
@@ -256,10 +252,6 @@
         dbgClasses |= TRACE_ON(clipboard) ? 8 : 0;
         sprintf(dbgClassMask, "%d", dbgClasses);
 
-        /* Get the clear selection preference */
-        sprintf(clearSelection, "%d",
-                PROFILE_GetWineIniInt("Clipboard", "ClearAllSelections", 0));
-
         /* Exec the clipboard server passing it the selection and debug class masks */
         execl( BINDIR "/wineclipsrv", "wineclipsrv",
                selMask, dbgClassMask, clearSelection, NULL );
@@ -295,7 +287,7 @@
 
         TRACE("Waiting for clipboard server to acquire selection\n");
 
-        if ( WaitForSingleObject( selectionClearEvent, 60000 ) != WAIT_OBJECT_0 )
+        if ( MsgWaitForMultipleObjects( 1, &selectionClearEvent, FALSE, 60000, QS_ALLINPUT ) != WAIT_OBJECT_0 )
             TRACE("Server could not acquire selection, or a timeout occurred!\n");
         else
             TRACE("Server successfully acquired selection\n");
@@ -320,6 +312,7 @@
  */
 int X11DRV_CLIPBOARD_CacheDataFormats( Atom SelectionName )
 {
+    Display *display = thread_display();
     HWND           hWnd = 0;
     HWND           hWndClipWindow = GetOpenClipboardWindow();
     WND*           wnd = NULL;
@@ -458,6 +451,7 @@
  */
 static BOOL X11DRV_CLIPBOARD_ReadSelection(UINT wFormat, Window w, Atom prop, Atom reqType)
 {
+    Display *display = thread_display();
     Atom	      atype=AnyPropertyType;
     int		      aformat;
     unsigned long     total,nitems,remain,itemSize,val_cnt;
@@ -685,6 +679,7 @@
  */
 void X11DRV_CLIPBOARD_ReleaseSelection(Atom selType, Window w, HWND hwnd)
 {
+    Display *display = thread_display();
     Atom xaClipboard = TSXInternAtom(display, "CLIPBOARD", False);
     int clearAllSelections = PROFILE_GetWineIniInt("Clipboard", "ClearAllSelections", 0);
     
@@ -797,6 +792,7 @@
  */
 void X11DRV_ReleaseClipboard(void)
 {
+    Display *display = thread_display();
     if( selectionAcquired )
     {
 	XEvent xe;
@@ -847,6 +843,7 @@
  */
 void X11DRV_AcquireClipboard(void)
 {
+    Display *display = thread_display();
     Window       owner;
     HWND         hWndClipWindow = GetOpenClipboardWindow();
 
@@ -900,6 +897,7 @@
  */
 BOOL X11DRV_IsClipboardFormatAvailable(UINT wFormat)
 {
+    Display *display = thread_display();
     Atom xaClipboard = TSXInternAtom(display, _CLIPBOARD, False);
     Window ownerPrimary = TSXGetSelectionOwner(display,XA_PRIMARY);
     Window ownerClipboard = TSXGetSelectionOwner(display,xaClipboard);
@@ -957,6 +955,7 @@
  */
 BOOL X11DRV_RegisterClipboardFormat( LPCSTR FormatName )
 {
+    Display *display = thread_display();
     Atom prop = None;
     char str[256];
     
@@ -1009,6 +1008,7 @@
  */
 BOOL X11DRV_GetClipboardData(UINT wFormat)
 {
+    Display *display = thread_display();
     BOOL bRet = selectionAcquired;
     HWND hWndClipWindow = GetOpenClipboardWindow();
     HWND hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow();
@@ -1087,6 +1087,7 @@
  */
 void X11DRV_ResetSelectionOwner(WND *pWnd, BOOL bFooBar)
 {
+    Display *display = thread_display();
     HWND hWndClipOwner = 0;
     Window XWnd = X11DRV_WND_GetXWindow(pWnd);
     Atom xaClipboard;