Create an X window for every window, including children.
Fixed non-client rectangle calculations in managed mode.
Added support for icon window in managed mode.

diff --git a/dlls/ttydrv/ttydrv.spec b/dlls/ttydrv/ttydrv.spec
index ffcdc9f..8a14613 100644
--- a/dlls/ttydrv/ttydrv.spec
+++ b/dlls/ttydrv/ttydrv.spec
@@ -27,7 +27,7 @@
 @ cdecl GetScreenSaveTimeout() TTYDRV_GetScreenSaveTimeout
 @ cdecl SetScreenSaveTimeout(long) TTYDRV_SetScreenSaveTimeout
 @ cdecl LoadOEMResource(long long) TTYDRV_LoadOEMResource
-@ cdecl CreateWindow(long) TTYDRV_CreateWindow
+@ cdecl CreateWindow(long ptr) TTYDRV_CreateWindow
 @ cdecl DestroyWindow(long) TTYDRV_DestroyWindow
 @ cdecl GetDC(long long long long) TTYDRV_GetDC
 @ cdecl SetWindowPos(ptr) TTYDRV_SetWindowPos
diff --git a/dlls/ttydrv/wnd.c b/dlls/ttydrv/wnd.c
index bb10699..b0ae7e1 100644
--- a/dlls/ttydrv/wnd.c
+++ b/dlls/ttydrv/wnd.c
@@ -17,8 +17,7 @@
 
 WND_DRIVER TTYDRV_WND_Driver =
 {
-  TTYDRV_WND_ForceWindowRaise,
-  TTYDRV_WND_SetHostAttr
+  TTYDRV_WND_ForceWindowRaise
 };
 
 #define SWP_AGG_NOGEOMETRYCHANGE \
@@ -31,8 +30,10 @@
 /**********************************************************************
  *		CreateWindow   (TTYDRV.@)
  */
-BOOL TTYDRV_CreateWindow( HWND hwnd )
+BOOL TTYDRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs )
 {
+    BOOL ret;
+
 #ifdef WINE_CURSES
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     WINDOW *window;
@@ -41,32 +42,40 @@
     TRACE("(%x)\n", hwnd);
 
     /* Only create top-level windows */
-    if (wndPtr->dwStyle & WS_CHILD)
+    if (!(wndPtr->dwStyle & WS_CHILD))
     {
-        WIN_ReleaseWndPtr( wndPtr );
-        return TRUE;
-    }
+        if (!wndPtr->parent)  /* desktop */
+            window = root_window;
+        else
+        {
+            int x = wndPtr->rectWindow.left;
+            int y = wndPtr->rectWindow.top;
+            int cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
+            int cy = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
 
-    if (!wndPtr->parent)  /* desktop */
-        window = root_window;
-    else
-    {
-        int x = wndPtr->rectWindow.left;
-        int y = wndPtr->rectWindow.top;
-        int cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
-        int cy = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
-
-        window = subwin( root_window, cy/cellHeight, cx/cellWidth,
-                         y/cellHeight, x/cellWidth);
-        werase(window);
-        wrefresh(window);
+            window = subwin( root_window, cy/cellHeight, cx/cellWidth,
+                             y/cellHeight, x/cellWidth);
+            werase(window);
+            wrefresh(window);
+        }
+        wndPtr->pDriverData = window;
     }
-    wndPtr->pDriverData = window;
     WIN_ReleaseWndPtr( wndPtr );
 #else /* defined(WINE_CURSES) */
     FIXME("(%x): stub\n", hwnd);
 #endif /* defined(WINE_CURSES) */
-    return TRUE;
+
+    if (IsWindowUnicode( hwnd ))
+    {
+        ret = SendMessageW( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
+        if (ret) ret = (SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
+    }
+    else
+    {
+        ret = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
+        if (ret) ret = (SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
+    }
+    return ret;
 }
 
 /***********************************************************************
@@ -97,16 +106,6 @@
   FIXME("(%p): stub\n", wndPtr);
 }
 
-/***********************************************************************
- *              TTYDRV_WND_SetHostAttr
- */
-BOOL TTYDRV_WND_SetHostAttr(WND *wndPtr, INT attr, INT value)
-{
-  FIXME("(%p): stub\n", wndPtr);
-
-  return TRUE;
-}
-
 
 /***********************************************************************
  *           DCE_OffsetVisRgn
diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c
index 63dbfb9..cdd1ff2 100644
--- a/dlls/user/user_main.c
+++ b/dlls/user/user_main.c
@@ -89,6 +89,7 @@
     GET_USER_FUNC(GetDC);
     GET_USER_FUNC(EnableWindow);
     GET_USER_FUNC(MsgWaitForMultipleObjectsEx);
+    GET_USER_FUNC(ScrollDC);
     GET_USER_FUNC(ScrollWindowEx);
     GET_USER_FUNC(SetFocus);
     GET_USER_FUNC(SetParent);
@@ -96,6 +97,7 @@
     GET_USER_FUNC(SetWindowRgn);
     GET_USER_FUNC(SetWindowIcon);
     GET_USER_FUNC(SetWindowText);
+    GET_USER_FUNC(ShowWindow);
     GET_USER_FUNC(SysCommandSizeMove);
 
     return TRUE;
diff --git a/dlls/x11drv/Makefile.in b/dlls/x11drv/Makefile.in
index e98cdd5..9ad31aa 100644
--- a/dlls/x11drv/Makefile.in
+++ b/dlls/x11drv/Makefile.in
@@ -9,6 +9,7 @@
 C_SRCS = \
 	desktop.c \
 	dga2.c \
+	scroll.c \
 	window.c \
 	winpos.c \
 	x11ddraw.c \
diff --git a/dlls/x11drv/desktop.c b/dlls/x11drv/desktop.c
index 1376899..ff57b37 100644
--- a/dlls/x11drv/desktop.c
+++ b/dlls/x11drv/desktop.c
@@ -55,11 +55,14 @@
     /* patch the desktop window queue to point to our queue */
     win = WIN_FindWndPtr( hwnd );
     win->hmemTaskQ = GetFastQueue16();
+    X11DRV_register_window( display, hwnd, win->pDriverData );
     WIN_ReleaseWndPtr( win );
 
     SetWindowLongW( hwnd, GWL_WNDPROC, (LONG)desktop_winproc );
-    X11DRV_register_window( display, hwnd, root_window );
-    TSXMapWindow( display, root_window );
+    wine_tsx11_lock();
+    XSetWMProtocols( display, root_window, &wmDeleteWindow, 1 );
+    XMapWindow( display, root_window );
+    wine_tsx11_unlock();
 
     while (GetMessageW( &msg, hwnd, 0, 0 )) DispatchMessageW( &msg );
     return 0;
diff --git a/dlls/x11drv/scroll.c b/dlls/x11drv/scroll.c
new file mode 100644
index 0000000..c6b4520
--- /dev/null
+++ b/dlls/x11drv/scroll.c
@@ -0,0 +1,234 @@
+/*
+ * Scroll windows and DCs
+ *
+ * Copyright 1993  David W. Metcalfe
+ * Copyright 1995, 1996 Alex Korobka
+ * Copyright 2001 Alexandre Julliard
+ */
+
+#include "config.h"
+
+#include "ts_xlib.h"
+#include "ts_xutil.h"
+
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+
+#include "x11drv.h"
+#include "win.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(x11drv);
+
+
+/*************************************************************************
+ *             fix_caret
+ */
+static BOOL fix_caret(HWND hWnd, LPRECT lprc, UINT flags)
+{
+   HWND hCaret = CARET_GetHwnd();
+
+   if( hCaret )
+   {
+       RECT rc;
+       CARET_GetRect( &rc );
+       if( hCaret == hWnd ||
+          (flags & SW_SCROLLCHILDREN && IsChild(hWnd, hCaret)) )
+       {
+           POINT pt;
+           pt.x = rc.left;
+           pt.y = rc.top;
+           MapWindowPoints( hCaret, hWnd, (LPPOINT)&rc, 2 );
+           if( IntersectRect(lprc, lprc, &rc) )
+           {
+               HideCaret(0);
+               lprc->left = pt.x;
+               lprc->top = pt.y;
+               return TRUE;
+           }
+       }
+   }
+   return FALSE;
+}
+
+
+/*************************************************************************
+ *		ScrollDC   (X11DRV.@)
+ * 
+ * Only the hrgnUpdate is returned in device coordinates.
+ * rcUpdate must be returned in logical coordinates to comply with win API.
+ * FIXME: the doc explicitly states the opposite, to be checked
+ */
+BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *rc,
+                      const RECT *clipRect, HRGN hrgnUpdate, LPRECT rcUpdate )
+{
+    RECT rect, rClip, rSrc;
+
+    TRACE( "%04x %d,%d hrgnUpdate=%04x rcUpdate = %p\n", hdc, dx, dy, hrgnUpdate, rcUpdate );
+    if (clipRect) TRACE( "cliprc = (%d,%d,%d,%d)\n",
+                         clipRect->left, clipRect->top, clipRect->right, clipRect->bottom );
+    if (rc) TRACE( "rc = (%d,%d,%d,%d)\n", rc->left, rc->top, rc->right, rc->bottom );
+
+    /* compute device clipping region (in device coordinates) */
+
+    if (rc) rect = *rc;
+    else GetClipBox( hdc, &rect );
+
+    if (clipRect)
+    {
+        rClip = *clipRect;
+        IntersectRect( &rClip, &rect, &rClip );
+    }
+    else rClip = rect;
+
+    rSrc = rClip;
+    OffsetRect( &rSrc, -dx, -dy );
+    IntersectRect( &rSrc, &rSrc, &rect );
+
+    if (!IsRectEmpty(&rSrc))
+    {
+        /* copy bits */
+        if (!BitBlt( hdc, rSrc.left + dx, rSrc.top + dy,
+                     rSrc.right - rSrc.left, rSrc.bottom - rSrc.top,
+                     hdc, rSrc.left, rSrc.top, SRCCOPY))
+            return FALSE;
+    }
+
+    /* compute update areas */
+
+    if (hrgnUpdate || rcUpdate)
+    {
+        HRGN hrgn = hrgnUpdate, hrgn2;
+        POINT pt;
+
+        /* map everything to device coordinates */
+        pt.x = rect.left + dx;
+        pt.y = rect.top + dy;
+        LPtoDP( hdc, &pt, 1 );
+        LPtoDP( hdc, (LPPOINT)&rect, 2 );
+        LPtoDP( hdc, (LPPOINT)&rClip, 2 );
+        dx = pt.x - rect.left;
+        dy = pt.y - rect.top;
+
+        hrgn2 = CreateRectRgnIndirect( &rect );
+        if (hrgn) SetRectRgn( hrgn, rClip.left, rClip.top, rClip.right, rClip.bottom );
+        else hrgn = CreateRectRgn( rClip.left, rClip.top, rClip.right, rClip.bottom );
+        CombineRgn( hrgn, hrgn, hrgn2, RGN_AND );
+        OffsetRgn( hrgn2, dx, dy );
+        CombineRgn( hrgn, hrgn, hrgn2, RGN_DIFF );
+
+        if( rcUpdate )
+        {
+            GetRgnBox( hrgn, rcUpdate );
+
+            /* Put the rcUpdate in logical coordinate */
+            DPtoLP( hdc, (LPPOINT)rcUpdate, 2 );
+        }
+        if (!hrgnUpdate) DeleteObject( hrgn );
+        DeleteObject( hrgn2 );
+    }
+    return TRUE;
+}
+
+
+/*************************************************************************
+ *		ScrollWindowEx   (X11DRV.@)
+ */
+INT X11DRV_ScrollWindowEx( HWND hwnd, INT dx, INT dy,
+                           const RECT *rect, const RECT *clipRect,
+                           HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags )
+{
+    INT  retVal = NULLREGION;
+    BOOL bCaret = FALSE, bOwnRgn = TRUE;
+    RECT rc, cliprc;
+    WND*   wnd = WIN_FindWndPtr( hwnd );
+
+    if( !wnd || !WIN_IsWindowDrawable( wnd, TRUE ))
+    {
+        retVal = ERROR;
+        goto END;
+    }
+
+    GetClientRect(hwnd, &rc);
+    if (rect) IntersectRect(&rc, &rc, rect);
+
+    if (clipRect) IntersectRect(&cliprc,&rc,clipRect);
+    else cliprc = rc;
+
+    if (!IsRectEmpty(&cliprc) && (dx || dy))
+    {
+        HDC   hDC;
+        BOOL  bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE));
+        HRGN  hrgnClip = CreateRectRgnIndirect(&cliprc);
+        HRGN  hrgnTemp;
+        RECT  caretrc;
+
+        TRACE( "%04x, %d,%d hrgnUpdate=%04x rcUpdate = %p rc=(%d,%d-%d,%d) %04x\n",
+               hwnd, dx, dy, hrgnUpdate, rcUpdate,
+               rc.left, rc.top, rc.right, rc.bottom, flags );
+        if (clipRect) TRACE( "cliprc = (%d,%d,%d,%d)\n",
+                             clipRect->left, clipRect->top,
+                             clipRect->right, clipRect->bottom );
+
+        caretrc = rc;
+        bCaret = fix_caret(hwnd, &caretrc, flags);
+
+        if( hrgnUpdate ) bOwnRgn = FALSE;
+        else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
+
+        hDC = GetDCEx( hwnd, 0, DCX_CACHE | DCX_USESTYLE );
+        if (hDC)
+        {
+            HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
+            X11DRV_StartGraphicsExposures( hDC );
+            X11DRV_ScrollDC( hDC, dx, dy, &rc, &cliprc, hrgnUpdate, rcUpdate );
+            X11DRV_EndGraphicsExposures( hDC, hrgn );
+            ReleaseDC( hwnd, hDC );
+            if (bUpdate) CombineRgn( hrgnUpdate, hrgnUpdate, hrgn, RGN_OR );
+            else RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE | RDW_ERASE );
+        }
+
+        /* Take into account the fact that some damages may have occured during the scroll */
+        hrgnTemp = CreateRectRgn( 0, 0, 0, 0 );
+        if (GetUpdateRgn( hwnd, hrgnTemp, FALSE ) != NULLREGION)
+        {
+            OffsetRgn( hrgnTemp, dx, dy );
+            CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND );
+            RedrawWindow( hwnd, NULL, hrgnTemp, RDW_INVALIDATE | RDW_ERASE );
+        }
+        DeleteObject( hrgnTemp );
+
+        if( flags & SW_SCROLLCHILDREN )
+        {
+            RECT r;
+            WND *w;
+            for( w =WIN_LockWndPtr(wnd->child); w; WIN_UpdateWndPtr(&w, w->next))
+            {
+                r = w->rectWindow;
+                if( !rect || IntersectRect(&r, &r, &rc) )
+                    SetWindowPos(w->hwndSelf, 0, w->rectWindow.left + dx,
+                                 w->rectWindow.top  + dy, 0,0, SWP_NOZORDER |
+                                 SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW |
+                                 SWP_DEFERERASE );
+            }
+        }
+
+        if( flags & (SW_INVALIDATE | SW_ERASE) )
+            RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
+                          ((flags & SW_ERASE) ? RDW_ERASENOW : 0) |
+                          ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) );
+
+        if( bCaret )
+        {
+            SetCaretPos( caretrc.left + dx, caretrc.top + dy );
+            ShowCaret(0);
+        }
+
+        if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate );
+        DeleteObject( hrgnClip );
+    }
+END:
+    WIN_ReleaseWndPtr(wnd);
+    return retVal;
+}
diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c
index ed3e966..2b54382 100644
--- a/dlls/x11drv/window.c
+++ b/dlls/x11drv/window.c
@@ -21,18 +21,27 @@
 #include "dce.h"
 #include "options.h"
 
-DEFAULT_DEBUG_CHANNEL(win);
+DEFAULT_DEBUG_CHANNEL(x11drv);
 
 extern Pixmap X11DRV_BITMAP_Pixmap( HBITMAP );
 
 #define HAS_DLGFRAME(style,exStyle) \
-((!((style) & WS_THICKFRAME)) && (((style) & WS_DLGFRAME) || ((exStyle) & WS_EX_DLGMODALFRAME)))
+    (((exStyle) & WS_EX_DLGMODALFRAME) || \
+     (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
+
+#define HAS_THICKFRAME(style,exStyle) \
+    (((style) & WS_THICKFRAME) && \
+     !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
+
+#define HAS_THINFRAME(style) \
+    (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
 
 /* X context to associate a hwnd to an X window */
 XContext winContext = 0;
 
 Atom wmProtocols = None;
 Atom wmDeleteWindow = None;
+Atom wmTakeFocus = None;
 Atom dndProtocol = None;
 Atom dndSelection = None;
 Atom wmChangeState = None;
@@ -41,51 +50,137 @@
 
 
 /***********************************************************************
- *		X11DRV_register_window
+ *		is_window_managed
  *
- * Associate an X window to a HWND.
+ * Check if a given window should be managed
  */
-void X11DRV_register_window( Display *display, HWND hwnd, Window win )
+inline static BOOL is_window_managed( WND *win )
 {
-    if (!winContext) winContext = TSXUniqueContext();
-    TSXSaveContext( display, win, winContext, (char *)hwnd );
-    TSXSetWMProtocols( display, win, &wmDeleteWindow, 1 );
+    if (!Options.managed) return FALSE;
+
+    /* tray window is always managed */
+    if (win->dwExStyle & WS_EX_TRAYWINDOW) return TRUE;
+    /* child windows are not managed */
+    if (win->dwStyle & WS_CHILD) return FALSE;
+    /* tool windows are not managed */
+    if (win->dwExStyle & WS_EX_TOOLWINDOW) return FALSE;
+    /* windows with caption or thick frame are managed */
+    if ((win->dwStyle & WS_CAPTION) == WS_CAPTION) return TRUE;
+    if (win->dwStyle & WS_THICKFRAME) return TRUE;
+    /* default: not managed */
+    return FALSE;
 }
 
 
 /***********************************************************************
- *              set_wm_hint
+ *		is_window_top_level
  *
- * Set a window manager hint.
+ * Check if a given window is a top level X11 window
  */
-static void set_wm_hint( Display *display, Window win, int hint, int val )
+inline static BOOL is_window_top_level( WND *win )
 {
-    XWMHints* wm_hints = TSXGetWMHints( display, win );
-    if (!wm_hints) wm_hints = TSXAllocWMHints();
-    if (wm_hints)
+    return (root_window == DefaultRootWindow(gdi_display) &&
+            win->parent->hwndSelf == GetDesktopWindow());
+}
+
+
+/***********************************************************************
+ *              get_window_attributes
+ *
+ * Fill the window attributes structure for an X window
+ */
+static int get_window_attributes( WND *win, XSetWindowAttributes *attr )
+{
+    BOOL is_top_level = is_window_top_level( win );
+    BOOL managed = is_top_level && is_window_managed( win );
+
+    if (managed) win->dwExStyle |= WS_EX_MANAGED;
+    else win->dwExStyle &= ~WS_EX_MANAGED;
+
+    attr->override_redirect = !managed;
+    attr->bit_gravity       = ForgetGravity;
+    attr->win_gravity       = NorthWestGravity;
+    attr->colormap          = X11DRV_PALETTE_PaletteXColormap;
+    attr->backing_store     = NotUseful/*WhenMapped*/;
+    attr->save_under        = ((win->clsStyle & CS_SAVEBITS) != 0);
+    attr->cursor            = None;
+    attr->event_mask        = (ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
+                               ButtonPressMask | ButtonReleaseMask);
+    if (is_window_top_level( win )) attr->event_mask |= StructureNotifyMask | FocusChangeMask;
+
+    return (CWBitGravity | CWWinGravity | CWBackingStore | CWOverrideRedirect |
+            CWSaveUnder | CWEventMask | CWColormap | CWCursor);
+}
+
+
+/***********************************************************************
+ *              get_window_changes
+ *
+ * fill the window changes structure
+ */
+static int get_window_changes( XWindowChanges *changes, const RECT *old, const RECT *new )
+{
+    int mask = 0;
+
+    if (old->right - old->left != new->right - new->left )
     {
-        wm_hints->flags = hint;
-        switch( hint )
-        {
-        case InputHint:
-            wm_hints->input = val;
-            break;
-
-        case StateHint:
-            wm_hints->initial_state = val;
-            break;
-
-        case IconPixmapHint:
-            wm_hints->icon_pixmap = (Pixmap)val;
-            break;
-
-        case IconWindowHint:
-            wm_hints->icon_window = (Window)val;
-            break;
-        }
-        TSXSetWMHints( display, win, wm_hints );
-        TSXFree(wm_hints);
+        if (!(changes->width = new->right - new->left)) changes->width = 1;
+        mask |= CWWidth;
     }
+    if (old->bottom - old->top != new->bottom - new->top)
+    {
+        if (!(changes->height = new->bottom - new->top)) changes->height = 1;
+        mask |= CWHeight;
+    }
+    if (old->left != new->left)
+    {
+        changes->x = new->left;
+        mask |= CWX;
+    }
+    if (old->top != new->top)
+    {
+        changes->y = new->top;
+        mask |= CWY;
+    }
+    return mask;
+}
+
+
+/***********************************************************************
+ *              create_icon_window
+ */
+static Window create_icon_window( Display *display, WND *win )
+{
+    struct x11drv_win_data *data = win->pDriverData;
+    XSetWindowAttributes attr;
+
+    attr.event_mask = (ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
+                       ButtonPressMask | ButtonReleaseMask);
+    attr.bit_gravity = NorthWestGravity;
+    attr.backing_store = NotUseful/*WhenMapped*/;
+
+    data->icon_window = TSXCreateWindow( display, root_window, 0, 0,
+                                         GetSystemMetrics( SM_CXICON ),
+                                         GetSystemMetrics( SM_CYICON ),
+                                         0, screen_depth,
+                                         InputOutput, visual,
+                                         CWEventMask | CWBitGravity | CWBackingStore, &attr );
+    XSaveContext( display, data->icon_window, winContext, (char *)win->hwndSelf );
+    TRACE( "created %lx\n", data->icon_window );
+    return data->icon_window;
+}
+
+
+
+/***********************************************************************
+ *              destroy_icon_window
+ */
+inline static void destroy_icon_window( Display *display, struct x11drv_win_data *data )
+{
+    if (!data->icon_window) return;
+    XDeleteContext( display, data->icon_window, winContext );
+    XDestroyWindow( display, data->icon_window );
+    data->icon_window = 0;
 }
 
 
@@ -106,7 +201,9 @@
     {
         data->hWMIconBitmap = 0;
         data->hWMIconMask = 0;
-        hints->flags &= ~(IconPixmapHint | IconMaskHint);
+        if (!data->icon_window) create_icon_window( display, wndPtr );
+        hints->icon_window = data->icon_window;
+        hints->flags = (hints->flags & ~(IconPixmapHint | IconMaskHint)) | IconWindowHint;
     }
     else
     {
@@ -138,31 +235,338 @@
 
         hints->icon_pixmap = X11DRV_BITMAP_Pixmap(data->hWMIconBitmap);
         hints->icon_mask = X11DRV_BITMAP_Pixmap(data->hWMIconMask);
-        hints->flags |= IconPixmapHint | IconMaskHint;
+        destroy_icon_window( display, data );
+        hints->flags = (hints->flags & ~IconWindowHint) | IconPixmapHint | IconMaskHint;
     }
 }
 
 
 /***********************************************************************
- *		dock_window
+ *              set_size_hints
  *
- * Set the X Property of the window that tells the windowmanager we really
- * want to be in the systray
- *
- * KDE: set "KWM_DOCKWINDOW", type "KWM_DOCKWINDOW" to 1 before a window is 
- * 	mapped.
- *
- * all others: to be added ;)
+ * set the window size hints
  */
-inline static void dock_window( Display *display, Window win )
+static void set_size_hints( Display *display, WND *win )
 {
-    int data = 1;
-    if (kwmDockWindow != None)
-        TSXChangeProperty( display, win, kwmDockWindow, kwmDockWindow,
-                           32, PropModeReplace, (char*)&data, 1 );
-    if (_kde_net_wm_system_tray_window_for != None)
-        TSXChangeProperty( display, win, _kde_net_wm_system_tray_window_for, XA_WINDOW,
-                           32, PropModeReplace, (char*)&win, 1 );
+    XSizeHints* size_hints;
+    struct x11drv_win_data *data = win->pDriverData;
+
+    if ((size_hints = XAllocSizeHints()))
+    {
+        size_hints->win_gravity = StaticGravity;
+        size_hints->x = data->whole_rect.left;
+        size_hints->y = data->whole_rect.top;
+        size_hints->flags = PWinGravity | PPosition;
+
+        if (HAS_DLGFRAME( win->dwStyle, win->dwExStyle ))
+        {
+            size_hints->max_width = data->whole_rect.right - data->whole_rect.left;
+            size_hints->max_height = data->whole_rect.bottom - data->whole_rect.top;
+            size_hints->min_width = size_hints->max_width;
+            size_hints->min_height = size_hints->max_height;
+            size_hints->flags |= PMinSize | PMaxSize;
+        }
+        XSetWMNormalHints( display, data->whole_window, size_hints );
+        XFree( size_hints );
+    }
+}
+
+
+/***********************************************************************
+ *              set_wm_hints
+ *
+ * Set the window manager hints for a newly-created window
+ */
+inline static void set_wm_hints( Display *display, WND *win )
+{
+    struct x11drv_win_data *data = win->pDriverData;
+    Window group_leader;
+    XClassHint *class_hints;
+    XWMHints* wm_hints;
+    Atom protocols[2];
+    int i;
+
+    wine_tsx11_lock();
+
+    /* wm protocols */
+    i = 0;
+    protocols[i++] = wmDeleteWindow;
+    if (wmTakeFocus) protocols[i++] = wmTakeFocus;
+    XSetWMProtocols( display, data->whole_window, protocols, i );
+
+    /* class hints */
+    if ((class_hints = XAllocClassHint()))
+    {
+        class_hints->res_name = "wine";
+        class_hints->res_class = "Wine";
+        XSetClassHint( display, data->whole_window, class_hints );
+        XFree( class_hints );
+    }
+
+    /* transient for hint */
+    if (win->owner)
+    {
+        struct x11drv_win_data *owner_data = win->owner->pDriverData;
+        XSetTransientForHint( display, data->whole_window, owner_data->whole_window );
+        group_leader = owner_data->whole_window;
+    }
+    else group_leader = data->whole_window;
+
+    /* wm hints */
+    if ((wm_hints = XAllocWMHints()))
+    {
+        wm_hints->flags = InputHint | StateHint | WindowGroupHint;
+        /* use globally active model if take focus is supported,
+         * passive model otherwise (cf. ICCCM) */
+        wm_hints->input = !wmTakeFocus;
+
+        set_icon_hints( display, win, wm_hints );
+
+        wm_hints->initial_state = (win->dwStyle & WS_MINIMIZE) ? IconicState : NormalState;
+        wm_hints->window_group = group_leader;
+
+        XSetWMHints( display, data->whole_window, wm_hints );
+        XFree(wm_hints);
+    }
+
+    /* size hints */
+    set_size_hints( display, win );
+
+    /* systray properties (KDE only for now) */
+    if (win->dwExStyle & WS_EX_TRAYWINDOW)
+    {
+        int val = 1;
+        if (kwmDockWindow != None)
+            TSXChangeProperty( display, data->whole_window, kwmDockWindow, kwmDockWindow,
+                               32, PropModeReplace, (char*)&val, 1 );
+        if (_kde_net_wm_system_tray_window_for != None)
+            TSXChangeProperty( display, data->whole_window, _kde_net_wm_system_tray_window_for,
+                               XA_WINDOW, 32, PropModeReplace, (char*)&data->whole_window, 1 );
+    }
+
+    wine_tsx11_unlock();
+}
+
+
+/***********************************************************************
+ *              X11DRV_set_iconic_state
+ *
+ * Set the X11 iconic state according to the window style.
+ */
+void X11DRV_set_iconic_state( WND *win )
+{
+    Display *display = thread_display();
+    struct x11drv_win_data *data = win->pDriverData;
+    XWMHints* wm_hints;
+    BOOL iconic = IsIconic( win->hwndSelf );
+
+    if (!(win->dwExStyle & WS_EX_MANAGED))
+    {
+        if (iconic) TSXUnmapWindow( display, data->client_window );
+        else TSXMapWindow( display, data->client_window );
+    }
+
+    wine_tsx11_lock();
+
+    if (!(wm_hints = XGetWMHints( display, data->whole_window ))) wm_hints = XAllocWMHints();
+    wm_hints->flags |= StateHint | IconPositionHint;
+    wm_hints->initial_state = iconic ? IconicState : NormalState;
+    wm_hints->icon_x = win->rectWindow.left;
+    wm_hints->icon_y = win->rectWindow.top;
+    XSetWMHints( display, data->whole_window, wm_hints );
+
+    if (win->dwStyle & WS_VISIBLE)
+    {
+        if (iconic)
+            XIconifyWindow( display, data->whole_window, DefaultScreen(display) );
+        else
+            if (!IsRectEmpty( &win->rectWindow )) XMapWindow( display, data->whole_window );
+    }
+
+    XFree(wm_hints);
+    wine_tsx11_unlock();
+}
+
+
+/***********************************************************************
+ *		X11DRV_window_to_X_rect
+ *
+ * Convert a rect from client to X window coordinates
+ */
+void X11DRV_window_to_X_rect( WND *win, RECT *rect )
+{
+    if (!(win->dwExStyle & WS_EX_MANAGED)) return;
+    if (win->dwStyle & WS_ICONIC) return;
+    if (IsRectEmpty( rect )) return;
+
+    if (HAS_THICKFRAME( win->dwStyle, win->dwExStyle ))
+        InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
+    else if (HAS_DLGFRAME( win->dwStyle, win->dwExStyle ))
+        InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME) );
+    else if (HAS_THINFRAME( win->dwStyle ))
+        InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
+
+    if ((win->dwStyle & WS_CAPTION) == WS_CAPTION)
+    {
+        if (win->dwExStyle & WS_EX_TOOLWINDOW)
+            rect->top += GetSystemMetrics(SM_CYSMCAPTION);
+        else
+            rect->top += GetSystemMetrics(SM_CYCAPTION);
+    }
+
+    if (win->dwExStyle & WS_EX_CLIENTEDGE)
+        InflateRect( rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE) );
+    if (win->dwExStyle & WS_EX_STATICEDGE)
+        InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
+
+    if (rect->top >= rect->bottom) rect->bottom = rect->top + 1;
+    if (rect->left >= rect->right) rect->right = rect->left + 1;
+}
+
+
+/***********************************************************************
+ *		X11DRV_X_to_window_rect
+ *
+ * Opposite of X11DRV_window_to_X_rect
+ */
+void X11DRV_X_to_window_rect( WND *win, RECT *rect )
+{
+    if (!(win->dwExStyle & WS_EX_MANAGED)) return;
+    if (win->dwStyle & WS_ICONIC) return;
+    if (IsRectEmpty( rect )) return;
+
+    if (HAS_THICKFRAME( win->dwStyle, win->dwExStyle ))
+        InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
+    else if (HAS_DLGFRAME( win->dwStyle, win->dwExStyle ))
+        InflateRect( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
+    else if (HAS_THINFRAME( win->dwStyle ))
+        InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER) );
+
+    if ((win->dwStyle & WS_CAPTION) == WS_CAPTION)
+    {
+        if (win->dwExStyle & WS_EX_TOOLWINDOW)
+            rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
+        else
+            rect->top -= GetSystemMetrics(SM_CYCAPTION);
+    }
+
+    if (win->dwExStyle & WS_EX_CLIENTEDGE)
+        InflateRect( rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE) );
+    if (win->dwExStyle & WS_EX_STATICEDGE)
+        InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER) );
+
+    if (rect->top >= rect->bottom) rect->bottom = rect->top + 1;
+    if (rect->left >= rect->right) rect->right = rect->left + 1;
+}
+
+
+/***********************************************************************
+ *		X11DRV_sync_whole_window_position
+ *
+ * Synchronize the X whole window position with the Windows one
+ */
+int X11DRV_sync_whole_window_position( Display *display, WND *win, int zorder )
+{
+    XWindowChanges changes;
+    int mask;
+    struct x11drv_win_data *data = win->pDriverData;
+    RECT whole_rect = win->rectWindow;
+
+    X11DRV_window_to_X_rect( win, &whole_rect );
+    mask = get_window_changes( &changes, &data->whole_rect, &whole_rect );
+
+    if (zorder)
+    {
+        /* find window that this one must be after */
+        WND *prev = win->parent->child;
+        if (prev == win)  /* top child */
+        {
+            changes.stack_mode = Above;
+            mask |= CWStackMode;
+        }
+        else
+        {
+            while (prev && prev->next != win) prev = prev->next;
+            if (prev)
+            {
+                changes.stack_mode = Below;
+                changes.sibling = get_whole_window(prev);
+                mask |= CWStackMode | CWSibling;
+            }
+            else ERR( "previous window not found for %x, list corrupted?\n", win->hwndSelf );
+        }
+    }
+
+    data->whole_rect = whole_rect;
+
+    if (mask)
+    {
+        TRACE( "setting win %lx pos %d,%d,%dx%d after %lx changes=%x\n",
+               data->whole_window, whole_rect.left, whole_rect.top,
+               whole_rect.right - whole_rect.left, whole_rect.bottom - whole_rect.top,
+               changes.sibling, mask );
+        wine_tsx11_lock();
+        XSync( gdi_display, False );  /* flush graphics operations before moving the window */
+        if (is_window_top_level( win ))
+        {
+            if (mask & (CWWidth|CWHeight)) set_size_hints( display, win );
+            XReconfigureWMWindow( display, data->whole_window,
+                                  DefaultScreen(display), mask, &changes );
+        }
+        else XConfigureWindow( display, data->whole_window, mask, &changes );
+        wine_tsx11_unlock();
+    }
+    return mask;
+}
+
+
+/***********************************************************************
+ *		X11DRV_sync_client_window_position
+ *
+ * Synchronize the X client window position with the Windows one
+ */
+int X11DRV_sync_client_window_position( Display *display, WND *win )
+{
+    XWindowChanges changes;
+    int mask;
+    struct x11drv_win_data *data = win->pDriverData;
+    RECT client_rect = win->rectClient;
+
+    OffsetRect( &client_rect, -data->whole_rect.left, -data->whole_rect.top );
+    /* client rect cannot be empty */
+    if (client_rect.top >= client_rect.bottom) client_rect.bottom = client_rect.top + 1;
+    if (client_rect.left >= client_rect.right) client_rect.right = client_rect.left + 1;
+
+    if ((mask = get_window_changes( &changes, &data->client_rect, &client_rect )))
+    {
+        TRACE( "setting win %lx pos %d,%d,%dx%d (was %d,%d,%dx%d) after %lx changes=%x\n",
+               data->client_window, client_rect.left, client_rect.top,
+               client_rect.right - client_rect.left, client_rect.bottom - client_rect.top,
+               data->client_rect.left, data->client_rect.top,
+               data->client_rect.right - data->client_rect.left,
+               data->client_rect.bottom - data->client_rect.top,
+               changes.sibling, mask );
+        data->client_rect = client_rect;
+        wine_tsx11_lock();
+        XSync( gdi_display, False );  /* flush graphics operations before moving the window */
+        XConfigureWindow( display, data->client_window, mask, &changes );
+        wine_tsx11_unlock();
+    }
+    return mask;
+}
+
+
+/***********************************************************************
+ *		X11DRV_register_window
+ *
+ * Associate an X window to a HWND.
+ */
+void X11DRV_register_window( Display *display, HWND hwnd, struct x11drv_win_data *data )
+{
+    wine_tsx11_lock();
+    XSaveContext( display, data->whole_window, winContext, (char *)hwnd );
+    XSaveContext( display, data->client_window, winContext, (char *)hwnd );
+    wine_tsx11_unlock();
 }
 
 
@@ -173,15 +577,20 @@
 {
     X11DRV_WND_DATA *data = wndPtr->pDriverData;
 
-    wmProtocols = TSXInternAtom( display, "WM_PROTOCOLS", True );
-    wmDeleteWindow = TSXInternAtom( display, "WM_DELETE_WINDOW", True );
-    dndProtocol = TSXInternAtom( display, "DndProtocol" , False );
-    dndSelection = TSXInternAtom( display, "DndSelection" , False );
-    wmChangeState = TSXInternAtom (display, "WM_CHANGE_STATE", False);
-    kwmDockWindow = TSXInternAtom( display, "KWM_DOCKWINDOW", False );
-    _kde_net_wm_system_tray_window_for = TSXInternAtom( display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False );
+    wine_tsx11_lock();
+    winContext     = XUniqueContext();
+    wmProtocols    = XInternAtom( display, "WM_PROTOCOLS", False );
+    wmDeleteWindow = XInternAtom( display, "WM_DELETE_WINDOW", False );
+/*    wmTakeFocus    = XInternAtom( display, "WM_TAKE_FOCUS", False );*/
+    wmTakeFocus = 0;  /* not yet */
+    dndProtocol = XInternAtom( display, "DndProtocol" , False );
+    dndSelection = XInternAtom( display, "DndSelection" , False );
+    wmChangeState = XInternAtom (display, "WM_CHANGE_STATE", False);
+    kwmDockWindow = XInternAtom( display, "KWM_DOCKWINDOW", False );
+    _kde_net_wm_system_tray_window_for = XInternAtom( display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False );
+    wine_tsx11_unlock();
 
-    data->window = root_window;
+    data->whole_window = data->client_window = root_window;
     if (root_window != DefaultRootWindow(display))
     {
         wndPtr->flags |= WIN_NATIVE;
@@ -191,167 +600,133 @@
 
 
 /**********************************************************************
- *		CreateWindow   (X11DRV.@)
+ *		create_whole_window
+ *
+ * Create the whole X window for a given window
  */
-BOOL X11DRV_CreateWindow( HWND hwnd )
+static Window create_whole_window( Display *display, WND *win )
+{
+    struct x11drv_win_data *data = win->pDriverData;
+    int cx, cy, mask;
+    XSetWindowAttributes attr;
+    Window parent;
+    RECT rect;
+    BOOL is_top_level = is_window_top_level( win );
+
+    mask = get_window_attributes( win, &attr );
+
+    rect = win->rectWindow;
+    X11DRV_window_to_X_rect( win, &rect );
+
+    if (!(cx = rect.right - rect.left)) cx = 1;
+    if (!(cy = rect.bottom - rect.top)) cy = 1;
+
+    parent = get_client_window( win->parent );
+
+    wine_tsx11_lock();
+
+    if (is_top_level) attr.cursor = X11DRV_GetCursor( display, GlobalLock16(GetCursor()) );
+    data->whole_rect = rect;
+    data->whole_window = XCreateWindow( display, parent, rect.left, rect.top, cx, cy,
+                                        0, screen_depth, InputOutput, visual,
+                                        mask, &attr );
+    if (attr.cursor) XFreeCursor( display, attr.cursor );
+
+    if (!data->whole_window) goto done;
+
+    /* non-maximized child must be at bottom of Z order */
+    if ((win->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
+    {
+        XWindowChanges changes;
+        changes.stack_mode = Below;
+        XConfigureWindow( display, data->whole_window, CWStackMode, &changes );
+    }
+
+    if (is_top_level && !attr.override_redirect) set_wm_hints( display, win );
+
+ done:
+    wine_tsx11_unlock();
+    return data->whole_window;
+}
+
+
+/**********************************************************************
+ *		create_client_window
+ *
+ * Create the client window for a given window
+ */
+static Window create_client_window( Display *display, WND *win )
+{
+    struct x11drv_win_data *data = win->pDriverData;
+    RECT rect;
+    XSetWindowAttributes attr;
+
+    rect = win->rectWindow;
+    SendMessageW( win->hwndSelf, WM_NCCALCSIZE, FALSE, (LPARAM)&rect );
+
+    if (rect.left > rect.right || rect.top > rect.bottom) rect = win->rectWindow;
+    if (rect.top >= rect.bottom) rect.bottom = rect.top + 1;
+    if (rect.left >= rect.right) rect.right = rect.left + 1;
+
+    win->rectClient = rect;
+    OffsetRect( &rect, -data->whole_rect.left, -data->whole_rect.top );
+    data->client_rect = rect;
+
+    attr.event_mask = (ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
+                       ButtonPressMask | ButtonReleaseMask);
+    attr.bit_gravity = (win->clsStyle & (CS_VREDRAW | CS_HREDRAW)) ?
+                       ForgetGravity : NorthWestGravity;
+    attr.backing_store = NotUseful/*WhenMapped*/;
+
+    data->client_window = TSXCreateWindow( display, data->whole_window,
+                                           rect.left, rect.top,
+                                           rect.right - rect.left,
+                                           rect.bottom - rect.top,
+                                           0, screen_depth,
+                                           InputOutput, visual,
+                                           CWEventMask | CWBitGravity | CWBackingStore, &attr );
+    if (data->client_window) TSXMapWindow( display, data->client_window );
+    return data->client_window;
+}
+
+
+/*****************************************************************
+ *		SetWindowText   (X11DRV.@)
+ */
+BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text )
 {
     Display *display = thread_display();
-    X11DRV_WND_DATA *data;
+    UINT count;
+    char *buffer;
+    static UINT text_cp = (UINT)-1;
+    Window win;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
-    int x = wndPtr->rectWindow.left;
-    int y = wndPtr->rectWindow.top;
-    int cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
-    int cy = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
 
-    if (!(data = HeapAlloc(GetProcessHeap(), 0, sizeof(X11DRV_WND_DATA))))
+    if (!wndPtr) return FALSE;
+    if ((win = get_whole_window(wndPtr)))
     {
-        WIN_ReleaseWndPtr( wndPtr );
-        return FALSE;
-    }
-    data->window = 0;
-    wndPtr->pDriverData = data;
-
-    if (!wndPtr->parent)
-    {
-        create_desktop( display, wndPtr );
-        WIN_ReleaseWndPtr( wndPtr );
-        return TRUE;
-    }
-
-    /* Create the X window (only for top-level windows, and then only */
-    /* when there's no desktop window) */
-
-    if ((root_window == DefaultRootWindow(display))
-        && (wndPtr->parent->hwndSelf == GetDesktopWindow()))
-    {
-        Window    wGroupLeader;
-        XWMHints* wm_hints;
-        XSetWindowAttributes win_attr;
-
-        /* Create "managed" windows only if a title bar or resizable */
-        /* frame is required. */
-        if (WIN_WindowNeedsWMBorder(wndPtr->dwStyle, wndPtr->dwExStyle))
+        if (text_cp == (UINT)-1)
         {
-            win_attr.event_mask = ExposureMask | KeyPressMask |
-                KeyReleaseMask | PointerMotionMask |
-                ButtonPressMask | ButtonReleaseMask |
-                FocusChangeMask | StructureNotifyMask;
-            win_attr.override_redirect = FALSE;
-            wndPtr->dwExStyle |= WS_EX_MANAGED;
+            text_cp = PROFILE_GetWineIniInt("x11drv", "TextCP", CP_ACP);
+            TRACE("text_cp = %u\n", text_cp);
         }
-        else
+
+        /* allocate new buffer for window text */
+        count = WideCharToMultiByte(text_cp, 0, text, -1, NULL, 0, NULL, NULL);
+        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, count * sizeof(WCHAR) )))
         {
-            win_attr.event_mask = ExposureMask | KeyPressMask |
-                KeyReleaseMask | PointerMotionMask |
-                ButtonPressMask | ButtonReleaseMask |
-                FocusChangeMask;
-            win_attr.override_redirect = TRUE;
-        }
-        wndPtr->flags |= WIN_NATIVE;
-
-        wine_tsx11_lock();
-
-        win_attr.bit_gravity   = (wndPtr->clsStyle & (CS_VREDRAW | CS_HREDRAW)) ? ForgetGravity : NorthWestGravity;
-        win_attr.colormap      = X11DRV_PALETTE_PaletteXColormap;
-        win_attr.backing_store = NotUseful;
-        win_attr.save_under    = ((wndPtr->clsStyle & CS_SAVEBITS) != 0);
-        win_attr.cursor        = X11DRV_GetCursor( display, GlobalLock16(GetCursor()) );
-
-        data->hWMIconBitmap = 0;
-        data->hWMIconMask = 0;
-        data->bit_gravity = win_attr.bit_gravity;
-
-        /* Zero-size X11 window hack.  X doesn't like them, and will crash */
-        /* with a BadValue unless we do something ugly like this. */
-        /* Zero size window won't be mapped  */
-        if (cx <= 0) cx = 1;
-        if (cy <= 0) cy = 1;
-
-        data->window = XCreateWindow( display, root_window,
-                                        x, y, cx, cy,
-                                        0, screen_depth,
-                                        InputOutput, visual,
-                                        CWEventMask | CWOverrideRedirect |
-                                        CWColormap | CWCursor | CWSaveUnder |
-                                        CWBackingStore | CWBitGravity,
-                                        &win_attr );
-
-        if (win_attr.cursor) XFreeCursor( display, win_attr.cursor );
-        wine_tsx11_unlock();
-
-        if(!(wGroupLeader = data->window))
-        {
-            HeapFree( GetProcessHeap(), 0, data );
+            ERR("Not enough memory for window text\n");
             WIN_ReleaseWndPtr( wndPtr );
             return FALSE;
         }
+        WideCharToMultiByte(text_cp, 0, text, -1, buffer, count, NULL, NULL);
 
-        /* If we are the systray, we need to be managed to be noticed by KWM */
-        if (wndPtr->dwExStyle & WS_EX_TRAYWINDOW) dock_window( display, data->window );
+        wine_tsx11_lock();
+        XStoreName( display, win, buffer );
+        XSetIconName( display, win, buffer );
+        wine_tsx11_unlock();
 
-        if (wndPtr->dwExStyle & WS_EX_MANAGED)
-        {
-            XClassHint *class_hints = TSXAllocClassHint();
-            XSizeHints* size_hints = TSXAllocSizeHints();
-
-            if (class_hints)
-            {
-                class_hints->res_name = "wineManaged";
-                class_hints->res_class = "Wine";
-                TSXSetClassHint( display, data->window, class_hints );
-                TSXFree (class_hints);
-            }
-
-            if (size_hints)
-            {
-                size_hints->win_gravity = StaticGravity;
-                size_hints->x = x;
-                size_hints->y = y;
-                size_hints->flags = PWinGravity|PPosition;
-
-                if (HAS_DLGFRAME(wndPtr->dwStyle,wndPtr->dwExStyle))
-                {
-                    size_hints->min_width = size_hints->max_width = cx;
-                    size_hints->min_height = size_hints->max_height = cy;
-                    size_hints->flags |= PMinSize | PMaxSize;
-                }
-
-                TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr), 
-                                   size_hints, XA_WM_NORMAL_HINTS );
-                TSXFree(size_hints);
-            }
-        }
-
-        if (wndPtr->owner)  /* Get window owner */
-        {
-            Window w = X11DRV_WND_FindXWindow( wndPtr->owner );
-            if (w != None)
-            {
-                TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), w );
-                wGroupLeader = w;
-            }
-        }
-
-        if ((wm_hints = TSXAllocWMHints()))
-        {
-            wm_hints->flags = InputHint | StateHint | WindowGroupHint;
-            wm_hints->input = True;
-
-            if (wndPtr->dwExStyle & WS_EX_MANAGED)
-            {
-                set_icon_hints( display, wndPtr, wm_hints );
-                wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE)
-                    ? IconicState : NormalState;
-            }
-            else
-                wm_hints->initial_state = NormalState;
-            wm_hints->window_group = wGroupLeader;
-
-            TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
-            TSXFree(wm_hints);
-        }
-        X11DRV_register_window( display, hwnd, data->window );
-        TSXFlush( display );
+        HeapFree( GetProcessHeap(), 0, buffer );
     }
     WIN_ReleaseWndPtr( wndPtr );
     return TRUE;
@@ -366,37 +741,209 @@
     Display *display = thread_display();
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     X11DRV_WND_DATA *data = wndPtr->pDriverData;
-    Window w;
 
-    if (data && (w = data->window))
+    if (!data) goto done;
+
+    if (data->whole_window)
     {
-        XEvent xe;
+        TRACE( "win %x xwin %lx/%lx\n", hwnd, data->whole_window, data->client_window );
         wine_tsx11_lock();
         XSync( gdi_display, False );  /* flush any reference to this drawable in GDI queue */
-        XDeleteContext( display, w, winContext );
-        XDestroyWindow( display, w );
-        while( XCheckWindowEvent(display, w, NoEventMask, &xe) );
+        XDeleteContext( display, data->whole_window, winContext );
+        XDeleteContext( display, data->client_window, winContext );
+        XDestroyWindow( display, data->whole_window );  /* this destroys client too */
+        destroy_icon_window( display, data );
         wine_tsx11_unlock();
-
-        data->window = None;
-        if( data->hWMIconBitmap )
-        {
-            DeleteObject( data->hWMIconBitmap );
-            data->hWMIconBitmap = 0;
-        }
-        if( data->hWMIconMask )
-        {
-            DeleteObject( data->hWMIconMask);
-            data->hWMIconMask= 0;
-        }
     }
+
+    if (data->hWMIconBitmap) DeleteObject( data->hWMIconBitmap );
+    if (data->hWMIconMask) DeleteObject( data->hWMIconMask);
     HeapFree( GetProcessHeap(), 0, data );
     wndPtr->pDriverData = NULL;
+ done:
     WIN_ReleaseWndPtr( wndPtr );
     return TRUE;
 }
 
 
+/**********************************************************************
+ *		CreateWindow   (X11DRV.@)
+ */
+BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs )
+{
+    Display *display = thread_display();
+    WND *wndPtr;
+    struct x11drv_win_data *data;
+    BOOL ret = FALSE;
+
+    if (!(data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data)))) return FALSE;
+    data->whole_window  = 0;
+    data->client_window = 0;
+    data->icon_window   = 0;
+    data->hWMIconBitmap = 0;
+    data->hWMIconMask   = 0;
+
+    wndPtr = WIN_FindWndPtr( hwnd );
+    wndPtr->pDriverData = data;
+    wndPtr->flags |= WIN_NATIVE;
+    WIN_ReleaseWndPtr( wndPtr );
+
+    if (IsWindowUnicode( hwnd ))
+        ret = SendMessageW( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
+    else
+        ret = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
+
+    if (!ret) goto failed;
+
+    TRACE( "hwnd %x cs %d,%d %dx%d\n", hwnd, cs->x, cs->y, cs->cx, cs->cy );
+
+    if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
+
+    if (!wndPtr->parent)
+    {
+        create_desktop( display, wndPtr );
+        WIN_ReleaseWndPtr( wndPtr );
+        return TRUE;
+    }
+
+    if (!create_whole_window( display, wndPtr )) goto failed;
+    if (!create_client_window( display, wndPtr )) goto failed;
+    TSXSync( display, False );
+
+    TRACE( "win %x window %d,%d,%d,%d client %d,%d,%d,%d whole %d,%d,%d,%d X client %d,%d,%d,%d xwin %x/%x\n",
+           hwnd, wndPtr->rectWindow.left, wndPtr->rectWindow.top,
+           wndPtr->rectWindow.right, wndPtr->rectWindow.bottom,
+           wndPtr->rectClient.left, wndPtr->rectClient.top,
+           wndPtr->rectClient.right, wndPtr->rectClient.bottom,
+           data->whole_rect.left, data->whole_rect.top,
+           data->whole_rect.right, data->whole_rect.bottom,
+           data->client_rect.left, data->client_rect.top,
+           data->client_rect.right, data->client_rect.bottom,
+           (unsigned int)data->whole_window, (unsigned int)data->client_window );
+
+    if ((wndPtr->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
+        WIN_LinkWindow( hwnd, HWND_BOTTOM );
+    else
+        WIN_LinkWindow( hwnd, HWND_TOP );
+
+    if (wndPtr->text) X11DRV_SetWindowText( hwnd, wndPtr->text );
+    X11DRV_register_window( display, hwnd, data );
+    WIN_ReleaseWndPtr( wndPtr );
+
+    if (IsWindowUnicode( hwnd ))
+        ret = (SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
+    else
+        ret = (SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
+
+    if (!ret)
+    {
+        WIN_UnlinkWindow( hwnd );
+        goto failed;
+    }
+
+    /* Send the size messages */
+
+    if (!(wndPtr->flags & WIN_NEED_SIZE))
+    {
+        /* send it anyway */
+        if (((wndPtr->rectClient.right-wndPtr->rectClient.left) <0)
+            ||((wndPtr->rectClient.bottom-wndPtr->rectClient.top)<0))
+            WARN("sending bogus WM_SIZE message 0x%08lx\n",
+                 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+                          wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+        SendMessageW( hwnd, WM_SIZE, SIZE_RESTORED,
+                      MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+                               wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+        SendMessageW( hwnd, WM_MOVE, 0,
+                      MAKELONG( wndPtr->rectClient.left, wndPtr->rectClient.top ) );
+    }
+
+    /* Show the window, maximizing or minimizing if needed */
+
+    if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
+    {
+        extern UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ); /*FIXME*/
+
+        RECT newPos;
+        UINT swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
+        wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
+        WINPOS_MinMaximize( hwnd, swFlag, &newPos );
+        swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow())
+            ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
+            : SWP_NOZORDER | SWP_FRAMECHANGED;
+        SetWindowPos( hwnd, 0, newPos.left, newPos.top,
+                      newPos.right, newPos.bottom, swFlag );
+    }
+
+    return TRUE;
+
+
+ failed:
+    X11DRV_DestroyWindow( wndPtr->hwndSelf );
+    WIN_ReleaseWndPtr( wndPtr );
+    return FALSE;
+}
+
+
+/***********************************************************************
+ *		X11DRV_get_client_window
+ *
+ * Return the X window associated with the client area of a window
+ */
+Window X11DRV_get_client_window( HWND hwnd )
+{
+    Window ret = 0;
+    WND *win = WIN_FindWndPtr( hwnd );
+    if (win)
+    {
+        struct x11drv_win_data *data = win->pDriverData;
+        ret = data->client_window;
+        WIN_ReleaseWndPtr( win );
+    }
+    return ret;
+}
+
+
+/***********************************************************************
+ *		X11DRV_get_whole_window
+ *
+ * Return the X window associated with the full area of a window
+ */
+Window X11DRV_get_whole_window( HWND hwnd )
+{
+    Window ret = 0;
+    WND *win = WIN_FindWndPtr( hwnd );
+    if (win)
+    {
+        struct x11drv_win_data *data = win->pDriverData;
+        ret = data->whole_window;
+        WIN_ReleaseWndPtr( win );
+    }
+    return ret;
+}
+
+
+/***********************************************************************
+ *		X11DRV_get_top_window
+ *
+ * Return the X window associated with the top-level parent of a window
+ */
+Window X11DRV_get_top_window( HWND hwnd )
+{
+    Window ret = 0;
+    WND *win = WIN_FindWndPtr( hwnd );
+    while (win && win->parent->hwndSelf != GetDesktopWindow())
+        WIN_UpdateWndPtr( &win, win->parent );
+    if (win)
+    {
+        struct x11drv_win_data *data = win->pDriverData;
+        ret = data->whole_window;
+        WIN_ReleaseWndPtr( win );
+    }
+    return ret;
+}
+
+
 /*****************************************************************
  *		SetParent   (X11DRV.@)
  */
@@ -427,34 +974,32 @@
     retvalue = wndPtr->parent->hwndSelf;  /* old parent */
     if (pWndParent != wndPtr->parent)
     {
-        if ( X11DRV_WND_GetXWindow(wndPtr) )
-        {
-            /* Toplevel window needs to be reparented.  Used by Tk 8.0 */
-            TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
-            ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
-        }
+        struct x11drv_win_data *data = wndPtr->pDriverData;
+        int mask;
+        XSetWindowAttributes attr;
+
         WIN_UnlinkWindow(wndPtr->hwndSelf);
         wndPtr->parent = pWndParent;
+        WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
 
-        /* Create an X counterpart for reparented top-level windows
-	     * when not in the desktop mode. */
-        if (parent == GetDesktopWindow())
+        mask = get_window_attributes( wndPtr, &attr );
+        if (is_window_top_level( wndPtr ) && !attr.override_redirect)
+            set_wm_hints( display, wndPtr );
+
+        if (parent != GetDesktopWindow()) /* a child window */
         {
-            if(root_window == DefaultRootWindow(display))
-                X11DRV_CreateWindow(wndPtr->hwndSelf);
-        }
-        else /* a child window */
-        {
-            if( !( wndPtr->dwStyle & WS_CHILD ) )
+            if (!(wndPtr->dwStyle & WS_CHILD) && wndPtr->wIDmenu)
             {
-                if( wndPtr->wIDmenu != 0)
-                {
-                    DestroyMenu( (HMENU) wndPtr->wIDmenu );
-                    wndPtr->wIDmenu = 0;
-                }
+                DestroyMenu( (HMENU)wndPtr->wIDmenu );
+                wndPtr->wIDmenu = 0;
             }
         }
-        WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
+
+        wine_tsx11_lock();
+        XChangeWindowAttributes( display, data->whole_window, mask, &attr );
+        XReparentWindow( display, data->whole_window, get_client_window(pWndParent),
+                         data->whole_rect.left, data->whole_rect.top );
+        wine_tsx11_unlock();
     }
     WIN_ReleaseWndPtr( pWndParent );
     WIN_ReleaseWndPtr( wndPtr );
@@ -479,9 +1024,9 @@
 BOOL X11DRV_EnableWindow( HWND hwnd, BOOL enable )
 {
     Display *display = thread_display();
+    XWMHints *wm_hints;
     WND *wndPtr;
     BOOL retvalue;
-    Window w;
 
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
 
@@ -492,8 +1037,20 @@
         /* Enable window */
         wndPtr->dwStyle &= ~WS_DISABLED;
 
-        if ((wndPtr->dwExStyle & WS_EX_MANAGED) && (w = X11DRV_WND_GetXWindow( wndPtr )))
-            set_wm_hint( display, w, InputHint, TRUE );
+        if (wndPtr->dwExStyle & WS_EX_MANAGED)
+        {
+            wine_tsx11_lock();
+            if (!(wm_hints = XGetWMHints( display, get_whole_window(wndPtr) )))
+                wm_hints = XAllocWMHints();
+            if (wm_hints)
+            {
+                wm_hints->flags |= InputHint;
+                wm_hints->input = TRUE;
+                XSetWMHints( display, get_whole_window(wndPtr), wm_hints );
+                XFree(wm_hints);
+            }
+            wine_tsx11_unlock();
+        }
 
         SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
     }
@@ -504,8 +1061,20 @@
         /* Disable window */
         wndPtr->dwStyle |= WS_DISABLED;
 
-        if ((wndPtr->dwExStyle & WS_EX_MANAGED) && (w = X11DRV_WND_GetXWindow( wndPtr )))
-            set_wm_hint( display, w, InputHint, FALSE );
+        if (wndPtr->dwExStyle & WS_EX_MANAGED)
+        {
+            wine_tsx11_lock();
+            if (!(wm_hints = XGetWMHints( display, get_whole_window(wndPtr) )))
+                wm_hints = XAllocWMHints();
+            if (wm_hints)
+            {
+                wm_hints->flags |= InputHint;
+                wm_hints->input = FALSE;
+                XSetWMHints( display, get_whole_window(wndPtr), wm_hints );
+                XFree(wm_hints);
+            }
+            wine_tsx11_unlock();
+        }
 
         if (hwnd == GetFocus())
             SetFocus( 0 );  /* A disabled window can't have the focus */
@@ -540,9 +1109,8 @@
     /* no desktop window and if the window is not managed by the WM. */
     if (root_window != DefaultRootWindow(display)) goto done;
 
-    while (w && !((X11DRV_WND_DATA *) w->pDriverData)->window)
-        w = w->parent;
-    if (!w) w = wndPtr;
+    while (w && !get_whole_window(w)) w = w->parent;
+    if (!w) goto done;
     if (w->dwExStyle & WS_EX_MANAGED) goto done;
 
     if (!hwnd)  /* If setting the focus to 0, uninstall the colormap */
@@ -550,18 +1118,23 @@
         if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
             TSXUninstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
     }
-    else if ((win = X11DRV_WND_FindXWindow(wndPtr)))
+    else if ((win = get_whole_window(w)))
     {
         /* Set X focus and install colormap */
-        if (TSXGetWindowAttributes( display, win, &win_attr ) &&
+        wine_tsx11_lock();
+        if (XGetWindowAttributes( display, win, &win_attr ) &&
             (win_attr.map_state == IsViewable))
         {
             /* If window is not viewable, don't change anything */
-            TSXSetInputFocus( display, win, RevertToParent, CurrentTime );
+
+            /* we must not use CurrentTime (ICCCM), so try to use last message time instead */
+            /* FIXME: this is not entirely correct */
+            XSetInputFocus( display, win, RevertToParent,
+                            /*CurrentTime*/ GetMessageTime() + X11DRV_server_startticks );
             if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
-                TSXInstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
-            X11DRV_Synchronize();
+                XInstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
         }
+        wine_tsx11_unlock();
     }
 
  done:
@@ -569,46 +1142,6 @@
 }
 
 
-/*****************************************************************
- *		SetWindowText   (X11DRV.@)
- */
-BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text )
-{
-    Display *display = thread_display();
-    UINT count;
-    char *buffer;
-    static UINT text_cp = (UINT)-1;
-    Window win;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-
-    if (!wndPtr) return FALSE;
-    if ((win = X11DRV_WND_GetXWindow(wndPtr)))
-    {
-        if (text_cp == (UINT)-1)
-        {
-            text_cp = PROFILE_GetWineIniInt("x11drv", "TextCP", CP_ACP);
-            TRACE("text_cp = %u\n", text_cp);
-        }
-
-        /* allocate new buffer for window text */
-        count = WideCharToMultiByte(text_cp, 0, text, -1, NULL, 0, NULL, NULL);
-        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, count * sizeof(WCHAR) )))
-        {
-            ERR("Not enough memory for window text\n");
-            WIN_ReleaseWndPtr( wndPtr );
-            return FALSE;
-        }
-        WideCharToMultiByte(text_cp, 0, text, -1, buffer, count, NULL, NULL);
-
-        TSXStoreName( display, win, buffer );
-        TSXSetIconName( display, win, buffer );
-        HeapFree( GetProcessHeap(), 0, buffer );
-    }
-    WIN_ReleaseWndPtr( wndPtr );
-    return TRUE;
-}
-
-
 /**********************************************************************
  *		X11DRV_SetWindowIcon
  *
@@ -636,7 +1169,7 @@
 
     if (wndPtr->dwExStyle & WS_EX_MANAGED)
     {
-        Window win = X11DRV_WND_GetXWindow(wndPtr);
+        Window win = get_whole_window(wndPtr);
         XWMHints* wm_hints = TSXGetWMHints( display, win );
 
         if (!wm_hints) wm_hints = TSXAllocWMHints();
@@ -651,154 +1184,3 @@
     WIN_ReleaseWndPtr( wndPtr );
     return old;
 }
-
-
-/*************************************************************************
- *             fix_caret
- */
-static BOOL fix_caret(HWND hWnd, LPRECT lprc, UINT flags)
-{
-   HWND hCaret = CARET_GetHwnd();
-
-   if( hCaret )
-   {
-       RECT rc;
-       CARET_GetRect( &rc );
-       if( hCaret == hWnd ||
-          (flags & SW_SCROLLCHILDREN && IsChild(hWnd, hCaret)) )
-       {
-           POINT pt;
-           pt.x = rc.left;
-           pt.y = rc.top;
-           MapWindowPoints( hCaret, hWnd, (LPPOINT)&rc, 2 );
-           if( IntersectRect(lprc, lprc, &rc) )
-           {
-               HideCaret(0);
-               lprc->left = pt.x;
-               lprc->top = pt.y;
-               return TRUE;
-           }
-       }
-   }
-   return FALSE;
-}
-
-
-/*************************************************************************
- *		ScrollWindowEx   (X11DRV.@)
- */
-INT X11DRV_ScrollWindowEx( HWND hwnd, INT dx, INT dy,
-                           const RECT *rect, const RECT *clipRect,
-                           HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags )
-{
-    INT  retVal = NULLREGION;
-    BOOL bCaret = FALSE, bOwnRgn = TRUE;
-    RECT rc, cliprc;
-    WND*   wnd = WIN_FindWndPtr( hwnd );
-
-    if( !wnd || !WIN_IsWindowDrawable( wnd, TRUE ))
-    {
-        retVal = ERROR;
-        goto END;
-    }
-
-    GetClientRect(hwnd, &rc);
-    if (rect) IntersectRect(&rc, &rc, rect);
-
-    if (clipRect) IntersectRect(&cliprc,&rc,clipRect);
-    else cliprc = rc;
-
-    if (!IsRectEmpty(&cliprc) && (dx || dy))
-    {
-        HDC   hDC;
-        BOOL  bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE));
-        HRGN  hrgnClip = CreateRectRgnIndirect(&cliprc);
-        HRGN  hrgnTemp = CreateRectRgnIndirect(&rc);
-        RECT  caretrc;
-
-        TRACE("%04x, %d,%d hrgnUpdate=%04x rcUpdate = %p cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d) %04x\n",
-              (HWND16)hwnd, dx, dy, hrgnUpdate, rcUpdate,
-              clipRect?clipRect->left:0, clipRect?clipRect->top:0,
-              clipRect?clipRect->right:0, clipRect?clipRect->bottom:0,
-              rc.left, rc.top, rc.right, rc.bottom, (UINT16)flags );
-
-        caretrc = rc;
-        bCaret = fix_caret(hwnd, &caretrc, flags);
-
-        if( hrgnUpdate ) bOwnRgn = FALSE;
-        else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
-
-        hDC = GetDCEx( hwnd, hrgnClip, DCX_CACHE | DCX_USESTYLE |
-                         DCX_KEEPCLIPRGN | DCX_INTERSECTRGN |
-                       ((flags & SW_SCROLLCHILDREN) ? DCX_NOCLIPCHILDREN : 0) );
-        if (hDC)
-        {
-            X11DRV_WND_SurfaceCopy(wnd,hDC,dx,dy,&rc,bUpdate);
-            if( bUpdate )
-            {
-                DC* dc;
-
-                if( (dc = DC_GetDCPtr(hDC)) )
-                {
-                    OffsetRgn( hrgnTemp, dc->DCOrgX, dc->DCOrgY );
-                    CombineRgn( hrgnTemp, hrgnTemp, dc->hVisRgn,
-                                RGN_AND );
-                    OffsetRgn( hrgnTemp, -dc->DCOrgX, -dc->DCOrgY );
-                    CombineRgn( hrgnUpdate, hrgnTemp, hrgnClip,
-                                RGN_AND );
-                    OffsetRgn( hrgnTemp, dx, dy );
-                    retVal =
-                        CombineRgn( hrgnUpdate, hrgnUpdate, hrgnTemp,
-                                    RGN_DIFF );
-
-                    if( rcUpdate ) GetRgnBox( hrgnUpdate, rcUpdate );
-                    GDI_ReleaseObj( hDC );
-                }
-            }
-            ReleaseDC(hwnd, hDC);
-        }
-
-        if( wnd->hrgnUpdate > 1 )
-        {
-            /* Takes into account the fact that some damages may have
-               occured during the scroll. */
-            CombineRgn( hrgnTemp, wnd->hrgnUpdate, 0, RGN_COPY );
-            OffsetRgn( hrgnTemp, dx, dy );
-            CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND );
-            CombineRgn( wnd->hrgnUpdate, wnd->hrgnUpdate, hrgnTemp, RGN_OR );
-        }
-
-        if( flags & SW_SCROLLCHILDREN )
-        {
-            RECT r;
-            WND *w;
-            for( w =WIN_LockWndPtr(wnd->child); w; WIN_UpdateWndPtr(&w, w->next))
-            {
-                r = w->rectWindow;
-                if( !rect || IntersectRect(&r, &r, &rc) )
-                    SetWindowPos(w->hwndSelf, 0, w->rectWindow.left + dx,
-                                 w->rectWindow.top  + dy, 0,0, SWP_NOZORDER |
-                                 SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW |
-                                 SWP_DEFERERASE );
-            }
-        }
-
-        if( flags & (SW_INVALIDATE | SW_ERASE) )
-            RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
-                          ((flags & SW_ERASE) ? RDW_ERASENOW : 0) |
-                          ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) );
-
-        if( bCaret )
-        {
-            SetCaretPos( caretrc.left + dx, caretrc.top + dy );
-            ShowCaret(0);
-        }
-
-        if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate );
-        DeleteObject( hrgnClip );
-        DeleteObject( hrgnTemp );
-    }
-END:
-    WIN_ReleaseWndPtr(wnd);
-    return retVal;
-}
diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c
index 721bd7b..5fdd44e 100644
--- a/dlls/x11drv/winpos.c
+++ b/dlls/x11drv/winpos.c
@@ -8,6 +8,7 @@
 #include "config.h"
 
 #include "ts_xlib.h"
+#include "ts_xutil.h"
 #include "ts_shape.h"
 
 #include "winbase.h"
@@ -26,8 +27,7 @@
 
 #include "debugtools.h"
 
-DEFAULT_DEBUG_CHANNEL(win);
-
+DEFAULT_DEBUG_CHANNEL(x11drv);
 
 #define SWP_AGG_NOGEOMETRYCHANGE \
     (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
@@ -53,480 +53,187 @@
 #define ON_BOTTOM_BORDER(hit) \
  (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
 
-/***********************************************************************
- *           DCE_OffsetVisRgn
- *
- * Change region from DC-origin relative coordinates to screen coords.
- */
-
-static void DCE_OffsetVisRgn( HDC hDC, HRGN hVisRgn )
-{
-    DC *dc;
-    if (!(dc = DC_GetDCPtr( hDC ))) return;
-
-    OffsetRgn( hVisRgn, dc->DCOrgX, dc->DCOrgY );
-
-    GDI_ReleaseObj( hDC );
-}
-
 
 /***********************************************************************
- *           DCE_GetVisRect
+ *		clip_children
  *
- * Calculate the visible rectangle of a window (i.e. the client or
- * window area clipped by the client area of all ancestors) in the
- * corresponding coordinates. Return FALSE if the visible region is empty.
+ * Clip all children of a given window out of the visible region
  */
-static BOOL DCE_GetVisRect( WND *wndPtr, BOOL clientArea, RECT *lprect )
+static void clip_children( WND *win, HRGN hrgn, int whole_window )
 {
-    *lprect = clientArea ? wndPtr->rectClient : wndPtr->rectWindow;
+    WND *ptr;
+    HRGN rectRgn;
+    int x, y;
 
-    if (wndPtr->dwStyle & WS_VISIBLE)
+    /* first check if we have anything to do */
+    for (ptr = win->child; ptr; ptr = ptr->next)
+        if (ptr->dwStyle & WS_VISIBLE) break;
+    if (!ptr) return; /* no children to clip */
+
+    if (whole_window)
     {
-        INT xoffset = lprect->left;
-        INT yoffset = lprect->top;
-
-        while( !(wndPtr->flags & WIN_NATIVE) &&
-               ( wndPtr = WIN_LockWndPtr(wndPtr->parent)) )
-        {
-            if ( (wndPtr->dwStyle & (WS_ICONIC | WS_VISIBLE)) != WS_VISIBLE )
-            {
-                WIN_ReleaseWndPtr(wndPtr);
-                goto fail;
-            }
-
-            xoffset += wndPtr->rectClient.left;
-            yoffset += wndPtr->rectClient.top;
-            OffsetRect( lprect, wndPtr->rectClient.left,
-                        wndPtr->rectClient.top );
-
-            if( (wndPtr->rectClient.left >= wndPtr->rectClient.right) ||
-                (wndPtr->rectClient.top >= wndPtr->rectClient.bottom) ||
-                (lprect->left >= wndPtr->rectClient.right) ||
-                (lprect->right <= wndPtr->rectClient.left) ||
-                (lprect->top >= wndPtr->rectClient.bottom) ||
-                (lprect->bottom <= wndPtr->rectClient.top) )
-            {
-                WIN_ReleaseWndPtr(wndPtr);
-                goto fail;
-            }
-
-            lprect->left = max( lprect->left, wndPtr->rectClient.left );
-            lprect->right = min( lprect->right, wndPtr->rectClient.right );
-            lprect->top = max( lprect->top, wndPtr->rectClient.top );
-            lprect->bottom = min( lprect->bottom, wndPtr->rectClient.bottom );
-
-            WIN_ReleaseWndPtr(wndPtr);
-        }
-        OffsetRect( lprect, -xoffset, -yoffset );
-        return TRUE;
+        x = win->rectWindow.left - win->rectClient.left;
+        y = win->rectWindow.top - win->rectClient.top;
     }
+    else x = y = 0;
 
-fail:
-    SetRectEmpty( lprect );
-    return FALSE;
-}
-
-
-/***********************************************************************
- *           DCE_AddClipRects
- *
- * Go through the linked list of windows from pWndStart to pWndEnd,
- * adding to the clip region the intersection of the target rectangle
- * with an offset window rectangle.
- */
-static BOOL DCE_AddClipRects( WND *pWndStart, WND *pWndEnd,
-                              HRGN hrgnClip, LPRECT lpRect, int x, int y )
-{
-    RECT rect;
-
-    if (X11DRV_WND_GetXWindow(pWndStart)) return TRUE; /* X will do the clipping */
-
-    for (WIN_LockWndPtr(pWndStart); (pWndStart && (pWndStart != pWndEnd)); WIN_UpdateWndPtr(&pWndStart,pWndStart->next))
+    rectRgn = CreateRectRgn( 0, 0, 0, 0 );
+    while (ptr)
     {
-        if( !(pWndStart->dwStyle & WS_VISIBLE) ) continue;
-
-        rect.left = pWndStart->rectWindow.left + x;
-        rect.top = pWndStart->rectWindow.top + y;
-        rect.right = pWndStart->rectWindow.right + x;
-        rect.bottom = pWndStart->rectWindow.bottom + y;
-
-        if( IntersectRect( &rect, &rect, lpRect ))
+        if (ptr->dwStyle & WS_VISIBLE)
         {
-            if(!REGION_UnionRectWithRgn( hrgnClip, &rect )) break;
+            SetRectRgn( rectRgn, ptr->rectWindow.left + x, ptr->rectWindow.top + y,
+                        ptr->rectWindow.right + x, ptr->rectWindow.bottom + y );
+            if (CombineRgn( hrgn, hrgn, rectRgn, RGN_DIFF ) == NULLREGION)
+                break;  /* no need to go on, region is empty */
         }
+        ptr = ptr->next;
     }
-    WIN_ReleaseWndPtr(pWndStart);
-    return (pWndStart == pWndEnd);
+    DeleteObject( rectRgn );
 }
 
 
 /***********************************************************************
- *           DCE_GetVisRgn
+ *		get_visible_region
  *
- * Return the visible region of a window, i.e. the client or window area
- * clipped by the client area of all ancestors, and then optionally
- * by siblings and children.
+ * Compute the visible region of a window
  */
-static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
+static HRGN get_visible_region( WND *win, UINT flags )
 {
-    HRGN hrgnVis = 0;
+    HRGN rgn;
     RECT rect;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    WND *childWnd = WIN_FindWndPtr( hwndChild );
+    int xoffset, yoffset;
+    X11DRV_WND_DATA *data = win->pDriverData;
 
-    /* Get visible rectangle and create a region with it. */
-
-    if (wndPtr && DCE_GetVisRect(wndPtr, !(flags & DCX_WINDOW), &rect))
+    if (flags & DCX_WINDOW)
     {
-        if((hrgnVis = CreateRectRgnIndirect( &rect )))
-        {
-            HRGN hrgnClip = CreateRectRgn( 0, 0, 0, 0 );
-            INT xoffset, yoffset;
-
-            if( hrgnClip )
-            {
-                /* Compute obscured region for the visible rectangle by 
-		 * clipping children, siblings, and ancestors. Note that
-		 * DCE_GetVisRect() returns a rectangle either in client
-		 * or in window coordinates (for DCX_WINDOW request). */
-
-                if( (flags & DCX_CLIPCHILDREN) && wndPtr->child )
-                {
-                    if( flags & DCX_WINDOW )
-                    {
-                        /* adjust offsets since child window rectangles are 
-			 * in client coordinates */
-
-                        xoffset = wndPtr->rectClient.left - wndPtr->rectWindow.left;
-                        yoffset = wndPtr->rectClient.top - wndPtr->rectWindow.top;
-                    }
-                    else
-                        xoffset = yoffset = 0;
-
-                    DCE_AddClipRects( wndPtr->child, NULL, hrgnClip, &rect, xoffset, yoffset );
-                }
-
-                /* We may need to clip children of child window, if a window with PARENTDC
-		 * class style and CLIPCHILDREN window style (like in Free Agent 16
-		 * preference dialogs) gets here, we take the region for the parent window
-		 * but apparently still need to clip the children of the child window... */
-
-                if( (cflags & DCX_CLIPCHILDREN) && childWnd && childWnd->child )
-                {
-                    if( flags & DCX_WINDOW )
-                    {
-                        /* adjust offsets since child window rectangles are 
-			 * in client coordinates */
-
-                        xoffset = wndPtr->rectClient.left - wndPtr->rectWindow.left;
-                        yoffset = wndPtr->rectClient.top - wndPtr->rectWindow.top;
-                    }
-                    else
-                        xoffset = yoffset = 0;
-
-                    /* client coordinates of child window */
-                    xoffset += childWnd->rectClient.left;
-                    yoffset += childWnd->rectClient.top;
-
-                    DCE_AddClipRects( childWnd->child, NULL, hrgnClip,
-                                      &rect, xoffset, yoffset );
-                }
-
-                /* sibling window rectangles are in client 
-		 * coordinates of the parent window */
-
-                if (flags & DCX_WINDOW)
-                {
-                    xoffset = -wndPtr->rectWindow.left;
-                    yoffset = -wndPtr->rectWindow.top;
-                }
-                else
-                {
-                    xoffset = -wndPtr->rectClient.left;
-                    yoffset = -wndPtr->rectClient.top;
-                }
-
-                if (flags & DCX_CLIPSIBLINGS && wndPtr->parent )
-                    DCE_AddClipRects( wndPtr->parent->child,
-                                      wndPtr, hrgnClip, &rect, xoffset, yoffset );
-
-                /* Clip siblings of all ancestors that have the
-                 * WS_CLIPSIBLINGS style
-		 */
-
-                while (wndPtr->parent)
-                {
-                    WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
-                    xoffset -= wndPtr->rectClient.left;
-                    yoffset -= wndPtr->rectClient.top;
-                    if(wndPtr->dwStyle & WS_CLIPSIBLINGS && wndPtr->parent)
-                    {
-                        DCE_AddClipRects( wndPtr->parent->child, wndPtr,
-                                          hrgnClip, &rect, xoffset, yoffset );
-                    }
-                }
-
-                /* Now once we've got a jumbo clip region we have
-		 * to substract it from the visible rectangle.
-	         */
-                CombineRgn( hrgnVis, hrgnVis, hrgnClip, RGN_DIFF );
-                DeleteObject( hrgnClip );
-            }
-            else
-            {
-                DeleteObject( hrgnVis );
-                hrgnVis = 0;
-            }
-        }
+        xoffset = win->rectWindow.left;
+        yoffset = win->rectWindow.top;
     }
     else
-        hrgnVis = CreateRectRgn(0, 0, 0, 0); /* empty */
-    WIN_ReleaseWndPtr(wndPtr);
-    WIN_ReleaseWndPtr(childWnd);
-    return hrgnVis;
+    {
+        xoffset = win->rectClient.left;
+        yoffset = win->rectClient.top;
+    }
+
+    if (flags & DCX_PARENTCLIP)
+        GetClientRect( win->parent->hwndSelf, &rect );
+    else if (flags & DCX_WINDOW)
+        rect = data->whole_rect;
+    else
+        rect = win->rectClient;
+
+    /* vis region is relative to the start of the client/window area */
+    OffsetRect( &rect, -xoffset, -yoffset );
+
+    if (!(rgn = CreateRectRgn( rect.left, rect.top, rect.right, rect.bottom ))) return 0;
+
+    if (flags & DCX_CLIPCHILDREN)
+    {
+        /* if we are clipping siblings and using the client area,
+         * X will do the clipping for us; otherwise, we need to
+         * clip children by hand here
+         */
+        if ((flags & DCX_WINDOW) || !(flags & DCX_CLIPSIBLINGS))
+            clip_children( win, rgn, (flags & DCX_WINDOW) );
+    }
+    return rgn;
 }
 
 
 /***********************************************************************
- *		GetDC   (X11DRV.@)
+ *		X11DRV_GetDC
  *
  * Set the drawable, origin and dimensions for the DC associated to
  * a given window.
  */
 BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
 {
-    WND *w, *wndPtr = WIN_FindWndPtr(hwnd);
-    DC *dc;
-    X11DRV_PDEVICE *physDev;
-    INT dcOrgXCopy = 0, dcOrgYCopy = 0;
-    BOOL offsetClipRgn = FALSE;
-    BOOL updateVisRgn;
-    HRGN hrgnVisible = 0;
+    WND *win = WIN_FindWndPtr( hwnd );
+    X11DRV_WND_DATA *data = win->pDriverData;
+    Drawable drawable;
+    int org_x, org_y, mode = IncludeInferiors;
 
-    if (!wndPtr) return FALSE;
+    /* don't clip siblings if using parent clip region */
+    if (flags & DCX_PARENTCLIP) flags &= ~DCX_CLIPSIBLINGS;
 
-    if (!(dc = DC_GetDCPtr( hdc )))
+    if (flags & DCX_CLIPSIBLINGS)
     {
-        WIN_ReleaseWndPtr( wndPtr );
-        return FALSE;
-    }
-
-    physDev = (X11DRV_PDEVICE *)dc->physDev;
-
-    /*
-     * This function change the coordinate system (DCOrgX,DCOrgY)
-     * values. When it moves the origin, other data like the current clipping
-     * region will not be moved to that new origin. In the case of DCs that are class
-     * or window DCs that clipping region might be a valid value from a previous use
-     * of the DC and changing the origin of the DC without moving the clip region
-     * results in a clip region that is not placed properly in the DC.
-     * This code will save the dc origin, let the SetDrawable
-     * modify the origin and reset the clipping. When the clipping is set,
-     * it is moved according to the new DC origin.
-     */
-    if ( (wndPtr->clsStyle & (CS_OWNDC | CS_CLASSDC)) && (dc->hClipRgn > 0))
-    {
-        dcOrgXCopy = dc->DCOrgX;
-        dcOrgYCopy = dc->DCOrgY;
-        offsetClipRgn = TRUE;
-    }
-
-    if (flags & DCX_WINDOW)
-    {
-        dc->DCOrgX  = wndPtr->rectWindow.left;
-        dc->DCOrgY  = wndPtr->rectWindow.top;
-    }
-    else
-    {
-        dc->DCOrgX  = wndPtr->rectClient.left;
-        dc->DCOrgY  = wndPtr->rectClient.top;
-    }
-
-    w = wndPtr;
-    while (!X11DRV_WND_GetXWindow(w))
-    {
-        w = w->parent;
-        dc->DCOrgX += w->rectClient.left;
-        dc->DCOrgY += w->rectClient.top;
-    }
-    dc->DCOrgX -= w->rectWindow.left;
-    dc->DCOrgY -= w->rectWindow.top;
-
-    /* reset the clip region, according to the new origin */
-    if ( offsetClipRgn )
-    {
-        OffsetRgn(dc->hClipRgn, dc->DCOrgX - dcOrgXCopy,dc->DCOrgY - dcOrgYCopy);
-    }
-
-    physDev->drawable = X11DRV_WND_GetXWindow(w);
-
-#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->DCOrgX, dc->DCOrgY );
-#endif
-
-    updateVisRgn = (dc->flags & DC_DIRTY) != 0;
-    GDI_ReleaseObj( hdc );
-
-    if (updateVisRgn)
-    {
-        if (flags & DCX_PARENTCLIP)
+        if (IsIconic( hwnd ))
         {
-            WND *parentPtr = WIN_LockWndPtr(wndPtr->parent);
-
-            if( wndPtr->dwStyle & WS_VISIBLE && !(parentPtr->dwStyle & WS_MINIMIZE) )
-            {
-                DWORD dcxFlags;
-
-                if( parentPtr->dwStyle & WS_CLIPSIBLINGS )
-                    dcxFlags = DCX_CLIPSIBLINGS | (flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW));
-                else
-                    dcxFlags = flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW);
-
-                hrgnVisible = DCE_GetVisRgn( parentPtr->hwndSelf, dcxFlags,
-                                             wndPtr->hwndSelf, flags );
-                if( flags & DCX_WINDOW )
-                    OffsetRgn( hrgnVisible, -wndPtr->rectWindow.left,
-                               -wndPtr->rectWindow.top );
-                else
-                    OffsetRgn( hrgnVisible, -wndPtr->rectClient.left,
-                               -wndPtr->rectClient.top );
-                DCE_OffsetVisRgn( hdc, hrgnVisible );
-            }
-            else
-                hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
-            WIN_ReleaseWndPtr(parentPtr);
+            drawable = data->icon_window ? data->icon_window : data->whole_window;
+            org_x = 0;
+            org_y = 0;
+        }
+        else if (flags & DCX_WINDOW)
+        {
+            drawable = data->whole_window;
+            org_x = win->rectWindow.left - data->whole_rect.left;
+            org_y = win->rectWindow.top - data->whole_rect.top;
         }
         else
         {
-            if ((hwnd == GetDesktopWindow()) && (root_window != DefaultRootWindow(thread_display())))
-                hrgnVisible = CreateRectRgn( 0, 0, GetSystemMetrics(SM_CXSCREEN),
-                                             GetSystemMetrics(SM_CYSCREEN) );
-            else
-            {
-                hrgnVisible = DCE_GetVisRgn( hwnd, flags, 0, 0 );
-                DCE_OffsetVisRgn( hdc, hrgnVisible );
-            }
+            drawable = data->client_window;
+            org_x = 0;
+            org_y = 0;
+            if (flags & DCX_CLIPCHILDREN) mode = ClipByChildren;  /* can use X11 clipping */
         }
-        SelectVisRgn16( hdc, hrgnVisible );
     }
-
-    /* apply additional region operation (if any) */
-
-    if( flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) )
+    else
     {
-        if( !hrgnVisible ) hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
-
-        TRACE("\tsaved VisRgn, clipRgn = %04x\n", hrgn);
-
-        SaveVisRgn16( hdc );
-        CombineRgn( hrgnVisible, hrgn, 0, RGN_COPY );
-        DCE_OffsetVisRgn( hdc, hrgnVisible );
-        CombineRgn( hrgnVisible, InquireVisRgn16( hdc ), hrgnVisible,
-                      (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
-        SelectVisRgn16( hdc, hrgnVisible );
+        /* not clipping siblings -> have to use parent client drawable */
+        if (win->parent) drawable = get_client_window( win->parent );
+        else drawable = root_window;
+        if (flags & DCX_WINDOW)
+        {
+            org_x = win->rectWindow.left;
+            org_y = win->rectWindow.top;
+        }
+        else
+        {
+            org_x = win->rectClient.left;
+            org_y = win->rectClient.top;
+        }
     }
 
-    if (hrgnVisible) DeleteObject( hrgnVisible );
+    X11DRV_SetDrawable( hdc, drawable, mode, org_x, org_y );
 
-    WIN_ReleaseWndPtr( wndPtr );
+    if (flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) ||
+        SetHookFlags16( hdc, DCHF_VALIDATEVISRGN ))  /* DC was dirty */
+    {
+        /* need to recompute the visible region */
+        HRGN visRgn = get_visible_region( win, flags );
+
+        if (flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN))
+            CombineRgn( visRgn, visRgn, hrgn, (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
+
+        /* make it relative to the drawable origin */
+        OffsetRgn( visRgn, org_x, org_y );
+        SelectVisRgn16( hdc, visRgn );
+        DeleteObject( visRgn );
+    }
+
+    WIN_ReleaseWndPtr( win );
     return TRUE;
 }
 
 
-/***********************************************************************
- *           SWP_DoSimpleFrameChanged
- *
- * NOTE: old and new client rect origins are identical, only
- *	 extents may have changed. Window extents are the same.
- */
-static void SWP_DoSimpleFrameChanged( WND* wndPtr, RECT* pOldClientRect,
-                                      WORD swpFlags, UINT uFlags )
-{
-    INT i = 0;
-    RECT rect;
-    HRGN hrgn = 0;
-
-    if( !(swpFlags & SWP_NOCLIENTSIZE) )
-    {
-        /* Client rect changed its position/size, most likely a scrollar
-	 * was added/removed.
-	 *
-	 * FIXME: WVR alignment flags
-	 */
-
-        if( wndPtr->rectClient.right >  pOldClientRect->right ) /* right edge */
-        {
-            i++;
-            rect.top = 0;
-            rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
-            rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
-            if(!(uFlags & SWP_EX_NOCOPY))
-                rect.left = pOldClientRect->right - wndPtr->rectClient.left;
-            else
-            {
-                rect.left = 0;
-                goto redraw;
-            }
-        }
-
-        if( wndPtr->rectClient.bottom > pOldClientRect->bottom ) /* bottom edge */
-        {
-            if( i )
-                hrgn = CreateRectRgnIndirect( &rect );
-            rect.left = 0;
-            rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
-            rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
-            if(!(uFlags & SWP_EX_NOCOPY))
-                rect.top = pOldClientRect->bottom - wndPtr->rectClient.top;
-            else
-                rect.top = 0;
-            if( i++ )
-                REGION_UnionRectWithRgn( hrgn, &rect );
-        }
-
-        if( i == 0 && (uFlags & SWP_EX_NOCOPY) ) /* force redraw anyway */
-        {
-            rect = wndPtr->rectWindow;
-            OffsetRect( &rect, wndPtr->rectWindow.left - wndPtr->rectClient.left,
-                        wndPtr->rectWindow.top - wndPtr->rectClient.top );
-            i++;
-        }
-    }
-
-    if( i )
-    {
-    redraw:
-        PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, hrgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
-                            RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME | RDW_EX_USEHRGN );
-    }
-    else
-    {
-        WIN_UpdateNCRgn(wndPtr, 0, UNC_UPDATE | UNC_ENTIRE);
-    }
-
-    if( hrgn > 1 )
-        DeleteObject( hrgn );
-}
 
 /***********************************************************************
  *           SWP_DoWinPosChanging
  */
-static BOOL SWP_DoWinPosChanging( WND* wndPtr, WINDOWPOS* pWinpos,
-                                  RECT* pNewWindowRect, RECT* pNewClientRect )
+static BOOL SWP_DoWinPosChanging( WINDOWPOS* pWinpos, RECT* pNewWindowRect, RECT* pNewClientRect )
 {
-      /* Send WM_WINDOWPOSCHANGING message */
+    WND *wndPtr;
+
+    /* Send WM_WINDOWPOSCHANGING message */
 
     if (!(pWinpos->flags & SWP_NOSENDCHANGING))
-        SendMessageA( wndPtr->hwndSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM)pWinpos );
+        SendMessageA( pWinpos->hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)pWinpos );
 
-      /* Calculate new position and size */
+    if (!(wndPtr = WIN_FindWndPtr( pWinpos->hwnd ))) return FALSE;
+
+    /* Calculate new position and size */
 
     *pNewWindowRect = wndPtr->rectWindow;
     *pNewClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
@@ -547,8 +254,8 @@
         OffsetRect( pNewClientRect, pWinpos->x - wndPtr->rectWindow.left,
                                     pWinpos->y - wndPtr->rectWindow.top );
     }
-
     pWinpos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
+    WIN_ReleaseWndPtr( wndPtr );
     return TRUE;
 }
 
@@ -556,7 +263,7 @@
  *           SWP_DoNCCalcSize
  */
 static UINT SWP_DoNCCalcSize( WND* wndPtr, WINDOWPOS* pWinpos,
-                              RECT* pNewWindowRect, RECT* pNewClientRect, WORD f)
+                              RECT* pNewWindowRect, RECT* pNewClientRect )
 {
     UINT wvrFlags = 0;
 
@@ -566,7 +273,6 @@
          wvrFlags = WINPOS_SendNCCalcSize( pWinpos->hwnd, TRUE, pNewWindowRect,
                                     &wndPtr->rectWindow, &wndPtr->rectClient,
                                     pWinpos, pNewClientRect );
-
          /* FIXME: WVR_ALIGNxxx */
 
          if( pNewClientRect->left != wndPtr->rectClient.left ||
@@ -580,8 +286,8 @@
              pWinpos->flags &= ~SWP_NOCLIENTSIZE;
     }
     else
-      if( !(f & SWP_NOMOVE) && (pNewClientRect->left != wndPtr->rectClient.left ||
-                                pNewClientRect->top != wndPtr->rectClient.top) )
+      if( !(pWinpos->flags & SWP_NOMOVE) && (pNewClientRect->left != wndPtr->rectClient.left ||
+                                             pNewClientRect->top != wndPtr->rectClient.top) )
             pWinpos->flags &= ~SWP_NOCLIENTMOVE;
     return wvrFlags;
 }
@@ -640,256 +346,24 @@
     return hwndInsertAfter;
 }
 
-/***********************************************************************
- *	     SWP_CopyValidBits
- *
- * Make window look nice without excessive repainting
- *
- * visible and update regions are in window coordinates
- * client and window rectangles are in parent client coordinates
- *
- * Returns: uFlags and a dirty region in *pVisRgn.
- */
-static UINT SWP_CopyValidBits( WND* Wnd, HRGN* pVisRgn,
-                               LPRECT lpOldWndRect,
-                               LPRECT lpOldClientRect, UINT uFlags )
+
+/* fix redundant flags and values in the WINDOWPOS structure */
+static BOOL fixup_flags( WINDOWPOS *winpos )
 {
-    RECT r;
-    HRGN newVisRgn, dirtyRgn;
-    INT  my = COMPLEXREGION;
-    DWORD dflags;
+    WND *wndPtr = WIN_FindWndPtr( winpos->hwnd );
+    BOOL ret = TRUE;
 
-    TRACE("\tnew wnd=(%i %i-%i %i) old wnd=(%i %i-%i %i), %04x\n",
-          Wnd->rectWindow.left, Wnd->rectWindow.top,
-          Wnd->rectWindow.right, Wnd->rectWindow.bottom,
-          lpOldWndRect->left, lpOldWndRect->top,
-          lpOldWndRect->right, lpOldWndRect->bottom, *pVisRgn);
-    TRACE("\tnew client=(%i %i-%i %i) old client=(%i %i-%i %i)\n",
-          Wnd->rectClient.left, Wnd->rectClient.top,
-          Wnd->rectClient.right, Wnd->rectClient.bottom,
-          lpOldClientRect->left, lpOldClientRect->top,
-          lpOldClientRect->right,lpOldClientRect->bottom );
+    if (!wndPtr) return FALSE;
 
-    if( Wnd->hrgnUpdate == 1 )
-        uFlags |= SWP_EX_NOCOPY; /* whole window is invalid, nothing to copy */
-
-    dflags = DCX_WINDOW;
-    if(Wnd->dwStyle & WS_CLIPSIBLINGS)
-        dflags |= DCX_CLIPSIBLINGS;
-    newVisRgn = DCE_GetVisRgn( Wnd->hwndSelf, dflags, 0, 0);
-
-    dirtyRgn = CreateRectRgn( 0, 0, 0, 0 );
-
-    if( !(uFlags & SWP_EX_NOCOPY) ) /* make sure dst region covers only valid bits */
-        my = CombineRgn( dirtyRgn, newVisRgn, *pVisRgn, RGN_AND );
-
-    if( (my == NULLREGION) || (uFlags & SWP_EX_NOCOPY) )
-    {
-    nocopy:
-
-        TRACE("\twon't copy anything!\n");
-
-        /* set dirtyRgn to the sum of old and new visible regions
-         * in parent client coordinates */
-
-        OffsetRgn( newVisRgn, Wnd->rectWindow.left, Wnd->rectWindow.top );
-        OffsetRgn( *pVisRgn, lpOldWndRect->left, lpOldWndRect->top );
-
-        CombineRgn(*pVisRgn, *pVisRgn, newVisRgn, RGN_OR );
-    }
-    else /* copy valid bits to a new location */
-    {
-        INT  dx, dy, ow, oh, nw, nh, ocw, ncw, och, nch;
-        HRGN hrgnValid = dirtyRgn; /* non-empty intersection of old and new visible rgns */
-
-        /* subtract already invalid region inside Wnd from the dst region */
-
-        if( Wnd->hrgnUpdate )
-            if( CombineRgn( hrgnValid, hrgnValid, Wnd->hrgnUpdate, RGN_DIFF) == NULLREGION )
-                goto nocopy;
-
-        /* check if entire window can be copied */
-
-        ow = lpOldWndRect->right - lpOldWndRect->left;
-        oh = lpOldWndRect->bottom - lpOldWndRect->top;
-        nw = Wnd->rectWindow.right - Wnd->rectWindow.left;
-        nh = Wnd->rectWindow.bottom - Wnd->rectWindow.top;
-
-        ocw = lpOldClientRect->right - lpOldClientRect->left;
-        och = lpOldClientRect->bottom - lpOldClientRect->top;
-        ncw = Wnd->rectClient.right  - Wnd->rectClient.left;
-        nch = Wnd->rectClient.bottom  - Wnd->rectClient.top;
-
-        if(  (ocw != ncw) || (och != nch) ||
-             ( ow !=  nw) || ( oh !=  nh) ||
-             ((lpOldClientRect->top - lpOldWndRect->top)   !=
-              (Wnd->rectClient.top - Wnd->rectWindow.top)) ||
-             ((lpOldClientRect->left - lpOldWndRect->left) !=
-              (Wnd->rectClient.left - Wnd->rectWindow.left)) )
-        {
-            if(uFlags & SWP_EX_PAINTSELF)
-            {
-                /* movement relative to the window itself */
-                dx = (Wnd->rectClient.left - Wnd->rectWindow.left) -
-                    (lpOldClientRect->left - lpOldWndRect->left) ;
-                dy = (Wnd->rectClient.top - Wnd->rectWindow.top) -
-                    (lpOldClientRect->top - lpOldWndRect->top) ;
-            }
-            else
-            {
-                /* movement relative to the parent's client area */
-                dx = Wnd->rectClient.left - lpOldClientRect->left;
-                dy = Wnd->rectClient.top - lpOldClientRect->top;
-            }
-
-            /* restrict valid bits to the common client rect */
-
-            r.left = Wnd->rectClient.left - Wnd->rectWindow.left;
-            r.top = Wnd->rectClient.top  - Wnd->rectWindow.top;
-            r.right = r.left + min( ocw, ncw );
-            r.bottom = r.top + min( och, nch );
-
-            REGION_CropRgn( hrgnValid, hrgnValid, &r,
-                            (uFlags & SWP_EX_PAINTSELF) ? NULL : (POINT*)&(Wnd->rectWindow));
-            GetRgnBox( hrgnValid, &r );
-            if( IsRectEmpty( &r ) )
-                goto nocopy;
-            r = *lpOldClientRect;
-        }
-        else
-        {
-            if(uFlags & SWP_EX_PAINTSELF) {
-                /*
-                 * with SWP_EX_PAINTSELF, the window repaints itself. Since a window can't move
-                 * relative to itself, only the client area can change.
-                 * if the client rect didn't change, there's nothing to do.
-                 */
-                dx = 0;
-                dy = 0;
-            }
-            else
-            {
-                dx = Wnd->rectWindow.left - lpOldWndRect->left;
-                dy = Wnd->rectWindow.top -  lpOldWndRect->top;
-                OffsetRgn( hrgnValid, Wnd->rectWindow.left, Wnd->rectWindow.top );
-            }
-            r = *lpOldWndRect;
-        }
-
-        if( !(uFlags & SWP_EX_PAINTSELF) )
-        {
-            /* Move remaining regions to parent coordinates */
-            OffsetRgn( newVisRgn, Wnd->rectWindow.left, Wnd->rectWindow.top );
-            OffsetRgn( *pVisRgn,  lpOldWndRect->left, lpOldWndRect->top );
-        }
-        else
-            OffsetRect( &r, -lpOldWndRect->left, -lpOldWndRect->top );
-
-        TRACE("\tcomputing dirty region!\n");
-
-        /* Compute combined dirty region (old + new - valid) */
-        CombineRgn( *pVisRgn, *pVisRgn, newVisRgn, RGN_OR);
-        CombineRgn( *pVisRgn, *pVisRgn, hrgnValid, RGN_DIFF);
-
-        /* Blt valid bits, r is the rect to copy  */
-
-        if( dx || dy )
-        {
-            RECT rClip;
-            HDC hDC;
-
-            /* get DC and clip rect with drawable rect to avoid superfluous expose events
-               from copying clipped areas */
-
-            if( uFlags & SWP_EX_PAINTSELF )
-            {
-                hDC = GetDCEx( Wnd->hwndSelf, hrgnValid, DCX_WINDOW | DCX_CACHE |
-                               DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CLIPSIBLINGS );
-                rClip.right = nw; rClip.bottom = nh;
-            }
-            else
-            {
-                hDC = GetDCEx( Wnd->parent->hwndSelf, hrgnValid, DCX_CACHE |
-                               DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CLIPSIBLINGS );
-                rClip.right = Wnd->parent->rectClient.right - Wnd->parent->rectClient.left;
-                rClip.bottom = Wnd->parent->rectClient.bottom - Wnd->parent->rectClient.top;
-            }
-            rClip.left = rClip.top = 0;
-
-            if( oh > nh ) r.bottom = r.top  + nh;
-            if( ow < nw ) r.right = r.left  + nw;
-
-            if( IntersectRect( &r, &r, &rClip ) )
-            {
-                X11DRV_WND_SurfaceCopy( Wnd->parent, hDC, dx, dy, &r, TRUE );
-
-                /* When you copy the bits without repainting, parent doesn't
-                   get validated appropriately. Therefore, we have to validate
-                   the parent with the windows' updated region when the
-                   parent's update region is not empty. */
-
-                if (Wnd->parent->hrgnUpdate != 0 && !(Wnd->parent->dwStyle & WS_CLIPCHILDREN))
-                {
-                    OffsetRect(&r, dx, dy);
-                    ValidateRect(Wnd->parent->hwndSelf, &r);
-                }
-            }
-            ReleaseDC( (uFlags & SWP_EX_PAINTSELF) ?
-                       Wnd->hwndSelf :  Wnd->parent->hwndSelf, hDC);
-        }
-    }
-
-    /* *pVisRgn now points to the invalidated region */
-
-    DeleteObject(newVisRgn);
-    DeleteObject(dirtyRgn);
-    return uFlags;
-}
-
-
-/***********************************************************************
- *		SetWindowPos   (X11DRV.@)
- */
-BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
-{
-    WND *wndPtr,*wndTemp;
-    RECT newWindowRect, newClientRect;
-    RECT oldWindowRect, oldClientRect;
-    HRGN visRgn = 0;
-    UINT wvrFlags = 0, uFlags = 0;
-    BOOL retvalue, resync = FALSE, bChangePos;
-    HWND hwndActive = GetForegroundWindow();
-
-    TRACE( "hwnd %04x, swp (%i,%i)-(%i,%i) flags %08x\n",
-           winpos->hwnd, winpos->x, winpos->y,
-           winpos->x + winpos->cx, winpos->y + winpos->cy, winpos->flags);
-
-    bChangePos = !(winpos->flags & SWP_WINE_NOHOSTMOVE);
-    winpos->flags &= ~SWP_WINE_NOHOSTMOVE;
-
-    /* ------------------------------------------------------------------------ CHECKS */
-
-      /* Check window handle */
-
-    if (winpos->hwnd == GetDesktopWindow()) return FALSE;
-    if (!(wndPtr = WIN_FindWndPtr( winpos->hwnd ))) return FALSE;
-
-    TRACE("\tcurrent (%i,%i)-(%i,%i), style %08x\n",
-          wndPtr->rectWindow.left, wndPtr->rectWindow.top,
-          wndPtr->rectWindow.right, wndPtr->rectWindow.bottom, (unsigned)wndPtr->dwStyle );
-
-    /* Fix redundant flags */
-
-    if(wndPtr->dwStyle & WS_VISIBLE)
-        winpos->flags &= ~SWP_SHOWWINDOW;
+    if (wndPtr->dwStyle & WS_VISIBLE) winpos->flags &= ~SWP_SHOWWINDOW;
     else
     {
-        if (!(winpos->flags & SWP_SHOWWINDOW)) winpos->flags |= SWP_NOREDRAW;
         winpos->flags &= ~SWP_HIDEWINDOW;
+        if (!(winpos->flags & SWP_SHOWWINDOW)) winpos->flags |= SWP_NOREDRAW;
     }
 
-    if ( winpos->cx < 0 ) winpos->cx = 0;
-    if ( winpos->cy < 0 ) winpos->cy = 0;
+    if (winpos->cx < 0) winpos->cx = 0;
+    if (winpos->cy < 0) winpos->cy = 0;
 
     if ((wndPtr->rectWindow.right - wndPtr->rectWindow.left == winpos->cx) &&
         (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top == winpos->cy))
@@ -898,15 +372,15 @@
     if ((wndPtr->rectWindow.left == winpos->x) && (wndPtr->rectWindow.top == winpos->y))
         winpos->flags |= SWP_NOMOVE;    /* Already the right position */
 
-    if (winpos->hwnd == hwndActive)
+    if (winpos->hwnd == GetForegroundWindow())
         winpos->flags |= SWP_NOACTIVATE;   /* Already active */
-    else if ( (wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD )
+    else if ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD)
     {
-        if(!(winpos->flags & SWP_NOACTIVATE)) /* Bring to the top when activating */
+        if (!(winpos->flags & SWP_NOACTIVATE)) /* Bring to the top when activating */
         {
             winpos->flags &= ~SWP_NOZORDER;
             winpos->hwndInsertAfter = HWND_TOP;
-            goto Pos;
+            goto done;
         }
     }
 
@@ -920,64 +394,68 @@
     if ((winpos->hwndInsertAfter != HWND_TOP) && (winpos->hwndInsertAfter != HWND_BOTTOM))
     {
         WND* wnd = WIN_FindWndPtr(winpos->hwndInsertAfter);
-
-        if( wnd ) {
-            if( wnd->parent != wndPtr->parent )
+        if (wnd)
+        {
+            if (wnd->parent != wndPtr->parent) ret = FALSE;
+            else
             {
-                retvalue = FALSE;
-                WIN_ReleaseWndPtr(wnd);
-                goto END;
+                /* don't need to change the Zorder of hwnd if it's already inserted
+                 * after hwndInsertAfter or when inserting hwnd after itself.
+                 */
+                if ((wnd->next == wndPtr ) || (winpos->hwnd == winpos->hwndInsertAfter))
+                    winpos->flags |= SWP_NOZORDER;
             }
-            /* don't need to change the Zorder of hwnd if it's already inserted
-             * after hwndInsertAfter or when inserting hwnd after itself.
-             */
-            if(( wnd->next == wndPtr ) || (winpos->hwnd == winpos->hwndInsertAfter))
-                winpos->flags |= SWP_NOZORDER;
+            WIN_ReleaseWndPtr(wnd);
         }
-        WIN_ReleaseWndPtr(wnd);
     }
+ done:
+    WIN_ReleaseWndPtr(wndPtr);
+    return ret;
+}
 
- Pos:  /* ------------------------------------------------------------------------ MAIN part */
 
-    SWP_DoWinPosChanging( wndPtr, winpos, &newWindowRect, &newClientRect );
+/***********************************************************************
+ *		SetWindowPos   (X11DRV.@)
+ */
+BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
+{
+    WND *wndPtr;
+    RECT newWindowRect, newClientRect;
+    RECT oldWindowRect, oldClientRect;
+    UINT wvrFlags = 0;
+    BOOL bChangePos;
+
+    TRACE( "hwnd %04x, swp (%i,%i)-(%i,%i) flags %08x\n",
+           winpos->hwnd, winpos->x, winpos->y,
+           winpos->x + winpos->cx, winpos->y + winpos->cy, winpos->flags);
+
+    bChangePos = !(winpos->flags & SWP_WINE_NOHOSTMOVE);
+    winpos->flags &= ~SWP_WINE_NOHOSTMOVE;
+
+    /* Check window handle */
+    if (winpos->hwnd == GetDesktopWindow()) return FALSE;
+
+    /* Fix redundant flags */
+    if (!fixup_flags( winpos )) return FALSE;
+
+    SWP_DoWinPosChanging( winpos, &newWindowRect, &newClientRect );
+
+    if (!(wndPtr = WIN_FindWndPtr( winpos->hwnd ))) return FALSE;
+
+    TRACE("\tcurrent (%i,%i)-(%i,%i), style %08x\n",
+          wndPtr->rectWindow.left, wndPtr->rectWindow.top,
+          wndPtr->rectWindow.right, wndPtr->rectWindow.bottom, (unsigned)wndPtr->dwStyle );
 
     if((winpos->flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER)
     {
-        if( wndPtr->parent == WIN_GetDesktop() )
+        if( wndPtr->parent->hwndSelf == GetDesktopWindow() )
             winpos->hwndInsertAfter = SWP_DoOwnedPopups( wndPtr->parent, wndPtr,
                                                          winpos->hwndInsertAfter, winpos->flags );
-        WIN_ReleaseDesktop();
-    }
-
-    if(!(wndPtr->flags & WIN_NATIVE) )
-    {
-        if( winpos->hwndInsertAfter == HWND_TOP )
-            winpos->flags |= ( wndPtr->parent->child == wndPtr)? SWP_NOZORDER: 0;
-        else
-            if( winpos->hwndInsertAfter == HWND_BOTTOM )
-                winpos->flags |= ( wndPtr->next )? 0: SWP_NOZORDER;
-            else
-                if( !(winpos->flags & SWP_NOZORDER) )
-                    if( GetWindow(winpos->hwndInsertAfter, GW_HWNDNEXT) == wndPtr->hwndSelf )
-                        winpos->flags |= SWP_NOZORDER;
-
-        if( !(winpos->flags & (SWP_NOREDRAW | SWP_SHOWWINDOW)) &&
-            ((winpos->flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW | SWP_FRAMECHANGED))
-             != (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER)) )
-        {
-            /* get a previous visible region for SWP_CopyValidBits() */
-            DWORD dflags = DCX_WINDOW;
-
-            if (wndPtr->dwStyle & WS_CLIPSIBLINGS)
-                dflags |= DCX_CLIPSIBLINGS;
-
-            visRgn = DCE_GetVisRgn(winpos->hwnd, dflags, 0, 0);
-        }
     }
 
     /* Common operations */
 
-    wvrFlags = SWP_DoNCCalcSize( wndPtr, winpos, &newWindowRect, &newClientRect, winpos->flags );
+    wvrFlags = SWP_DoNCCalcSize( wndPtr, winpos, &newWindowRect, &newClientRect );
 
     if(!(winpos->flags & SWP_NOZORDER) && winpos->hwnd != winpos->hwndInsertAfter)
     {
@@ -1008,161 +486,81 @@
     if( oldClientRect.right - oldClientRect.left ==
         newClientRect.right - newClientRect.left ) wvrFlags &= ~WVR_HREDRAW;
 
-    if( (winpos->flags & SWP_NOCOPYBITS) ||
-        (!(winpos->flags & SWP_NOCLIENTSIZE) &&
-         (wvrFlags >= WVR_HREDRAW) && (wvrFlags < WVR_VALIDRECTS)) )
-    {
-        uFlags |= SWP_EX_NOCOPY;
-    }
-/*
- *  Use this later in CopyValidBits()
- *
-    else if( 0  )
-	uFlags |= SWP_EX_NONCLIENT;
- */
-
     /* FIXME: actually do something with WVR_VALIDRECTS */
 
     wndPtr->rectWindow = newWindowRect;
     wndPtr->rectClient = newClientRect;
 
-    if (wndPtr->flags & WIN_NATIVE)  /* -------------------------------------------- hosted window */
+    if (winpos->flags & SWP_SHOWWINDOW) wndPtr->dwStyle |= WS_VISIBLE;
+    else if (winpos->flags & SWP_HIDEWINDOW)
     {
-        BOOL bCallDriver = TRUE;
-        HWND tempInsertAfter = winpos->hwndInsertAfter;
-
-        winpos->hwndInsertAfter = winpos->hwndInsertAfter;
-
-        if( !(winpos->flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) )
-        {
-            /* This is the only place where we need to force repainting of the contents
-               of windows created by the host window system, all other cases go through the
-               expose event handling */
-
-            if( (winpos->flags & (SWP_NOSIZE | SWP_FRAMECHANGED)) == (SWP_NOSIZE | SWP_FRAMECHANGED) )
-            {
-                winpos->cx = newWindowRect.right - newWindowRect.left;
-                winpos->cy = newWindowRect.bottom - newWindowRect.top;
-
-                X11DRV_WND_SetWindowPos(wndPtr, winpos, bChangePos);
-                winpos->hwndInsertAfter = tempInsertAfter;
-                bCallDriver = FALSE;
-
-                if( winpos->flags & SWP_NOCLIENTMOVE )
-                    SWP_DoSimpleFrameChanged(wndPtr, &oldClientRect, winpos->flags, uFlags );
-                else
-                {
-                    /* client area moved but window extents remained the same, copy valid bits */
-
-                    visRgn = CreateRectRgn( 0, 0, winpos->cx, winpos->cy );
-                    uFlags = SWP_CopyValidBits( wndPtr, &visRgn, &oldWindowRect, &oldClientRect,
-                                                uFlags | SWP_EX_PAINTSELF );
-                }
-            }
-        }
-
-        if( bCallDriver )
-        {
-            if( !(winpos->flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOREDRAW)) )
-            {
-                if( (oldClientRect.left - oldWindowRect.left == newClientRect.left - newWindowRect.left) &&
-                    (oldClientRect.top - oldWindowRect.top == newClientRect.top - newWindowRect.top) &&
-                    !(uFlags & SWP_EX_NOCOPY) )
-                {
-                    /* The origin of the client rect didn't move so we can try to repaint
-                     * only the nonclient area by setting bit gravity hint for the host window system.
-                     */
-
-                    if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
-                    {
-                        HRGN hrgn = CreateRectRgn( 0, 0, newWindowRect.right - newWindowRect.left,
-                                                   newWindowRect.bottom - newWindowRect.top);
-                        RECT rcn = newClientRect;
-                        RECT rco = oldClientRect;
-
-                        OffsetRect( &rcn, -newWindowRect.left, -newWindowRect.top );
-                        OffsetRect( &rco, -oldWindowRect.left, -oldWindowRect.top );
-                        IntersectRect( &rcn, &rcn, &rco );
-                        visRgn = CreateRectRgnIndirect( &rcn );
-                        CombineRgn( visRgn, hrgn, visRgn, RGN_DIFF );
-                        DeleteObject( hrgn );
-                        uFlags = SWP_EX_PAINTSELF;
-                    }
-                    X11DRV_WND_SetGravity(wndPtr, NorthWestGravity );
-                }
-            }
-
-            X11DRV_WND_SetWindowPos(wndPtr, winpos, bChangePos);
-            X11DRV_WND_SetGravity(wndPtr, ForgetGravity );
-            winpos->hwndInsertAfter = tempInsertAfter;
-        }
-
-        if( winpos->flags & SWP_SHOWWINDOW )
-        {
-            HWND focus, curr;
-
-            wndPtr->dwStyle |= WS_VISIBLE;
-
-            if (wndPtr->dwExStyle & WS_EX_MANAGED) resync = TRUE;
-
-            /* focus was set to unmapped window, reset host focus
-             * since the window is now visible */
-
-            focus = curr = GetFocus();
-            while (curr)
-            {
-                if (curr == winpos->hwnd)
-                {
-                    X11DRV_SetFocus(focus);
-                    break;
-                }
-                curr = GetParent(curr);
-            }
-        }
-    }
-    else  /* -------------------------------------------- emulated window */
-    {
-        if( winpos->flags & SWP_SHOWWINDOW )
-        {
-            wndPtr->dwStyle |= WS_VISIBLE;
-            uFlags |= SWP_EX_PAINTSELF;
-            visRgn = 1; /* redraw the whole window */
-        }
-        else if( !(winpos->flags & SWP_NOREDRAW) )
-        {
-            if( winpos->flags & SWP_HIDEWINDOW )
-            {
-                if( visRgn > 1 ) /* map to parent */
-                    OffsetRgn( visRgn, oldWindowRect.left, oldWindowRect.top );
-                else
-                    visRgn = 0;
-            }
-            else
-            {
-                if( (winpos->flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE )
-                    uFlags = SWP_CopyValidBits(wndPtr, &visRgn, &oldWindowRect,
-                                               &oldClientRect, uFlags);
-                else
-                {
-                    /* nothing moved, redraw frame if needed */
-
-                    if( winpos->flags & SWP_FRAMECHANGED )
-                        SWP_DoSimpleFrameChanged( wndPtr, &oldClientRect, winpos->flags, uFlags );
-                    if( visRgn )
-                    {
-                        DeleteObject( visRgn );
-                        visRgn = 0;
-                    }
-                }
-            }
-        }
-    }
-
-    if( winpos->flags & SWP_HIDEWINDOW )
-    {
+        /* clear the update region */
+        RedrawWindow( winpos->hwnd, NULL, 0, RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE |
+                                             RDW_NOINTERNALPAINT | RDW_ALLCHILDREN );
         wndPtr->dwStyle &= ~WS_VISIBLE;
     }
 
+    if (get_whole_window(wndPtr))  /* don't do anything if X window not created yet */
+    {
+        Display *display = thread_display();
+
+        wine_tsx11_lock();
+        if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW))
+        {
+            if (!IsRectEmpty( &oldWindowRect ))
+            {
+                XUnmapWindow( display, get_whole_window(wndPtr) );
+                TRACE( "unmapping win %x\n", winpos->hwnd );
+            }
+            else TRACE( "not unmapping zero size win %x\n", winpos->hwnd );
+        }
+        else if ((wndPtr->dwStyle & WS_VISIBLE) &&
+                 !IsRectEmpty( &oldWindowRect ) && IsRectEmpty( &newWindowRect ))
+        {
+            /* resizing to zero size -> unmap */
+            TRACE( "unmapping zero size win %x\n", winpos->hwnd );
+            XUnmapWindow( display, get_whole_window(wndPtr) );
+        }
+
+        if (bChangePos)
+            X11DRV_sync_whole_window_position( display, wndPtr, !(winpos->flags & SWP_NOZORDER) );
+        else
+        {
+            struct x11drv_win_data *data = wndPtr->pDriverData;
+            data->whole_rect = wndPtr->rectWindow;
+            X11DRV_window_to_X_rect( wndPtr, &data->whole_rect );
+        }
+
+        if (X11DRV_sync_client_window_position( display, wndPtr ) ||
+            (winpos->flags & SWP_FRAMECHANGED))
+        {
+            /* if we moved the client area, repaint the whole non-client window */
+            XClearArea( display, get_whole_window(wndPtr), 0, 0, 0, 0, True );
+        }
+        if (winpos->flags & SWP_SHOWWINDOW)
+        {
+            if (!IsRectEmpty( &newWindowRect ))
+            {
+                XMapWindow( display, get_whole_window(wndPtr) );
+                TRACE( "mapping win %x\n", winpos->hwnd );
+            }
+            else TRACE( "not mapping win %x, size is zero\n", winpos->hwnd );
+        }
+        else if ((wndPtr->dwStyle & WS_VISIBLE) &&
+                 IsRectEmpty( &oldWindowRect ) && !IsRectEmpty( &newWindowRect ))
+        {
+            /* resizing from zero size to non-zero -> map */
+            TRACE( "mapping non zero size win %x\n", winpos->hwnd );
+            XMapWindow( display, get_whole_window(wndPtr) );
+        }
+        XFlush( display );  /* FIXME: should not be necessary */
+        wine_tsx11_unlock();
+    }
+
+    WIN_ReleaseWndPtr(wndPtr);
+
+    if (wvrFlags & WVR_REDRAW) RedrawWindow( winpos->hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE );
+
     if (winpos->hwnd == CARET_GetHwnd())
     {
         if( winpos->flags & SWP_HIDEWINDOW )
@@ -1171,54 +569,6 @@
             ShowCaret(winpos->hwnd);
     }
 
-    /* ------------------------------------------------------------------------ FINAL */
-
-    if (wndPtr->flags & WIN_NATIVE)
-        X11DRV_Synchronize();  /* Synchronize with the host window system */
-
-    wndTemp = WIN_GetDesktop();
-
-    /* repaint invalidated region (if any)
-     *
-     * FIXME: if SWP_NOACTIVATE is not set then set invalid regions here without any painting
-     *        and force update after ChangeActiveWindow() to avoid painting frames twice.
-     */
-
-    if( visRgn )
-    {
-        if( !(winpos->flags & SWP_NOREDRAW) )
-        {
-
-            /*  Use PAINT_RedrawWindow to explicitly force an invalidation of the window,
-		its parent and sibling and so on, and then erase the parent window
-		background if the parent is either a top-level window or its parent's parent
-		is top-level window. Rely on the system to repaint other affected
-		windows later on.  */
-            if( uFlags & SWP_EX_PAINTSELF )
-            {
-                PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, (visRgn == 1) ? 0 : visRgn,
-                                    RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN,
-                                    RDW_EX_XYWINDOW | RDW_EX_USEHRGN );
-            }
-            else
-            {
-                PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, (visRgn == 1) ? 0 : visRgn,
-                                    RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN,
-                                    RDW_EX_USEHRGN );
-            }
-
-            if(wndPtr -> parent == wndTemp || wndPtr->parent->parent == wndTemp )
-            {
-                RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0,
-                              RDW_ERASENOW | RDW_NOCHILDREN );
-            }
-        }
-        if( visRgn != 1 )
-            DeleteObject( visRgn );
-    }
-
-    WIN_ReleaseDesktop();
-
     if (!(winpos->flags & SWP_NOACTIVATE))
         WINPOS_ChangeActiveWindow( winpos->hwnd, FALSE );
 
@@ -1226,18 +576,593 @@
 
     TRACE("\tstatus flags = %04x\n", winpos->flags & SWP_AGG_STATUSFLAGS);
 
-    if ( resync ||
-         (((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
-          !(winpos->flags & SWP_NOSENDCHANGING)) )
-    {
+    if (((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
+          !(winpos->flags & SWP_NOSENDCHANGING))
         SendMessageA( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)winpos );
-        if (resync) X11DRV_Synchronize();
+
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           WINPOS_FindIconPos
+ *
+ * Find a suitable place for an iconic window.
+ */
+static POINT WINPOS_FindIconPos( WND* wndPtr, POINT pt )
+{
+    RECT rectParent;
+    short x, y, xspacing, yspacing;
+
+    GetClientRect( wndPtr->parent->hwndSelf, &rectParent );
+    if ((pt.x >= rectParent.left) && (pt.x + GetSystemMetrics(SM_CXICON) < rectParent.right) &&
+        (pt.y >= rectParent.top) && (pt.y + GetSystemMetrics(SM_CYICON) < rectParent.bottom))
+        return pt;  /* The icon already has a suitable position */
+
+    xspacing = GetSystemMetrics(SM_CXICONSPACING);
+    yspacing = GetSystemMetrics(SM_CYICONSPACING);
+
+    y = rectParent.bottom;
+    for (;;)
+    {
+        x = rectParent.left;
+        do
+        {
+              /* Check if another icon already occupies this spot */
+            WND *childPtr = WIN_LockWndPtr(wndPtr->parent->child);
+            while (childPtr)
+            {
+                if ((childPtr->dwStyle & WS_MINIMIZE) && (childPtr != wndPtr))
+                {
+                    if ((childPtr->rectWindow.left < x + xspacing) &&
+                        (childPtr->rectWindow.right >= x) &&
+                        (childPtr->rectWindow.top <= y) &&
+                        (childPtr->rectWindow.bottom > y - yspacing))
+                        break;  /* There's a window in there */
+                }
+                WIN_UpdateWndPtr(&childPtr,childPtr->next);
+            }
+            WIN_ReleaseWndPtr(childPtr);
+            if (!childPtr) /* No window was found, so it's OK for us */
+            {
+                pt.x = x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
+                pt.y = y - (yspacing + GetSystemMetrics(SM_CYICON)) / 2;
+                return pt;
+            }
+            x += xspacing;
+        } while(x <= rectParent.right-xspacing);
+        y -= yspacing;
+    }
+}
+
+
+
+
+
+UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
+{
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    UINT swpFlags = 0;
+    POINT size;
+    WINDOWPLACEMENT wpl;
+
+    TRACE("0x%04x %u\n", hwnd, cmd );
+
+    wpl.length = sizeof(wpl);
+    GetWindowPlacement( hwnd, &wpl );
+
+    size.x = wndPtr->rectWindow.left;
+    size.y = wndPtr->rectWindow.top;
+
+    if (!HOOK_CallHooksA(WH_CBT, HCBT_MINMAX, wndPtr->hwndSelf, cmd))
+    {
+        if( wndPtr->dwStyle & WS_MINIMIZE )
+        {
+            if( !SendMessageA( wndPtr->hwndSelf, WM_QUERYOPEN, 0, 0L ) )
+            {
+                swpFlags = SWP_NOSIZE | SWP_NOMOVE;
+                goto done;
+            }
+            swpFlags |= SWP_NOCOPYBITS;
+        }
+        switch( cmd )
+        {
+        case SW_MINIMIZE:
+            if( wndPtr->dwStyle & WS_MAXIMIZE)
+            {
+                wndPtr->flags |= WIN_RESTORE_MAX;
+                wndPtr->dwStyle &= ~WS_MAXIMIZE;
+            }
+            else
+                wndPtr->flags &= ~WIN_RESTORE_MAX;
+            wndPtr->dwStyle |= WS_MINIMIZE;
+
+            X11DRV_set_iconic_state( wndPtr );
+
+            wpl.ptMinPosition = WINPOS_FindIconPos( wndPtr, wpl.ptMinPosition );
+
+            SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y,
+                     GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
+            swpFlags |= SWP_NOCOPYBITS;
+            break;
+
+        case SW_MAXIMIZE:
+            WINPOS_GetMinMaxInfo( wndPtr, &size, &wpl.ptMaxPosition, NULL, NULL );
+
+            if( wndPtr->dwStyle & WS_MINIMIZE )
+            {
+                wndPtr->dwStyle &= ~WS_MINIMIZE;
+                WINPOS_ShowIconTitle( wndPtr, FALSE );
+                X11DRV_set_iconic_state( wndPtr );
+            }
+            wndPtr->dwStyle |= WS_MAXIMIZE;
+
+            SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
+            break;
+
+        case SW_RESTORE:
+            if( wndPtr->dwStyle & WS_MINIMIZE )
+            {
+                wndPtr->dwStyle &= ~WS_MINIMIZE;
+                WINPOS_ShowIconTitle( wndPtr, FALSE );
+                X11DRV_set_iconic_state( wndPtr );
+
+                if( wndPtr->flags & WIN_RESTORE_MAX)
+                {
+                    /* Restore to maximized position */
+                    WINPOS_GetMinMaxInfo( wndPtr, &size, &wpl.ptMaxPosition, NULL, NULL);
+                    wndPtr->dwStyle |= WS_MAXIMIZE;
+                    SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
+                    break;
+                }
+            }
+            else
+                if( !(wndPtr->dwStyle & WS_MAXIMIZE) )
+                {
+                    swpFlags = (UINT16)(-1);
+                    goto done;
+                }
+                else wndPtr->dwStyle &= ~WS_MAXIMIZE;
+
+            /* Restore to normal position */
+
+            *rect = wpl.rcNormalPosition;
+            rect->right -= rect->left;
+            rect->bottom -= rect->top;
+
+            break;
+        }
+    } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
+
+ done:
+    WIN_ReleaseWndPtr( wndPtr );
+    return swpFlags;
+}
+
+
+/***********************************************************************
+ *              X11DRV_ShowWindow   (X11DRV.@)
+ */
+BOOL X11DRV_ShowWindow( HWND hwnd, INT cmd )
+{
+    WND* 	wndPtr = WIN_FindWndPtr( hwnd );
+    BOOL 	wasVisible, showFlag;
+    RECT 	newPos = {0, 0, 0, 0};
+    UINT 	swp = 0;
+
+    if (!wndPtr) return FALSE;
+
+    TRACE("hwnd=%04x, cmd=%d\n", hwnd, cmd);
+
+    wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
+
+    switch(cmd)
+    {
+        case SW_HIDE:
+            if (!wasVisible) goto END;;
+	    swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | 
+		        SWP_NOACTIVATE | SWP_NOZORDER;
+	    break;
+
+	case SW_SHOWMINNOACTIVE:
+            swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+            /* fall through */
+	case SW_SHOWMINIMIZED:
+            swp |= SWP_SHOWWINDOW;
+            /* fall through */
+	case SW_MINIMIZE:
+            swp |= SWP_FRAMECHANGED;
+            if( !(wndPtr->dwStyle & WS_MINIMIZE) )
+		 swp |= WINPOS_MinMaximize( hwnd, SW_MINIMIZE, &newPos );
+            else swp |= SWP_NOSIZE | SWP_NOMOVE;
+	    break;
+
+	case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
+            swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
+            if( !(wndPtr->dwStyle & WS_MAXIMIZE) )
+		 swp |= WINPOS_MinMaximize( hwnd, SW_MAXIMIZE, &newPos );
+            else swp |= SWP_NOSIZE | SWP_NOMOVE;
+            break;
+
+	case SW_SHOWNA:
+            swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+            /* fall through */
+	case SW_SHOW:
+	    swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+
+	    /*
+	     * ShowWindow has a little peculiar behavior that if the
+	     * window is already the topmost window, it will not
+	     * activate it.
+	     */
+	    if (GetTopWindow((HWND)0)==hwnd && (wasVisible || GetActiveWindow() == hwnd))
+	      swp |= SWP_NOACTIVATE;
+
+	    break;
+
+	case SW_SHOWNOACTIVATE:
+            swp |= SWP_NOZORDER;
+            if (GetActiveWindow()) swp |= SWP_NOACTIVATE;
+            /* fall through */
+	case SW_SHOWNORMAL:  /* same as SW_NORMAL: */
+	case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
+	case SW_RESTORE:
+	    swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
+
+            if( wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE) )
+		 swp |= WINPOS_MinMaximize( hwnd, SW_RESTORE, &newPos );
+            else swp |= SWP_NOSIZE | SWP_NOMOVE;
+	    break;
     }
 
-    retvalue = TRUE;
- END:
+    showFlag = (cmd != SW_HIDE);
+    if (showFlag != wasVisible)
+    {
+        SendMessageA( hwnd, WM_SHOWWINDOW, showFlag, 0 );
+        if (!IsWindow( hwnd )) goto END;
+    }
+
+    /* We can't activate a child window */
+    if ((wndPtr->dwStyle & WS_CHILD) &&
+        !(wndPtr->dwExStyle & WS_EX_MDICHILD))
+        swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+
+    SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
+                  newPos.right, newPos.bottom, LOWORD(swp) );
+    if (cmd == SW_HIDE)
+    {
+        /* FIXME: This will cause the window to be activated irrespective
+         * of whether it is owned by the same thread. Has to be done
+         * asynchronously.
+         */
+
+        if (hwnd == GetActiveWindow())
+            WINPOS_ActivateOtherWindow(wndPtr);
+
+        /* Revert focus to parent */
+        if (hwnd == GetFocus() || IsChild(hwnd, GetFocus()))
+            SetFocus( GetParent(hwnd) );
+    }
+    if (!IsWindow( hwnd )) goto END;
+    else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
+
+    if (wndPtr->flags & WIN_NEED_SIZE)
+    {
+        /* should happen only in CreateWindowEx() */
+	int wParam = SIZE_RESTORED;
+
+	wndPtr->flags &= ~WIN_NEED_SIZE;
+	if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
+	else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
+	SendMessageA( hwnd, WM_SIZE, wParam,
+		     MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+			    wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+	SendMessageA( hwnd, WM_MOVE, 0,
+		   MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
+    }
+
+END:
     WIN_ReleaseWndPtr(wndPtr);
-    return retvalue;
+    return wasVisible;
+}
+
+
+/**********************************************************************
+ *		X11DRV_MapNotify
+ */
+void X11DRV_MapNotify( HWND hwnd, XMapEvent *event )
+{
+    HWND hwndFocus = GetFocus();
+    WND *win;
+
+    if (!(win = WIN_FindWndPtr( hwnd ))) return;
+
+    if ((win->dwStyle & WS_VISIBLE) &&
+        (win->dwStyle & WS_MINIMIZE) &&
+        (win->dwExStyle & WS_EX_MANAGED))
+    {
+        int x, y;
+        unsigned int width, height, border, depth;
+        Window root, top;
+        RECT rect;
+
+        DCE_InvalidateDCE( win, &win->rectWindow );
+        win->dwStyle &= ~WS_MINIMIZE;
+        win->dwStyle |= WS_VISIBLE;
+        WIN_InternalShowOwnedPopups( hwnd, TRUE, TRUE );
+
+        if (win->flags & WIN_RESTORE_MAX)
+            win->dwStyle |= WS_MAXIMIZE;
+        else
+            win->dwStyle &= ~WS_MAXIMIZE;
+
+        /* FIXME: hack */
+        wine_tsx11_lock();
+        XGetGeometry( event->display, get_whole_window(win), &root, &x, &y, &width, &height,
+                        &border, &depth );
+        XTranslateCoordinates( event->display, get_whole_window(win), root, 0, 0, &x, &y, &top );
+        wine_tsx11_unlock();
+        rect.left   = x;
+        rect.top    = y;
+        rect.right  = x + width;
+        rect.bottom = y + height;
+        X11DRV_X_to_window_rect( win, &rect );
+
+        SendMessageA( hwnd, WM_SHOWWINDOW, SW_RESTORE, 0 );
+        SetWindowPos( hwnd, 0, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
+                      SWP_NOZORDER | SWP_WINE_NOHOSTMOVE );
+    }
+    if (hwndFocus && IsChild( hwnd, hwndFocus )) X11DRV_SetFocus(hwndFocus);  /* FIXME */
+    WIN_ReleaseWndPtr( win );
+}
+
+
+/**********************************************************************
+ *              X11DRV_UnmapNotify
+ */
+void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event )
+{
+    WND *win;
+
+    if (!(win = WIN_FindWndPtr( hwnd ))) return;
+
+    if ((win->dwStyle & WS_VISIBLE) && (win->dwExStyle & WS_EX_MANAGED))
+    {
+        EndMenu();
+        SendMessageA( hwnd, WM_SHOWWINDOW, SW_MINIMIZE, 0 );
+
+        win->flags &= ~WIN_RESTORE_MAX;
+        win->dwStyle |= WS_MINIMIZE;
+
+        if (win->dwStyle & WS_MAXIMIZE)
+        {
+            win->flags |= WIN_RESTORE_MAX;
+            win->dwStyle &= ~WS_MAXIMIZE;
+        }
+
+        SetWindowPos( hwnd, 0, 0, 0, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON),
+                      SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_WINE_NOHOSTMOVE );
+
+        WIN_InternalShowOwnedPopups( hwnd, FALSE, TRUE );
+    }
+    WIN_ReleaseWndPtr( win );
+}
+
+
+/***********************************************************************
+ *           query_zorder
+ *
+ * Synchronize internal z-order with the window manager's.
+ */
+static BOOL __check_query_condition( WND** pWndA, WND** pWndB )
+{
+    /* return TRUE if we have at least two managed windows */
+
+    for( *pWndB = NULL; *pWndA; *pWndA = (*pWndA)->next )
+        if( ((*pWndA)->dwExStyle & WS_EX_MANAGED) &&
+            ((*pWndA)->dwStyle & WS_VISIBLE )) break;
+    if( *pWndA )
+        for( *pWndB = (*pWndA)->next; *pWndB; *pWndB = (*pWndB)->next )
+            if( ((*pWndB)->dwExStyle & WS_EX_MANAGED) &&
+                ((*pWndB)->dwStyle & WS_VISIBLE )) break;
+    return ((*pWndB) != NULL);
+}
+
+static Window __get_common_ancestor( Display *display, Window A, Window B,
+                                     Window** children, unsigned* total )
+{
+    /* find the real root window */
+
+    Window      root, *childrenB;
+    unsigned    totalB;
+
+    while( A != B && A && B )
+    {
+      TSXQueryTree( display, A, &root, &A, children, total );
+      TSXQueryTree( display, B, &root, &B, &childrenB, &totalB );
+      if( childrenB ) TSXFree( childrenB );
+      if( *children ) TSXFree( *children ), *children = NULL;
+    }
+
+    if( A && B )
+    {
+        TSXQueryTree( display, A, &root, &B, children, total );
+        return A;
+    }
+    return 0 ;
+}
+
+static Window __get_top_decoration( Display *display, Window w, Window ancestor )
+{
+    Window*     children, root, prev = w, parent = w;
+    unsigned    total;
+
+    do
+    {
+        w = parent;
+        TSXQueryTree( display, w, &root, &parent, &children, &total );
+        if( children ) TSXFree( children );
+    } while( parent && parent != ancestor );
+    TRACE("\t%08x -> %08x\n", (unsigned)prev, (unsigned)w );
+    return ( parent ) ? w : 0 ;
+}
+
+static unsigned __td_lookup( Window w, Window* list, unsigned max )
+{
+    unsigned    i;
+    for( i = max - 1; i >= 0; i-- ) if( list[i] == w ) break;
+    return i;
+}
+
+static HWND query_zorder( Display *display, HWND hWndCheck)
+{
+    HWND      hwndInsertAfter = HWND_TOP;
+    WND      *pWndCheck = WIN_FindWndPtr(hWndCheck);
+    WND      *pDesktop = WIN_GetDesktop();
+    WND      *pWnd, *pWndZ = WIN_LockWndPtr(pDesktop->child);
+    Window      w, parent, *children = NULL;
+    unsigned    total, check, pos, best;
+
+    if( !__check_query_condition(&pWndZ, &pWnd) )
+    {
+        WIN_ReleaseWndPtr(pWndCheck);
+        WIN_ReleaseWndPtr(pDesktop->child);
+        WIN_ReleaseDesktop();
+        return hwndInsertAfter;
+    }
+    WIN_LockWndPtr(pWndZ);
+    WIN_LockWndPtr(pWnd);
+    WIN_ReleaseWndPtr(pDesktop->child);
+    WIN_ReleaseDesktop();
+
+    parent = __get_common_ancestor( display, get_whole_window(pWndZ),
+                                    get_whole_window(pWnd), &children, &total );
+    if( parent && children )
+    {
+        /* w is the ancestor if pWndCheck that is a direct descendant of 'parent' */
+
+        w = __get_top_decoration( display, get_whole_window(pWndCheck), parent );
+
+        if( w != children[total-1] ) /* check if at the top */
+        {
+            /* X child at index 0 is at the bottom, at index total-1 is at the top */
+            check = __td_lookup( w, children, total );
+            best = total;
+
+            for( WIN_UpdateWndPtr(&pWnd,pWndZ); pWnd;WIN_UpdateWndPtr(&pWnd,pWnd->next))
+            {
+                /* go through all windows in Wine z-order... */
+
+                if( pWnd != pWndCheck )
+                {
+                    if( !(pWnd->dwExStyle & WS_EX_MANAGED) ||
+                        !(w = __get_top_decoration( display, get_whole_window(pWnd), parent )) )
+                        continue;
+                    pos = __td_lookup( w, children, total );
+                    if( pos < best && pos > check )
+                    {
+                        /* find a nearest Wine window precedes 
+                         * pWndCheck in the real z-order... */
+                        best = pos;
+                        hwndInsertAfter = pWnd->hwndSelf;
+                    }
+                    if( best - check == 1 ) break;
+                }
+            }
+        }
+    }
+    if( children ) TSXFree( children );
+    WIN_ReleaseWndPtr(pWnd);
+    WIN_ReleaseWndPtr(pWndZ);
+    WIN_ReleaseWndPtr(pWndCheck);
+    return hwndInsertAfter;
+}
+
+
+/***********************************************************************
+ *		X11DRV_ConfigureNotify
+ */
+void X11DRV_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
+{
+    HWND oldInsertAfter;
+    struct x11drv_win_data *data;
+    WND *win;
+    RECT rect;
+    WINDOWPOS winpos;
+    int x = event->x, y = event->y;
+
+    if (!(win = WIN_FindWndPtr( hwnd ))) return;
+    data = win->pDriverData;
+
+    /* Get geometry */
+
+    if (!event->send_event)  /* normal event, need to map coordinates to the root */
+    {
+        Window child;
+        wine_tsx11_lock();
+        XTranslateCoordinates( event->display, data->whole_window, root_window,
+                               0, 0, &x, &y, &child );
+        wine_tsx11_unlock();
+    }
+    rect.left   = x;
+    rect.top    = y;
+    rect.right  = x + event->width;
+    rect.bottom = y + event->height;
+    TRACE( "win %x new X rect %d,%d,%dx%d (event %d,%d,%dx%d)\n",
+           hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
+           event->x, event->y, event->width, event->height );
+    X11DRV_X_to_window_rect( win, &rect );
+    WIN_ReleaseWndPtr( win );
+
+    winpos.hwnd  = hwnd;
+    winpos.x     = rect.left;
+    winpos.y     = rect.top;
+    winpos.cx    = rect.right - rect.left;
+    winpos.cy    = rect.bottom - rect.top;
+    winpos.flags = SWP_NOACTIVATE;
+
+    /* Get Z-order (FIXME) */
+
+    winpos.hwndInsertAfter = query_zorder( event->display, hwnd );
+
+    /* needs to find the first Visible Window above the current one */
+    oldInsertAfter = hwnd;
+    for (;;)
+    {
+        oldInsertAfter = GetWindow( oldInsertAfter, GW_HWNDPREV );
+        if (!oldInsertAfter)
+        {
+            oldInsertAfter = HWND_TOP;
+            break;
+        }
+        if (GetWindowLongA( oldInsertAfter, GWL_STYLE ) & WS_VISIBLE) break;
+    }
+
+    /* Compare what has changed */
+
+    GetWindowRect( hwnd, &rect );
+    if (rect.left == winpos.x && rect.top == winpos.y) winpos.flags |= SWP_NOMOVE;
+    else
+        TRACE( "%04x moving from (%d,%d) to (%d,%d)\n",
+               hwnd, rect.left, rect.top, winpos.x, winpos.y );
+
+    if (rect.right - rect.left == winpos.cx &&
+        rect.bottom - rect.top == winpos.cy) winpos.flags |= SWP_NOSIZE;
+    else
+        TRACE( "%04x resizing from (%dx%d) to (%dx%d)\n",
+               hwnd, rect.right - rect.left, rect.bottom - rect.top,
+               winpos.cx, winpos.cy );
+
+    if (winpos.hwndInsertAfter == oldInsertAfter) winpos.flags |= SWP_NOZORDER;
+    else
+        TRACE( "%04x restacking from after %04x to after %04x\n",
+               hwnd, oldInsertAfter, winpos.hwndInsertAfter );
+
+    /* if nothing changed, don't do anything */
+    if (winpos.flags == (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE)) return;
+
+    SetWindowPos( hwnd, winpos.hwndInsertAfter, winpos.x, winpos.y,
+                  winpos.cx, winpos.cy, winpos.flags | SWP_WINE_NOHOSTMOVE );
 }
 
 
@@ -1281,17 +1206,19 @@
 #ifdef HAVE_LIBXSHAPE
     {
         Display *display = thread_display();
-        Window win = X11DRV_WND_GetXWindow(wndPtr);
+        X11DRV_WND_DATA *data = wndPtr->pDriverData;
 
-        if (win)
+        if (data->whole_window)
         {
             if (!hrgn)
             {
-                TSXShapeCombineMask( display, win, ShapeBounding, 0, 0, None, ShapeSet );
+                TSXShapeCombineMask( display, data->whole_window,
+                                     ShapeBounding, 0, 0, None, ShapeSet );
             }
             else
             {
                 XRectangle *aXRect;
+                int x_offset, y_offset;
                 DWORD size;
                 DWORD dwBufferSize = GetRegionData(hrgn, 0, NULL);
                 PRGNDATA pRegionData = HeapAlloc(GetProcessHeap(), 0, dwBufferSize);
@@ -1299,6 +1226,8 @@
 
                 GetRegionData(hrgn, dwBufferSize, pRegionData);
                 size = pRegionData->rdh.nCount;
+                x_offset = wndPtr->rectWindow.left - data->whole_rect.left;
+                y_offset = wndPtr->rectWindow.top - data->whole_rect.top;
                 /* convert region's "Windows rectangles" to XRectangles */
                 aXRect = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*aXRect) );
                 if (aXRect)
@@ -1307,8 +1236,8 @@
                     RECT *pRect = (RECT*) pRegionData->Buffer;
                     for (; pRect < ((RECT*) pRegionData->Buffer) + size ; ++pRect, ++pCurrRect)
                     {
-                        pCurrRect->x      = pRect->left;
-                        pCurrRect->y      = pRect->top;
+                        pCurrRect->x      = pRect->left + x_offset;
+                        pCurrRect->y      = pRect->top + y_offset;
                         pCurrRect->height = pRect->bottom - pRect->top;
                         pCurrRect->width  = pRect->right  - pRect->left;
 
@@ -1322,7 +1251,7 @@
                     }
 
                     /* shape = non-rectangular windows (X11/extensions) */
-                    TSXShapeCombineRectangles( display, win, ShapeBounding,
+                    TSXShapeCombineRectangles( display, data->whole_window, ShapeBounding,
                                                0, 0, aXRect,
                                                pCurrRect - aXRect, ShapeSet, YXBanded );
                     HeapFree(GetProcessHeap(), 0, aXRect );
@@ -1543,17 +1472,9 @@
     {
         MapWindowPoints( wndPtr->parent->hwndSelf, 0, (LPPOINT)&mouseRect, 2 );
     }
-    SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
 
-    if (GetCapture() != hwnd) SetCapture( hwnd );
-
-    if (wndPtr->parent && (wndPtr->parent->hwndSelf != GetDesktopWindow()))
-    {
-          /* Retrieve a default cache DC (without using the window style) */
-        hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
-    }
-    else
-        hdc = GetDC( 0 );
+    /* Retrieve a default cache DC (without using the window style) */
+    hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
 
     if( iconic ) /* create a cursor for dragging */
     {
@@ -1566,19 +1487,28 @@
     /* repaint the window before moving it around */
     RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
 
+    SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
+    SetCapture( hwnd );
+
     /* grab the server only when moving top-level windows without desktop */
     grab = (!DragFullWindows && (root_window == DefaultRootWindow(gdi_display)) &&
             (wndPtr->parent->hwndSelf == GetDesktopWindow()));
+
+    wine_tsx11_lock();
     if (grab)
     {
-        wine_tsx11_lock();
         XSync( gdi_display, False );
         XGrabServer( display );
+        XSync( display, False );
         /* switch gdi display to the thread display, since the server is grabbed */
         old_gdi_display = gdi_display;
         gdi_display = display;
-        wine_tsx11_unlock();
     }
+    XGrabPointer( display, get_whole_window(wndPtr), False,
+                  PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
+                  GrabModeAsync, GrabModeAsync, get_client_window(wndPtr->parent),
+                  None, CurrentTime );
+    wine_tsx11_unlock();
 
     while(1)
     {
@@ -1681,19 +1611,18 @@
     else if (moved && !DragFullWindows)
         draw_moving_frame( hdc, &sizingRect, thickframe );
 
-    if (wndPtr->parent && (wndPtr->parent->hwndSelf != GetDesktopWindow()))
-        ReleaseDC( wndPtr->parent->hwndSelf, hdc );
-    else
-        ReleaseDC( 0, hdc );
+    ReleaseDC( wndPtr->parent->hwndSelf, hdc );
 
+    wine_tsx11_lock();
+    XUngrabPointer( display, CurrentTime );
     if (grab)
     {
-        wine_tsx11_lock();
         XSync( display, False );
         XUngrabServer( display );
+        XSync( display, False );
         gdi_display = old_gdi_display;
-        wine_tsx11_unlock();
     }
+    wine_tsx11_unlock();
 
     if (HOOK_CallHooksA( WH_CBT, HCBT_MOVESIZE, hwnd, (LPARAM)&sizingRect ))
         sizingRect = wndPtr->rectWindow;
diff --git a/dlls/x11drv/x11ddraw.c b/dlls/x11drv/x11ddraw.c
index a867222..76ec411 100644
--- a/dlls/x11drv/x11ddraw.c
+++ b/dlls/x11drv/x11ddraw.c
@@ -18,7 +18,6 @@
 #include "wingdi.h"
 #include "ddrawi.h"
 #include "bitmap.h"
-#include "win.h"
 #include "debugtools.h"
 
 DEFAULT_DEBUG_CHANNEL(x11drv);
@@ -50,19 +49,12 @@
 {
   Display *display = thread_display();
   if (hWnd) {
-    WND *tmpWnd;
-    Window win;
     /* find the X11 window that ddraw uses */
-    tmpWnd = WIN_FindWndPtr(hWnd);
-    win = X11DRV_WND_GetXWindow(tmpWnd);
-    TRACE("WND: %p win: %ld\n", tmpWnd, win);
-    WIN_ReleaseWndPtr(tmpWnd);
+    Window win = X11DRV_get_whole_window(hWnd);
+    TRACE("WND: %x win: %ld\n", hWnd, win);
     if (!win) {
       TRACE("host off desktop\n");
-      tmpWnd = WIN_FindWndPtr(GetDesktopWindow());
-      win = X11DRV_WND_GetXWindow(tmpWnd);
-      TRACE("Owner WND: %p win: %ld\n", tmpWnd, win);
-      WIN_ReleaseWndPtr(tmpWnd);
+      win = root_window;
     }
     TSXGrabPointer(display, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
   }
diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec
index 118e318..70d3aa3 100644
--- a/dlls/x11drv/x11drv.spec
+++ b/dlls/x11drv/x11drv.spec
@@ -27,11 +27,12 @@
 @ cdecl GetScreenSaveTimeout() X11DRV_GetScreenSaveTimeout
 @ cdecl SetScreenSaveTimeout(long) X11DRV_SetScreenSaveTimeout
 @ cdecl LoadOEMResource(long long) X11DRV_LoadOEMResource
-@ cdecl CreateWindow(long) X11DRV_CreateWindow
+@ cdecl CreateWindow(long ptr) X11DRV_CreateWindow
 @ cdecl DestroyWindow(long) X11DRV_DestroyWindow
 @ cdecl GetDC(long long long long) X11DRV_GetDC
 @ cdecl EnableWindow(long long) X11DRV_EnableWindow
 @ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) X11DRV_MsgWaitForMultipleObjectsEx
+@ cdecl ScrollDC(long long long ptr ptr long ptr) X11DRV_ScrollDC
 @ cdecl ScrollWindowEx(long long long ptr ptr long ptr long) X11DRV_ScrollWindowEx
 @ cdecl SetFocus(long) X11DRV_SetFocus
 @ cdecl SetParent(long long) X11DRV_SetParent
@@ -39,6 +40,7 @@
 @ cdecl SetWindowRgn(long long long) X11DRV_SetWindowRgn
 @ cdecl SetWindowIcon(long long long) X11DRV_SetWindowIcon
 @ cdecl SetWindowText(long wstr) X11DRV_SetWindowText
+@ cdecl ShowWindow(long long) X11DRV_ShowWindow
 @ cdecl SysCommandSizeMove(long long) X11DRV_SysCommandSizeMove
 @ cdecl AcquireClipboard() X11DRV_AcquireClipboard
 @ cdecl ReleaseClipboard() X11DRV_ReleaseClipboard
diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c
index 17a0b9d..d0c8b86 100644
--- a/graphics/x11drv/bitblt.c
+++ b/graphics/x11drv/bitblt.c
@@ -1306,28 +1306,22 @@
     case SRCCOPY:  /* 0xcc */
         if (dcSrc->bitsPerPixel == dcDst->bitsPerPixel)
         {
-            BOOL expose = !(dcSrc->flags & DC_MEMORY) && !(dcDst->flags & DC_MEMORY);
-            if ( expose ) XSetGraphicsExposures( gdi_display, physDevDst->gc, True );
             XSetFunction( gdi_display, physDevDst->gc, GXcopy );
             XCopyArea( gdi_display, physDevSrc->drawable,
                        physDevDst->drawable, physDevDst->gc,
                        visRectSrc.left, visRectSrc.top,
                        width, height, visRectDst.left, visRectDst.top );
-            if ( expose ) XSetGraphicsExposures( gdi_display, physDevDst->gc, False );
             return TRUE;
         }
         if (dcSrc->bitsPerPixel == 1)
         {
-            BOOL expose = !(dcSrc->flags & DC_MEMORY) && !(dcDst->flags & DC_MEMORY);
             XSetBackground( gdi_display, physDevDst->gc, physDevDst->textPixel );
             XSetForeground( gdi_display, physDevDst->gc, physDevDst->backgroundPixel );
             XSetFunction( gdi_display, physDevDst->gc, GXcopy );
-            if ( expose ) XSetGraphicsExposures( gdi_display, physDevDst->gc, True );
             XCopyPlane( gdi_display, physDevSrc->drawable,
                         physDevDst->drawable, physDevDst->gc,
                         visRectSrc.left, visRectSrc.top,
                         width, height, visRectDst.left, visRectDst.top, 1 );
-            if ( expose ) XSetGraphicsExposures( gdi_display, physDevDst->gc, False );
             return TRUE;
         }
         break;
@@ -1355,6 +1349,7 @@
     }
 
     tmpGC = XCreateGC( gdi_display, physDevDst->drawable, 0, NULL );
+    XSetSubwindowMode( gdi_display, tmpGC, IncludeInferiors );
     XSetGraphicsExposures( gdi_display, tmpGC, False );
     pixmaps[DST] = XCreatePixmap( gdi_display, root_window, width, height,
                                   dcDst->bitsPerPixel );
diff --git a/graphics/x11drv/bitmap.c b/graphics/x11drv/bitmap.c
index 343323e..26e06c6 100644
--- a/graphics/x11drv/bitmap.c
+++ b/graphics/x11drv/bitmap.c
@@ -41,6 +41,7 @@
     {
         BITMAP_monoGC = XCreateGC( gdi_display, tmpPixmap, 0, NULL );
         XSetGraphicsExposures( gdi_display, BITMAP_monoGC, False );
+        XSetSubwindowMode( gdi_display, BITMAP_monoGC, IncludeInferiors );
         XFreePixmap( gdi_display, tmpPixmap );
     }
 
@@ -50,6 +51,7 @@
         {
             BITMAP_colorGC = XCreateGC( gdi_display, tmpPixmap, 0, NULL );
             XSetGraphicsExposures( gdi_display, BITMAP_colorGC, False );
+            XSetSubwindowMode( gdi_display, BITMAP_colorGC, IncludeInferiors );
             XFreePixmap( gdi_display, tmpPixmap );
         }
     }
@@ -101,6 +103,8 @@
         XFreeGC( gdi_display, physDev->gc );
         physDev->gc = XCreateGC( gdi_display, physDev->drawable, 0, NULL );
         XSetGraphicsExposures( gdi_display, physDev->gc, False );
+        XSetSubwindowMode( gdi_display, physDev->gc, IncludeInferiors );
+        XFlush( gdi_display );
         wine_tsx11_unlock();
 	dc->bitsPerPixel = bmp->bitmap.bmBitsPixel;
         DC_InitDC( dc );
diff --git a/graphics/x11drv/clipping.c b/graphics/x11drv/clipping.c
index e1090e8..384561e 100644
--- a/graphics/x11drv/clipping.c
+++ b/graphics/x11drv/clipping.c
@@ -72,3 +72,102 @@
     GDI_ReleaseObj( dc->hGCClipRgn );
 }
 
+
+/***********************************************************************
+ *           X11DRV_SetDrawable
+ *
+ * Set the drawable, clipping mode and origin for a DC.
+ */
+void X11DRV_SetDrawable( HDC hdc, Drawable drawable, int mode, int org_x, int org_y )
+{
+    DC *dc = DC_GetDCPtr( hdc );
+    if (dc)
+    {
+        X11DRV_PDEVICE *physDev = dc->physDev;
+        /*
+         * This function change the coordinate system (DCOrgX,DCOrgY)
+         * values. When it moves the origin, other data like the current clipping
+         * region will not be moved to that new origin. In the case of DCs that are class
+         * or window DCs that clipping region might be a valid value from a previous use
+         * of the DC and changing the origin of the DC without moving the clip region
+         * results in a clip region that is not placed properly in the DC.
+         * This code will save the dc origin, let the SetDrawable
+         * modify the origin and reset the clipping. When the clipping is set,
+         * it is moved according to the new DC origin.
+         */
+        if (dc->hClipRgn) OffsetRgn( dc->hClipRgn, org_x - dc->DCOrgX, org_y - dc->DCOrgY );
+        dc->DCOrgX = org_x;
+        dc->DCOrgY = org_y;
+        physDev->drawable = drawable;
+        TSXSetSubwindowMode( gdi_display, physDev->gc, mode );
+        GDI_ReleaseObj( hdc );
+    }
+}
+
+
+/***********************************************************************
+ *           X11DRV_StartGraphicsExposures
+ *
+ * Set the DC in graphics exposures mode
+ */
+void X11DRV_StartGraphicsExposures( HDC hdc )
+{
+    DC *dc = DC_GetDCPtr( hdc );
+    if (dc)
+    {
+        X11DRV_PDEVICE *physDev = dc->physDev;
+        TSXSetGraphicsExposures( gdi_display, physDev->gc, True );
+        GDI_ReleaseObj( hdc );
+    }
+}
+
+
+/***********************************************************************
+ *           X11DRV_EndGraphicsExposures
+ *
+ * End the graphics exposures mode and process the events
+ */
+void X11DRV_EndGraphicsExposures( HDC hdc, HRGN hrgn )
+{
+    HRGN tmp = 0;
+    DC *dc = DC_GetDCPtr( hdc );
+
+    if (dc)
+    {
+        XEvent event;
+        X11DRV_PDEVICE *physDev = dc->physDev;
+
+        SetRectRgn( hrgn, 0, 0, 0, 0 );
+        wine_tsx11_lock();
+        XSetGraphicsExposures( gdi_display, physDev->gc, False );
+        XSync( gdi_display, False );
+        for (;;)
+        {
+            XWindowEvent( gdi_display, physDev->drawable, ~0, &event );
+            if (event.type == NoExpose) break;
+            if (event.type == GraphicsExpose)
+            {
+                TRACE( "got %d,%d %dx%d count %d\n",
+                       event.xgraphicsexpose.x, event.xgraphicsexpose.y,
+                       event.xgraphicsexpose.width, event.xgraphicsexpose.height,
+                       event.xgraphicsexpose.count );
+
+                if (!tmp) tmp = CreateRectRgn( 0, 0, 0, 0 );
+                SetRectRgn( tmp, event.xgraphicsexpose.x, event.xgraphicsexpose.y,
+                            event.xgraphicsexpose.x + event.xgraphicsexpose.width,
+                            event.xgraphicsexpose.y + event.xgraphicsexpose.height );
+                CombineRgn( hrgn, hrgn, tmp, RGN_OR );
+                if (!event.xgraphicsexpose.count) break;
+            }
+            else
+            {
+                ERR( "got unexpected event %d\n", event.type );
+                break;
+            }
+            if (tmp) DeleteObject( tmp );
+        }
+        wine_tsx11_unlock();
+        GDI_ReleaseObj( hdc );
+    }
+}
+
diff --git a/include/user.h b/include/user.h
index a69feb0..51d45ac 100644
--- a/include/user.h
+++ b/include/user.h
@@ -69,11 +69,12 @@
     void   (*pResetSelectionOwner)(struct tagWND *, BOOL);
 
     /* windowing functions */
-    BOOL   (*pCreateWindow)(HWND);
+    BOOL   (*pCreateWindow)(HWND,CREATESTRUCTA*);
     BOOL   (*pDestroyWindow)(HWND);
     BOOL   (*pGetDC)(HWND,HDC,HRGN,DWORD);
     BOOL   (*pEnableWindow)(HWND,BOOL);
     DWORD  (*pMsgWaitForMultipleObjectsEx)(DWORD,const HANDLE*,DWORD,DWORD,DWORD);
+    BOOL   (*pScrollDC)(HDC,INT,INT,const RECT*,const RECT*,HRGN,LPRECT);
     INT    (*pScrollWindowEx)(HWND,INT,INT,const RECT*,const RECT*,HRGN,LPRECT,UINT);
     void   (*pSetFocus)(HWND);
     HWND   (*pSetParent)(HWND,HWND);
@@ -81,6 +82,7 @@
     BOOL   (*pSetWindowRgn)(HWND,HRGN,BOOL);
     HICON  (*pSetWindowIcon)(HWND,HICON,BOOL);
     BOOL   (*pSetWindowText)(HWND,LPCWSTR);
+    BOOL   (*pShowWindow)(HWND,INT);
     void   (*pSysCommandSizeMove)(HWND,WPARAM);
 } USER_DRIVER;
 
diff --git a/include/win.h b/include/win.h
index 2ccf79d..4fda6b2 100644
--- a/include/win.h
+++ b/include/win.h
@@ -16,13 +16,6 @@
 
 #define WND_MAGIC     0x444e4957  /* 'WIND' */
 
-  /* PAINT_RedrawWindow() control flags */
-#define RDW_EX_USEHRGN		0x0001
-#define RDW_EX_DELETEHRGN	0x0002
-#define RDW_EX_XYWINDOW		0x0004
-#define RDW_EX_TOPFRAME		0x0010
-#define RDW_EX_DELAY_NCPAINT    0x0020
-
 struct tagCLASS;
 struct tagDCE;
 struct tagMESSAGEQUEUE;
@@ -65,13 +58,9 @@
     DWORD          wExtra[1];     /* Window extra bytes */
 } WND;
 
-/* Host attributes */
-#define HAK_ICONICSTATE	   3
-
 typedef struct tagWND_DRIVER
 {
     void   (*pForceWindowRaise)(WND *);
-    BOOL   (*pSetHostAttr)(WND *, INT haKey, INT value);
 } WND_DRIVER;
 
 extern WND_DRIVER *WND_Driver;
@@ -104,14 +93,6 @@
 #define BWA_SKIPOWNED		0x0004
 #define BWA_SKIPICONIC		0x0008
 
-  /* WIN_UpdateNCRgn() flags */
-#define UNC_CHECK		0x0001
-#define UNC_ENTIRE		0x0002
-#define UNC_REGION		0x0004
-#define UNC_UPDATE		0x0008
-#define UNC_DELAY_NCPAINT       0x0010
-#define UNC_IN_BEGINPAINT       0x0020
-
   /* Window functions */
 extern void   WIN_LockWnds( void );
 extern void   WIN_UnlockWnds( void );
@@ -137,8 +118,6 @@
 extern void   WIN_ReleaseWinArray(WND **wndArray);
 extern BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly );
 
-extern HICON16 NC_IconForWindow( WND *wndPtr );
-
 extern HWND CARET_GetHwnd(void);
 extern void CARET_GetRect(LPRECT lprc);  /* windows/caret.c */
 
@@ -149,11 +128,6 @@
 
 extern void PROPERTY_RemoveWindowProps( WND *pWnd );  		      /* windows/property.c */
 
-extern BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
-                                  HRGN hrgnUpdate, UINT flags,
-                                  UINT control );		      /* windows/painting.c */
-extern HRGN WIN_UpdateNCRgn(WND* wnd, HRGN hRgn, UINT flags);     /* windows/painting.c */
-
 /* Classes functions */
 struct tagCLASS;  /* opaque structure */
 struct builtin_class_descr;
@@ -167,8 +141,4 @@
 /* windows/focus.c */
 extern void FOCUS_SwitchFocus( struct tagMESSAGEQUEUE *pMsgQ, HWND , HWND );
 
-/* generic method that returns TRUE if the window properties ask for a 
-   window manager type of border */
-extern BOOL WIN_WindowNeedsWMBorder( DWORD style, DWORD exStyle );
-
 #endif  /* __WINE_WIN_H */
diff --git a/include/winpos.h b/include/winpos.h
index 3a89fb1..59f76de 100644
--- a/include/winpos.h
+++ b/include/winpos.h
@@ -28,7 +28,6 @@
 extern void   WINPOS_GetMinMaxInfo( struct tagWND* pWnd, POINT *maxSize,
                                     POINT *maxPos, POINT *minTrack,
                                     POINT *maxTrack );
-extern UINT WINPOS_MinMaximize( struct tagWND* pWnd, UINT16 cmd, LPRECT16 lpPos);
 extern BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse,
                                       BOOL fChangeFocus );
 extern BOOL WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg );
diff --git a/include/x11drv.h b/include/x11drv.h
index ea8c479..c288d92 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -19,6 +19,7 @@
 #include "winbase.h"
 #include "gdi.h"
 #include "user.h"
+#include "win.h"
 #include "thread.h"
 
 #define MAX_PIXELFORMATS 8
@@ -181,8 +182,11 @@
 extern Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc );
 extern Pixmap X11DRV_BITMAP_CreatePixmapFromBitmap( HBITMAP hBmp, HDC hdc );
 
-extern BOOL X11DRV_SetupGCForPatBlt( struct tagDC *dc, GC gc,
-				       BOOL fMapColors );
+extern void X11DRV_SetDrawable( HDC hdc, Drawable drawable, int mode, int org_x, int org_y );
+extern void X11DRV_StartGraphicsExposures( HDC hdc );
+extern void X11DRV_EndGraphicsExposures( HDC hdc, HRGN hrgn );
+
+extern BOOL X11DRV_SetupGCForPatBlt( struct tagDC *dc, GC gc, BOOL fMapColors );
 extern BOOL X11DRV_SetupGCForBrush( struct tagDC *dc );
 extern BOOL X11DRV_SetupGCForPen( struct tagDC *dc );
 extern BOOL X11DRV_SetupGCForText( struct tagDC *dc );
@@ -307,7 +311,7 @@
 {
     Display *display;
     HANDLE   display_fd;
-    int      process_event_count;
+    int      process_event_count;  /* recursion count for event processing */
 };
 
 extern struct x11drv_thread_data *x11drv_init_thread_data(void);
@@ -327,6 +331,15 @@
 extern unsigned int screen_height;
 extern unsigned int screen_depth;
 
+extern Atom wmProtocols;
+extern Atom wmDeleteWindow;
+extern Atom wmTakeFocus;
+extern Atom dndProtocol;
+extern Atom dndSelection;
+extern Atom wmChangeState;
+extern Atom kwmDockWindow;
+extern Atom _kde_net_wm_system_tray_window_for;
+
 static inline Visual *X11DRV_GetVisual(void)     { return visual; }
 static inline Window X11DRV_GetXRootWindow(void) { return root_window; }
 
@@ -345,8 +358,6 @@
 
 extern WORD X11DRV_EVENT_XStateToKeyState( int state ) ;
 
-extern void X11DRV_Synchronize( void );
-
 typedef enum {
   X11DRV_INPUT_RELATIVE,
   X11DRV_INPUT_ABSOLUTE
@@ -381,28 +392,50 @@
 
 extern struct tagWND_DRIVER X11DRV_WND_Driver;
 
-typedef struct _X11DRV_WND_DATA {
-  Window window;
-  HBITMAP hWMIconBitmap;
-  HBITMAP hWMIconMask;
-  int bit_gravity;
-} X11DRV_WND_DATA;
+/* x11drv private window data */
+struct x11drv_win_data
+{
+    Window  whole_window;   /* X window for the complete window */
+    Window  client_window;  /* X window for the client area */
+    Window  icon_window;    /* X window for the icon */
+    RECT    whole_rect;     /* X window rectangle for the whole window relative to parent */
+    RECT    client_rect;    /* client area relative to whole window */
+    HBITMAP hWMIconBitmap;
+    HBITMAP hWMIconMask;
+};
 
-extern Window X11DRV_WND_GetXWindow(struct tagWND *wndPtr);
-extern Window X11DRV_WND_FindXWindow(struct tagWND *wndPtr);
+typedef struct x11drv_win_data X11DRV_WND_DATA;
+
+extern Window X11DRV_get_client_window( HWND hwnd );
+extern Window X11DRV_get_whole_window( HWND hwnd );
+extern Window X11DRV_get_top_window( HWND hwnd );
+
+inline static Window get_client_window( WND *wnd )
+{
+    struct x11drv_win_data *data = wnd->pDriverData;
+    return data->client_window;
+}
+
+inline static Window get_whole_window( WND *wnd )
+{
+    struct x11drv_win_data *data = wnd->pDriverData;
+    return data->whole_window;
+}
 
 extern void X11DRV_WND_ForceWindowRaise(struct tagWND *pWnd);
-extern void X11DRV_WND_SetWindowPos(struct tagWND *wndPtr, const struct tagWINDOWPOS *winpos, BOOL bSMC_SETXPOS);
-extern void X11DRV_WND_SetText(struct tagWND *wndPtr, LPCWSTR text);
-extern void X11DRV_WND_SurfaceCopy(struct tagWND *wndPtr, HDC hdc, INT dx, INT dy, const RECT *clipRect, BOOL bUpdate);
-extern void X11DRV_WND_SetGravity(struct tagWND* wndPtr, int value );
-extern BOOL X11DRV_WND_SetHostAttr(struct tagWND *wndPtr, INT haKey, INT value);
 
 extern void X11DRV_SetFocus( HWND hwnd );
 extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );
 
-extern void X11DRV_register_window( Display *display, HWND hwnd, Window win );
+extern void X11DRV_expect_error( unsigned char request, unsigned char error, XID id );
+extern int X11DRV_check_error(void);
+extern void X11DRV_register_window( Display *display, HWND hwnd, struct x11drv_win_data *data );
+extern void X11DRV_set_iconic_state( WND *win );
+extern void X11DRV_window_to_X_rect( WND *win, RECT *rect );
+extern void X11DRV_X_to_window_rect( WND *win, RECT *rect );
 extern void X11DRV_create_desktop_thread(void);
 extern Window X11DRV_create_desktop( XVisualInfo *desktop_vi, const char *geometry );
+extern int X11DRV_sync_whole_window_position( Display *display, WND *win, int zorder );
+extern int X11DRV_sync_client_window_position( Display *display, WND *win );
 
 #endif  /* __WINE_X11DRV_H */
diff --git a/windows/dce.c b/windows/dce.c
index 400231a..3a143ae 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -211,9 +211,9 @@
 
     dce->hClipRgn = 0;
 
-    TRACE("\trestoring VisRgn\n");
-
-    RestoreVisRgn16(dce->hDC);
+    /* make it dirty so that the vis rgn gets recomputed next time */
+    dce->DCXflags |= DCX_DCEDIRTY;
+    SetHookFlags16( dce->hDC, DCHF_INVALIDATEVISRGN );
 }
 
 
@@ -412,8 +412,9 @@
     BOOL	bUpdateClipOrigin = FALSE;
 
     TRACE("hwnd %04x, hrgnClip %04x, flags %08x\n", 
-				hwnd, hrgnClip, (unsigned)flags);
-    
+          hwnd, hrgnClip, (unsigned)flags);
+
+    if (!hwnd) hwnd = GetDesktopWindow();
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
 
     /* fixup flags */
@@ -437,17 +438,11 @@
 	else flags |= DCX_CACHE;
     }
 
-    if( flags & DCX_NOCLIPCHILDREN )
-    {
-        flags |= DCX_CACHE;
-        flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);
-    }
-
     if (flags & DCX_WINDOW) 
 	flags = (flags & ~DCX_CLIPCHILDREN) | DCX_CACHE;
 
-    if (!(wndPtr->dwStyle & WS_CHILD) || !wndPtr->parent ) 
-	flags &= ~DCX_PARENTCLIP;
+    if (!wndPtr->parent || (wndPtr->parent->hwndSelf == GetDesktopWindow()))
+        flags = (flags & ~DCX_PARENTCLIP) | DCX_CLIPSIBLINGS;
     else if( flags & DCX_PARENTCLIP )
     {
 	flags |= DCX_CACHE;
@@ -514,25 +509,6 @@
 	{
 	    TRACE("\tskipping hVisRgn update\n");
 	    bUpdateVisRgn = FALSE; /* updated automatically, via DCHook() */
-
-            /* Abey - 16Jul99. to take care of the nested GetDC. first one
-               with DCX_EXCLUDERGN or DCX_INTERSECTRGN flags and the next
-               one with or without these flags. */
-
-	    if(dce->DCXflags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN))
-	    {
-		/* This is likely to be a nested BeginPaint().
-                   or a BeginPaint() followed by a GetDC()*/
-
-		if( dce->hClipRgn != hrgnClip )
-		{
-		    FIXME("new hrgnClip[%04x] smashes the previous[%04x]\n",
-			  hrgnClip, dce->hClipRgn );
-		    DCE_DeleteClipRgn( dce );
-		}
-		else 
-		    RestoreVisRgn16(dce->hDC);
-	    }
 	}
     }
     if (!dce)
@@ -542,6 +518,14 @@
     }
 
     if (!(flags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN))) hrgnClip = 0;
+
+    if (((flags ^ dce->DCXflags) & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) &&
+        (dce->hClipRgn != hrgnClip))
+    {
+        /* if the extra clip region has changed, get rid of the old one */
+        DCE_DeleteClipRgn( dce );
+    }
+
     dce->hwndCurrent = hwnd;
     dce->hClipRgn = hrgnClip;
     dce->DCXflags = flags & (DCX_PARENTCLIP | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
@@ -581,7 +565,7 @@
 	     HWND hwnd /* [in] handle of window */
 ) {
     if (!hwnd)
-        return GetDCEx( GetDesktopWindow(), 0, DCX_CACHE | DCX_WINDOW );
+        return GetDCEx( 0, 0, DCX_CACHE | DCX_WINDOW );
     return GetDCEx( hwnd, 0, DCX_USESTYLE );
 }
 
@@ -591,7 +575,6 @@
  */
 HDC16 WINAPI GetWindowDC16( HWND16 hwnd )
 {
-    if (!hwnd) hwnd = GetDesktopWindow16();
     return GetDCEx16( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
 }
 
@@ -601,7 +584,6 @@
  */
 HDC WINAPI GetWindowDC( HWND hwnd )
 {
-    if (!hwnd) hwnd = GetDesktopWindow();
     return GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
 }
 
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 7a2b647..3c5e537 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -415,11 +415,7 @@
 	}
 
     case WM_SYNCPAINT:
-	if (wndPtr->hrgnUpdate) 
-	{
-	   RedrawWindow ( wndPtr->hwndSelf, 0, wndPtr->hrgnUpdate,
-                    RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
-        }
+        RedrawWindow ( wndPtr->hwndSelf, NULL, 0, RDW_ERASENOW | RDW_ERASE | RDW_ALLCHILDREN );
         return 0;
 
     case WM_SETREDRAW:
diff --git a/windows/nonclient.c b/windows/nonclient.c
index cc47c45..b25049c 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -75,24 +75,6 @@
 
 #define HAS_MENU(w)  (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
 
-/***********************************************************************
- *           WIN_WindowNeedsWMBorder
- *
- * This method defines the rules for a window to have a WM border,
- * caption...  It is used for consistency purposes.
- */
-BOOL WIN_WindowNeedsWMBorder( DWORD style, DWORD exStyle )
-{
-    if (!(style & WS_CHILD) && 
-	Options.managed  &&
-	!(exStyle & WS_EX_TOOLWINDOW) &&
-        ( ((style & WS_CAPTION) == WS_CAPTION) ||
-	  (style & WS_THICKFRAME)))
-        return TRUE;
-    if (exStyle & WS_EX_TRAYWINDOW)
-	return TRUE;
-    return FALSE;
-}
 
 /***********************************************************************
  *           NC_AdjustRect
@@ -106,21 +88,17 @@
 	ERR("Called in Win95 mode. Aiee! Please report this.\n" );
 
     if(style & WS_ICONIC) return;
-    /* Decide if the window will be managed (see CreateWindowEx) */
-    if (!WIN_WindowNeedsWMBorder(style, exStyle))
-    {
-        if (HAS_THICKFRAME( style, exStyle ))
-            InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
-        else
-        if (HAS_DLGFRAME( style, exStyle ))
-            InflateRect( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
-        else
-        if (HAS_THINFRAME( style ))
-            InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
 
-        if ((style & WS_CAPTION) == WS_CAPTION)
-            rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
-    }
+    if (HAS_THICKFRAME( style, exStyle ))
+        InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
+    else if (HAS_DLGFRAME( style, exStyle ))
+        InflateRect( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
+    else if (HAS_THINFRAME( style ))
+        InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
+
+    if ((style & WS_CAPTION) == WS_CAPTION)
+        rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
+
     if (menu) rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
 
     if (style & WS_VSCROLL) {
@@ -172,29 +150,21 @@
 {
     if(style & WS_ICONIC) return;
 
-    /* Decide if the window will be managed (see CreateWindowEx) */
-    if (!WIN_WindowNeedsWMBorder(style, exStyle))
+    if (HAS_THICKFRAME( style, exStyle ))
+        InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
+    else if (HAS_DLGFRAME( style, exStyle ))
+        InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
+    else if (HAS_THINFRAME( style ))
+        InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
+
+    if ((style & WS_CAPTION) == WS_CAPTION)
     {
-        if (HAS_THICKFRAME( style, exStyle ))
-            InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
+        if (exStyle & WS_EX_TOOLWINDOW)
+            rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
         else
-        if (HAS_DLGFRAME( style, exStyle ))
-            InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
-        else
-        if (HAS_THINFRAME( style ))
-            InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
-
-        if ((style & WS_CAPTION) == WS_CAPTION)
-        {
-	    if (exStyle & WS_EX_TOOLWINDOW)
-		rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
-	    else
-		rect->top -= GetSystemMetrics(SM_CYCAPTION);
-        }
+            rect->top -= GetSystemMetrics(SM_CYCAPTION);
     }
-
-    if (menu)
-	rect->top -= GetSystemMetrics(SM_CYMENU);
+    if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
 }
 
 
@@ -240,6 +210,20 @@
 }
 
 
+
+static HICON NC_IconForWindow( HWND hwnd )
+{
+    HICON hIcon = (HICON) GetClassLongA( hwnd, GCL_HICONSM );
+    if (!hIcon) hIcon = (HICON) GetClassLongA( hwnd, GCL_HICON );
+
+    /* If there is no hIcon specified and this is a modal dialog,
+     * get the default one.
+     */
+    if (!hIcon && (GetWindowLongA( hwnd, GWL_STYLE ) & DS_MODALFRAME))
+        hIcon = LoadImageA(0, IDI_WINLOGOA, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
+    return hIcon;
+}
+
 /***********************************************************************
  *		DrawCaption (USER.660) Draws a caption bar
  *
@@ -355,18 +339,9 @@
 	pt.x = rc.left + 2;
 	pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
 
-	if (hIcon) {
-	    DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
-			  GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
-	}
-	else {
-	    WND* wndPtr = WIN_FindWndPtr(hwnd);
-	    HICON hAppIcon = (HICON) NC_IconForWindow(wndPtr);
-	    DrawIconEx (hdc, pt.x, pt.y, hAppIcon, GetSystemMetrics(SM_CXSMICON),
-			  GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
-            WIN_ReleaseWndPtr(wndPtr);
-	}
-
+        if (!hIcon) hIcon = NC_IconForWindow(hwnd);
+        DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
+                    GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
 	rc.left += (rc.bottom - rc.top);
     }
 
@@ -574,7 +549,7 @@
     rect->right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
     rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
 
-    if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->dwExStyle & WS_EX_MANAGED)) goto END;
+    if (wndPtr->dwStyle & WS_ICONIC) goto END;
 
     /* Remove frame from rectangle */
     if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
@@ -630,76 +605,73 @@
 
     if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
 
-    if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
+    /* Check borders */
+    if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
     {
-        /* Check borders */
-        if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+        InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
+        if (!PtInRect( &rect, pt ))
         {
-            InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
-            if (!PtInRect( &rect, pt ))
+            /* Check top sizing border */
+            if (pt.y < rect.top)
             {
-                /* Check top sizing border */
-                if (pt.y < rect.top)
-                {
-                    if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
-                    if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
-                    return HTTOP;
-                }
-                /* Check bottom sizing border */
-                if (pt.y >= rect.bottom)
-                {
-                    if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
-                    if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
-                    return HTBOTTOM;
-                }
-                /* Check left sizing border */
-                if (pt.x < rect.left)
-                {
-                    if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
-                    if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
-                    return HTLEFT;
-                }
-                /* Check right sizing border */
-                if (pt.x >= rect.right)
-                {
-                    if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
-                    if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
-                    return HTRIGHT;
-                }
+                if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
+                if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
+                return HTTOP;
+            }
+            /* Check bottom sizing border */
+            if (pt.y >= rect.bottom)
+            {
+                if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
+                if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
+                return HTBOTTOM;
+            }
+            /* Check left sizing border */
+            if (pt.x < rect.left)
+            {
+                if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
+                if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
+                return HTLEFT;
+            }
+            /* Check right sizing border */
+            if (pt.x >= rect.right)
+            {
+                if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
+                if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
+                return HTRIGHT;
             }
         }
-        else  /* No thick frame */
+    }
+    else  /* No thick frame */
+    {
+        if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+            InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
+        else if (HAS_THINFRAME( wndPtr->dwStyle ))
+            InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
+        if (!PtInRect( &rect, pt )) return HTBORDER;
+    }
+
+    /* Check caption */
+
+    if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+    {
+        rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
+        if (!PtInRect( &rect, pt ))
         {
-            if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
-                InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
-            else if (HAS_THINFRAME( wndPtr->dwStyle ))
-                InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
-            if (!PtInRect( &rect, pt )) return HTBORDER;
-        }
+            /* Check system menu */
+            if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
+                rect.left += GetSystemMetrics(SM_CXSIZE);
+            if (pt.x <= rect.left) return HTSYSMENU;
 
-        /* Check caption */
+            /* Check maximize box */
+            if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
+                rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
 
-        if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
-        {
-            rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
-            if (!PtInRect( &rect, pt ))
-            {
-                /* Check system menu */
-                if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
-                    rect.left += GetSystemMetrics(SM_CXSIZE);
-                if (pt.x <= rect.left) return HTSYSMENU;
-
-                /* Check maximize box */
-                if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
-                    rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
-
-                if (pt.x >= rect.right) return HTMAXBUTTON;
-                /* Check minimize box */
-                if (wndPtr->dwStyle & WS_MINIMIZEBOX)
-                    rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
-                if (pt.x >= rect.right) return HTMINBUTTON;
-                return HTCAPTION;
-            }
+            if (pt.x >= rect.right) return HTMAXBUTTON;
+            /* Check minimize box */
+            if (wndPtr->dwStyle & WS_MINIMIZEBOX)
+                rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+            if (pt.x >= rect.right) return HTMINBUTTON;
+            return HTCAPTION;
         }
     }
 
@@ -765,90 +737,87 @@
 
     if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
 
-    if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
+    /* Check borders */
+    if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
     {
-        /* Check borders */
-        if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+        InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
+        if (!PtInRect( &rect, pt ))
         {
-            InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
-            if (!PtInRect( &rect, pt ))
+            /* Check top sizing border */
+            if (pt.y < rect.top)
             {
-                /* Check top sizing border */
-                if (pt.y < rect.top)
-                {
-                    if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
-                    if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
-                    return HTTOP;
-                }
-                /* Check bottom sizing border */
-                if (pt.y >= rect.bottom)
-                {
-                    if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
-                    if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
-                    return HTBOTTOM;
-                }
-                /* Check left sizing border */
-                if (pt.x < rect.left)
-                {
-                    if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
-                    if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
-                    return HTLEFT;
-                }
-                /* Check right sizing border */
-                if (pt.x >= rect.right)
-                {
-                    if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
-                    if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
-                    return HTRIGHT;
-                }
+                if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
+                if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
+                return HTTOP;
+            }
+            /* Check bottom sizing border */
+            if (pt.y >= rect.bottom)
+            {
+                if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
+                if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
+                return HTBOTTOM;
+            }
+            /* Check left sizing border */
+            if (pt.x < rect.left)
+            {
+                if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
+                if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
+                return HTLEFT;
+            }
+            /* Check right sizing border */
+            if (pt.x >= rect.right)
+            {
+                if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
+                if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
+                return HTRIGHT;
             }
         }
-        else  /* No thick frame */
-        {
-            if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
-                InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
-            else if (HAS_THINFRAME( wndPtr->dwStyle ))
-                InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
-            if (!PtInRect( &rect, pt )) return HTBORDER;
-        }
+    }
+    else  /* No thick frame */
+    {
+        if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+            InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
+        else if (HAS_THINFRAME( wndPtr->dwStyle ))
+            InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
+        if (!PtInRect( &rect, pt )) return HTBORDER;
+    }
 
-        /* Check caption */
+    /* Check caption */
 
-        if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+    if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+    {
+        if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
+            rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
+        else
+            rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
+        if (!PtInRect( &rect, pt ))
         {
-	    if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
-	        rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
-	    else
-	        rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
-            if (!PtInRect( &rect, pt ))
+            /* Check system menu */
+            if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
             {
-                /* Check system menu */
-                if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
-		{
-		    if (NC_IconForWindow(wndPtr))
-			rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
-		}
-                if (pt.x < rect.left) return HTSYSMENU;
-
-                /* Check close button */
-                if (wndPtr->dwStyle & WS_SYSMENU)
-                    rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
-                if (pt.x > rect.right) return HTCLOSE;
-
-                /* Check maximize box */
-		/* In win95 there is automatically a Maximize button when there is a minimize one*/
-                if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
-                    rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
-                if (pt.x > rect.right) return HTMAXBUTTON;
-
-                /* Check minimize box */
-		/* In win95 there is automatically a Maximize button when there is a Maximize one*/
-                if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
-                    rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
-
-                if (pt.x > rect.right) return HTMINBUTTON;
-                return HTCAPTION;
+                if (NC_IconForWindow(wndPtr->hwndSelf))
+                    rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
             }
+            if (pt.x < rect.left) return HTSYSMENU;
+
+            /* Check close button */
+            if (wndPtr->dwStyle & WS_SYSMENU)
+                rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
+            if (pt.x > rect.right) return HTCLOSE;
+
+            /* Check maximize box */
+            /* In win95 there is automatically a Maximize button when there is a minimize one*/
+            if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
+                rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+            if (pt.x > rect.right) return HTMAXBUTTON;
+
+            /* Check minimize box */
+            /* In win95 there is automatically a Maximize button when there is a Maximize one*/
+            if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
+                rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+
+            if (pt.x > rect.right) return HTMINBUTTON;
+            return HTCAPTION;
         }
     }
 
@@ -925,20 +894,15 @@
     RECT rect;
     HDC hdcMem;
     HBITMAP hbitmap;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
 
-    if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
-    {
-      NC_GetInsideRect( hwnd, &rect );
-      hdcMem = CreateCompatibleDC( hdc );
-      hbitmap = SelectObject( hdcMem, hbitmapClose );
-      BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
-               hdcMem, (wndPtr->dwStyle & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
-               down ? NOTSRCCOPY : SRCCOPY );
-      SelectObject( hdcMem, hbitmap );
-      DeleteDC( hdcMem );
-    }
-    WIN_ReleaseWndPtr(wndPtr);
+    NC_GetInsideRect( hwnd, &rect );
+    hdcMem = CreateCompatibleDC( hdc );
+    hbitmap = SelectObject( hdcMem, hbitmapClose );
+    BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
+           hdcMem, (GetWindowLongA(hwnd,GWL_STYLE) & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
+           down ? NOTSRCCOPY : SRCCOPY );
+    SelectObject( hdcMem, hbitmap );
+    DeleteDC( hdcMem );
 }
 
 
@@ -948,22 +912,17 @@
 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
 {
     RECT rect;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
     HDC hdcMem;
 
-    if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
-    {
-      NC_GetInsideRect( hwnd, &rect );
-      hdcMem = CreateCompatibleDC( hdc );
-      SelectObject( hdcMem,  (IsZoomed(hwnd) 
-			     ? (down ? hbitmapRestoreD : hbitmapRestore)
-			     : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
-      BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
-		GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
-		SRCCOPY );
-      DeleteDC( hdcMem );
-    }
-    WIN_ReleaseWndPtr(wndPtr);
+    NC_GetInsideRect( hwnd, &rect );
+    hdcMem = CreateCompatibleDC( hdc );
+    SelectObject( hdcMem,  (IsZoomed(hwnd)
+                            ? (down ? hbitmapRestoreD : hbitmapRestore)
+                            : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
+    BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
+            GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
+            SRCCOPY );
+    DeleteDC( hdcMem );
 
 }
 
@@ -974,21 +933,17 @@
 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
 {
     RECT rect;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
     HDC hdcMem;
 
-    if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
-    {
-      NC_GetInsideRect( hwnd, &rect );
-      hdcMem = CreateCompatibleDC( hdc );
-      SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
-      if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
-      BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
-		GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
-		SRCCOPY );
-      DeleteDC( hdcMem );
-    }
-    WIN_ReleaseWndPtr(wndPtr);
+    NC_GetInsideRect( hwnd, &rect );
+    hdcMem = CreateCompatibleDC( hdc );
+    SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
+    if (GetWindowLongA(hwnd,GWL_STYLE) & WS_MAXIMIZEBOX)
+        rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
+    BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
+            GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
+            SRCCOPY );
+    DeleteDC( hdcMem );
 }
 
 
@@ -1012,28 +967,17 @@
 BOOL
 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
 {
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    HICON hIcon = NC_IconForWindow( hwnd );
 
-    if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
+    if (hIcon)
     {
-	HICON  hIcon;
-	RECT rect;
-
-	NC_GetInsideRect( hwnd, &rect );
-
-	hIcon = NC_IconForWindow( wndPtr );
-
-	if (hIcon)
-	    DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
-			  GetSystemMetrics(SM_CXSMICON),
-			  GetSystemMetrics(SM_CYSMICON),
-			  0, 0, DI_NORMAL);
-
-        WIN_ReleaseWndPtr(wndPtr);
-	return (hIcon != 0);
+        RECT rect;
+        NC_GetInsideRect( hwnd, &rect );
+        DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
+                    GetSystemMetrics(SM_CXSMICON),
+                    GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
     }
-    WIN_ReleaseWndPtr(wndPtr);
-    return FALSE;
+    return (hIcon != 0);
 }
 
 
@@ -1058,37 +1002,32 @@
 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
 {
     RECT rect;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
 
-    if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
+    NC_GetInsideRect( hwnd, &rect );
+
+    /* A tool window has a smaller Close button */
+    if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW)
     {
-        NC_GetInsideRect( hwnd, &rect );
+        INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE   */
+        INT iBmpWidth = 11;  /* it uses 11x11 for  the close button in tool window */
+        INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
 
-	/* A tool window has a smaller Close button */
-	if(wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
-	{
-            INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE   */
-            INT iBmpWidth = 11;  /* it uses 11x11 for  the close button in tool window */
-            INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
-
-            rect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
-            rect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
-            rect.bottom = rect.top + iBmpHeight;
-            rect.right = rect.left + iBmpWidth;
-        }
-        else
-        {
-            rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) - 1;
-            rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
-            rect.top += 2;
-            rect.right -= 2;
-        }
-        DrawFrameControl( hdc, &rect, DFC_CAPTION,
-                          (DFCS_CAPTIONCLOSE |
-                           (down ? DFCS_PUSHED : 0) |
-                           (bGrayed ? DFCS_INACTIVE : 0)) );
+        rect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
+        rect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
+        rect.bottom = rect.top + iBmpHeight;
+        rect.right = rect.left + iBmpWidth;
     }
-    WIN_ReleaseWndPtr(wndPtr);
+    else
+    {
+        rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) - 1;
+        rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
+        rect.top += 2;
+        rect.right -= 2;
+    }
+    DrawFrameControl( hdc, &rect, DFC_CAPTION,
+                      (DFCS_CAPTIONCLOSE |
+                       (down ? DFCS_PUSHED : 0) |
+                       (bGrayed ? DFCS_INACTIVE : 0)) );
 }
 
 /******************************************************************************
@@ -1100,23 +1039,18 @@
 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
 {
     RECT rect;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    UINT flags = IsZoomed(hwnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX;
 
-    if( !(wndPtr->dwExStyle & WS_EX_MANAGED))
-    {
-        UINT flags = IsZoomed(hwnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX;
-        NC_GetInsideRect( hwnd, &rect );
-        if (wndPtr->dwStyle & WS_SYSMENU)
-            rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
-        rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
-        rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
-        rect.top += 2;
-        rect.right -= 2;
-        if (down) flags |= DFCS_PUSHED;
-        if (bGrayed) flags |= DFCS_INACTIVE;
-        DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
-    }
-    WIN_ReleaseWndPtr(wndPtr);
+    NC_GetInsideRect( hwnd, &rect );
+    if (GetWindowLongA( hwnd, GWL_STYLE) & WS_SYSMENU)
+        rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+    rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
+    rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
+    rect.top += 2;
+    rect.right -= 2;
+    if (down) flags |= DFCS_PUSHED;
+    if (bGrayed) flags |= DFCS_INACTIVE;
+    DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
 }
 
 /******************************************************************************
@@ -1128,25 +1062,21 @@
 static void  NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
 {
     RECT rect;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    UINT flags = DFCS_CAPTIONMIN;
+    DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
 
-    if( !(wndPtr->dwExStyle & WS_EX_MANAGED))
-    {
-        UINT flags = DFCS_CAPTIONMIN;
-        NC_GetInsideRect( hwnd, &rect );
-        if (wndPtr->dwStyle & WS_SYSMENU)
-            rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
-        if (wndPtr->dwStyle & (WS_MAXIMIZEBOX|WS_MINIMIZEBOX))
-            rect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
-        rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
-        rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
-        rect.top += 2;
-        rect.right -= 2;
-        if (down) flags |= DFCS_PUSHED;
-        if (bGrayed) flags |= DFCS_INACTIVE;
-        DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
-    }
-    WIN_ReleaseWndPtr(wndPtr);
+    NC_GetInsideRect( hwnd, &rect );
+    if (style & WS_SYSMENU)
+        rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+    if (style & (WS_MAXIMIZEBOX|WS_MINIMIZEBOX))
+        rect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
+    rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
+    rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
+    rect.top += 2;
+    rect.right -= 2;
+    if (down) flags |= DFCS_PUSHED;
+    if (bGrayed) flags |= DFCS_INACTIVE;
+    DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
 }
 
 /***********************************************************************
@@ -1306,22 +1236,11 @@
 			    DWORD style, BOOL active )
 {
     RECT r = *rect;
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
     char buffer[256];
 
-    if (wndPtr->dwExStyle & WS_EX_MANAGED)
-    {
-        WIN_ReleaseWndPtr(wndPtr);
-        return;
-    }
-
     if (!hbitmapClose)
     {
-	if (!(hbitmapClose = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE) )))
-        {
-            WIN_ReleaseWndPtr(wndPtr);
-	    return;
-        }
+	if (!(hbitmapClose = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE) ))) return;
 	hbitmapMinimize  = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCE) );
 	hbitmapMinimizeD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCED) );
 	hbitmapMaximize  = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOM) );
@@ -1330,7 +1249,7 @@
 	hbitmapRestoreD  = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORED) );
     }
     
-    if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
+    if (GetWindowLongA( hwnd, GWL_EXSTYLE) & WS_EX_DLGMODALFRAME)
     {
         HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
 	PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
@@ -1340,7 +1259,6 @@
 	r.right--;
 	SelectObject( hdc, hbrushOld );
     }
-    WIN_ReleaseWndPtr(wndPtr);
     MoveToEx( hdc, r.left, r.bottom, NULL );
     LineTo( hdc, r.right, r.bottom );
 
@@ -1409,18 +1327,10 @@
     BOOL active )
 {
     RECT  r = *rect;
-    WND     *wndPtr = WIN_FindWndPtr( hwnd );
     char    buffer[256];
     HPEN  hPrevPen;
     HMENU hSysMenu;
 
-    if (wndPtr->dwExStyle & WS_EX_MANAGED)
-    {
-        WIN_ReleaseWndPtr(wndPtr);
-        return;
-    }
-    WIN_ReleaseWndPtr(wndPtr);
-
     hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
     MoveToEx( hdc, r.left, r.bottom - 1, NULL );
     LineTo( hdc, r.right, r.bottom - 1 );
@@ -1521,27 +1431,24 @@
 
     SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
 
-    if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
+    if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
     {
-        if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
-	{
-	    SelectObject( hdc, GetStockObject(NULL_BRUSH) );
-            Rectangle( hdc, 0, 0, rect.right, rect.bottom );
-            InflateRect( &rect, -1, -1 );
-        }
+        SelectObject( hdc, GetStockObject(NULL_BRUSH) );
+        Rectangle( hdc, 0, 0, rect.right, rect.bottom );
+        InflateRect( &rect, -1, -1 );
+    }
 
-	if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
-            NC_DrawFrame(hdc, &rect, FALSE, active );
-	else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) 
-            NC_DrawFrame( hdc, &rect, TRUE, active );
+    if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+        NC_DrawFrame(hdc, &rect, FALSE, active );
+    else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+        NC_DrawFrame( hdc, &rect, TRUE, active );
 
-        if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
-        {
-            RECT r = rect;
-            r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
-            rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
-            NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
-        }
+    if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+    {
+        RECT r = rect;
+        r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
+        rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
+        NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
     }
 
     if (HAS_MENU(wndPtr))
@@ -1652,34 +1559,32 @@
 
     SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
 
-    if(!(wndPtr->dwExStyle & WS_EX_MANAGED)) {
-        if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
-            DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
-        }
-	if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
-            NC_DrawFrame95(hdc, &rect, FALSE, active );
-        else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) 
-            NC_DrawFrame95( hdc, &rect, TRUE, active );
-	else if (HAS_THINFRAME( wndPtr->dwStyle )) {
-            SelectObject( hdc, GetStockObject(NULL_BRUSH) );
-            Rectangle( hdc, 0, 0, rect.right, rect.bottom );
-	}
+    if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
+        DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
+    }
+    if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+        NC_DrawFrame95(hdc, &rect, FALSE, active );
+    else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+        NC_DrawFrame95( hdc, &rect, TRUE, active );
+    else if (HAS_THINFRAME( wndPtr->dwStyle )) {
+        SelectObject( hdc, GetStockObject(NULL_BRUSH) );
+        Rectangle( hdc, 0, 0, rect.right, rect.bottom );
+    }
 
-        if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
-        {
-            RECT  r = rect;
-	    if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
-		r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
-		rect.top += GetSystemMetrics(SM_CYSMCAPTION);
-	    }
-	    else {
-		r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
-		rect.top += GetSystemMetrics(SM_CYCAPTION);
-	    }
-	    if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
-                NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
-                                  wndPtr->dwExStyle, active);
+    if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+    {
+        RECT  r = rect;
+        if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
+            r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
+            rect.top += GetSystemMetrics(SM_CYSMCAPTION);
         }
+        else {
+            r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
+            rect.top += GetSystemMetrics(SM_CYCAPTION);
+        }
+        if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
+            NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
+                              wndPtr->dwExStyle, active);
     }
 
     if (HAS_MENU(wndPtr))
@@ -2351,16 +2256,3 @@
     
     return TRUE;
 }
-
-HICON16 NC_IconForWindow(WND *wndPtr)
-{
-	HICON16 hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
-	if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
-
-	/* If there is no hIcon specified and this is a modal dialog, */ 
-        /* get the default one.                                       */
-	if (!hIcon && (wndPtr->dwStyle & DS_MODALFRAME))
-		hIcon = LoadImageA(0, IDI_WINLOGOA, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
-
-	return hIcon;
-}
diff --git a/windows/painting.c b/windows/painting.c
index 86d7b64..898d9d8 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -28,6 +28,17 @@
 					(r).right = (wnd)->rectClient.right - (wnd)->rectWindow.left; \
 					(r).bottom = (wnd)->rectClient.bottom - (wnd)->rectWindow.top
 
+  /* PAINT_RedrawWindow() control flags */
+#define RDW_EX_DELAY_NCPAINT    0x0020
+
+  /* WIN_UpdateNCRgn() flags */
+#define UNC_CHECK		0x0001
+#define UNC_ENTIRE		0x0002
+#define UNC_REGION		0x0004
+#define UNC_UPDATE		0x0008
+#define UNC_DELAY_NCPAINT       0x0010
+#define UNC_IN_BEGINPAINT       0x0020
+
   /* Last COLOR id */
 #define COLOR_MAX   COLOR_GRADIENTINACTIVECAPTION
 
@@ -127,7 +138,7 @@
  *	  is 1 then the hRgn is preserved and RDW_Paint() will have to get 
  *	  a DC without extra clipping region.
  */
-HRGN WIN_UpdateNCRgn(WND* wnd, HRGN hRgn, UINT uncFlags )
+static HRGN WIN_UpdateNCRgn(WND* wnd, HRGN hRgn, UINT uncFlags )
 {
     RECT  r;
     HRGN  hClip = 0;
@@ -323,7 +334,7 @@
 
     TRACE("hrgnUpdate = %04x, \n", hrgnUpdate);
 
-    if (GetClassWord16(wndPtr->hwndSelf, GCW_STYLE) & CS_PARENTDC)
+    if (GetClassLongA(wndPtr->hwndSelf, GCL_STYLE) & CS_PARENTDC)
     {
         /* Don't clip the output to the update region for CS_PARENTDC window */
 	if( hrgnUpdate ) 
@@ -336,7 +347,7 @@
 	if( hrgnUpdate ) /* convert to client coordinates */
 	    OffsetRgn( hrgnUpdate, wndPtr->rectWindow.left - wndPtr->rectClient.left,
 			           wndPtr->rectWindow.top - wndPtr->rectClient.top );
-        lps->hdc = GetDCEx(hwnd, hrgnUpdate, DCX_INTERSECTRGN |
+        lps->hdc = GetDCEx(hwnd, hrgnUpdate, DCX_INTERSECTRGN | 
                              DCX_WINDOWPAINT | DCX_USESTYLE | (bIcon ? DCX_WINDOW : 0) );
 	/* ReleaseDC() in EndPaint() will delete the region */
     }
@@ -477,7 +488,7 @@
  *  Validate the portions of parents that are covered by a validated child
  *  wndPtr = child
  */
-void  RDW_ValidateParent(WND *wndChild)  
+static void RDW_ValidateParent(WND *wndChild)
 {
     WND *wndParent = WIN_LockWndPtr(wndChild->parent);
     WND *wndDesktop = WIN_GetDesktop();
@@ -611,15 +622,14 @@
 
 		if( CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate, hRgn, RGN_DIFF )
 		    == NULLREGION )
-		    goto EMPTY;
+                {
+                    DeleteObject( wndPtr->hrgnUpdate );
+                    wndPtr->hrgnUpdate = 0;
+                }
 	    }
 	    else /* validate everything */
 	    {
-		if( wndPtr->hrgnUpdate > 1 )
-		{
-EMPTY:
-		    DeleteObject( wndPtr->hrgnUpdate );
-		}
+		if( wndPtr->hrgnUpdate > 1 ) DeleteObject( wndPtr->hrgnUpdate );
 		wndPtr->hrgnUpdate = 0;
 	    }
 
@@ -757,7 +767,7 @@
         if (wndPtr->hrgnUpdate) /* wm_painticon wparam is 1 */
             SendMessage16( hWnd, (bIcon) ? WM_PAINTICON : WM_PAINT, bIcon, 0 );
     }
-    else if ((flags & RDW_ERASENOW) || (ex & RDW_EX_TOPFRAME))
+    else if (flags & RDW_ERASENOW)
     {
 	UINT dcx = DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN | DCX_WINDOWPAINT | DCX_CACHE;
 	HRGN hrgnRet;
@@ -765,7 +775,6 @@
 	hrgnRet = WIN_UpdateNCRgn(wndPtr, 
 				  hrgn, 
 				  UNC_REGION | UNC_CHECK | 
-				  ((ex & RDW_EX_TOPFRAME) ? UNC_ENTIRE : 0) |
 				  ((ex & RDW_EX_DELAY_NCPAINT) ? UNC_DELAY_NCPAINT : 0) ); 
 
         if( hrgnRet )
@@ -792,7 +801,6 @@
     }
 
     if( !IsWindow(hWnd) ) return hrgn;
-    ex &= ~RDW_EX_TOPFRAME;
 
       /* ... and its child windows */
 
@@ -820,12 +828,12 @@
     return hrgn;
 }
 
+
 /***********************************************************************
- *           PAINT_RedrawWindow
- *
+ *		RedrawWindow (USER32.@)
  */
-BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate,
-                           HRGN hrgnUpdate, UINT flags, UINT ex )
+BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rectUpdate,
+                              HRGN hrgnUpdate, UINT flags )
 {
     HRGN hRgn = 0;
     RECT r, r2;
@@ -848,8 +856,8 @@
 	if( hrgnUpdate )
 	{
 	    GetRgnBox( hrgnUpdate, &r );
-            TRACE( "%04x (%04x) NULL %04x box (%i,%i-%i,%i) flags=%04x, exflags=%04x\n", 
-	          hwnd, wndPtr->hrgnUpdate, hrgnUpdate, r.left, r.top, r.right, r.bottom, flags, ex);
+            TRACE( "%04x (%04x) NULL %04x box (%i,%i-%i,%i) flags=%04x\n",
+	          hwnd, wndPtr->hrgnUpdate, hrgnUpdate, r.left, r.top, r.right, r.bottom, flags );
 	}
 	else
 	{
@@ -857,9 +865,9 @@
 		r = *rectUpdate;
 	    else
 		SetRectEmpty( &r );
-	    TRACE( "%04x (%04x) %s %d,%d-%d,%d %04x flags=%04x, exflags=%04x\n",
+	    TRACE( "%04x (%04x) %s %d,%d-%d,%d %04x flags=%04x\n",
 			hwnd, wndPtr->hrgnUpdate, rectUpdate ? "rect" : "NULL", r.left, 
-			r.top, r.right, r.bottom, hrgnUpdate, flags, ex );
+			r.top, r.right, r.bottom, hrgnUpdate, flags );
 	}
     }
 
@@ -870,17 +878,9 @@
     else
 	r = wndPtr->rectClient;
 
-    if( ex & RDW_EX_XYWINDOW )
-    {
-	pt.x = pt.y = 0;
-        OffsetRect( &r, -wndPtr->rectWindow.left, -wndPtr->rectWindow.top );
-    }
-    else
-    {
-	pt.x = wndPtr->rectClient.left - wndPtr->rectWindow.left;
-	pt.y = wndPtr->rectClient.top - wndPtr->rectWindow.top;
-	OffsetRect( &r, -wndPtr->rectClient.left, -wndPtr->rectClient.top );
-    }
+    pt.x = wndPtr->rectClient.left - wndPtr->rectWindow.left;
+    pt.y = wndPtr->rectClient.top - wndPtr->rectWindow.top;
+    OffsetRect( &r, -wndPtr->rectClient.left, -wndPtr->rectClient.top );
 
     if (flags & RDW_INVALIDATE)  /* ------------------------- Invalidate */
     {
@@ -935,7 +935,6 @@
 	{
 	    if( !IntersectRect( &r2, &r, rectUpdate ) ) goto END;
 		OffsetRect( &r2, pt.x, pt.y );
-rect2v:
 	    hRgn = CreateRectRgnIndirect( &r2 );
 	}
 	else /* entire window or client depending on RDW_FRAME */
@@ -945,7 +944,7 @@
 	    else
 	    {
 		GETCLIENTRECTW( wndPtr, r2 );
-		goto rect2v;
+                hRgn = CreateRectRgnIndirect( &r2 );
             }
         }
     }
@@ -956,7 +955,7 @@
 
     /* Erase/update windows, from now on hRgn is a scratch region */
 
-    hRgn = RDW_Paint( wndPtr, (hRgn == 1) ? 0 : hRgn, flags, ex );
+    hRgn = RDW_Paint( wndPtr, (hRgn == 1) ? 0 : hRgn, flags, 0 );
 
 END:
     if( hRgn > 1 && (hRgn != hrgnUpdate) )
@@ -967,16 +966,6 @@
 
 
 /***********************************************************************
- *		RedrawWindow (USER32.@)
- */
-BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rectUpdate,
-                              HRGN hrgnUpdate, UINT flags )
-{
-    return PAINT_RedrawWindow( hwnd, rectUpdate, hrgnUpdate, flags, 0 );
-}
-
-
-/***********************************************************************
  *		RedrawWindow (USER.290)
  */
 BOOL16 WINAPI RedrawWindow16( HWND16 hwnd, const RECT16 *rectUpdate,
diff --git a/windows/scroll.c b/windows/scroll.c
index dba6111..bf094eb 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -13,10 +13,6 @@
 #include "wingdi.h"
 #include "wine/winuser16.h"
 #include "winuser.h"
-#include "win.h"
-#include "gdi.h"
-#include "dce.h"
-#include "region.h"
 #include "user.h"
 #include "debugtools.h"
 
@@ -79,109 +75,9 @@
                           const RECT *prLClip, HRGN hrgnUpdate,
                           LPRECT rcUpdate )
 {
-    RECT rect, rClip, rSrc;
-    POINT src, dest;
-    DC *dc = DC_GetDCUpdate( hdc );
-
-    TRACE("%04x %d,%d hrgnUpdate=%04x rcUpdate = %p cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d)\n",
-                   (HDC16)hdc, dx, dy, hrgnUpdate, rcUpdate, 
-		   prLClip ? prLClip->left : 0, prLClip ? prLClip->top : 0, prLClip ? prLClip->right : 0, prLClip ? prLClip->bottom : 0,
-		   rc ? rc->left : 0, rc ? rc->top : 0, rc ? rc->right : 0, rc ? rc->bottom : 0 );
-
-    if ( !dc || !hdc ) return FALSE;
-
-/*
-    TRACE(scroll,"\t[wndOrgX=%i, wndExtX=%i, vportOrgX=%i, vportExtX=%i]\n",
-          dc->wndOrgX, dc->wndExtX, dc->vportOrgX, dc->vportExtX );
-    TRACE(scroll,"\t[wndOrgY=%i, wndExtY=%i, vportOrgY=%i, vportExtY=%i]\n",
-	  dc->wndOrgY, dc->wndExtY, dc->vportOrgY, dc->vportExtY );
-*/
-
-    /* compute device clipping region (in device coordinates) */
-
-    if ( rc )
-	rect = *rc;
-    else /* maybe we should just return FALSE? */
-	GetClipBox( hdc, &rect );
-
-    LPtoDP( hdc, (LPPOINT)&rect, 2 );
-
-    if (prLClip)
-    {
-        rClip = *prLClip;
-        LPtoDP( hdc, (LPPOINT)&rClip, 2 );
-	IntersectRect( &rClip, &rect, &rClip );
-    }
-    else
-        rClip = rect;
-
-    dx = XLPTODP ( dc, rect.left + dx ) - XLPTODP ( dc, rect.left );
-    dy = YLPTODP ( dc, rect.top + dy ) - YLPTODP ( dc, rect.top );
-
-    rSrc = rClip;
-    OffsetRect( &rSrc, -dx, -dy );
-    IntersectRect( &rSrc, &rSrc, &rect );
-
-    if(dc->hVisRgn)
-    {
-        if (!IsRectEmpty(&rSrc))
-        {
-            dest.x = (src.x = rSrc.left) + dx;
-            dest.y = (src.y = rSrc.top) + dy;
-
-            /* copy bits */
-    
-            DPtoLP( hdc, (LPPOINT)&rSrc, 2 );
-            DPtoLP( hdc, &src, 1 );
-            DPtoLP( hdc, &dest, 1 );
-
-            if (!BitBlt( hdc, dest.x, dest.y,
-                           rSrc.right - rSrc.left, rSrc.bottom - rSrc.top,
-                           hdc, src.x, src.y, SRCCOPY))
-            {
-                GDI_ReleaseObj( hdc );
-                return FALSE;
-            }
-        }
-
-        /* compute update areas */
-
-        if (hrgnUpdate || rcUpdate)
-        {
-            HRGN hrgn =
-              (hrgnUpdate) ? hrgnUpdate : CreateRectRgn( 0,0,0,0 );
-            HRGN hrgn2;
-
-            hrgn2 = CreateRectRgnIndirect( &rect );
-            OffsetRgn( hrgn2, dc->DCOrgX, dc->DCOrgY );
-            CombineRgn( hrgn2, hrgn2, dc->hVisRgn, RGN_AND );
-            OffsetRgn( hrgn2, -dc->DCOrgX, -dc->DCOrgY );
-            SetRectRgn( hrgn, rClip.left, rClip.top,
-                          rClip.right, rClip.bottom );
-            CombineRgn( hrgn, hrgn, hrgn2, RGN_AND );
-            OffsetRgn( hrgn2, dx, dy );
-            CombineRgn( hrgn, hrgn, hrgn2, RGN_DIFF );
-
-            if( rcUpdate )
-	    {
-		GetRgnBox( hrgn, rcUpdate );
-
-		/* Put the rcUpdate in logical coordinate */
-		DPtoLP( hdc, (LPPOINT)rcUpdate, 2 );
-	    }
-            if (!hrgnUpdate) DeleteObject( hrgn );
-            DeleteObject( hrgn2 );
-
-        }
-    }
-    else
-    {
-       if (hrgnUpdate) SetRectRgn(hrgnUpdate, 0, 0, 0, 0);
-       if (rcUpdate) SetRectEmpty(rcUpdate);
-    }
-
-    GDI_ReleaseObj( hdc );
-    return TRUE;
+    if (USER_Driver.pScrollDC)
+        return USER_Driver.pScrollDC( hdc, dx, dy, rc, prLClip, hrgnUpdate, rcUpdate );
+    return FALSE;
 }
 
 
diff --git a/windows/win.c b/windows/win.c
index 77a73c6..0ad24dc 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -553,6 +553,7 @@
     DWORD clsStyle;
     WNDPROC winproc;
     DCE *dce;
+    CREATESTRUCTA cs;
 
     TRACE("Creating desktop window\n");
 
@@ -601,9 +602,21 @@
     pWndDesktop->cbWndExtra        = wndExtra;
     pWndDesktop->irefCount         = 0;
 
-    if (!USER_Driver.pCreateWindow( hwndDesktop )) return FALSE;
+    cs.lpCreateParams = NULL;
+    cs.hInstance      = 0;
+    cs.hMenu          = 0;
+    cs.hwndParent     = 0;
+    cs.x              = 0;
+    cs.y              = 0;
+    cs.cx             = pWndDesktop->rectWindow.right;
+    cs.cy             = pWndDesktop->rectWindow.bottom;
+    cs.style          = pWndDesktop->dwStyle;
+    cs.dwExStyle      = pWndDesktop->dwExStyle;
+    cs.lpszName       = NULL;
+    cs.lpszClass      = DESKTOP_CLASS_ATOM;
 
-    SendMessageW( hwndDesktop, WM_NCCREATE, 0, 0 );
+    if (!USER_Driver.pCreateWindow( hwndDesktop, &cs )) return FALSE;
+
     pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
     return TRUE;
 }
@@ -685,14 +698,12 @@
     INT sw = SW_SHOW; 
     struct tagCLASS *classPtr;
     WND *wndPtr;
-    HWND retvalue;
-    HWND16 hwnd, hwndLinkAfter;
+    HWND hwnd, hwndLinkAfter;
     POINT maxSize, maxPos, minTrack, maxTrack;
     INT wndExtra;
     DWORD clsStyle;
     WNDPROC winproc;
     DCE *dce;
-    LRESULT CALLBACK (*localSend32)(HWND, UINT, WPARAM, LPARAM);
 
     TRACE("%s %s %08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n",
           (type == WIN_PROC_32W) ? debugres_w((LPWSTR)cs->lpszName) : debugres_a(cs->lpszName), 
@@ -811,7 +822,7 @@
 	    TRACE("CBT-hook returned 0\n");
 	    USER_HEAP_FREE( hwnd );
             CLASS_RemoveWindow( classPtr );
-            retvalue =  0;
+            hwnd =  0;
             goto end;
 	}
     }
@@ -862,12 +873,6 @@
     wndPtr->rectWindow.bottom = cs->y + cs->cy;
     wndPtr->rectClient        = wndPtr->rectWindow;
 
-    if (!USER_Driver.pCreateWindow(wndPtr->hwndSelf))
-    {
-        retvalue = FALSE;
-        goto end;
-    }
-
     /* Set the window menu */
 
     if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
@@ -889,96 +894,44 @@
     }
     else wndPtr->wIDmenu = (UINT)cs->hMenu;
 
-    /* Send the WM_CREATE message 
-     * Perhaps we shouldn't allow width/height changes as well. 
-     * See p327 in "Internals". 
-     */
-
-    maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
-
-    localSend32 = (type == WIN_PROC_32W) ? SendMessageW : SendMessageA;
-    if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
+    if (!USER_Driver.pCreateWindow( wndPtr->hwndSelf, cs ))
     {
-        /* Insert the window in the linked list */
-
-        WIN_LinkWindow( hwnd, hwndLinkAfter );
-
-        WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
-                               NULL, NULL, 0, &wndPtr->rectClient );
-        OffsetRect(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
-                                          maxPos.y - wndPtr->rectWindow.top);
-        if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
-        {
-            /* Send the size messages */
-
-            if (!(wndPtr->flags & WIN_NEED_SIZE))
-            {
-                /* send it anyway */
-	        if (((wndPtr->rectClient.right-wndPtr->rectClient.left) <0)
-		    ||((wndPtr->rectClient.bottom-wndPtr->rectClient.top)<0))
-		  WARN("sending bogus WM_SIZE message 0x%08lx\n",
-			MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
-				 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
-                (*localSend32)( hwnd, WM_SIZE, SIZE_RESTORED,
-                                MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
-                                         wndPtr->rectClient.bottom-wndPtr->rectClient.top));
-                (*localSend32)( hwnd, WM_MOVE, 0,
-                                MAKELONG( wndPtr->rectClient.left,
-                                          wndPtr->rectClient.top ) );
-            }
-
-            /* Show the window, maximizing or minimizing if needed */
-
-            if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
-            {
-		RECT16 newPos;
-		UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
-                wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
-		WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
-                swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow())
-                    ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
-                    : SWP_NOZORDER | SWP_FRAMECHANGED;
-                SetWindowPos( hwnd, 0, newPos.left, newPos.top,
-                                newPos.right, newPos.bottom, swFlag );
-            }
-
-	    if( (wndPtr->dwStyle & WS_CHILD) && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
-	    {
-		/* Notify the parent window only */
-
-		SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
-				MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
-                if( !IsWindow(hwnd) )
-                {
-                    retvalue = 0;
-                    goto end;
-                }
-	    }
-
-            if (cs->style & WS_VISIBLE) ShowWindow( hwnd, sw );
-
-            /* Call WH_SHELL hook */
-
-            if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
-                HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
-
-            TRACE("created window %04x\n", hwnd);
-            retvalue = hwnd;
-            goto end;
-        }
-        WIN_UnlinkWindow( hwnd );
+        WARN("aborted by WM_xxCREATE!\n");
+        WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
+        CLASS_RemoveWindow( classPtr );
+        WIN_ReleaseWndPtr(wndPtr);
+        return 0;
     }
 
-    /* Abort window creation */
+    if( (wndPtr->dwStyle & WS_CHILD) && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
+    {
+        /* Notify the parent window only */
 
-    WARN("aborted by WM_xxCREATE!\n");
-    WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
-    CLASS_RemoveWindow( classPtr );
-    retvalue = 0;
-end:
+        SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
+                      MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
+        if( !IsWindow(hwnd) )
+        {
+            hwnd = 0;
+            goto end;
+        }
+    }
+
+    if (cs->style & WS_VISIBLE)
+    {
+        /* in case WS_VISIBLE got set in the meantime */
+        wndPtr->dwStyle &= ~WS_VISIBLE;
+        ShowWindow( hwnd, sw );
+    }
+
+    /* Call WH_SHELL hook */
+
+    if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
+        HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
+
+    TRACE("created window %04x\n", hwnd);
+ end:
     WIN_ReleaseWndPtr(wndPtr);
-
-    return retvalue;
+    return hwnd;
 }
 
 
@@ -2176,8 +2129,12 @@
  */
 INT WINAPI InternalGetWindowText(HWND hwnd,LPWSTR lpString,INT nMaxCount )
 {
-    FIXME("(0x%08x,%p,0x%x),stub!\n",hwnd,lpString,nMaxCount);
-    return GetWindowTextW(hwnd,lpString,nMaxCount);
+    WND *win = WIN_FindWndPtr( hwnd );
+    if (!win) return 0;
+    if (win->text) lstrcpynW( lpString, win->text, nMaxCount );
+    else lpString[0] = 0;
+    WIN_ReleaseWndPtr( win );
+    return strlenW(lpString);
 }
 
 
diff --git a/windows/winpos.c b/windows/winpos.c
index ae3e946..42e87c3 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -42,8 +42,6 @@
 #define PLACE_MAX		0x0002
 #define PLACE_RECT		0x0004
 
-#define MINMAX_NOSWP		0x00010000
-
 
 #define DWP_MAGIC  ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
 
@@ -119,58 +117,6 @@
 }
 
 /***********************************************************************
- *           WINPOS_FindIconPos
- *
- * Find a suitable place for an iconic window.
- */
-static POINT16 WINPOS_FindIconPos( WND* wndPtr, POINT16 pt )
-{
-    RECT16 rectParent;
-    short x, y, xspacing, yspacing;
-
-    GetClientRect16( wndPtr->parent->hwndSelf, &rectParent );
-    if ((pt.x >= rectParent.left) && (pt.x + GetSystemMetrics(SM_CXICON) < rectParent.right) &&
-        (pt.y >= rectParent.top) && (pt.y + GetSystemMetrics(SM_CYICON) < rectParent.bottom))
-        return pt;  /* The icon already has a suitable position */
-
-    xspacing = GetSystemMetrics(SM_CXICONSPACING);
-    yspacing = GetSystemMetrics(SM_CYICONSPACING);
-
-    y = rectParent.bottom;
-    for (;;)
-    {
-        x = rectParent.left;
-        do 
-        {
-              /* Check if another icon already occupies this spot */
-            WND *childPtr = WIN_LockWndPtr(wndPtr->parent->child);
-            while (childPtr)
-            {
-                if ((childPtr->dwStyle & WS_MINIMIZE) && (childPtr != wndPtr))
-                {
-                    if ((childPtr->rectWindow.left < x + xspacing) &&
-                        (childPtr->rectWindow.right >= x) &&
-                        (childPtr->rectWindow.top <= y) &&
-                        (childPtr->rectWindow.bottom > y - yspacing))
-                        break;  /* There's a window in there */
-                }
-                WIN_UpdateWndPtr(&childPtr,childPtr->next);
-            }
-            WIN_ReleaseWndPtr(childPtr);
-            if (!childPtr) /* No window was found, so it's OK for us */
-            {
-		pt.x = x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
-		pt.y = y - (yspacing + GetSystemMetrics(SM_CYICON)) / 2;
-		return pt;
-            }
-	    x += xspacing;
-        } while(x <= rectParent.right-xspacing);
-        y -= yspacing;
-    }
-}
-
-
-/***********************************************************************
  *		ArrangeIconicWindows (USER.170)
  */
 UINT16 WINAPI ArrangeIconicWindows16( HWND16 parent) 
@@ -440,7 +386,8 @@
         MapWindowPoints( GetDesktopWindow(), wndScope->parent->hwndSelf, &xy, 1 );
 
     if (xy.x < wndScope->rectClient.left || pt.x >= wndScope->rectClient.right ||
-        xy.y < wndScope->rectClient.top || pt.y >= wndScope->rectClient.bottom)
+        xy.y < wndScope->rectClient.top || pt.y >= wndScope->rectClient.bottom ||
+        wndScope->dwStyle & WS_MINIMIZE)
         goto hittest;
 
     xy.x -= wndScope->rectClient.left;
@@ -1154,8 +1101,7 @@
     MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
     MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
 
-    if (wndPtr->dwExStyle & WS_EX_MANAGED) xinc = yinc = 0;
-    else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+    if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
     {
         xinc = GetSystemMetrics(SM_CXDLGFRAME);
         yinc = GetSystemMetrics(SM_CYDLGFRAME);
@@ -1207,107 +1153,6 @@
 }
 
 /***********************************************************************
- *           WINPOS_MinMaximize
- *
- * Fill in lpRect and return additional flags to be used with SetWindowPos().
- * This function assumes that 'cmd' is different from the current window
- * state.
- */
-UINT WINPOS_MinMaximize( WND* wndPtr, UINT16 cmd, LPRECT16 lpRect )
-{
-    UINT swpFlags = 0;
-    POINT pt, size;
-    LPINTERNALPOS lpPos;
-
-    TRACE("0x%04x %u\n", wndPtr->hwndSelf, cmd );
-
-    size.x = wndPtr->rectWindow.left; size.y = wndPtr->rectWindow.top;
-    lpPos = WINPOS_InitInternalPos( wndPtr, size, &wndPtr->rectWindow );
-
-    if (lpPos && !HOOK_CallHooksA(WH_CBT, HCBT_MINMAX, wndPtr->hwndSelf, cmd))
-    {
-	if( wndPtr->dwStyle & WS_MINIMIZE )
-	{
-	    if( !SendMessageA( wndPtr->hwndSelf, WM_QUERYOPEN, 0, 0L ) )
-		return (SWP_NOSIZE | SWP_NOMOVE);
-	    swpFlags |= SWP_NOCOPYBITS;
-	}
-	switch( cmd )
-	{
-	    case SW_MINIMIZE:
-		 if( wndPtr->dwStyle & WS_MAXIMIZE)
-		 {
-		     wndPtr->flags |= WIN_RESTORE_MAX;
-		     wndPtr->dwStyle &= ~WS_MAXIMIZE;
-                 }
-                 else
-		     wndPtr->flags &= ~WIN_RESTORE_MAX;
-		 wndPtr->dwStyle |= WS_MINIMIZE;
-
-                 if( wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
-                     swpFlags |= MINMAX_NOSWP;
-
-		 lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
-
-		 SetRect16( lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
-				    GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
-		 swpFlags |= SWP_NOCOPYBITS;
-		 break;
-
-	    case SW_MAXIMIZE:
-                CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
-                WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL );
-                CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
-
-		 if( wndPtr->dwStyle & WS_MINIMIZE )
-		 {
-                     wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE );
-
-		     WINPOS_ShowIconTitle( wndPtr, FALSE );
-		     wndPtr->dwStyle &= ~WS_MINIMIZE;
-		 }
-                 wndPtr->dwStyle |= WS_MAXIMIZE;
-
-		 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
-				    size.x, size.y );
-		 break;
-
-	    case SW_RESTORE:
-		 if( wndPtr->dwStyle & WS_MINIMIZE )
-		 {
-                     wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE );
-
-		     wndPtr->dwStyle &= ~WS_MINIMIZE;
-		     WINPOS_ShowIconTitle( wndPtr, FALSE );
-
-		     if( wndPtr->flags & WIN_RESTORE_MAX)
-		     {
-			 /* Restore to maximized position */
-                         CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
-                         WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL);
-                         CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
-			 wndPtr->dwStyle |= WS_MAXIMIZE;
-			 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y, size.x, size.y );
-			 break;
-		     }
-		 } 
-		 else 
-		     if( !(wndPtr->dwStyle & WS_MAXIMIZE) ) return (UINT16)(-1);
- 		     else wndPtr->dwStyle &= ~WS_MAXIMIZE;
-
-		 /* Restore to normal position */
-
-		*lpRect = lpPos->rectNormal; 
-		 lpRect->right -= lpRect->left; 
-		 lpRect->bottom -= lpRect->top;
-
-		 break;
-	}
-    } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
-    return swpFlags;
-}
-
-/***********************************************************************
  *		ShowWindowAsync (USER32.@)
  *
  * doesn't wait; returns immediately.
@@ -1332,140 +1177,9 @@
 /***********************************************************************
  *		ShowWindow (USER32.@)
  */
-BOOL WINAPI ShowWindow( HWND hwnd, INT cmd ) 
-{    
-    WND* 	wndPtr = WIN_FindWndPtr( hwnd );
-    BOOL 	wasVisible, showFlag;
-    RECT16 	newPos = {0, 0, 0, 0};
-    UINT 	swp = 0;
-
-    if (!wndPtr) return FALSE;
-
-    TRACE("hwnd=%04x, cmd=%d\n", hwnd, cmd);
-
-    wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
-
-    switch(cmd)
-    {
-        case SW_HIDE:
-            if (!wasVisible) goto END;;
-	    swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | 
-		        SWP_NOACTIVATE | SWP_NOZORDER;
-	    break;
-
-	case SW_SHOWMINNOACTIVE:
-            swp |= SWP_NOACTIVATE | SWP_NOZORDER;
-            /* fall through */
-	case SW_SHOWMINIMIZED:
-            swp |= SWP_SHOWWINDOW;
-            /* fall through */
-	case SW_MINIMIZE:
-            swp |= SWP_FRAMECHANGED;
-            if( !(wndPtr->dwStyle & WS_MINIMIZE) )
-		 swp |= WINPOS_MinMaximize( wndPtr, SW_MINIMIZE, &newPos );
-            else swp |= SWP_NOSIZE | SWP_NOMOVE;
-	    break;
-
-	case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
-            swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
-            if( !(wndPtr->dwStyle & WS_MAXIMIZE) )
-		 swp |= WINPOS_MinMaximize( wndPtr, SW_MAXIMIZE, &newPos );
-            else swp |= SWP_NOSIZE | SWP_NOMOVE;
-            break;
-
-	case SW_SHOWNA:
-            swp |= SWP_NOACTIVATE | SWP_NOZORDER;
-            /* fall through */
-	case SW_SHOW:
-	    swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
-
-	    /*
-	     * ShowWindow has a little peculiar behavior that if the
-	     * window is already the topmost window, it will not
-	     * activate it.
-	     */
-	    if (GetTopWindow((HWND)0)==hwnd && (wasVisible || GetActiveWindow() == hwnd))
-	      swp |= SWP_NOACTIVATE;
-
-	    break;
-
-	case SW_SHOWNOACTIVATE:
-            swp |= SWP_NOZORDER;
-            if (GetActiveWindow()) swp |= SWP_NOACTIVATE;
-            /* fall through */
-	case SW_SHOWNORMAL:  /* same as SW_NORMAL: */
-	case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
-	case SW_RESTORE:
-	    swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
-
-            if( wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE) )
-		 swp |= WINPOS_MinMaximize( wndPtr, SW_RESTORE, &newPos );
-            else swp |= SWP_NOSIZE | SWP_NOMOVE;
-	    break;
-    }
-
-    showFlag = (cmd != SW_HIDE);
-    if (showFlag != wasVisible)
-    {
-        SendMessageA( hwnd, WM_SHOWWINDOW, showFlag, 0 );
-        if (!IsWindow( hwnd )) goto END;
-    }
-
-    if ((wndPtr->dwStyle & WS_CHILD) &&
-        !IsWindowVisible( wndPtr->parent->hwndSelf ) &&
-        (swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE) )
-    {
-        /* Don't call SetWindowPos() on invisible child windows */
-        if (cmd == SW_HIDE) wndPtr->dwStyle &= ~WS_VISIBLE;
-        else wndPtr->dwStyle |= WS_VISIBLE;
-    }
-    else
-    {
-        /* We can't activate a child window */
-        if ((wndPtr->dwStyle & WS_CHILD) &&
-            !(wndPtr->dwExStyle & WS_EX_MDICHILD))
-            swp |= SWP_NOACTIVATE | SWP_NOZORDER;
-	if (!(swp & MINMAX_NOSWP))
-        {
-	    SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top, 
-					  newPos.right, newPos.bottom, LOWORD(swp) );
-            if (cmd == SW_HIDE)
-            {
-               /* FIXME: This will cause the window to be activated irrespective
-                * of whether it is owned by the same thread. Has to be done
-                * asynchronously.
-                */
-
-               if (hwnd == GetActiveWindow())
-                  WINPOS_ActivateOtherWindow(wndPtr);
-
-               /* Revert focus to parent */
-               if (hwnd == GetFocus() || IsChild(hwnd, GetFocus()))
-                  SetFocus( GetParent(hwnd) );
-            }
-        }
-        if (!IsWindow( hwnd )) goto END;
-	else if( wndPtr->dwStyle & WS_MINIMIZE ) WINPOS_ShowIconTitle( wndPtr, TRUE );
-    }
-
-    if (wndPtr->flags & WIN_NEED_SIZE)
-    {
-        /* should happen only in CreateWindowEx() */
-	int wParam = SIZE_RESTORED;
-
-	wndPtr->flags &= ~WIN_NEED_SIZE;
-	if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
-	else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
-	SendMessageA( hwnd, WM_SIZE, wParam,
-		     MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
-			    wndPtr->rectClient.bottom-wndPtr->rectClient.top));
-	SendMessageA( hwnd, WM_MOVE, 0,
-		   MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
-    }
-
-END:
-    WIN_ReleaseWndPtr(wndPtr);
-    return wasVisible;
+BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
+{
+    return USER_Driver.pShowWindow( hwnd, cmd );
 }
 
 
diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c
index 9de7f5f..b115853 100644
--- a/windows/x11drv/clipboard.c
+++ b/windows/x11drv/clipboard.c
@@ -315,7 +315,6 @@
     Display *display = thread_display();
     HWND           hWnd = 0;
     HWND           hWndClipWindow = GetOpenClipboardWindow();
-    WND*           wnd = NULL;
     XEvent         xe;
     Atom           aTargets;
     Atom           atype=AnyPropertyType;
@@ -343,10 +342,7 @@
     /*
      * Query the selection owner for the TARGETS property
      */
-    wnd = WIN_FindWndPtr(hWnd);
-    w = X11DRV_WND_FindXWindow(wnd);
-    WIN_ReleaseWndPtr(wnd);
-    wnd = NULL;
+    w = X11DRV_get_top_window(hWnd);
 
     aTargets = TSXInternAtom(display, "TARGETS", False);
 
@@ -863,9 +859,7 @@
     if ( !(selectionAcquired == (S_PRIMARY | S_CLIPBOARD)) )
     {
         Atom xaClipboard = TSXInternAtom(display, _CLIPBOARD, False);
-        WND *tmpWnd = WIN_FindWndPtr( hWndClipWindow ? hWndClipWindow : AnyPopup() );
-        owner = X11DRV_WND_FindXWindow(tmpWnd );
-        WIN_ReleaseWndPtr(tmpWnd);
+        owner = X11DRV_get_top_window( hWndClipWindow ? hWndClipWindow : AnyPopup() );
 
         /* Grab PRIMARY selection if not owned */
         if ( !(selectionAcquired & S_PRIMARY) )
@@ -1012,18 +1006,15 @@
     BOOL bRet = selectionAcquired;
     HWND hWndClipWindow = GetOpenClipboardWindow();
     HWND hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow();
-    WND* wnd = NULL;
     LPWINE_CLIPFORMAT lpFormat;
 
     TRACE("%d\n", wFormat);
 
-    if( !selectionAcquired && (wnd = WIN_FindWndPtr(hWnd)) )
+    if (!selectionAcquired)
     {
 	XEvent xe;
         Atom propRequest;
-	Window w = X11DRV_WND_FindXWindow(wnd);
-        WIN_ReleaseWndPtr(wnd);
-        wnd = NULL;
+	Window w = X11DRV_get_top_window(hWnd);
 
         /* Map the format ID requested to an X selection property.
          * If the format is in the cache, use the atom associated
@@ -1089,7 +1080,7 @@
 {
     Display *display = thread_display();
     HWND hWndClipOwner = 0;
-    Window XWnd = X11DRV_WND_GetXWindow(pWnd);
+    Window XWnd = get_whole_window(pWnd);
     Atom xaClipboard;
     BOOL bLostSelection = FALSE;
 
@@ -1118,10 +1109,10 @@
     selectionWindow = None;
 
     if( pWnd->next ) 
-        selectionWindow = X11DRV_WND_GetXWindow(pWnd->next);
+        selectionWindow = get_whole_window(pWnd->next);
     else if( pWnd->parent )
          if( pWnd->parent->child != pWnd ) 
-             selectionWindow = X11DRV_WND_GetXWindow(pWnd->parent->child);
+             selectionWindow = get_whole_window(pWnd->parent->child);
 
     if( selectionWindow != None )
     {
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c
index 9757619..5ac098a 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -51,7 +51,7 @@
 extern Atom dndSelection;
 
 extern void X11DRV_KEYBOARD_UpdateState(void);
-extern void X11DRV_KEYBOARD_HandleEvent(WND *pWnd, XKeyEvent *event);
+extern void X11DRV_KEYBOARD_HandleEvent( XKeyEvent *event, int x, int y );
 
 #define NB_BUTTONS      5     /* Windows can handle 3 buttons and the wheel too */
 
@@ -97,16 +97,16 @@
 static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event );
 static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event );
 static void EVENT_Expose( HWND hWnd, XExposeEvent *event );
-static void EVENT_GraphicsExpose( HWND hWnd, XGraphicsExposeEvent *event );
-static void EVENT_ConfigureNotify( HWND hWnd, XConfigureEvent *event );
 static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple );
 static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event);
 static void EVENT_PropertyNotify( XPropertyEvent *event );
 static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event );
-static void EVENT_MapNotify( HWND pWnd, XMapEvent *event );
-static void EVENT_UnmapNotify( HWND pWnd, XUnmapEvent *event );
 static void EVENT_MappingNotify( XMappingEvent *event );
 
+extern void X11DRV_MapNotify( HWND hwnd, XMapEvent *event );
+extern void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event );
+extern void X11DRV_ConfigureNotify( HWND hwnd, XConfigureEvent *event );
+
 #ifdef HAVE_LIBXXF86DGA2
 static int DGAMotionEventType;
 static int DGAButtonPressEventType;
@@ -122,14 +122,6 @@
 static void EVENT_DGAButtonReleaseEvent( XDGAButtonEvent *event );
 #endif
 
-/* Usable only with OLVWM - compile option perhaps?
-static void EVENT_EnterNotify( HWND hWnd, XCrossingEvent *event );
-*/
-
-static void EVENT_GetGeometry( Display *display, Window win, int *px, int *py,
-                               unsigned int *pwidth, unsigned int *pheight );
-
-
 /* Static used for the current input method */
 static INPUT_TYPE current_input_type = X11DRV_INPUT_ABSOLUTE;
 static BOOL in_transition = FALSE; /* This is not used as for today */
@@ -138,31 +130,22 @@
 /***********************************************************************
  *           process_events
  */
-static void process_events( Display *display )
+static int process_events( struct x11drv_thread_data *data )
 {
     XEvent event;
+    int count = 0;
 
     wine_tsx11_lock();
-    while ( XPending( display ) )
+    while ( XPending( data->display ) )
     {
-        XNextEvent( display, &event );
+        XNextEvent( data->display, &event );
         wine_tsx11_unlock();
         EVENT_ProcessEvent( &event );
+        count++;
         wine_tsx11_lock();
     }
     wine_tsx11_unlock();
-}
-
-/***********************************************************************
- *		X11DRV_Synchronize
- *
- * Synchronize with the X server. Should not be used too often.
- */
-void X11DRV_Synchronize( void )
-{
-    Display *display = thread_display();
-    TSXSync( display, False );
-    process_events( display );
+    return count;
 }
 
 
@@ -183,14 +166,19 @@
     for (i = 0; i < count; i++) new_handles[i] = handles[i];
     new_handles[count] = data->display_fd;
 
-    data->process_event_count++;
     wine_tsx11_lock();
     XFlush( gdi_display );
     XFlush( data->display );
     wine_tsx11_unlock();
-    ret = WaitForMultipleObjectsEx( count+1, new_handles, flags & MWMO_WAITALL,
-                                    timeout, flags & MWMO_ALERTABLE );
-    if (ret == count) process_events( data->display );
+
+    data->process_event_count++;
+    if (process_events( data )) ret = count;
+    else
+    {
+        ret = WaitForMultipleObjectsEx( count+1, new_handles, flags & MWMO_WAITALL,
+                                        timeout, flags & MWMO_ALERTABLE );
+        if (ret == count) process_events( data );
+    }
     data->process_event_count--;
     return ret;
 }
@@ -272,33 +260,20 @@
       ke.keycode = evt->keycode;
       ke.same_screen = TRUE;
       
-      X11DRV_KEYBOARD_HandleEvent(NULL, &ke);
+      X11DRV_KEYBOARD_HandleEvent(&ke,pt.x,pt.y);
       return;
     }
   }
 #endif
-  
-  if ( TSXFindContext( display, event->xany.window, winContext,
-		       (char **)&hWnd ) != 0) {
-    if ( event->type == ClientMessage) {
-      /* query window (drag&drop event contains only drag window) */
-      Window   	root, child;
-      int      	root_x, root_y, child_x, child_y;
-      unsigned	u;
-      TSXQueryPointer( display, root_window, &root, &child,
-		       &root_x, &root_y, &child_x, &child_y, &u);
-      if (TSXFindContext( display, child, winContext, (char **)&hWnd ) != 0)
-	return;
-    } else {
+
+  if (TSXFindContext( display, event->xany.window, winContext, (char **)&hWnd ) != 0)
       hWnd = 0;  /* Not for a registered window */
-    }
-  }
 
   if ( !hWnd && event->xany.window != root_window
              && event->type != PropertyNotify 
              && event->type != MappingNotify)
-      ERR("Got event %s for unknown Window %08lx\n",
-          event_names[event->type], event->xany.window );
+      WARN( "Got event %s for unknown Window %08lx\n",
+            event_names[event->type], event->xany.window );
   else
       TRACE("Got event %s for hwnd %04x\n",
             event_names[event->type], hWnd );
@@ -334,65 +309,22 @@
 					MotionNotify, event));    
       EVENT_MotionNotify( hWnd, (XMotionEvent*)event );
       break;
-      
+
     case FocusIn:
-    {
-      WND *pWndLastFocus = 0;
-      XWindowAttributes win_attr;
-      BOOL bIsDisabled;
-      XFocusChangeEvent *xfocChange = (XFocusChangeEvent*)event;
-
-      if (!hWnd) return;
-
-      bIsDisabled = GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED;
-
-      /* If the window has been disabled and we are in managed mode,
-       * revert the X focus back to the last focus window. This is to disallow
-       * the window manager from switching focus away while the app is
-       * in a modal state.
-       */
-      if ( Options.managed && bIsDisabled && glastXFocusWin)
-      {
-        /* Change focus only if saved focus window is registered and viewable */
-        if ( TSXFindContext( xfocChange->display, glastXFocusWin, winContext,
-                             (char **)&pWndLastFocus ) == 0 )
-        {
-          if ( TSXGetWindowAttributes( display, glastXFocusWin, &win_attr ) &&
-                 (win_attr.map_state == IsViewable) )
-          {
-            TSXSetInputFocus( xfocChange->display, glastXFocusWin, RevertToParent, CurrentTime );
-            X11DRV_Synchronize();
-            break;
-          }
-        }
-      }
-       
-      EVENT_FocusIn( hWnd, xfocChange );
+      EVENT_FocusIn( hWnd, (XFocusChangeEvent*)event );
       break;
-    }
-      
+
     case FocusOut:
-    {
-      /* Save the last window which had the focus */
-      XFocusChangeEvent *xfocChange = (XFocusChangeEvent*)event;
-      glastXFocusWin = xfocChange->window;
-      if (!hWnd) return;
-      if (GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED) glastXFocusWin = 0;
       EVENT_FocusOut( hWnd, (XFocusChangeEvent*)event );
       break;
-    }
-      
+
     case Expose:
-      EVENT_Expose( hWnd, (XExposeEvent *)event );
+      EVENT_Expose( hWnd, &event->xexpose );
       break;
-      
-    case GraphicsExpose:
-      EVENT_GraphicsExpose( hWnd, (XGraphicsExposeEvent *)event );
-      break;
-      
+
     case ConfigureNotify:
       if (!hWnd) return;
-      EVENT_ConfigureNotify( hWnd, (XConfigureEvent*)event );
+      X11DRV_ConfigureNotify( hWnd, &event->xconfigure );
       break;
 
     case SelectionRequest:
@@ -414,23 +346,15 @@
       EVENT_ClientMessage( hWnd, (XClientMessageEvent *) event );
       break;
 
-#if 0
-    case EnterNotify:
-      EVENT_EnterNotify( hWnd, (XCrossingEvent *) event );
-      break;
-#endif
-
     case NoExpose:
       break;
-      
+
     case MapNotify:
-      if (!hWnd) return;
-      EVENT_MapNotify( hWnd, (XMapEvent *)event );
+      X11DRV_MapNotify( hWnd, (XMapEvent *)event );
       break;
 
     case UnmapNotify:
-      if (!hWnd) return;
-      EVENT_UnmapNotify( hWnd, (XUnmapEvent *)event );
+      X11DRV_UnmapNotify( hWnd, (XUnmapEvent *)event );
       break;
 
     case MappingNotify:
@@ -446,136 +370,6 @@
 }
 
 /***********************************************************************
- *           EVENT_QueryZOrder
- *
- * Synchronize internal z-order with the window manager's.
- */
-static BOOL __check_query_condition( WND** pWndA, WND** pWndB )
-{
-  /* return TRUE if we have at least two managed windows */
-  
-  for( *pWndB = NULL; *pWndA; *pWndA = (*pWndA)->next )
-    if( ((*pWndA)->dwExStyle & WS_EX_MANAGED) &&
-	((*pWndA)->dwStyle & WS_VISIBLE )) break;
-  if( *pWndA )
-    for( *pWndB = (*pWndA)->next; *pWndB; *pWndB = (*pWndB)->next )
-      if( ((*pWndB)->dwExStyle & WS_EX_MANAGED) &&
-	  ((*pWndB)->dwStyle & WS_VISIBLE )) break;
-  return ((*pWndB) != NULL);
-}
-
-static Window __get_common_ancestor( Display *display, Window A, Window B,
-                                     Window** children, unsigned* total )
-{
-    /* find the real root window */
-  
-    Window      root, *childrenB;
-    unsigned    totalB;
-
-    while( A != B && A && B )
-    {
-      TSXQueryTree( display, A, &root, &A, children, total );
-      TSXQueryTree( display, B, &root, &B, &childrenB, &totalB );
-      if( childrenB ) TSXFree( childrenB );
-      if( *children ) TSXFree( *children ), *children = NULL;
-    }
-
-    if( A && B )
-    {
-	TSXQueryTree( display, A, &root, &B, children, total );
-	return A;
-    }
-    return 0 ;
-}
-
-static Window __get_top_decoration( Display *display, Window w, Window ancestor )
-{
-  Window*     children, root, prev = w, parent = w;
-  unsigned    total;
-  
-  do
-    {
-      w = parent;
-      TSXQueryTree( display, w, &root, &parent, &children, &total );
-      if( children ) TSXFree( children );
-    } while( parent && parent != ancestor );
-  TRACE("\t%08x -> %08x\n", (unsigned)prev, (unsigned)w );
-  return ( parent ) ? w : 0 ;
-}
-
-static unsigned __td_lookup( Window w, Window* list, unsigned max )
-{
-  unsigned    i;
-  for( i = max - 1; i >= 0; i-- ) if( list[i] == w ) break;
-  return i;
-}
-
-static HWND EVENT_QueryZOrder( Display *display, HWND hWndCheck)
-{
-  HWND      hwndInsertAfter = HWND_TOP;
-  WND      *pWndCheck = WIN_FindWndPtr(hWndCheck);
-  WND      *pDesktop = WIN_GetDesktop();
-  WND      *pWnd, *pWndZ = WIN_LockWndPtr(pDesktop->child);
-  Window      w, parent, *children = NULL;
-  unsigned    total, check, pos, best;
-  
-  if( !__check_query_condition(&pWndZ, &pWnd) )
-  {
-      WIN_ReleaseWndPtr(pWndCheck);
-      WIN_ReleaseWndPtr(pDesktop->child);
-      WIN_ReleaseDesktop();
-      return hwndInsertAfter;
-  }
-  WIN_LockWndPtr(pWndZ);
-  WIN_LockWndPtr(pWnd);
-  WIN_ReleaseWndPtr(pDesktop->child);
-  WIN_ReleaseDesktop();
-  
-  parent = __get_common_ancestor( display, X11DRV_WND_GetXWindow(pWndZ),
-				  X11DRV_WND_GetXWindow(pWnd),
-				  &children, &total );
-  if( parent && children )
-  {
-      /* w is the ancestor if pWndCheck that is a direct descendant of 'parent' */
-
-      w = __get_top_decoration( display, X11DRV_WND_GetXWindow(pWndCheck), parent );
-
-      if( w != children[total-1] ) /* check if at the top */
-      {
-	  /* X child at index 0 is at the bottom, at index total-1 is at the top */
-	  check = __td_lookup( w, children, total );
-	  best = total;
-
-          for( WIN_UpdateWndPtr(&pWnd,pWndZ); pWnd;WIN_UpdateWndPtr(&pWnd,pWnd->next))
-          {
-	      /* go through all windows in Wine z-order... */
-
-	      if( pWnd != pWndCheck )
-              {
-		  if( !(pWnd->dwExStyle & WS_EX_MANAGED) ||
-		      !(w = __get_top_decoration( display, X11DRV_WND_GetXWindow(pWnd), parent )) )
-		    continue;
-		  pos = __td_lookup( w, children, total );
-		  if( pos < best && pos > check )
-                  {
-		      /* find a nearest Wine window precedes 
-		       * pWndCheck in the real z-order... */
-		      best = pos;
-		      hwndInsertAfter = pWnd->hwndSelf;
-                  }
-		  if( best - check == 1 ) break;
-              }
-          }
-      }
-  }
-  if( children ) TSXFree( children );
-  WIN_ReleaseWndPtr(pWnd);
-  WIN_ReleaseWndPtr(pWndZ);
-  WIN_ReleaseWndPtr(pWndCheck);
-  return hwndInsertAfter;
-}
-
-/***********************************************************************
  *           X11DRV_EVENT_XStateToKeyState
  *
  * Translate a X event state (Button1Mask, ShiftMask, etc...) to
@@ -593,62 +387,74 @@
   return kstate;
 }
 
+
 /***********************************************************************
  *           EVENT_Expose
  */
-static void EVENT_Expose( HWND hWnd, XExposeEvent *event )
+static void EVENT_Expose( HWND hwnd, XExposeEvent *event )
 {
-  RECT rect;
-  int  offx = 0,offy = 0;
+    RECT rect;
+    struct x11drv_win_data *data;
+    int flags = RDW_INVALIDATE | RDW_ERASE;
+    WND *win;
 
-  WND *pWnd = WIN_FindWndPtr(hWnd);
-  /* Make position relative to client area instead of window */
-  offx =  (pWnd? (pWnd->rectClient.left - pWnd->rectWindow.left) : 0);
-  offy =  (pWnd? (pWnd->rectClient.top - pWnd->rectWindow.top) : 0);
+    TRACE( "win %x (%lx) %d,%d %dx%d\n",
+           hwnd, event->window, event->x, event->y, event->width, event->height );
 
-  rect.left   = event->x - offx;
-  rect.top    = event->y - offy;
+    rect.left   = event->x;
+    rect.top    = event->y;
+    rect.right  = rect.left + event->width;
+    rect.bottom = rect.top + event->height;
 
-  rect.right  = rect.left + event->width;
-  rect.bottom = rect.top + event->height;
+    if (!(win = WIN_FindWndPtr(hwnd))) return;
+    data = win->pDriverData;
 
-  WIN_ReleaseWndPtr(pWnd);
+    if (event->window != data->client_window)  /* whole window or icon window */
+    {
+        flags |= RDW_FRAME;
+        /* make position relative to client area instead of window */
+        OffsetRect( &rect, -data->client_rect.left, -data->client_rect.top );
+    }
 
-  RedrawWindow( hWnd, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
-
-  if (event->count == 0)
-    SendNotifyMessageA(hWnd,WM_SYNCPAINT, 0, 0);
+    /* find the top level parent that doesn't clip children and invalidate the area */
+    /* on the parent (which will invalidate all the children too) */
+    while (win->parent && win->parent->hwndSelf != GetDesktopWindow() &&
+           !(win->parent->dwStyle & WS_CLIPCHILDREN))
+    {
+        OffsetRect( &rect, win->rectClient.left, win->rectClient.top );
+        WIN_UpdateWndPtr( &win, win->parent );
+        flags &= ~RDW_FRAME;  /* parent will invalidate children frame anyway */
+    }
+    hwnd = win->hwndSelf;
+    WIN_ReleaseWndPtr(win);
+    RedrawWindow( hwnd, &rect, 0, flags );
 }
 
 
-/***********************************************************************
- *           EVENT_GraphicsExpose
- *
- * This is needed when scrolling area is partially obscured
- * by non-Wine X window.
- */
-static void EVENT_GraphicsExpose( HWND hWnd, XGraphicsExposeEvent *event )
+/* get the coordinates of a mouse event */
+static void get_coords( HWND *hwnd, Window window, int x, int y, POINT *pt )
 {
-  RECT rect;
-  int  offx = 0,offy = 0;
+    struct x11drv_win_data *data;
+    WND *win;
 
-  WND *pWnd = WIN_FindWndPtr(hWnd);
-  /* Make position relative to client area instead of window */
-  offx =  (pWnd? (pWnd->rectClient.left - pWnd->rectWindow.left) : 0);
-  offy =  (pWnd? (pWnd->rectClient.top - pWnd->rectWindow.top) : 0);
+    if (!(win = WIN_FindWndPtr( *hwnd ))) return;
+    data = win->pDriverData;
 
-  rect.left   = event->x - offx;
-  rect.top    = event->y - offy;
-
-  rect.right  = rect.left + event->width;
-  rect.bottom = rect.top + event->height;
-
-  WIN_ReleaseWndPtr(pWnd);
-
-  RedrawWindow( hWnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE );
-
-  if (event->count == 0)
-    SendNotifyMessageA(hWnd,WM_SYNCPAINT, 0, 0);
+    if (window == data->whole_window)
+    {
+        x -= data->client_rect.left;
+        y -= data->client_rect.top;
+    }
+    while (win->parent && win->parent->hwndSelf != GetDesktopWindow())
+    {
+        x += win->rectClient.left;
+        y += win->rectClient.top;
+        WIN_UpdateWndPtr( &win, win->parent );
+    }
+    pt->x = x + win->rectClient.left;
+    pt->y = y + win->rectClient.top;
+    *hwnd = win->hwndSelf;
+    WIN_ReleaseWndPtr( win );
 }
 
 
@@ -659,10 +465,9 @@
  */
 static void EVENT_Key( HWND hWnd, XKeyEvent *event )
 {
-    WND *pWnd = WIN_FindWndPtr(hWnd);
-  X11DRV_KEYBOARD_HandleEvent( pWnd, event );
-    WIN_ReleaseWndPtr(pWnd);
-
+    POINT pt;
+    get_coords( &hWnd, event->window, event->x, event->y, &pt );
+    X11DRV_KEYBOARD_HandleEvent( event, pt.x, pt.y );
 }
 
 
@@ -671,22 +476,22 @@
  */
 static void EVENT_MotionNotify( HWND hWnd, XMotionEvent *event )
 {
-  if (current_input_type == X11DRV_INPUT_ABSOLUTE) {
-    WND *pWnd = WIN_FindWndPtr(hWnd);
-    int xOffset = pWnd? pWnd->rectWindow.left : 0;
-    int yOffset = pWnd? pWnd->rectWindow.top  : 0;
-    WIN_ReleaseWndPtr(pWnd);
-    
-    X11DRV_SendEvent( MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, 
-                            xOffset + event->x, yOffset + event->y,
-                            X11DRV_EVENT_XStateToKeyState( event->state ), 
-                            event->time - X11DRV_server_startticks, hWnd);
-  } else {
-    X11DRV_SendEvent( MOUSEEVENTF_MOVE,
-                            event->x_root, event->y_root,
-                            X11DRV_EVENT_XStateToKeyState( event->state ), 
-                            event->time - X11DRV_server_startticks, hWnd);
-  }
+    POINT pt;
+
+    if (current_input_type == X11DRV_INPUT_ABSOLUTE)
+    {
+        get_coords( &hWnd, event->window, event->x, event->y, &pt );
+        X11DRV_SendEvent( MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, pt.x, pt.y,
+                          X11DRV_EVENT_XStateToKeyState( event->state ),
+                          event->time - X11DRV_server_startticks, hWnd);
+    }
+    else
+    {
+        X11DRV_SendEvent( MOUSEEVENTF_MOVE,
+                          event->x_root, event->y_root,
+                          X11DRV_EVENT_XStateToKeyState( event->state ),
+                          event->time - X11DRV_server_startticks, hWnd);
+    }
 }
 
 
@@ -695,51 +500,46 @@
  */
 static void EVENT_ButtonPress( HWND hWnd, XButtonEvent *event )
 {
-  static WORD statusCodes[NB_BUTTONS] = 
-  { MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_WHEEL, MOUSEEVENTF_WHEEL};
-  int buttonNum = event->button - 1;
-  
-  WND *pWnd = WIN_FindWndPtr(hWnd);
-  int xOffset = pWnd? pWnd->rectWindow.left : 0;
-  int yOffset = pWnd? pWnd->rectWindow.top  : 0;
-  WORD keystate,wData = 0;
-  
-  WIN_ReleaseWndPtr(pWnd);
+    static const WORD statusCodes[NB_BUTTONS] = { MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_MIDDLEDOWN,
+                                                  MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_WHEEL,
+                                                  MOUSEEVENTF_WHEEL};
+    int buttonNum = event->button - 1;
+    WORD keystate, wData = 0;
+    POINT pt;
 
-  if (buttonNum >= NB_BUTTONS) return;
+    if (buttonNum >= NB_BUTTONS) return;
 
-  /*
-   * Get the compatible keystate
-   */
-  keystate = X11DRV_EVENT_XStateToKeyState( event->state );
-  
-  /*
-   * Make sure that the state of the button that was just 
-   * pressed is "down".
-   */
-  switch (buttonNum)
-  {
+    get_coords( &hWnd, event->window, event->x, event->y, &pt );
+
+    /* Get the compatible keystate */
+    keystate = X11DRV_EVENT_XStateToKeyState( event->state );
+
+    /*
+     * Make sure that the state of the button that was just 
+     * pressed is "down".
+     */
+    switch (buttonNum)
+    {
     case 0:
-      keystate |= MK_LBUTTON;
-      break;
+        keystate |= MK_LBUTTON;
+        break;
     case 1:
-      keystate |= MK_MBUTTON;
-      break;
+        keystate |= MK_MBUTTON;
+        break;
     case 2:
-      keystate |= MK_RBUTTON;
-      break;
+        keystate |= MK_RBUTTON;
+        break;
     case 3:
         wData = WHEEL_DELTA;
         break;
     case 4:
         wData = -WHEEL_DELTA;
         break;
-  }
-  
-  X11DRV_SendEvent( statusCodes[buttonNum], 
-                          xOffset + event->x, yOffset + event->y,
-                          MAKEWPARAM(keystate,wData),
-                          event->time - X11DRV_server_startticks, hWnd);
+    }
+
+    X11DRV_SendEvent( statusCodes[buttonNum], pt.x, pt.y,
+                      MAKEWPARAM(keystate,wData),
+                      event->time - X11DRV_server_startticks, hWnd);
 }
 
 
@@ -748,45 +548,39 @@
  */
 static void EVENT_ButtonRelease( HWND hWnd, XButtonEvent *event )
 {
-  static WORD statusCodes[NB_BUTTONS] = 
-  { MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_RIGHTUP };
-  int buttonNum = event->button - 1;
-  WND *pWnd = WIN_FindWndPtr(hWnd);
-  int xOffset = pWnd? pWnd->rectWindow.left : 0;
-  int yOffset = pWnd? pWnd->rectWindow.top  : 0;
-  WORD keystate;
-  
-  WIN_ReleaseWndPtr(pWnd);
-  
-  if (buttonNum >= NB_BUTTONS) return;    
-  
-  /*
-   * Get the compatible keystate
-   */
-  keystate = X11DRV_EVENT_XStateToKeyState( event->state );
+    static const WORD statusCodes[NB_BUTTONS] = { MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEUP,
+                                                  MOUSEEVENTF_RIGHTUP, 0, 0 };
+    int buttonNum = event->button - 1;
+    WORD keystate;
+    POINT pt;
 
-  /*
-   * Make sure that the state of the button that was just 
-   * released is "up".
-   */
-  switch (buttonNum)
-  {
+    if (buttonNum >= NB_BUTTONS) return;
+
+    get_coords( &hWnd, event->window, event->x, event->y, &pt );
+
+    /* Get the compatible keystate */
+    keystate = X11DRV_EVENT_XStateToKeyState( event->state );
+
+    /*
+     * Make sure that the state of the button that was just 
+     * released is "up".
+     */
+    switch (buttonNum)
+    {
     case 0:
-      keystate &= ~MK_LBUTTON;
-      break;
+        keystate &= ~MK_LBUTTON;
+        break;
     case 1:
-      keystate &= ~MK_MBUTTON;
-      break;
+        keystate &= ~MK_MBUTTON;
+        break;
     case 2:
-      keystate &= ~MK_RBUTTON;
-      break;
-  default:
-      return;
-  }
-
-  X11DRV_SendEvent( statusCodes[buttonNum], 
-                          xOffset + event->x, yOffset + event->y,
-                          keystate, event->time - X11DRV_server_startticks, hWnd);
+        keystate &= ~MK_RBUTTON;
+        break;
+    default:
+        return;
+    }
+    X11DRV_SendEvent( statusCodes[buttonNum], pt.x, pt.y,
+                      keystate, event->time - X11DRV_server_startticks, hWnd);
 }
 
 
@@ -795,12 +589,42 @@
  */
 static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event )
 {
-    if (event->detail != NotifyPointer)
-        if (hWnd != GetForegroundWindow())
+    WND *pWndLastFocus;
+    XWindowAttributes win_attr;
+    BOOL bIsDisabled;
+
+    if (!hWnd) return;
+
+    bIsDisabled = GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED;
+
+    /* If the window has been disabled and we are in managed mode,
+       * revert the X focus back to the last focus window. This is to disallow
+       * the window manager from switching focus away while the app is
+       * in a modal state.
+       */
+    if ( Options.managed && bIsDisabled && glastXFocusWin)
+    {
+        /* Change focus only if saved focus window is registered and viewable */
+        wine_tsx11_lock();
+        if (XFindContext( event->display, glastXFocusWin, winContext,
+                           (char **)&pWndLastFocus ) == 0 )
         {
-            SetForegroundWindow( hWnd );
-	    X11DRV_KEYBOARD_UpdateState();
+            if (XGetWindowAttributes( event->display, glastXFocusWin, &win_attr ) &&
+                (win_attr.map_state == IsViewable) )
+            {
+                XSetInputFocus( event->display, glastXFocusWin, RevertToParent, CurrentTime );
+                wine_tsx11_unlock();
+                return;
+            }
         }
+        wine_tsx11_unlock();
+    }
+
+    if (event->detail != NotifyPointer && hWnd != GetForegroundWindow())
+    {
+        SetForegroundWindow( hWnd );
+        X11DRV_KEYBOARD_UpdateState();
+    }
 }
 
 
@@ -811,25 +635,27 @@
  */
 static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event )
 {
-    if (event->detail != NotifyPointer)
-        if (hWnd == GetForegroundWindow())
-	{
-	    SendMessageA( hWnd, WM_CANCELMODE, 0, 0 );
+    /* Save the last window which had the focus */
+    glastXFocusWin = event->window;
+    if (!hWnd) return;
+    if (GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED) glastXFocusWin = 0;
 
-
-            /* don't reset the foreground window, if the window who's 
+    if (event->detail != NotifyPointer && hWnd == GetForegroundWindow())
+    {
+        /* don't reset the foreground window, if the window which is
                getting the focus is a Wine window */
-            if (!X11DRV_CheckFocus())
-            {
-                /* Abey : 6-Oct-99. Check again if the focus out window is the
-                   Foreground window, because in most cases the messages sent
-                   above must have already changed the foreground window, in which
-                   case we don't have to change the foreground window to 0 */
+        if (!X11DRV_CheckFocus())
+        {
+            SendMessageA( hWnd, WM_CANCELMODE, 0, 0 );
+            /* Abey : 6-Oct-99. Check again if the focus out window is the
+               Foreground window, because in most cases the messages sent
+               above must have already changed the foreground window, in which
+               case we don't have to change the foreground window to 0 */
 
-                if (hWnd == GetForegroundWindow())
-                    SetForegroundWindow( 0 );
-            }
-	}
+            if (hWnd == GetForegroundWindow())
+                SetForegroundWindow( 0 );
+        }
+    }
 }
 
 /**********************************************************************
@@ -849,100 +675,6 @@
     return TRUE;
 }
 
-/**********************************************************************
- *              EVENT_GetGeometry
- *
- * Helper function for ConfigureNotify handling.
- * Get the new geometry of a window relative to the root window.
- */
-static void EVENT_GetGeometry( Display *display, Window win, int *px, int *py,
-                               unsigned int *pwidth, unsigned int *pheight )
-{
-    Window root, top;
-    int x, y, width, height, border, depth;
-
-    wine_tsx11_lock();
-
-    /* Get the geometry of the window */
-    XGetGeometry( display, win, &root, &x, &y, &width, &height,
-                  &border, &depth );
-
-    /* Translate the window origin to root coordinates */
-    XTranslateCoordinates( display, win, root, 0, 0, &x, &y, &top );
-
-    wine_tsx11_unlock();
-
-    *px = x;
-    *py = y;
-    *pwidth = width;
-    *pheight = height;
-}
-
-/**********************************************************************
- *              EVENT_ConfigureNotify
- *
- * The ConfigureNotify event is only selected on top-level windows
- * when the -managed flag is used.
- */
-static void EVENT_ConfigureNotify( HWND hWnd, XConfigureEvent *event )
-{
-    RECT rectWindow;
-    int x, y, flags = 0;
-    unsigned int width, height;
-    HWND newInsertAfter, oldInsertAfter;
-  
-    /* Get geometry and Z-order according to X */
-
-    EVENT_GetGeometry( event->display, event->window, &x, &y, &width, &height );
-    newInsertAfter = EVENT_QueryZOrder( event->display, hWnd );
-
-    /* Get geometry and Z-order according to Wine */
-
-    /*
-     *  Needs to find the first Visible Window above the current one
-     */
-    oldInsertAfter = hWnd;
-    for (;;)
-    {
-        oldInsertAfter = GetWindow( oldInsertAfter, GW_HWNDPREV );
-        if (!oldInsertAfter)
-        {
-            oldInsertAfter = HWND_TOP;
-            break;
-        }
-        if (GetWindowLongA( oldInsertAfter, GWL_STYLE ) & WS_VISIBLE) break;
-    }
-
-    /* Compare what has changed */
-
-    GetWindowRect( hWnd, &rectWindow );
-    if ( rectWindow.left == x && rectWindow.top == y )
-        flags |= SWP_NOMOVE;
-    else
-        TRACE_(win)( "%04x moving from (%d,%d) to (%d,%d)\n", hWnd, 
-	             rectWindow.left, rectWindow.top, x, y );
-
-    if (    rectWindow.right - rectWindow.left == width
-         && rectWindow.bottom - rectWindow.top == height )
-        flags |= SWP_NOSIZE;
-    else
-        TRACE_(win)( "%04x resizing from (%d,%d) to (%d,%d)\n", hWnd, 
-                     rectWindow.right - rectWindow.left, 
-                     rectWindow.bottom - rectWindow.top, width, height );
-
-    if ( newInsertAfter == oldInsertAfter )
-        flags |= SWP_NOZORDER;
-    else
-        TRACE_(win)( "%04x restacking from after %04x to after %04x\n", hWnd, 
-                     oldInsertAfter, newInsertAfter );
-
-    /* If anything changed, call SetWindowPos */
-
-    if ( flags != (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER) )
-        SetWindowPos( hWnd, newInsertAfter, x, y, width, height, 
-                            flags | SWP_NOACTIVATE | SWP_WINE_NOHOSTMOVE );
-}
-
 
 /***********************************************************************
  *           EVENT_SelectionRequest_TARGETS
@@ -1524,7 +1256,7 @@
   
   pWnd = WIN_FindWndPtr(hWnd);
   
-  TSXQueryPointer( event->display, X11DRV_WND_GetXWindow(pWnd), &w_aux_root, &w_aux_child, 
+  TSXQueryPointer( event->display, get_whole_window(pWnd), &w_aux_root, &w_aux_child,
                    &x, &y, (int *) &u.pt_aux.x, (int *) &u.pt_aux.y,
                    (unsigned int*)&aux_long);
   
@@ -1743,22 +1475,24 @@
     if ((event->message_type == wmProtocols) && 
 	(((Atom) event->data.l[0]) == wmDeleteWindow))
     {
-      /* Ignore the delete window request if the window has been disabled
-       * and we are in managed mode. This is to disallow applications from
-       * being closed by the window manager while in a modal state.
-       */
-      BOOL bIsDisabled;
-      bIsDisabled = GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED;
-
-      if ( !Options.managed || !bIsDisabled )
-      PostMessage16( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
+        /* Ignore the delete window request if the window has been disabled */
+        if (!(GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED))
+            PostMessageA( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
     }
-    else if ( event->message_type == dndProtocol &&
-	      (event->data.l[0] == DndFile || event->data.l[0] == DndFiles) )
-      EVENT_DropFromOffiX(hWnd, event);
-    else if ( event->message_type == dndProtocol &&
-	      event->data.l[0] == DndURL )
-      EVENT_DropURLs(hWnd, event);
+    else if (event->message_type == dndProtocol)
+    {
+        /* query window (drag&drop event contains only drag window) */
+        Window root, child;
+        int root_x, root_y, child_x, child_y;
+        unsigned int u;
+        TSXQueryPointer( event->display, root_window, &root, &child,
+                         &root_x, &root_y, &child_x, &child_y, &u);
+        if (TSXFindContext( event->display, child, winContext, (char **)&hWnd ) != 0) return;
+        if (event->data.l[0] == DndFile || event->data.l[0] == DndFiles)
+            EVENT_DropFromOffiX(hWnd, event);
+        else if (event->data.l[0] == DndURL)
+            EVENT_DropURLs(hWnd, event);
+    }
     else {
 #if 0
       /* enable this if you want to see the message */
@@ -1782,65 +1516,6 @@
   }
 }
 
-/**********************************************************************
- *           EVENT_EnterNotify
- *
- * Install colormap when Wine window is focused in
- * self-managed mode with private colormap
- */
-#if 0
-void EVENT_EnterNotify( HWND hWnd, XCrossingEvent *event )
-{
-  if( !Options.managed && root_window == DefaultRootWindow(event->display) &&
-      (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE) && GetFocus() )
-    TSXInstallColormap( event->display, X11DRV_PALETTE_GetColormap() );
-}
-#endif
-
-/**********************************************************************
- *		EVENT_MapNotify
- */
-void EVENT_MapNotify( HWND hWnd, XMapEvent *event )
-{
-  HWND hwndFocus = GetFocus();
-  WND *wndFocus = WIN_FindWndPtr(hwndFocus);
-  WND *pWnd = WIN_FindWndPtr(hWnd);
-  if (pWnd && (pWnd->dwExStyle & WS_EX_MANAGED))
-  {
-      DCE_InvalidateDCE( pWnd, &pWnd->rectWindow );
-      pWnd->dwStyle &= ~WS_MINIMIZE;
-      pWnd->dwStyle |=  WS_VISIBLE;
-      WIN_InternalShowOwnedPopups(hWnd,TRUE,TRUE);
-  }
-  WIN_ReleaseWndPtr(pWnd);
-
-  if (hwndFocus && IsChild( hWnd, hwndFocus ))
-      X11DRV_SetFocus(hwndFocus);
-
-  WIN_ReleaseWndPtr(wndFocus);
-  
-  return;
-}
-
-
-/**********************************************************************
- *              EVENT_UnmapNotify
- */
-void EVENT_UnmapNotify( HWND hWnd, XUnmapEvent *event )
-{
-  WND *pWnd = WIN_FindWndPtr(hWnd);
-  if (pWnd && (pWnd->dwExStyle & WS_EX_MANAGED))
-  {
-      EndMenu();
-      if( pWnd->dwStyle & WS_VISIBLE )
-      {
-	  pWnd->dwStyle |=  WS_MINIMIZE;
-	  pWnd->dwStyle &= ~WS_VISIBLE;
-            WIN_InternalShowOwnedPopups(hWnd,FALSE,TRUE);
-      }
-  }
-  WIN_ReleaseWndPtr(pWnd);
-}
 
 /***********************************************************************
  *           EVENT_MappingNotify
diff --git a/windows/x11drv/keyboard.c b/windows/x11drv/keyboard.c
index 3fc1e1f..78ff6aa 100644
--- a/windows/x11drv/keyboard.c
+++ b/windows/x11drv/keyboard.c
@@ -708,7 +708,7 @@
  *
  * Handle a X key event
  */
-void X11DRV_KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
+void X11DRV_KEYBOARD_HandleEvent( XKeyEvent *event, int x, int y )
 {
     char Str[24]; 
     KeySym keysym;
@@ -717,8 +717,6 @@
     static BOOL force_extended = FALSE; /* hack for AltGr translation */
     int ascii_chars;
 
-    INT event_x = (pWnd? pWnd->rectWindow.left : 0) + event->x;
-    INT event_y = (pWnd? pWnd->rectWindow.top  : 0) + event->y;
     DWORD event_time = event->time - X11DRV_server_startticks;
 
     /* this allows support for dead keys */
@@ -745,11 +743,11 @@
 	{
 	TRACE_(key)("Alt Gr key event received\n");
 	event->keycode = kcControl; /* Simulate Control */
-	X11DRV_KEYBOARD_HandleEvent( pWnd, event );
+	X11DRV_KEYBOARD_HandleEvent( event, x, y );
 
 	event->keycode = kcAlt; /* Simulate Alt */
 	force_extended = TRUE;
-	X11DRV_KEYBOARD_HandleEvent( pWnd, event );
+	X11DRV_KEYBOARD_HandleEvent( event, x, y );
 	force_extended = FALSE;
     
     /* Here we save the pressed/released state of the AltGr key, to be able to 
@@ -783,13 +781,11 @@
     switch (vkey & 0xff)
     {
     case VK_NUMLOCK:    
-      KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, event_x, event_y,
-                            event_time );
+      KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, x, y, event_time );
       break;
     case VK_CAPITAL:
       TRACE("Caps Lock event. (type %d). State before : %#.2x\n",event->type,pKeyStateTable[vkey]);
-      KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, event_x, event_y,
-                            event_time ); 
+      KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, x, y, event_time );
       TRACE("State after : %#.2x\n",pKeyStateTable[vkey]);
       break;
     default:
@@ -797,19 +793,15 @@
 	if (!(pKeyStateTable[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask))
 	  { 
 	    TRACE("Adjusting NumLock state. \n");
-	    KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, event_x, event_y,
-                                  event_time );
-	    KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyRelease, event_x, event_y,
-                                  event_time );
+	    KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, x, y, event_time );
+	    KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyRelease, x, y, event_time );
 	  }
         /* Adjust the CAPSLOCK state if it has been changed outside wine */
 	if (!(pKeyStateTable[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
 	  {
               TRACE("Adjusting Caps Lock state.\n");
-	    KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyPress, event_x, event_y,
-                                  event_time );
-	    KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyRelease, event_x, event_y,
-                                  event_time );
+	    KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyPress, x, y, event_time );
+	    KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyRelease, x, y, event_time );
 	  }
 	/* Not Num nor Caps : end of intermediary states for both. */
 	NumState = FALSE;
@@ -823,8 +815,7 @@
 	if ( vkey & 0x100 )              dwFlags |= KEYEVENTF_EXTENDEDKEY;
 	if ( force_extended )            dwFlags |= KEYEVENTF_WINE_FORCEEXTENDED;
 
-	KEYBOARD_SendEvent( vkey & 0xff, bScan, dwFlags, 
-                            event_x, event_y, event_time );
+        KEYBOARD_SendEvent( vkey & 0xff, bScan, dwFlags, x, y, event_time );
     }
    }
 }
diff --git a/windows/x11drv/mouse.c b/windows/x11drv/mouse.c
index 255972a..03f68a1 100644
--- a/windows/x11drv/mouse.c
+++ b/windows/x11drv/mouse.c
@@ -154,13 +154,8 @@
 /* set the cursor of a window; helper for X11DRV_SetCursor */
 static BOOL CALLBACK set_win_cursor( HWND hwnd, LPARAM cursor )
 {
-    WND *wndPtr = WIN_FindWndPtr(hwnd);
-    if (wndPtr)
-    {
-        Window win = X11DRV_WND_GetXWindow(wndPtr);
-        if (win) TSXDefineCursor( thread_display(), win, (Cursor)cursor );
-    }
-    WIN_ReleaseWndPtr( wndPtr );
+    Window win = X11DRV_get_whole_window( hwnd );
+    if (win) TSXDefineCursor( thread_display(), win, (Cursor)cursor );
     return TRUE;
 }
 
diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c
index 901a13b..601219e 100644
--- a/windows/x11drv/wnd.c
+++ b/windows/x11drv/wnd.c
@@ -40,37 +40,11 @@
 
 WND_DRIVER X11DRV_WND_Driver =
 {
-  X11DRV_WND_ForceWindowRaise,
-  X11DRV_WND_SetHostAttr
+  X11DRV_WND_ForceWindowRaise
 };
 
 
 /***********************************************************************
- *		X11DRV_WND_GetXWindow
- *
- * Return the X window associated to a window.
- */
-Window X11DRV_WND_GetXWindow(WND *wndPtr)
-{
-    return wndPtr && wndPtr->pDriverData ? 
-      ((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;
-}
-
-/***********************************************************************
  *		X11DRV_WND_IsZeroSizeWnd
  *
  * Return TRUE if the window has a height or widht less or equal to 0
@@ -101,7 +75,7 @@
     return;
   }
   
-  if( !wndPtr || !X11DRV_WND_GetXWindow(wndPtr) || (wndPtr->dwExStyle & WS_EX_MANAGED) )
+  if( !wndPtr || !get_whole_window(wndPtr) || (wndPtr->dwExStyle & WS_EX_MANAGED) )
   {
       WIN_ReleaseDesktop();
     return;
@@ -114,9 +88,9 @@
   winChanges.stack_mode = Above;
   while (wndPtr)
     {
-      if ( !X11DRV_WND_IsZeroSizeWnd(wndPtr) && X11DRV_WND_GetXWindow(wndPtr) )         
-         TSXReconfigureWMWindow( thread_display(), X11DRV_WND_GetXWindow(wndPtr), 0,
-				CWStackMode, &winChanges );
+      if ( !X11DRV_WND_IsZeroSizeWnd(wndPtr) && get_whole_window(wndPtr) )
+         TSXReconfigureWMWindow( thread_display(), get_whole_window(wndPtr), 0,
+                                 CWStackMode, &winChanges );
 
       wndPrev = pDesktop->child;
       if (wndPrev == wndPtr) break;
@@ -126,345 +100,3 @@
     }
   WIN_ReleaseDesktop();
 }
-
-/***********************************************************************
- *		X11DRV_WND_FindDesktopXWindow	[Internal]
- *
- * Find the actual X window which needs be restacked.
- * Used by X11DRV_WND_SetWindowPos().
- */
-static Window X11DRV_WND_FindDesktopXWindow( WND *wndPtr )
-{
-  if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
-    return X11DRV_WND_GetXWindow(wndPtr);
-  else
-    {
-      Window window, root, parent, *children;
-      int nchildren;
-      window = X11DRV_WND_GetXWindow(wndPtr);
-      for (;;)
-        {
-	  TSXQueryTree( thread_display(), window, &root, &parent,
-                        &children, &nchildren );
-	  TSXFree( children );
-	  if (parent == root)
-	    return window;
-	  window = parent;
-        }
-    }
-}
-
-/***********************************************************************
- *           WINPOS_SetXWindowPos
- *
- * SetWindowPos() for an X window. Used by the real SetWindowPos().
- */
-void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangePos)
-{
-    XWindowChanges winChanges;
-    Display *display = thread_display();
-    int changeMask = 0;
-    BOOL isZeroSizeWnd = FALSE;
-    BOOL forceMapWindow = FALSE;
-    WND *winposPtr = WIN_FindWndPtr( winpos->hwnd );
-    if ( !winposPtr ) return;
-
-    /* find out if after this function we will end out with a zero-size window */
-    if (X11DRV_WND_IsZeroSizeWnd(winposPtr))
-    {
-        /* if current size is 0, and no resizing */
-        if (winpos->flags & SWP_NOSIZE)
-            isZeroSizeWnd = TRUE;
-        else if ((winpos->cx > 0) && (winpos->cy > 0)) 
-        {
-            /* if this function is setting a new size > 0 for the window, we
-               should map the window if WS_VISIBLE is set */
-            if ((winposPtr->dwStyle & WS_VISIBLE) && !(winpos->flags & SWP_HIDEWINDOW))
-                forceMapWindow = TRUE;
-        }
-    }
-    /* if resizing to 0 */
-    if ( !(winpos->flags & SWP_NOSIZE) && ((winpos->cx <= 0) || (winpos->cy <= 0)) )
-            isZeroSizeWnd = TRUE;
-
-    if(!wndPtr->hwndSelf) wndPtr = NULL; /* FIXME: WND destroyed, shouldn't happen!!! */
-  
-    if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW))
-    {
-      if(X11DRV_WND_GetXWindow(wndPtr)) 
-	TSXUnmapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
-    }
-
-    if(bChangePos)
-    {
-	if ( !(winpos->flags & SWP_NOSIZE))
-	{
-	  winChanges.width     = (winpos->cx > 0 ) ? winpos->cx : 1;
-	  winChanges.height    = (winpos->cy > 0 ) ? winpos->cy : 1;
-	  changeMask |= CWWidth | CWHeight;
-	  
-	  /* Tweak dialog window size hints */
-	  
-	  if ((winposPtr->dwExStyle & WS_EX_MANAGED) &&
-               HAS_DLGFRAME(winposPtr->dwStyle,winposPtr->dwExStyle))
-	    {
-	      XSizeHints *size_hints = TSXAllocSizeHints();
-	      
-	      if (size_hints)
-		{
-		  long supplied_return;
-		  
-		  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, X11DRV_WND_GetXWindow(winposPtr), size_hints,
-				     XA_WM_NORMAL_HINTS );
-		  TSXFree(size_hints);
-		}
-	    }
-	}
-	if (!(winpos->flags & SWP_NOMOVE))
-	{
-	  winChanges.x = winpos->x;
-	  winChanges.y = winpos->y;
-	  changeMask |= CWX | CWY;
-	}
-	if (!(winpos->flags & SWP_NOZORDER) && !isZeroSizeWnd)
-	{
-	  winChanges.stack_mode = Below;
-	  changeMask |= CWStackMode;
-	  
-	  if (winpos->hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above;
-	  else if (winpos->hwndInsertAfter != HWND_BOTTOM)
-	    {
-	      WND*   insertPtr = WIN_FindWndPtr( winpos->hwndInsertAfter );
-	      Window stack[2];
-
-          /* If the window where we should do the insert is zero-sized (not mapped)
-             don't used this window since it will possibly crash the X server,
-             use the "non zero-sized" window above */ 
-	      if (X11DRV_WND_IsZeroSizeWnd(insertPtr))
-          {
-              /* find the window on top of the zero sized window */ 
-              WND *pDesktop = WIN_GetDesktop();
-              WND *wndPrev = pDesktop->child;
-              WND *wndZeroSized = insertPtr;
-
-              while (1)
-              {
-                  if (wndPrev == wndZeroSized)
-                      break;  /* zero-sized window is on top */
-
-                  while (wndPrev && (wndPrev->next != wndZeroSized))
-                      wndPrev = wndPrev->next;
-
-                  /* check if the window found is not zero-sized */
-                  if (X11DRV_WND_IsZeroSizeWnd(wndPrev))
-                  {
-                      wndZeroSized = wndPrev; /* restart the search */
-                      wndPrev = pDesktop->child;
-                  }
-                  else
-                      break;   /* "above" window is found */
-              }
-              WIN_ReleaseDesktop();
-              
-              if (wndPrev == wndZeroSized)
-              {
-                  /* the zero-sized window is on top */
-                  /* so set the window on top */
-                  winChanges.stack_mode = Above;
-              }
-              else
-              {
-                  stack[0] = X11DRV_WND_FindDesktopXWindow( wndPrev );
-                  stack[1] = X11DRV_WND_FindDesktopXWindow( winposPtr );
-
-                  TSXRestackWindows(display, stack, 2);
-                  changeMask &= ~CWStackMode;
-              }
-          }
-          else  /* Normal behavior, windows are not zero-sized */
-          {
-              stack[0] = X11DRV_WND_FindDesktopXWindow( insertPtr );
-              stack[1] = X11DRV_WND_FindDesktopXWindow( winposPtr );
-	      
-	          TSXRestackWindows(display, stack, 2);
-	          changeMask &= ~CWStackMode;
-          }
-
-          WIN_ReleaseWndPtr(insertPtr);
-	    }
-	}
-	if (changeMask && X11DRV_WND_GetXWindow(winposPtr))
-	{
-	    TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges );
-	    if( winposPtr->clsStyle & (CS_VREDRAW | CS_HREDRAW) )
-		X11DRV_WND_SetGravity( winposPtr, ForgetGravity );
-	}
-    }
-    
-    /* don't map the window if it's a zero size window */
-    if ( ((winpos->flags & SWP_SHOWWINDOW) && !isZeroSizeWnd) || forceMapWindow )
-    {
-	if(X11DRV_WND_GetXWindow(wndPtr)) 
-	   TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
-    }
-    WIN_ReleaseWndPtr(winposPtr);
-}
-
-/*****************************************************************
- *		 X11DRV_WND_SurfaceCopy
- *
- * Copies rect to (rect.left + dx, rect.top + dy). 
- */
-void X11DRV_WND_SurfaceCopy(WND* wndPtr, HDC hdc, INT dx, INT dy, 
-			    const RECT *rect, BOOL bUpdate)
-{
-    X11DRV_PDEVICE *physDev;
-    POINT dst, src;
-    DC *dcPtr = DC_GetDCPtr( hdc );
-
-    if (!dcPtr) return;
-    physDev = (X11DRV_PDEVICE *)dcPtr->physDev;
-    dst.x = (src.x = dcPtr->DCOrgX + rect->left) + dx;
-    dst.y = (src.y = dcPtr->DCOrgY + rect->top) + dy;
-
-    wine_tsx11_lock();
-    if (bUpdate) /* handles non-Wine windows hanging over the copied area */
-        XSetGraphicsExposures( gdi_display, physDev->gc, True );
-    XSetFunction( gdi_display, physDev->gc, GXcopy );
-    XCopyArea( gdi_display, physDev->drawable, physDev->drawable, physDev->gc,
-               src.x, src.y, rect->right - rect->left, rect->bottom - rect->top,
-               dst.x, dst.y );
-    if (bUpdate)
-        XSetGraphicsExposures( gdi_display, physDev->gc, False );
-    wine_tsx11_unlock();
-    GDI_ReleaseObj( hdc );
-
-    if (bUpdate) /* Make sure exposure events have been processed */
-        X11DRV_Synchronize();
-}
-
-/***********************************************************************
- *              X11DRV_SetWMHint
- */
-static BOOL X11DRV_SetWMHint(Display* display, WND* wndPtr, int hint, int val)
-{
-    XWMHints* wm_hints = TSXGetWMHints( display, X11DRV_WND_GetXWindow(wndPtr) );
-    if (!wm_hints) wm_hints = TSXAllocWMHints();
-    if (wm_hints)
-    {
-        wm_hints->flags = hint;
-	switch( hint )
-	{
-	    case InputHint:
-		 wm_hints->input = val;
-		 break;
-
-	    case StateHint:
-		 wm_hints->initial_state = val;
-		 break;
-
-	    case IconPixmapHint:
-		 wm_hints->icon_pixmap = (Pixmap)val;
-		 break;
-
-	    case IconWindowHint:
-		 wm_hints->icon_window = (Window)val;
-		 break;
-	}
-
-        TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
-        TSXFree(wm_hints);
-        return TRUE;
-    }
-    return FALSE;
-}
-
-
-void X11DRV_WND_SetGravity( WND* wnd, int value )
-{
-    X11DRV_WND_DATA *data = wnd->pDriverData;
-
-    if (data && data->window && data->bit_gravity != value )
-    {
-        XSetWindowAttributes win_attr;
-        win_attr.bit_gravity = value;
-        data->bit_gravity = value;
-        TSXChangeWindowAttributes( thread_display(), data->window, CWBitGravity, &win_attr );
-    }
-}
-
-
-/***********************************************************************
- *              X11DRV_WND_SetHostAttr
- *
- * This function returns TRUE if the attribute is supported and the
- * action was successful. Otherwise it should return FALSE and Wine will try 
- * to get by without the functionality provided by the host window system.
- */
-BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value)
-{
-    Window w;
-
-    if( (w = X11DRV_WND_GetXWindow(wnd)) )
-    {
-        Display *display = thread_display();
-	switch( ha )
-	{
-	case HAK_ICONICSTATE: /* called when a window is minimized/restored */
-
-            /* don't do anything if it'a zero size window */ 
-            if (X11DRV_WND_IsZeroSizeWnd(wnd))
-                return TRUE;
-
-		    if( (wnd->dwExStyle & WS_EX_MANAGED) )
-		    {
-			if( value )
-			{
-			    if( wnd->dwStyle & WS_VISIBLE )
-			    {
-				XClientMessageEvent ev;
-
-				/* FIXME: set proper icon */
-
-				ev.type = ClientMessage;
-				ev.display = display;
-				ev.message_type = wmChangeState;
-				ev.format = 32;
-				ev.data.l[0] = IconicState;
-				ev.window = w;
-
-				if( TSXSendEvent (display, DefaultRootWindow(display),
-		True, (SubstructureRedirectMask | SubstructureNotifyMask), (XEvent*)&ev))
-				{
-				    XEvent xe;
-				    TSXFlush (display);
-				    while( !TSXCheckTypedWindowEvent( display, w, UnmapNotify, &xe) );
-				}
-				else 
-				    break;
-			    }
-			    else
-				X11DRV_SetWMHint( display, wnd, StateHint, IconicState );
-			}
-			else
-			{
-			    if( !(wnd->flags & WS_VISIBLE) )
-				X11DRV_SetWMHint( display, wnd, StateHint, NormalState );
-			    else
-			    {
-				XEvent xe;
-				TSXMapWindow(display, w );
-				while( !TSXCheckTypedWindowEvent( display, w, MapNotify, &xe) );
-			    }
-			}
-			return TRUE;
-		    }
-		    break;
-	}
-    }
-    return FALSE;
-}