Moved more things to the X11 driver.

diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c
index 39c1f47..7d98737 100644
--- a/windows/x11drv/clipboard.c
+++ b/windows/x11drv/clipboard.c
@@ -38,19 +38,21 @@
  */
 static void X11DRV_CLIPBOARD_CheckSelection(WND* pWnd)
 {
-    TRACE(clipboard,"\tchecking %08x\n", (unsigned)pWnd->window);
+    TRACE(clipboard,"\tchecking %08x\n",
+        (unsigned) X11DRV_WND_GetXWindow(pWnd)
+    );
 
     if( selectionAcquired && selectionWindow != None &&
-        pWnd->window == selectionWindow )
+        X11DRV_WND_GetXWindow(pWnd) == selectionWindow )
     {
 	selectionPrevWindow = selectionWindow;
 	selectionWindow = None;
 
 	if( pWnd->next ) 
-	    selectionWindow = pWnd->next->window;
+	    selectionWindow = X11DRV_WND_GetXWindow(pWnd->next);
 	else if( pWnd->parent )
              if( pWnd->parent->child != pWnd ) 
-                 selectionWindow = pWnd->parent->child->window;
+                 selectionWindow = X11DRV_WND_GetXWindow(pWnd->parent->child);
 
 	TRACE(clipboard,"\tswitching selection from %08x to %08x\n", 
                     (unsigned)selectionPrevWindow, (unsigned)selectionWindow);
@@ -208,7 +210,9 @@
     if( !selectionAcquired && 
 	(wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
     {
-	owner = X11DRV_WND_GetXWindow( hWndClipWindow ? hWndClipWindow : AnyPopup32() );
+	owner = X11DRV_WND_FindXWindow( 
+	    WIN_FindWndPtr( hWndClipWindow ? hWndClipWindow : AnyPopup32() ) 
+	);
 
 	TSXSetSelectionOwner(display,XA_PRIMARY, owner, CurrentTime);
 	if( TSXGetSelectionOwner(display,XA_PRIMARY) == owner )
@@ -240,9 +244,10 @@
    * CLIPBOARD_ReadSelection() will be invoked 
    * from the SelectionNotify event handler */
 
-    TSXConvertSelection(display,XA_PRIMARY,XA_STRING,
-                      TSXInternAtom(display,"PRIMARY_TEXT",False),
-                      X11DRV_WND_GetXWindow(hWnd),CurrentTime);
+    TSXConvertSelection(display, XA_PRIMARY, XA_STRING,
+			TSXInternAtom(display, "PRIMARY_TEXT", False),
+			X11DRV_WND_FindXWindow( WIN_FindWndPtr( hWnd ) ),
+			CurrentTime);
 
   /* wait until SelectionNotify is processed 
    *
@@ -265,10 +270,16 @@
  *
  * Called from DestroyWindow().
  */
-void X11DRV_CLIPBOARD_ResetOwner(WND *pWnd)
+void X11DRV_CLIPBOARD_ResetOwner(WND *pWnd, BOOL32 bFooBar)
 {
     LPCLIPFORMAT lpFormat = ClipFormats;
 
+    if(bFooBar && X11DRV_WND_GetXWindow(pWnd))
+      return;
+
+    if(!bFooBar && !X11DRV_WND_GetXWindow(pWnd))
+      return;
+
     TRACE(clipboard,"clipboard owner = %04x, selection = %08x\n", 
 				hWndClipOwner, (unsigned)selectionWindow);
 
@@ -293,7 +304,7 @@
 
     /* now try to salvage current selection from being destroyed by X */
 
-    if( pWnd->window ) X11DRV_CLIPBOARD_CheckSelection(pWnd);
+    if( X11DRV_WND_GetXWindow(pWnd) ) X11DRV_CLIPBOARD_CheckSelection(pWnd);
 }
 
 #endif /* !defined(X_DISPLAY_MISSING) */
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c
index 0a47590..fc4b0b7 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -1,5 +1,5 @@
 /*
- * X11 windows driver
+ * X11 event driver
  *
  * Copyright 1993 Alexandre Julliard
  */
@@ -526,11 +526,12 @@
   
   if( !__check_query_condition(&pWndZ, &pWnd) ) return TRUE;
   
-  parent = __get_common_ancestor( pWndZ->window, pWnd->window,
+  parent = __get_common_ancestor( X11DRV_WND_GetXWindow(pWndZ), 
+				  X11DRV_WND_GetXWindow(pWnd),
 				  &children, &total );
   if( parent && children )
     {
-      w = __get_top_decoration( pWndCheck->window, parent );
+      w = __get_top_decoration( X11DRV_WND_GetXWindow(pWndCheck), parent );
       if( w != children[total - 1] )
         {
 	  check = __td_lookup( w, children, total );
@@ -540,7 +541,7 @@
 	      if( pWnd != pWndCheck )
                 {
 		  if( !(pWnd->flags & WIN_MANAGED) ||
-		      !(w = __get_top_decoration( pWnd->window, parent )) )
+		      !(w = __get_top_decoration( X11DRV_WND_GetXWindow(pWnd), parent )) )
 		    continue;
 		  pos = __td_lookup( w, children, total );
 		  if( pos < best && pos > check )
@@ -1029,7 +1030,7 @@
   
   if( !lpDragInfo || !spDragInfo ) return;
   
-  TSXQueryPointer( display, pWnd->window, &w_aux_root, &w_aux_child, 
+  TSXQueryPointer( display, X11DRV_WND_GetXWindow(pWnd), &w_aux_root, &w_aux_child, 
 		   &x, &y, &u.pt_aux.x, &u.pt_aux.y, (unsigned int*)&aux_long);
   
   lpDragInfo->hScope = pWnd->hwndSelf;
diff --git a/windows/x11drv/init.c b/windows/x11drv/init.c
index cdae2aa..734b8a5 100644
--- a/windows/x11drv/init.c
+++ b/windows/x11drv/init.c
@@ -12,6 +12,8 @@
 
 WND_DRIVER X11DRV_WND_Driver =
 {
+  X11DRV_WND_Initialize,
+  X11DRV_WND_Finalize,
   X11DRV_WND_CreateDesktopWindow,
   X11DRV_WND_CreateWindow,
   X11DRV_WND_DestroyWindow,
@@ -21,7 +23,10 @@
   X11DRV_WND_SetText,
   X11DRV_WND_SetFocus,
   X11DRV_WND_PreSizeMove,
-  X11DRV_WND_PostSizeMove
+  X11DRV_WND_PostSizeMove,
+  X11DRV_WND_ScrollWindow,
+  X11DRV_WND_SetDrawable,
+  X11DRV_WND_IsSelfClipping
 };
 
 CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver =
@@ -55,16 +60,12 @@
   X11DRV_EVENT_IsUserIdle
 };
 
-#if 0 
 MOUSE_DRIVER X11DRV_MOUSE_Driver =
 {
+  X11DRV_MOUSE_SetCursor,
+  X11DRV_MOUSE_MoveCursor
 };
-#endif
 
 #endif /* !defined(X_DISPLAY_MISSING) */
 
 
-
-
-
-
diff --git a/windows/x11drv/mouse.c b/windows/x11drv/mouse.c
index ed87b98..6015636 100644
--- a/windows/x11drv/mouse.c
+++ b/windows/x11drv/mouse.c
@@ -1,13 +1,215 @@
 /*
- * X11 windows driver
+ * X11 mouse driver
  *
- * Copyright 1998 Patrik Stridvall
+ * Copyright 1998 Ulrich Weigand
  */
 
 #include "config.h"
 
 #ifndef X_DISPLAY_MISSING
 
+#include "ts_xlib.h"
+
+#include "debug.h"
+#include "callback.h"
+#include "wintypes.h"
 #include "x11drv.h"
 
+/**********************************************************************/
+
+Cursor DISPLAY_XCursor = None;    /* Current X cursor */
+
+BOOL32 DISPLAY_DisableWarpPointer = FALSE;  /* hack; see DISPLAY_MoveCursor */
+
+/***********************************************************************
+ *		X11DRV_MOUSE_DoSetCursor
+ */
+static BOOL32 X11DRV_MOUSE_DoSetCursor( CURSORICONINFO *ptr )
+{
+    Pixmap pixmapBits, pixmapMask, pixmapAll;
+    XColor fg, bg;
+    Cursor cursor = None;
+
+    if (!ptr)  /* Create an empty cursor */
+    {
+        static const char data[] = { 0 };
+
+        bg.red = bg.green = bg.blue = 0x0000;
+        pixmapBits = XCreateBitmapFromData( display, rootWindow, data, 1, 1 );
+        if (pixmapBits)
+        {
+            cursor = XCreatePixmapCursor( display, pixmapBits, pixmapBits,
+                                          &bg, &bg, 0, 0 );
+            XFreePixmap( display, pixmapBits );
+        }
+    }
+    else  /* Create the X cursor from the bits */
+    {
+        XImage *image;
+
+        if (ptr->bPlanes * ptr->bBitsPerPixel != 1)
+        {
+            WARN(cursor, "Cursor has more than 1 bpp!\n" );
+            return FALSE;
+        }
+
+        /* Create a pixmap and transfer all the bits to it */
+
+        /* NOTE: Following hack works, but only because XFree depth
+         *       1 images really use 1 bit/pixel (and so the same layout
+         *       as the Windows cursor data). Perhaps use a more generic
+         *       algorithm here.
+         */
+        pixmapAll = XCreatePixmap( display, rootWindow,
+                                   ptr->nWidth, ptr->nHeight * 2, 1 );
+        image = XCreateImage( display, DefaultVisualOfScreen(screen),
+                              1, ZPixmap, 0, (char *)(ptr + 1), ptr->nWidth,
+                              ptr->nHeight * 2, 16, ptr->nWidthBytes);
+        if (image)
+        {
+            image->byte_order = MSBFirst;
+            image->bitmap_bit_order = MSBFirst;
+            image->bitmap_unit = 16;
+            _XInitImageFuncPtrs(image);
+            if (pixmapAll)
+                XPutImage( display, pixmapAll, BITMAP_monoGC, image,
+                           0, 0, 0, 0, ptr->nWidth, ptr->nHeight * 2 );
+            image->data = NULL;
+            XDestroyImage( image );
+        }
+
+        /* Now create the 2 pixmaps for bits and mask */
+
+        pixmapBits = XCreatePixmap( display, rootWindow,
+                                    ptr->nWidth, ptr->nHeight, 1 );
+        pixmapMask = XCreatePixmap( display, rootWindow,
+                                    ptr->nWidth, ptr->nHeight, 1 );
+
+        /* Make sure everything went OK so far */
+
+        if (pixmapBits && pixmapMask && pixmapAll)
+        {
+            /* We have to do some magic here, as cursors are not fully
+             * compatible between Windows and X11. Under X11, there
+             * are only 3 possible color cursor: black, white and
+             * masked. So we map the 4th Windows color (invert the
+             * bits on the screen) to black. This require some boolean
+             * arithmetic:
+             *
+             *         Windows          |          X11
+             * Xor    And      Result   |   Bits     Mask     Result
+             *  0      0     black      |    0        1     background
+             *  0      1     no change  |    X        0     no change
+             *  1      0     white      |    1        1     foreground
+             *  1      1     inverted   |    0        1     background
+             *
+             * which gives:
+             *  Bits = 'Xor' and not 'And'
+             *  Mask = 'Xor' or not 'And'
+             *
+             * FIXME: apparently some servers do support 'inverted' color.
+             * I don't know if it's correct per the X spec, but maybe
+             * we ought to take advantage of it.  -- AJ
+             */
+            XCopyArea( display, pixmapAll, pixmapBits, BITMAP_monoGC,
+                       0, 0, ptr->nWidth, ptr->nHeight, 0, 0 );
+            XCopyArea( display, pixmapAll, pixmapMask, BITMAP_monoGC,
+                       0, 0, ptr->nWidth, ptr->nHeight, 0, 0 );
+            XSetFunction( display, BITMAP_monoGC, GXandReverse );
+            XCopyArea( display, pixmapAll, pixmapBits, BITMAP_monoGC,
+                       0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 );
+            XSetFunction( display, BITMAP_monoGC, GXorReverse );
+            XCopyArea( display, pixmapAll, pixmapMask, BITMAP_monoGC,
+                       0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 );
+            XSetFunction( display, BITMAP_monoGC, GXcopy );
+            fg.red = fg.green = fg.blue = 0xffff;
+            bg.red = bg.green = bg.blue = 0x0000;
+            cursor = XCreatePixmapCursor( display, pixmapBits, pixmapMask,
+                                &fg, &bg, ptr->ptHotSpot.x, ptr->ptHotSpot.y );
+        }
+
+        /* Now free everything */
+
+        if (pixmapAll) XFreePixmap( display, pixmapAll );
+        if (pixmapBits) XFreePixmap( display, pixmapBits );
+        if (pixmapMask) XFreePixmap( display, pixmapMask );
+    }
+
+    if (cursor == None) return FALSE;
+    if (DISPLAY_XCursor != None) XFreeCursor( display, DISPLAY_XCursor );
+    DISPLAY_XCursor = cursor;
+
+    if (rootWindow != DefaultRootWindow(display) || !WIN_GetDesktop())
+    {
+        /* Set the cursor on the desktop window */
+        XDefineCursor( display, rootWindow, cursor );
+    }
+    else
+    {
+        /* FIXME: this won't work correctly with native USER !*/
+
+        /* Set the same cursor for all top-level windows */
+        HWND32 hwnd = GetWindow32( GetDesktopWindow32(), GW_CHILD );
+        while(hwnd)
+        {
+            Window win = X11DRV_WND_FindXWindow( WIN_FindWndPtr( hwnd ) );
+            if (win && win!=DefaultRootWindow(display))
+                XDefineCursor( display, win, cursor );
+            hwnd = GetWindow32( hwnd, GW_HWNDNEXT );
+        }
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *		X11DRV_MOUSE_SetCursor
+ */
+void X11DRV_MOUSE_SetCursor( CURSORICONINFO *lpCursor )
+{
+    EnterCriticalSection( &X11DRV_CritSection );
+    CALL_LARGE_STACK( X11DRV_MOUSE_DoSetCursor, lpCursor );
+    LeaveCriticalSection( &X11DRV_CritSection );
+}
+
+/***********************************************************************
+ *		X11DRV_MOUSE_MoveCursor
+ */
+void X11DRV_MOUSE_MoveCursor(WORD wAbsX, WORD wAbsY)
+{
+  /* 
+   * We do not want the to create MotionNotify events here, 
+   * otherwise we will get an endless recursion:
+   * XMotionEvent -> MOUSEEVENTF_MOVE -> mouse_event -> DisplayMoveCursor
+   * -> XWarpPointer -> XMotionEvent -> ...
+   *
+   * Unfortunately, the XWarpPointer call does create a MotionNotify
+   * event. So, we use a hack: before MOUSE_SendEvent calls the mouse event
+   * procedure, it sets a global flag. If this flag is set, we skip the
+   * XWarpPointer call.  If we are *not* called from within MOUSE_SendEvent,
+   * we will call XWarpPointer, which will create a MotionNotify event.
+   * Strictly speaking, this is also wrong, but that should normally not
+   * have any negative effects ...
+   *
+   * But first of all, we check whether we already are at the position
+   * are supposed to move to; if so, we don't need to do anything.
+   */
+  
+  Window root, child;
+  int rootX, rootY, winX, winY;
+  unsigned int xstate;
+  
+  if (DISPLAY_DisableWarpPointer) return;
+
+  if (!TSXQueryPointer( display, rootWindow, &root, &child,
+			&rootX, &rootY, &winX, &winY, &xstate ))
+    return;
+  
+  if ( winX == wAbsX && winY == wAbsY )
+    return;
+  
+  TRACE( cursor, "(%d,%d): moving from (%d,%d)\n", wAbsX, wAbsY, winX, winY );
+  
+  TSXWarpPointer( display, rootWindow, rootWindow, 0, 0, 0, 0, wAbsX, wAbsY );
+}
+
 #endif /* !defined(X_DISPLAY_MISSING) */
diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c
index cf5ae7b..2575e38 100644
--- a/windows/x11drv/wnd.c
+++ b/windows/x11drv/wnd.c
@@ -17,12 +17,14 @@
 #include <stdlib.h>
 #include <string.h>
 #include "color.h"
+#include "debug.h"
 #include "display.h"
 #include "dce.h"
 #include "options.h"
 #include "message.h"
+#include "heap.h"
 #include "win.h"
-#include "windows.h"
+#include "wintypes.h"
 #include "x11drv.h"
 
 /**********************************************************************/
@@ -40,15 +42,28 @@
 Atom dndSelection = None;
 
 /***********************************************************************
- *           X11DRV_WND_GetXWindow
+ *		X11DRV_WND_GetXWindow
  *
  * Return the X window associated to a window.
  */
-Window X11DRV_WND_GetXWindow(HWND32 hwnd)
+Window X11DRV_WND_GetXWindow(WND *wndPtr)
 {
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
-    return wndPtr ? wndPtr->window : 0;
+    return wndPtr ? 
+      ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0;
+}
+
+/***********************************************************************
+ *		X11DRV_WND_FindXWindow
+ *
+ * Return the the first X window associated to a window chain.
+ */
+Window X11DRV_WND_FindXWindow(WND *wndPtr)
+{
+    while (wndPtr && 
+	   !((X11DRV_WND_DATA *) wndPtr->pDriverData)->window) 
+      wndPtr = wndPtr->parent;
+    return wndPtr ?
+      ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0;
 }
 
 /***********************************************************************
@@ -58,10 +73,42 @@
  */
 static void X11DRV_WND_RegisterWindow(WND *pWnd)
 {
-  TSXSetWMProtocols( display, pWnd->window, &wmDeleteWindow, 1 );
+  TSXSetWMProtocols( display, X11DRV_WND_GetXWindow(pWnd), &wmDeleteWindow, 1 );
   
   if (!winContext) winContext = TSXUniqueContext();
-  TSXSaveContext( display, pWnd->window, winContext, (char *)pWnd );
+  TSXSaveContext( display, X11DRV_WND_GetXWindow(pWnd), winContext, (char *)pWnd );
+}
+
+/**********************************************************************
+ *		X11DRV_WND_Initialize
+ */
+void X11DRV_WND_Initialize(WND *wndPtr)
+{
+  X11DRV_WND_DATA *pWndDriverData = 
+    (X11DRV_WND_DATA *) HeapAlloc(SystemHeap, 0, sizeof(X11DRV_WND_DATA));
+
+  wndPtr->pDriverData = (void *) pWndDriverData;
+
+  pWndDriverData->window = 0;
+}
+
+/**********************************************************************
+ *		X11DRV_WND_Finalize
+ */
+void X11DRV_WND_Finalize(WND *wndPtr)
+{
+  X11DRV_WND_DATA *pWndDriverData =
+    (X11DRV_WND_DATA *) wndPtr->pDriverData;
+
+  if(pWndDriverData->window)
+    {
+      ERR(win, 
+	  "WND destroyed without destroying "
+	  "the associated X Window (%ld)\n", 
+	  pWndDriverData->window
+      );
+    }
+  HeapFree(SystemHeap, 0, wndPtr->pDriverData);
 }
 
 /**********************************************************************
@@ -78,7 +125,7 @@
     if( dndSelection == None )
 	dndSelection = TSXInternAtom( display, "DndSelection" , False );
 
-    wndPtr->window = rootWindow;
+    ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = rootWindow;
     X11DRV_WND_RegisterWindow( wndPtr );
 
     return TRUE;
@@ -118,14 +165,15 @@
       win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
       win_attr.save_under    = ((classPtr->style & CS_SAVEBITS) != 0);
       win_attr.cursor        = DISPLAY_XCursor;
-      wndPtr->window = TSXCreateWindow( display, rootWindow, cs->x, cs->y,
-                                        cs->cx, cs->cy, 0, CopyFromParent,
-                                        InputOutput, CopyFromParent,
-                                        CWEventMask | CWOverrideRedirect |
-                                        CWColormap | CWCursor | CWSaveUnder |
-                                        CWBackingStore, &win_attr );
-     
-      if(!wndPtr->window)
+      ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = 
+	TSXCreateWindow( display, rootWindow, cs->x, cs->y,
+			 cs->cx, cs->cy, 0, CopyFromParent,
+			 InputOutput, CopyFromParent,
+			 CWEventMask | CWOverrideRedirect |
+			 CWColormap | CWCursor | CWSaveUnder |
+			 CWBackingStore, &win_attr );
+      
+      if(!X11DRV_WND_GetXWindow(wndPtr))
 	return FALSE;
 
       if (wndPtr->flags & WIN_MANAGED) {
@@ -134,7 +182,7 @@
 	if (class_hints) {
 	  class_hints->res_name = "wineManaged";
 	  class_hints->res_class = "Wine";
-	  TSXSetClassHint( display, wndPtr->window, class_hints );
+	  TSXSetClassHint( display, ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window, class_hints );
 	  TSXFree (class_hints);
 	}
 
@@ -145,7 +193,7 @@
 	      size_hints->min_width = size_hints->max_width = cs->cx;
 	      size_hints->min_height = size_hints->max_height = cs->cy;
                 size_hints->flags = (PSize | PMinSize | PMaxSize);
-                TSXSetWMSizeHints( display, wndPtr->window, size_hints,
+                TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr), size_hints,
 				   XA_WM_NORMAL_HINTS );
                 TSXFree(size_hints);
             }
@@ -154,8 +202,8 @@
       
       if (cs->hwndParent)  /* Get window owner */
 	{
-	  Window win = X11DRV_WND_GetXWindow( cs->hwndParent );
-	  if (win) TSXSetTransientForHint( display, wndPtr->window, win );
+	  Window win = X11DRV_WND_FindXWindow( WIN_FindWndPtr( cs->hwndParent ) );
+	  if (win) TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), win );
 	}
       X11DRV_WND_RegisterWindow( wndPtr );
     }
@@ -167,13 +215,13 @@
  */
 BOOL32 X11DRV_WND_DestroyWindow(WND *pWnd)
 {
-   if (pWnd->window)
+   if (X11DRV_WND_GetXWindow(pWnd))
      {
        XEvent xe;
-       TSXDeleteContext( display, pWnd->window, winContext );
-       TSXDestroyWindow( display, pWnd->window );
-       while( TSXCheckWindowEvent(display, pWnd->window, NoEventMask, &xe) );
-       pWnd->window = None;
+       TSXDeleteContext( display, X11DRV_WND_GetXWindow(pWnd), winContext );
+       TSXDestroyWindow( display, X11DRV_WND_GetXWindow(pWnd) );
+       while( TSXCheckWindowEvent(display, X11DRV_WND_GetXWindow(pWnd), NoEventMask, &xe) );
+       ((X11DRV_WND_DATA *) pWnd->pDriverData)->window = None;
      }
 
    return TRUE;
@@ -192,12 +240,12 @@
 	{
 	    BOOL32 bFixupDCE = IsWindowVisible32(wndPtr->hwndSelf);
 
-	    if ( wndPtr->window )
+	    if ( X11DRV_WND_GetXWindow(wndPtr) )
 	    {
 		/* Toplevel window needs to be reparented.  Used by Tk 8.0 */
 
-		TSXDestroyWindow( display, wndPtr->window );
-		wndPtr->window = None;
+		TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
+		((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
 	    }
 	    else if( bFixupDCE )
 		DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
@@ -233,7 +281,7 @@
   XWindowChanges winChanges;
   WND *wndPrev;
   
-  if( !pWnd || !pWnd->window || (pWnd->flags & WIN_MANAGED) )
+  if( !pWnd || !X11DRV_WND_GetXWindow(pWnd) || (pWnd->flags & WIN_MANAGED) )
     return;
   
   /* Raise all windows up to pWnd according to their Z order.
@@ -243,8 +291,9 @@
   winChanges.stack_mode = Above;
   while (pWnd)
     {
-      if (pWnd->window) TSXReconfigureWMWindow( display, pWnd->window, 0,
-                                                CWStackMode, &winChanges );
+      if (X11DRV_WND_GetXWindow(pWnd)) 
+	TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(pWnd), 0,
+				CWStackMode, &winChanges );
       wndPrev = WIN_GetDesktop()->child;
       if (wndPrev == pWnd) break;
       while (wndPrev && (wndPrev->next != pWnd)) wndPrev = wndPrev->next;
@@ -261,12 +310,12 @@
 static Window X11DRV_WND_FindDesktopXWindow( WND *wndPtr )
 {
   if (!(wndPtr->flags & WIN_MANAGED))
-    return wndPtr->window;
+    return X11DRV_WND_GetXWindow(wndPtr);
   else
     {
       Window window, root, parent, *children;
       int nchildren;
-      window = wndPtr->window;
+      window = X11DRV_WND_GetXWindow(wndPtr);
       for (;;)
         {
 	  TSXQueryTree( display, window, &root, &parent,
@@ -292,7 +341,8 @@
   
   if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW))
     {
-      if(wndPtr && wndPtr->window) TSXUnmapWindow( display, wndPtr->window );
+      if(X11DRV_WND_GetXWindow(wndPtr)) 
+	TSXUnmapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
     }
 
   if(bSMC_SETXPOS)
@@ -314,11 +364,11 @@
 		{
 		  long supplied_return;
 		  
-		  TSXGetWMSizeHints( display, winposPtr->window, size_hints,
+		  TSXGetWMSizeHints( display, X11DRV_WND_GetXWindow(winposPtr), size_hints,
 				     &supplied_return, XA_WM_NORMAL_HINTS);
 		  size_hints->min_width = size_hints->max_width = winpos->cx;
 		  size_hints->min_height = size_hints->max_height = winpos->cy;
-		  TSXSetWMSizeHints( display, winposPtr->window, size_hints,
+		  TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(winposPtr), size_hints,
 				     XA_WM_NORMAL_HINTS );
 		  TSXFree(size_hints);
 		}
@@ -352,13 +402,13 @@
 	}
       if (changeMask)
 	{
-	  TSXReconfigureWMWindow( display, winposPtr->window, 0, changeMask, &winChanges );
+	  TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges );
 	}
     }
 
   if ( winpos->flags & SWP_SHOWWINDOW )
     {
-      if(wndPtr && wndPtr->window) TSXMapWindow( display, wndPtr->window );
+      if(X11DRV_WND_GetXWindow(wndPtr)) TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
     }
 }
 
@@ -367,11 +417,11 @@
  */
 void X11DRV_WND_SetText(WND *wndPtr, LPCSTR text)
 {   
-  if (!wndPtr->window)
+  if (!X11DRV_WND_GetXWindow(wndPtr))
     return;
 
-  TSXStoreName( display, wndPtr->window, text );
-  TSXSetIconName( display, wndPtr->window, text );
+  TSXStoreName( display, X11DRV_WND_GetXWindow(wndPtr), text );
+  TSXSetIconName( display, X11DRV_WND_GetXWindow(wndPtr), text );
 }
 
 /*****************************************************************
@@ -398,13 +448,13 @@
   
   /* Set X focus and install colormap */
   
-  if (!wndPtr->window) return;
+  if (!X11DRV_WND_GetXWindow(wndPtr)) return;
   
-  if (!TSXGetWindowAttributes( display, wndPtr->window, &win_attr ) ||
+  if (!TSXGetWindowAttributes( display, X11DRV_WND_GetXWindow(wndPtr), &win_attr ) ||
       (win_attr.map_state != IsViewable))
     return;  /* If window is not viewable, don't change anything */
   
-  TSXSetInputFocus( display,wndPtr->window, RevertToParent, CurrentTime );
+  TSXSetInputFocus( display, X11DRV_WND_GetXWindow(wndPtr), RevertToParent, CurrentTime );
   if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE)
     TSXInstallColormap( display, COLOR_GetColormap() );
   
@@ -429,4 +479,100 @@
     TSXUngrabServer( display );
 }
 
+
+/*****************************************************************
+ *		 X11DRV_WND_ScrollWindow
+ */
+void X11DRV_WND_ScrollWindow(
+  WND *wndPtr, DC *dcPtr, INT32 dx, INT32 dy, 
+  const RECT32 *clipRect, BOOL32 bUpdate)
+{
+  X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcPtr->physDev;
+  POINT32 dst, src;
+  
+  if( dx > 0 ) dst.x = (src.x = dcPtr->w.DCOrgX + clipRect->left) + dx;
+  else src.x = (dst.x = dcPtr->w.DCOrgX + clipRect->left) - dx;
+  
+  if( dy > 0 ) dst.y = (src.y = dcPtr->w.DCOrgY + clipRect->top) + dy;
+  else src.y = (dst.y = dcPtr->w.DCOrgY + clipRect->top) - dy;
+  
+  
+  if ((clipRect->right - clipRect->left > abs(dx)) &&
+      (clipRect->bottom - clipRect->top > abs(dy)))
+    {
+      if (bUpdate) /* handles non-Wine windows hanging over the scrolled area */
+	TSXSetGraphicsExposures( display, physDev->gc, True );
+      TSXSetFunction( display, physDev->gc, GXcopy );
+      TSXCopyArea( display, physDev->drawable, physDev->drawable,
+		   physDev->gc, src.x, src.y,
+		   clipRect->right - clipRect->left - abs(dx),
+		   clipRect->bottom - clipRect->top - abs(dy),
+		   dst.x, dst.y );
+      if (bUpdate)
+	TSXSetGraphicsExposures( display, physDev->gc, False );
+    }
+}
+
+/***********************************************************************
+ *		X11DRV_WND_SetDrawable
+ *
+ * Set the drawable, origin and dimensions for the DC associated to
+ * a given window.
+ */
+void X11DRV_WND_SetDrawable(WND *wndPtr, DC *dc, WORD flags, BOOL32 bSetClipOrigin)
+{
+    X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
+
+    if (!wndPtr)  /* Get a DC for the whole screen */
+    {
+        dc->w.DCOrgX = 0;
+        dc->w.DCOrgY = 0;
+        physDev->drawable = rootWindow;
+        TSXSetSubwindowMode( display, physDev->gc, IncludeInferiors );
+    }
+    else
+    {
+        if (flags & DCX_WINDOW)
+        {
+            dc->w.DCOrgX  = wndPtr->rectWindow.left;
+            dc->w.DCOrgY  = wndPtr->rectWindow.top;
+        }
+        else
+        {
+            dc->w.DCOrgX  = wndPtr->rectClient.left;
+            dc->w.DCOrgY  = wndPtr->rectClient.top;
+        }
+        while (!X11DRV_WND_GetXWindow(wndPtr))
+        {
+            wndPtr = wndPtr->parent;
+            dc->w.DCOrgX += wndPtr->rectClient.left;
+            dc->w.DCOrgY += wndPtr->rectClient.top;
+        }
+        dc->w.DCOrgX -= wndPtr->rectWindow.left;
+        dc->w.DCOrgY -= wndPtr->rectWindow.top;
+        physDev->drawable = X11DRV_WND_GetXWindow(wndPtr);
+
+#if 0
+	/* This is needed when we reuse a cached DC because
+	 * SetDCState() called by ReleaseDC() screws up DC
+	 * origins for child windows.
+	 */
+
+	if( bSetClipOrigin )
+	    TSXSetClipOrigin( display, physDev->gc, dc->w.DCOrgX, dc->w.DCOrgY );
+#endif
+    }
+}
+
+/***********************************************************************
+ *		X11DRV_WND_IsSelfClipping
+ */
+BOOL32 X11DRV_WND_IsSelfClipping(WND *wndPtr)
+{
+  if( X11DRV_WND_GetXWindow(wndPtr) ) 
+      return TRUE; /* X itself will do the clipping */
+
+  return FALSE;
+}
+
 #endif /* !defined(X_DISPLAY_MISSING) */