user32: Factorize graphics driver's WindowCreate and ShowWindow in user32.

Pierre d'Herbemont pdherbemont at free.fr
Wed Nov 29 19:23:10 CST 2006


Hi,

The goal of this patch is to move factorize graphics drivers' 
WindowCreate in user32.

At the same time ShowWindow gets factorized because WindowCreate and 
ShowWindow share both the use of WINPOS_MinMaximize, so it is easier to 
factorize both functions in a single patch. In fact ShowWindow is 
removed entirely from the drivers as it is driver independant.

To properly factorize WindowCreate we have to export 3 new functions 
from the graphics driver which are SetIconicState, SyncWindowStyle, 
SystrayDockWindow.

I am not sure that we can't use SetWindowStyle instead of 
SyncWindowStyle, because SetWindowStyle involves a mapping on screen 
whereas SyncWindowStyle does not. Moving most of the SetWindowStyle in 
user and having a function to map the Window on screen could be a way to 
get rid of the quasi duplication of those style functions. This could be 
done in an other patch.

A few notes on some part I have been careful with:

The X11DRV_DestroyWindow involved when X11DRV_CreateWindow failed was 
unuseful as returning FALSE triggers WIN_DestroyWindow which calls 
DestroyWindow, so now returning false in USER_CreateWindow when 
HOOK_CallHooks fails is ok.

I was wondering what the policy with the function name prefix should be. 
I tend to use USER_ for the used-to-be-in-x11drv functions. But it 
appears that WIN_ or WINPOS_ might be more appropriate. If you want me 
to follow an other rule please ask, I'll send a patch for it.

Thanks,

Pierre.

---
  dlls/user32/driver.c              |   37 ++++-
  dlls/user32/user_private.h        |    5 +-
  dlls/user32/win.c                 |  135 +++++++++++++++-
  dlls/user32/winpos.c              |  322 
++++++++++++++++++++++++++++++++++++-
  dlls/winex11.drv/window.c         |  191 ++++------------------
  dlls/winex11.drv/winex11.drv.spec |    4 +-
  dlls/winex11.drv/winpos.c         |  324 
+------------------------------------
  dlls/winex11.drv/x11drv.h         |    3 +-
  8 files changed, 529 insertions(+), 492 deletions(-)
-------------- next part --------------
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index b5bf7a8..25543a9 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -112,14 +112,16 @@ static const USER_DRIVER *load_driver(vo
         GET_USER_FUNC(ReleaseDC);
         GET_USER_FUNC(ScrollDC);
         GET_USER_FUNC(SetFocus);
+        GET_USER_FUNC(SetIconicState);
         GET_USER_FUNC(SetParent);
         GET_USER_FUNC(SetWindowPos);
         GET_USER_FUNC(SetWindowRgn);
         GET_USER_FUNC(SetWindowIcon);
         GET_USER_FUNC(SetWindowStyle);
         GET_USER_FUNC(SetWindowText);
-        GET_USER_FUNC(ShowWindow);
+        GET_USER_FUNC(SyncWindowStyle);
         GET_USER_FUNC(SysCommandSizeMove);
+        GET_USER_FUNC(SystrayDockWindow);
         GET_USER_FUNC(WindowFromDC);
         GET_USER_FUNC(WindowMessage);
 #undef GET_USER_FUNC
@@ -365,6 +367,10 @@ static void nulldrv_SetFocus( HWND hwnd
 {
 }
 
+static void nulldrv_SetIconicState( HWND hwnd )
+{
+}
+
 static HWND nulldrv_SetParent( HWND hwnd, HWND parent )
 {
     return 0;
@@ -393,15 +399,18 @@ static void nulldrv_SetWindowText( HWND
 {
 }
 
-static BOOL nulldrv_ShowWindow( HWND hwnd, INT cmd )
+static void nulldrv_SyncWindowStyle( HWND hwnd )
 {
-    return FALSE;
 }
 
 static void nulldrv_SysCommandSizeMove( HWND hwnd, WPARAM wparam )
 {
 }
 
+static void nulldrv_SystrayDockWindow( HWND hwnd )
+{
+}
+
 static HWND nulldrv_WindowFromDC( HDC hdc )
 {
     return 0;
@@ -460,14 +469,16 @@ static const USER_DRIVER null_driver =
     nulldrv_ReleaseDC,
     nulldrv_ScrollDC,
     nulldrv_SetFocus,
+    nulldrv_SetIconicState,
     nulldrv_SetParent,
     nulldrv_SetWindowPos,
     nulldrv_SetWindowRgn,
     nulldrv_SetWindowIcon,
     nulldrv_SetWindowStyle,
     nulldrv_SetWindowText,
-    nulldrv_ShowWindow,
+    nulldrv_SyncWindowStyle,
     nulldrv_SysCommandSizeMove,
+    nulldrv_SystrayDockWindow,
     nulldrv_WindowFromDC,
     nulldrv_WindowMessage
 };
@@ -684,6 +695,11 @@ static void loaderdrv_SetFocus( HWND hwn
     load_driver()->pSetFocus( hwnd );
 }
 
+static void loaderdrv_SetIconicState( HWND hwnd )
+{
+    load_driver()->pSetIconicState( hwnd );
+}
+
 static HWND loaderdrv_SetParent( HWND hwnd, HWND parent )
 {
     return load_driver()->pSetParent( hwnd, parent );
@@ -715,9 +731,9 @@ static void loaderdrv_SetWindowText( HWN
     load_driver()->pSetWindowText( hwnd, text );
 }
 
-static BOOL loaderdrv_ShowWindow( HWND hwnd, INT cmd )
+static void loaderdrv_SyncWindowStyle( HWND hwnd )
 {
-    return load_driver()->pShowWindow( hwnd, cmd );
+    load_driver()->pSyncWindowStyle( hwnd );
 }
 
 static void loaderdrv_SysCommandSizeMove( HWND hwnd, WPARAM wparam )
@@ -725,6 +741,11 @@ static void loaderdrv_SysCommandSizeMove
     load_driver()->pSysCommandSizeMove( hwnd, wparam );
 }
 
+static void loaderdrv_SystrayDockWindow( HWND hwnd )
+{
+    load_driver()->pSystrayDockWindow( hwnd );
+}
+
 static HWND loaderdrv_WindowFromDC( HDC hdc )
 {
     return load_driver()->pWindowFromDC( hdc );
@@ -783,14 +804,16 @@ static const USER_DRIVER lazy_load_drive
     loaderdrv_ReleaseDC,
     loaderdrv_ScrollDC,
     loaderdrv_SetFocus,
+    loaderdrv_SetIconicState,
     loaderdrv_SetParent,
     loaderdrv_SetWindowPos,
     loaderdrv_SetWindowRgn,
     loaderdrv_SetWindowIcon,
     loaderdrv_SetWindowStyle,
     loaderdrv_SetWindowText,
-    loaderdrv_ShowWindow,
+    loaderdrv_SyncWindowStyle,
     loaderdrv_SysCommandSizeMove,
+    loaderdrv_SystrayDockWindow,
     loaderdrv_WindowFromDC,
     loaderdrv_WindowMessage
 };
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 5fad289..8056e5a 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -148,14 +148,16 @@ typedef struct tagUSER_DRIVER {
     INT    (*pReleaseDC)(HWND,HDC,BOOL);
     BOOL   (*pScrollDC)(HDC, INT, INT, const RECT *, const RECT *, HRGN, LPRECT);
     void   (*pSetFocus)(HWND);
+    void   (*pSetIconicState)(HWND);
     HWND   (*pSetParent)(HWND,HWND);
     BOOL   (*pSetWindowPos)(HWND,HWND,const RECT *,const RECT *,UINT,const RECT *);
     int    (*pSetWindowRgn)(HWND,HRGN,BOOL);
     void   (*pSetWindowIcon)(HWND,UINT,HICON);
     void   (*pSetWindowStyle)(HWND,DWORD);
     void   (*pSetWindowText)(HWND,LPCWSTR);
-    BOOL   (*pShowWindow)(HWND,INT);
+    void   (*pSyncWindowStyle)(HWND);
     void   (*pSysCommandSizeMove)(HWND,WPARAM);
+    void   (*pSystrayDockWindow)(HWND);
     HWND   (*pWindowFromDC)(HDC);
     LRESULT (*pWindowMessage)(HWND,UINT,WPARAM,LPARAM);
 } USER_DRIVER;
@@ -222,6 +224,7 @@ extern void USER_CheckNotLock(void);
 extern BOOL USER_IsExitingThread( DWORD tid );
 
 extern BOOL USER_SetWindowPos( WINDOWPOS * winpos );
+extern UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect );
 
 /* message spy definitions */
 
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 9ee1c00..e34e2ec 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -852,6 +852,139 @@ static void dump_window_styles( DWORD st
 #undef DUMPED_EX_STYLES
 }
 
+/***********************************************************************
+ *           USER_CreateWindow
+ */
+static BOOL USER_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
+{
+    WND *wndPtr;
+    HWND insert_after;
+    RECT rect;
+    DWORD style;
+    CBT_CREATEWNDA cbtc;
+    CREATESTRUCTA cbcs;
+    BOOL ret = FALSE;
+
+    if (!USER_Driver->pCreateWindow( hwnd, cs, unicode ))
+        return FALSE;
+        
+    /* Call the WH_CBT hook */
+
+    /* the window style passed to the hook must be the real window style,
+     * rather than just the window style that the caller to CreateWindowEx
+     * passed in, so we have to copy the original CREATESTRUCT and get the
+     * the real style. */
+    cbcs = *cs;
+    cbcs.style = GetWindowLongW(hwnd, GWL_STYLE);
+
+    cbtc.lpcs = &cbcs;
+    cbtc.hwndInsertAfter = HWND_TOP;
+    if (HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc, unicode ))
+    {
+        TRACE("CBT-hook returned !0\n");
+        return FALSE;
+    }
+
+    /* Send the WM_GETMINMAXINFO message and fix the size if needed */
+    if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
+    {
+        POINT maxSize, maxPos, minTrack, maxTrack;
+
+        WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack);
+        if (maxSize.x < cs->cx) cs->cx = maxSize.x;
+        if (maxSize.y < cs->cy) cs->cy = maxSize.y;
+        if (cs->cx < 0) cs->cx = 0;
+        if (cs->cy < 0) cs->cy = 0;
+
+        SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
+        if (!USER_Driver->pSetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER, NULL )) return FALSE;
+    }
+
+    /* send WM_NCCREATE */
+    TRACE( "hwnd %p cs %d,%d %dx%d\n", hwnd, cs->x, cs->y, cs->cx, cs->cy );
+    if (unicode)
+        ret = SendMessageW( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
+    else
+        ret = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
+    if (!ret)
+    {
+        WARN("aborted by WM_xxCREATE!\n");
+        return FALSE;
+    }
+
+    /* make sure the window is still valid */
+    USER_Driver->pSyncWindowStyle( hwnd );
+
+    /* send WM_NCCALCSIZE */
+    GetWindowRect( hwnd, &rect);
+    SendMessageW( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect );
+
+    if (!(wndPtr = WIN_GetPtr(hwnd))) return FALSE;
+
+    /* yes, even if the CBT hook was called with HWND_TOP */
+    insert_after = ((wndPtr->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
+
+    USER_Driver->pSetWindowPos( hwnd, insert_after, &wndPtr->rectWindow, &rect, 0, NULL );
+
+    TRACE( "win %p window %d,%d,%d,%d client %d,%d,%d,%d\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 );
+
+    WIN_ReleasePtr( wndPtr );
+
+    if (unicode)
+        ret = (SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
+    else
+        ret = (SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
+
+    if (!ret) return FALSE;
+
+    NotifyWinEvent(EVENT_OBJECT_CREATE, hwnd, OBJID_WINDOW, 0);
+
+    /* Send the size messages */
+
+    if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS) return FALSE;
+    if (!(wndPtr->flags & WIN_NEED_SIZE))
+    {
+        RECT rect = wndPtr->rectClient;
+        WIN_ReleasePtr( wndPtr );
+        /* send it anyway */
+        if (((rect.right-rect.left) <0) ||((rect.bottom-rect.top)<0))
+            WARN("sending bogus WM_SIZE message 0x%08x\n",
+                 MAKELONG(rect.right-rect.left, rect.bottom-rect.top));
+        SendMessageW( hwnd, WM_SIZE, SIZE_RESTORED,
+                      MAKELONG(rect.right-rect.left, rect.bottom-rect.top));
+        SendMessageW( hwnd, WM_MOVE, 0, MAKELONG( rect.left, rect.top ) );
+    }
+    else WIN_ReleasePtr( wndPtr );
+
+    /* Show the window, maximizing or minimizing if needed */
+
+    style = GetWindowLongW( hwnd, GWL_STYLE );
+    if (style & (WS_MINIMIZE | WS_MAXIMIZE))
+    {
+        RECT newPos;
+        UINT swFlag = (style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
+        WIN_SetStyle( hwnd, 0, WS_MAXIMIZE | WS_MINIMIZE );
+        WINPOS_MinMaximize( hwnd, swFlag, &newPos );
+
+        swFlag = SWP_FRAMECHANGED | SWP_NOZORDER; /* Frame always gets changed */
+        if (!(style & WS_VISIBLE) || (style & WS_CHILD) || GetActiveWindow()) swFlag |= SWP_NOACTIVATE;
+
+        SetWindowPos( hwnd, 0, newPos.left, newPos.top,
+                      newPos.right, newPos.bottom, swFlag );
+    }
+
+    /* Dock system tray windows. */
+    /* Dock after the window is created so we don't have problems calling
+     * SetWindowPos. */
+    if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_TRAYWINDOW)
+        USER_Driver->pSystrayDockWindow( hwnd );
+
+    return TRUE;
+}
 
 /***********************************************************************
  *           WIN_CreateWindowEx
@@ -1077,7 +1210,7 @@ static HWND WIN_CreateWindowEx( CREATEST
     else SetWindowLongPtrW( hwnd, GWLP_ID, (ULONG_PTR)cs->hMenu );
     WIN_ReleasePtr( wndPtr );
 
-    if (!USER_Driver->pCreateWindow( hwnd, cs, unicode))
+    if (!USER_CreateWindow( hwnd, cs, unicode))
     {
         WIN_DestroyWindow( hwnd );
         return 0;
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index 46f9a26..b1e753b 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -851,6 +851,323 @@ void WINPOS_GetMinMaxInfo( HWND hwnd, PO
 }
 
 /***********************************************************************
+ *           WINPOS_FindIconPos
+ *
+ * Find a suitable place for an iconic window.
+ */
+static POINT WINPOS_FindIconPos( HWND hwnd, POINT pt )
+{
+    RECT rect, rectParent;
+    HWND parent, child;
+    HRGN hrgn, tmp;
+    int xspacing, yspacing;
+
+    parent = GetAncestor( hwnd, GA_PARENT );
+    GetClientRect( parent, &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);
+
+    /* Check if another icon already occupies this spot */
+    /* FIXME: this is completely inefficient */
+
+    hrgn = CreateRectRgn( 0, 0, 0, 0 );
+    tmp = CreateRectRgn( 0, 0, 0, 0 );
+    for (child = GetWindow( parent, GW_HWNDFIRST ); child; child = GetWindow( child, GW_HWNDNEXT ))
+    {
+        WND *childPtr;
+        if (child == hwnd) continue;
+        if ((GetWindowLongW( child, GWL_STYLE ) & (WS_VISIBLE|WS_MINIMIZE)) != (WS_VISIBLE|WS_MINIMIZE))
+            continue;
+        if (!(childPtr = WIN_GetPtr( child )) || childPtr == WND_OTHER_PROCESS)
+            continue;
+        SetRectRgn( tmp, childPtr->rectWindow.left, childPtr->rectWindow.top,
+                    childPtr->rectWindow.right, childPtr->rectWindow.bottom );
+        CombineRgn( hrgn, hrgn, tmp, RGN_OR );
+        WIN_ReleasePtr( childPtr );
+    }
+    DeleteObject( tmp );
+
+    for (rect.bottom = rectParent.bottom; rect.bottom >= yspacing; rect.bottom -= yspacing)
+    {
+        for (rect.left = rectParent.left; rect.left <= rectParent.right - xspacing; rect.left += xspacing)
+        {
+            rect.right = rect.left + xspacing;
+            rect.top = rect.bottom - yspacing;
+            if (!RectInRegion( hrgn, &rect ))
+            {
+                /* No window was found, so it's OK for us */
+                pt.x = rect.left + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
+                pt.y = rect.top + (yspacing - GetSystemMetrics(SM_CYICON)) / 2;
+                DeleteObject( hrgn );
+                return pt;
+            }
+        }
+    }
+    DeleteObject( hrgn );
+    pt.x = pt.y = 0;
+    return pt;
+}
+
+/***********************************************************************
+ *           WINPOS_MinMaximize
+ */
+UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
+{
+    WND *wndPtr;
+    UINT swpFlags = 0;
+    POINT size;
+    LONG old_style;
+    WINDOWPLACEMENT wpl;
+
+    TRACE("%p %u\n", hwnd, cmd );
+
+    wpl.length = sizeof(wpl);
+    GetWindowPlacement( hwnd, &wpl );
+
+    if (HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)hwnd, cmd, TRUE ))
+        return SWP_NOSIZE | SWP_NOMOVE;
+
+    if (IsIconic( hwnd ))
+    {
+        switch (cmd)
+        {
+        case SW_SHOWMINNOACTIVE:
+        case SW_SHOWMINIMIZED:
+        case SW_FORCEMINIMIZE:
+        case SW_MINIMIZE:
+            return SWP_NOSIZE | SWP_NOMOVE;
+        }
+        if (!SendMessageW( hwnd, WM_QUERYOPEN, 0, 0 )) return SWP_NOSIZE | SWP_NOMOVE;
+        swpFlags |= SWP_NOCOPYBITS;
+    }
+
+    switch( cmd )
+    {
+    case SW_SHOWMINNOACTIVE:
+    case SW_SHOWMINIMIZED:
+    case SW_FORCEMINIMIZE:
+    case SW_MINIMIZE:
+        if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
+        if( wndPtr->dwStyle & WS_MAXIMIZE) wndPtr->flags |= WIN_RESTORE_MAX;
+        else wndPtr->flags &= ~WIN_RESTORE_MAX;
+        WIN_ReleasePtr( wndPtr );
+
+        WIN_SetStyle( hwnd, WS_MINIMIZE, WS_MAXIMIZE );
+        
+        USER_Driver->pSetIconicState( hwnd );
+
+        wpl.ptMinPosition = WINPOS_FindIconPos( hwnd, wpl.ptMinPosition );
+
+        SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y,
+                 GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
+        swpFlags |= SWP_NOCOPYBITS;
+        break;
+
+    case SW_MAXIMIZE:
+        old_style = GetWindowLongW( hwnd, GWL_STYLE );
+        if ((old_style & WS_MAXIMIZE) && (old_style & WS_VISIBLE)) return SWP_NOSIZE | SWP_NOMOVE;
+
+        WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL );
+
+        old_style = WIN_SetStyle( hwnd, WS_MAXIMIZE, WS_MINIMIZE );
+        if (old_style & WS_MINIMIZE)
+        {
+            WINPOS_ShowIconTitle( hwnd, FALSE );
+            USER_Driver->pSetIconicState( hwnd );
+        }
+        SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
+        break;
+
+    case SW_RESTORE:
+        old_style = WIN_SetStyle( hwnd, 0, WS_MINIMIZE | WS_MAXIMIZE );
+        if (old_style & WS_MINIMIZE)
+        {
+            BOOL restore_max;
+
+            WINPOS_ShowIconTitle( hwnd, FALSE );
+            
+            USER_Driver->pSetIconicState( hwnd );
+
+            if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
+            restore_max = (wndPtr->flags & WIN_RESTORE_MAX) != 0;
+            WIN_ReleasePtr( wndPtr );
+            if (restore_max)
+            {
+                /* Restore to maximized position */
+                WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL);
+                WIN_SetStyle( hwnd, WS_MAXIMIZE, 0 );
+                SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
+                break;
+            }
+        }
+        else if (!(old_style & WS_MAXIMIZE)) break;
+
+        /* Restore to normal position */
+
+        *rect = wpl.rcNormalPosition;
+        rect->right -= rect->left;
+        rect->bottom -= rect->top;
+
+        break;
+    }
+
+    return swpFlags;
+}
+
+/***********************************************************************
+ *		USER_ShowWindow
+ */
+static BOOL USER_ShowWindow( HWND hwnd, INT cmd )
+{
+    WND *wndPtr;
+    HWND parent;
+    LONG style = GetWindowLongW( hwnd, GWL_STYLE );
+    BOOL wasVisible = (style & WS_VISIBLE) != 0;
+    BOOL showFlag = TRUE, state_change = FALSE;
+    RECT newPos = {0, 0, 0, 0};
+    UINT swp = 0;
+
+    TRACE("hwnd=%p, cmd=%d, wasVisible %d\n", hwnd, cmd, wasVisible);
+
+    switch(cmd)
+    {
+        case SW_HIDE:
+            if (!wasVisible) return FALSE;
+            showFlag = FALSE;
+            swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+            if (hwnd != GetActiveWindow())
+                swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+	    break;
+
+	case SW_SHOWMINNOACTIVE:
+            swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+            /* fall through */
+        case SW_MINIMIZE:
+        case SW_FORCEMINIMIZE: /* FIXME: Does not work if thread is hung. */
+            if (style & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+            /* fall through */
+	case SW_SHOWMINIMIZED:
+            swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
+            swp |= WINPOS_MinMaximize( hwnd, cmd, &newPos );
+            if (style & WS_MINIMIZE) return wasVisible;
+            state_change = TRUE;
+	    break;
+
+	case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
+            swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
+            swp |= WINPOS_MinMaximize( hwnd, SW_MAXIMIZE, &newPos );
+            if ((style & WS_MAXIMIZE) && wasVisible) return wasVisible;
+            state_change = TRUE;
+            break;
+
+	case SW_SHOWNA:
+            swp |= SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+            if (style & WS_CHILD) swp |= SWP_NOZORDER;
+            break;
+	case SW_SHOW:
+            if (wasVisible) return TRUE;
+	    swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+            if (style & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+	    break;
+
+	case SW_RESTORE:
+	    swp |= SWP_FRAMECHANGED;
+            state_change = TRUE;
+            /* fall through */
+	case SW_SHOWNOACTIVATE:
+            swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+            /* fall through */
+	case SW_SHOWNORMAL:  /* same as SW_NORMAL: */
+	case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
+	    swp |= SWP_SHOWWINDOW;
+            if (style & (WS_MINIMIZE | WS_MAXIMIZE))
+		 swp |= WINPOS_MinMaximize( hwnd, SW_RESTORE, &newPos );
+            else swp |= SWP_NOSIZE | SWP_NOMOVE;
+            if (style & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+	    break;
+    }
+
+    if ((showFlag != wasVisible || cmd == SW_SHOWNA) && !state_change)
+    {
+        SendMessageW( hwnd, WM_SHOWWINDOW, showFlag, 0 );
+        if (!IsWindow( hwnd )) return wasVisible;
+    }
+
+    parent = GetAncestor( hwnd, GA_PARENT );
+    if (parent && !IsWindowVisible( parent ) && !state_change)
+    {
+        /* if parent is not visible simply toggle WS_VISIBLE and return */
+        if (showFlag) WIN_SetStyle( hwnd, WS_VISIBLE, 0 );
+        else WIN_SetStyle( hwnd, 0, WS_VISIBLE );
+    }
+    else
+    {
+        if (style & WS_CHILD)
+        {
+            if (state_change)
+            {
+                /* it appears that Windows always adds an undocumented 0x8000
+                 * flag if the state of a window changes.
+                 */
+                swp |= SWP_STATECHANGED;
+            }
+        }
+
+        SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
+                      newPos.right, newPos.bottom, LOWORD(swp) );
+    }
+
+    if (cmd == SW_HIDE)
+    {
+        HWND hFocus;
+
+        /* 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(hwnd);
+
+        /* Revert focus to parent */
+        hFocus = GetFocus();
+        if (hwnd == hFocus || IsChild(hwnd, hFocus))
+        {
+            HWND parent = GetAncestor(hwnd, GA_PARENT);
+            if (parent == GetDesktopWindow()) parent = 0;
+            SetFocus(parent);
+        }
+    }
+
+    if (IsIconic(hwnd)) WINPOS_ShowIconTitle( hwnd, TRUE );
+
+    if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return wasVisible;
+
+    if (wndPtr->flags & WIN_NEED_SIZE)
+    {
+        /* should happen only in CreateWindowEx() */
+	int wParam = SIZE_RESTORED;
+        RECT client = wndPtr->rectClient;
+
+	wndPtr->flags &= ~WIN_NEED_SIZE;
+	if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
+	else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
+        WIN_ReleasePtr( wndPtr );
+
+        SendMessageW( hwnd, WM_SIZE, wParam,
+                      MAKELONG( client.right - client.left, client.bottom - client.top ));
+        SendMessageW( hwnd, WM_MOVE, 0, MAKELONG( client.left, client.top ));
+    }
+    else WIN_ReleasePtr( wndPtr );
+
+    return wasVisible;
+}
+
+/***********************************************************************
  *		ShowWindowAsync (USER32.@)
  *
  * doesn't wait; returns immediately.
@@ -867,12 +1184,11 @@ BOOL WINAPI ShowWindowAsync( HWND hwnd,
     }
 
     if ((full_handle = WIN_IsCurrentThread( hwnd )))
-        return USER_Driver->pShowWindow( full_handle, cmd );
+        return USER_ShowWindow( full_handle, cmd );
 
     return SendNotifyMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 );
 }
 
-
 /***********************************************************************
  *		ShowWindow (USER32.@)
  */
@@ -886,7 +1202,7 @@ BOOL WINAPI ShowWindow( HWND hwnd, INT c
         return FALSE;
     }
     if ((full_handle = WIN_IsCurrentThread( hwnd )))
-        return USER_Driver->pShowWindow( full_handle, cmd );
+        return USER_ShowWindow( full_handle, cmd );
 
     return SendMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 );
 }
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 58b0c9c..337ce37 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -145,23 +145,6 @@ static int get_window_attributes( Displa
 
 
 /***********************************************************************
- *              X11DRV_sync_window_style
- *
- * Change the X window attributes when the window style has changed.
- */
-void X11DRV_sync_window_style( Display *display, struct x11drv_win_data *data )
-{
-    XSetWindowAttributes attr;
-    int mask = get_window_attributes( display, data, &attr );
-
-    wine_tsx11_lock();
-    if (data->whole_window != DefaultRootWindow(display))
-        XChangeWindowAttributes( display, data->whole_window, mask, &attr );
-    wine_tsx11_unlock();
-}
-
-
-/***********************************************************************
  *              get_window_changes
  *
  * fill the window changes structure
@@ -299,14 +282,18 @@ static void set_icon_hints( Display *dis
 }
 
 /***********************************************************************
- *              systray_dock_window
+ *              SystrayDockWindow   (X11DRV.@)
  *
- * Docks the given X window with the NETWM system tray.
+ * Docks the given window with the NETWM system tray.
  */
-static void systray_dock_window( Display *display, struct x11drv_win_data *data )
+void X11DRV_SystrayDockWindow( HWND hwnd )
 {
+    Display *display = thread_display();
+    struct x11drv_win_data *data;
     static Atom systray_atom;
     Window systray_window;
+    
+    if (!(data = X11DRV_get_win_data( hwnd ))) return;
 
     wine_tsx11_lock();
     if (!systray_atom)
@@ -588,11 +575,11 @@ void X11DRV_set_wm_hints( Display *displ
 
 
 /***********************************************************************
- *              X11DRV_set_iconic_state
+ *              X11DRV_SetIconicState    (X11DRV.@)
  *
  * Set the X11 iconic state according to the window style.
  */
-void X11DRV_set_iconic_state( HWND hwnd )
+void X11DRV_SetIconicState( HWND hwnd )
 {
     Display *display = thread_display();
     struct x11drv_win_data *data;
@@ -1005,14 +992,8 @@ BOOL X11DRV_CreateDesktopWindow( HWND hw
 BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
 {
     Display *display = thread_display();
-    WND *wndPtr;
     struct x11drv_win_data *data;
-    HWND insert_after;
     RECT rect;
-    DWORD style;
-    CBT_CREATEWNDA cbtc;
-    CREATESTRUCTA cbcs;
-    BOOL ret = FALSE;
 
     if (!(data = alloc_win_data( display, hwnd ))) return FALSE;
 
@@ -1044,7 +1025,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CRE
     /* create an X window if it's a top level window */
     if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
     {
-        if (!create_whole_window( display, data, cs->style )) goto failed;
+        if (!create_whole_window( display, data, cs->style )) return FALSE;
     }
     else if (hwnd == GetDesktopWindow())
     {
@@ -1054,134 +1035,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CRE
     /* get class or window DC if needed */
     alloc_window_dce( data );
 
-    /* Call the WH_CBT hook */
-
-    /* the window style passed to the hook must be the real window style,
-     * rather than just the window style that the caller to CreateWindowEx
-     * passed in, so we have to copy the original CREATESTRUCT and get the
-     * the real style. */
-    cbcs = *cs;
-    cbcs.style = GetWindowLongW(hwnd, GWL_STYLE);
-
-    cbtc.lpcs = &cbcs;
-    cbtc.hwndInsertAfter = HWND_TOP;
-    if (HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc, unicode ))
-    {
-        TRACE("CBT-hook returned !0\n");
-        goto failed;
-    }
-
-    /* Send the WM_GETMINMAXINFO message and fix the size if needed */
-    if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
-    {
-        POINT maxSize, maxPos, minTrack, maxTrack;
-
-        WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack);
-        if (maxSize.x < cs->cx) cs->cx = maxSize.x;
-        if (maxSize.y < cs->cy) cs->cy = maxSize.y;
-        if (cs->cx < 0) cs->cx = 0;
-        if (cs->cy < 0) cs->cy = 0;
-
-        SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
-        if (!X11DRV_SetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER, NULL )) return FALSE;
-    }
-
-    /* send WM_NCCREATE */
-    TRACE( "hwnd %p cs %d,%d %dx%d\n", hwnd, cs->x, cs->y, cs->cx, cs->cy );
-    if (unicode)
-        ret = SendMessageW( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
-    else
-        ret = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
-    if (!ret)
-    {
-        WARN("aborted by WM_xxCREATE!\n");
-        return FALSE;
-    }
-
-    /* make sure the window is still valid */
-    if (!(data = X11DRV_get_win_data( hwnd ))) return FALSE;
-    if (data->whole_window) X11DRV_sync_window_style( display, data );
-
-    /* send WM_NCCALCSIZE */
-    rect = data->window_rect;
-    SendMessageW( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect );
-
-    if (!(wndPtr = WIN_GetPtr(hwnd))) return FALSE;
-
-    /* yes, even if the CBT hook was called with HWND_TOP */
-    insert_after = ((wndPtr->dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
-
-    X11DRV_SetWindowPos( hwnd, insert_after, &wndPtr->rectWindow, &rect, 0, NULL );
-
-    TRACE( "win %p window %d,%d,%d,%d client %d,%d,%d,%d whole %d,%d,%d,%d X client %d,%d,%d,%d xwin %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 );
-
-    WIN_ReleasePtr( wndPtr );
-
-    if (unicode)
-        ret = (SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
-    else
-        ret = (SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
-
-    if (!ret) return FALSE;
-
-    NotifyWinEvent(EVENT_OBJECT_CREATE, hwnd, OBJID_WINDOW, 0);
-
-    /* Send the size messages */
-
-    if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS) return FALSE;
-    if (!(wndPtr->flags & WIN_NEED_SIZE))
-    {
-        RECT rect = wndPtr->rectClient;
-        WIN_ReleasePtr( wndPtr );
-        /* send it anyway */
-        if (((rect.right-rect.left) <0) ||((rect.bottom-rect.top)<0))
-            WARN("sending bogus WM_SIZE message 0x%08x\n",
-                 MAKELONG(rect.right-rect.left, rect.bottom-rect.top));
-        SendMessageW( hwnd, WM_SIZE, SIZE_RESTORED,
-                      MAKELONG(rect.right-rect.left, rect.bottom-rect.top));
-        SendMessageW( hwnd, WM_MOVE, 0, MAKELONG( rect.left, rect.top ) );
-    }
-    else WIN_ReleasePtr( wndPtr );
-
-    /* Show the window, maximizing or minimizing if needed */
-
-    style = GetWindowLongW( hwnd, GWL_STYLE );
-    if (style & (WS_MINIMIZE | WS_MAXIMIZE))
-    {
-        extern UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ); /*FIXME*/
-
-        RECT newPos;
-        UINT swFlag = (style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
-        WIN_SetStyle( hwnd, 0, WS_MAXIMIZE | WS_MINIMIZE );
-        WINPOS_MinMaximize( hwnd, swFlag, &newPos );
-
-        swFlag = SWP_FRAMECHANGED | SWP_NOZORDER; /* Frame always gets changed */
-        if (!(style & WS_VISIBLE) || (style & WS_CHILD) || GetActiveWindow()) swFlag |= SWP_NOACTIVATE;
-
-        SetWindowPos( hwnd, 0, newPos.left, newPos.top,
-                      newPos.right, newPos.bottom, swFlag );
-    }
-
-    /* Dock system tray windows. */
-    /* Dock after the window is created so we don't have problems calling
-     * SetWindowPos. */
-    if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_TRAYWINDOW)
-        systray_dock_window( display, data );
-
     return TRUE;
-
- failed:
-    X11DRV_DestroyWindow( hwnd );
-    return FALSE;
 }
 
 
@@ -1226,6 +1080,31 @@ XIC X11DRV_get_ic( HWND hwnd )
     return data->xic;
 }
 
+/***********************************************************************
+ *              SyncWindowStyle   (X11DRV.@)
+ *
+ * Change the X window attributes when the window style has changed.
+ */
+void X11DRV_SyncWindowStyle( HWND hwnd )
+{
+    XSetWindowAttributes attr;
+    int mask;
+    
+    Display *display = thread_display();
+    struct x11drv_win_data *data;
+
+    if (!(data = X11DRV_get_win_data( hwnd ))) return;
+
+    if(!data->whole_window)
+        return;
+
+    mask = get_window_attributes( display, data, &attr );
+
+    wine_tsx11_lock();
+    if (data->whole_window != DefaultRootWindow(display))
+        XChangeWindowAttributes( display, data->whole_window, mask, &attr );
+    wine_tsx11_unlock();
+}
 
 /*****************************************************************
  *		SetParent   (X11DRV.@)
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index 4b136b2..caff77d 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -103,14 +103,16 @@
 @ cdecl ScrollDC(long long long ptr ptr long ptr) X11DRV_ScrollDC
 @ cdecl SetClipboardData(long long long long) X11DRV_SetClipboardData
 @ cdecl SetFocus(long) X11DRV_SetFocus
+@ cdecl SetIconicState(long) X11DRV_SetIconicState
 @ cdecl SetParent(long long) X11DRV_SetParent
 @ cdecl SetWindowIcon(long long long) X11DRV_SetWindowIcon
 @ cdecl SetWindowPos(ptr ptr ptr ptr long ptr) X11DRV_SetWindowPos
 @ cdecl SetWindowRgn(long long long) X11DRV_SetWindowRgn
 @ cdecl SetWindowStyle(ptr long) X11DRV_SetWindowStyle
 @ cdecl SetWindowText(long wstr) X11DRV_SetWindowText
-@ cdecl ShowWindow(long long) X11DRV_ShowWindow
+@ cdecl SyncWindowStyle(long) X11DRV_SyncWindowStyle
 @ cdecl SysCommandSizeMove(long long) X11DRV_SysCommandSizeMove
+@ cdecl SystrayDockWindow(long) X11DRV_SystrayDockWindow
 @ cdecl WindowFromDC(long) X11DRV_WindowFromDC
 @ cdecl WindowMessage(long long long long) X11DRV_WindowMessage
 
diff --git a/dlls/winex11.drv/winpos.c b/dlls/winex11.drv/winpos.c
index 5a88a74..9dc3bdb 100644
--- a/dlls/winex11.drv/winpos.c
+++ b/dlls/winex11.drv/winpos.c
@@ -148,7 +148,7 @@ void X11DRV_SetWindowStyle( HWND hwnd, D
             if (new_style & WS_VISIBLE)
             {
                 TRACE( "mapping win %p\n", hwnd );
-                X11DRV_sync_window_style( display, data );
+                X11DRV_SyncWindowStyle( hwnd );
                 X11DRV_set_wm_hints( display, data );
                 wine_tsx11_lock();
                 XMapWindow( display, data->whole_window );
@@ -359,7 +359,7 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWN
                 {
                     /* window got shown, map it */
                     TRACE( "mapping win %p\n", hwnd );
-                    X11DRV_sync_window_style( display, data );
+                    X11DRV_SyncWindowStyle( hwnd );
                     X11DRV_set_wm_hints( display, data );
                     wine_tsx11_lock();
                     XMapWindow( display, data->whole_window );
@@ -382,326 +382,6 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWN
     return ret;
 }
 
-
-/***********************************************************************
- *           WINPOS_FindIconPos
- *
- * Find a suitable place for an iconic window.
- */
-static POINT WINPOS_FindIconPos( HWND hwnd, POINT pt )
-{
-    RECT rect, rectParent;
-    HWND parent, child;
-    HRGN hrgn, tmp;
-    int xspacing, yspacing;
-
-    parent = GetAncestor( hwnd, GA_PARENT );
-    GetClientRect( parent, &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);
-
-    /* Check if another icon already occupies this spot */
-    /* FIXME: this is completely inefficient */
-
-    hrgn = CreateRectRgn( 0, 0, 0, 0 );
-    tmp = CreateRectRgn( 0, 0, 0, 0 );
-    for (child = GetWindow( parent, GW_HWNDFIRST ); child; child = GetWindow( child, GW_HWNDNEXT ))
-    {
-        WND *childPtr;
-        if (child == hwnd) continue;
-        if ((GetWindowLongW( child, GWL_STYLE ) & (WS_VISIBLE|WS_MINIMIZE)) != (WS_VISIBLE|WS_MINIMIZE))
-            continue;
-        if (!(childPtr = WIN_GetPtr( child )) || childPtr == WND_OTHER_PROCESS)
-            continue;
-        SetRectRgn( tmp, childPtr->rectWindow.left, childPtr->rectWindow.top,
-                    childPtr->rectWindow.right, childPtr->rectWindow.bottom );
-        CombineRgn( hrgn, hrgn, tmp, RGN_OR );
-        WIN_ReleasePtr( childPtr );
-    }
-    DeleteObject( tmp );
-
-    for (rect.bottom = rectParent.bottom; rect.bottom >= yspacing; rect.bottom -= yspacing)
-    {
-        for (rect.left = rectParent.left; rect.left <= rectParent.right - xspacing; rect.left += xspacing)
-        {
-            rect.right = rect.left + xspacing;
-            rect.top = rect.bottom - yspacing;
-            if (!RectInRegion( hrgn, &rect ))
-            {
-                /* No window was found, so it's OK for us */
-                pt.x = rect.left + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
-                pt.y = rect.top + (yspacing - GetSystemMetrics(SM_CYICON)) / 2;
-                DeleteObject( hrgn );
-                return pt;
-            }
-        }
-    }
-    DeleteObject( hrgn );
-    pt.x = pt.y = 0;
-    return pt;
-}
-
-
-/***********************************************************************
- *           WINPOS_MinMaximize
- */
-UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
-{
-    WND *wndPtr;
-    UINT swpFlags = 0;
-    POINT size;
-    LONG old_style;
-    WINDOWPLACEMENT wpl;
-
-    TRACE("%p %u\n", hwnd, cmd );
-
-    wpl.length = sizeof(wpl);
-    GetWindowPlacement( hwnd, &wpl );
-
-    if (HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)hwnd, cmd, TRUE ))
-        return SWP_NOSIZE | SWP_NOMOVE;
-
-    if (IsIconic( hwnd ))
-    {
-        switch (cmd)
-        {
-        case SW_SHOWMINNOACTIVE:
-        case SW_SHOWMINIMIZED:
-        case SW_FORCEMINIMIZE:
-        case SW_MINIMIZE:
-            return SWP_NOSIZE | SWP_NOMOVE;
-        }
-        if (!SendMessageW( hwnd, WM_QUERYOPEN, 0, 0 )) return SWP_NOSIZE | SWP_NOMOVE;
-        swpFlags |= SWP_NOCOPYBITS;
-    }
-
-    switch( cmd )
-    {
-    case SW_SHOWMINNOACTIVE:
-    case SW_SHOWMINIMIZED:
-    case SW_FORCEMINIMIZE:
-    case SW_MINIMIZE:
-        if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
-        if( wndPtr->dwStyle & WS_MAXIMIZE) wndPtr->flags |= WIN_RESTORE_MAX;
-        else wndPtr->flags &= ~WIN_RESTORE_MAX;
-        WIN_ReleasePtr( wndPtr );
-
-        WIN_SetStyle( hwnd, WS_MINIMIZE, WS_MAXIMIZE );
-
-        X11DRV_set_iconic_state( hwnd );
-
-        wpl.ptMinPosition = WINPOS_FindIconPos( hwnd, wpl.ptMinPosition );
-
-        SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y,
-                 GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
-        swpFlags |= SWP_NOCOPYBITS;
-        break;
-
-    case SW_MAXIMIZE:
-        old_style = GetWindowLongW( hwnd, GWL_STYLE );
-        if ((old_style & WS_MAXIMIZE) && (old_style & WS_VISIBLE)) return SWP_NOSIZE | SWP_NOMOVE;
-
-        WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL );
-
-        old_style = WIN_SetStyle( hwnd, WS_MAXIMIZE, WS_MINIMIZE );
-        if (old_style & WS_MINIMIZE)
-        {
-            WINPOS_ShowIconTitle( hwnd, FALSE );
-            X11DRV_set_iconic_state( hwnd );
-        }
-        SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
-        break;
-
-    case SW_RESTORE:
-        old_style = WIN_SetStyle( hwnd, 0, WS_MINIMIZE | WS_MAXIMIZE );
-        if (old_style & WS_MINIMIZE)
-        {
-            BOOL restore_max;
-
-            WINPOS_ShowIconTitle( hwnd, FALSE );
-            X11DRV_set_iconic_state( hwnd );
-
-            if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
-            restore_max = (wndPtr->flags & WIN_RESTORE_MAX) != 0;
-            WIN_ReleasePtr( wndPtr );
-            if (restore_max)
-            {
-                /* Restore to maximized position */
-                WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL);
-                WIN_SetStyle( hwnd, WS_MAXIMIZE, 0 );
-                SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
-                break;
-            }
-        }
-        else if (!(old_style & WS_MAXIMIZE)) break;
-
-        /* Restore to normal position */
-
-        *rect = wpl.rcNormalPosition;
-        rect->right -= rect->left;
-        rect->bottom -= rect->top;
-
-        break;
-    }
-
-    return swpFlags;
-}
-
-
-/***********************************************************************
- *              ShowWindow   (X11DRV.@)
- */
-BOOL X11DRV_ShowWindow( HWND hwnd, INT cmd )
-{
-    WND *wndPtr;
-    HWND parent;
-    LONG style = GetWindowLongW( hwnd, GWL_STYLE );
-    BOOL wasVisible = (style & WS_VISIBLE) != 0;
-    BOOL showFlag = TRUE, state_change = FALSE;
-    RECT newPos = {0, 0, 0, 0};
-    UINT swp = 0;
-
-    TRACE("hwnd=%p, cmd=%d, wasVisible %d\n", hwnd, cmd, wasVisible);
-
-    switch(cmd)
-    {
-        case SW_HIDE:
-            if (!wasVisible) return FALSE;
-            showFlag = FALSE;
-            swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
-            if (hwnd != GetActiveWindow())
-                swp |= SWP_NOACTIVATE | SWP_NOZORDER;
-	    break;
-
-	case SW_SHOWMINNOACTIVE:
-            swp |= SWP_NOACTIVATE | SWP_NOZORDER;
-            /* fall through */
-        case SW_MINIMIZE:
-        case SW_FORCEMINIMIZE: /* FIXME: Does not work if thread is hung. */
-            if (style & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
-            /* fall through */
-	case SW_SHOWMINIMIZED:
-            swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
-            swp |= WINPOS_MinMaximize( hwnd, cmd, &newPos );
-            if (style & WS_MINIMIZE) return wasVisible;
-            state_change = TRUE;
-	    break;
-
-	case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
-            swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
-            swp |= WINPOS_MinMaximize( hwnd, SW_MAXIMIZE, &newPos );
-            if ((style & WS_MAXIMIZE) && wasVisible) return wasVisible;
-            state_change = TRUE;
-            break;
-
-	case SW_SHOWNA:
-            swp |= SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
-            if (style & WS_CHILD) swp |= SWP_NOZORDER;
-            break;
-	case SW_SHOW:
-            if (wasVisible) return TRUE;
-	    swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
-            if (style & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
-	    break;
-
-	case SW_RESTORE:
-	    swp |= SWP_FRAMECHANGED;
-            state_change = TRUE;
-            /* fall through */
-	case SW_SHOWNOACTIVATE:
-            swp |= SWP_NOACTIVATE | SWP_NOZORDER;
-            /* fall through */
-	case SW_SHOWNORMAL:  /* same as SW_NORMAL: */
-	case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
-	    swp |= SWP_SHOWWINDOW;
-            if (style & (WS_MINIMIZE | WS_MAXIMIZE))
-		 swp |= WINPOS_MinMaximize( hwnd, SW_RESTORE, &newPos );
-            else swp |= SWP_NOSIZE | SWP_NOMOVE;
-            if (style & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
-	    break;
-    }
-
-    if ((showFlag != wasVisible || cmd == SW_SHOWNA) && !state_change)
-    {
-        SendMessageW( hwnd, WM_SHOWWINDOW, showFlag, 0 );
-        if (!IsWindow( hwnd )) return wasVisible;
-    }
-
-    parent = GetAncestor( hwnd, GA_PARENT );
-    if (parent && !IsWindowVisible( parent ) && !state_change)
-    {
-        /* if parent is not visible simply toggle WS_VISIBLE and return */
-        if (showFlag) WIN_SetStyle( hwnd, WS_VISIBLE, 0 );
-        else WIN_SetStyle( hwnd, 0, WS_VISIBLE );
-    }
-    else
-    {
-        if (style & WS_CHILD)
-        {
-            if (state_change)
-            {
-                /* it appears that Windows always adds an undocumented 0x8000
-                 * flag if the state of a window changes.
-                 */
-                swp |= SWP_STATECHANGED;
-            }
-        }
-
-        SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
-                      newPos.right, newPos.bottom, LOWORD(swp) );
-    }
-
-    if (cmd == SW_HIDE)
-    {
-        HWND hFocus;
-
-        /* 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(hwnd);
-
-        /* Revert focus to parent */
-        hFocus = GetFocus();
-        if (hwnd == hFocus || IsChild(hwnd, hFocus))
-        {
-            HWND parent = GetAncestor(hwnd, GA_PARENT);
-            if (parent == GetDesktopWindow()) parent = 0;
-            SetFocus(parent);
-        }
-    }
-
-    if (IsIconic(hwnd)) WINPOS_ShowIconTitle( hwnd, TRUE );
-
-    if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return wasVisible;
-
-    if (wndPtr->flags & WIN_NEED_SIZE)
-    {
-        /* should happen only in CreateWindowEx() */
-	int wParam = SIZE_RESTORED;
-        RECT client = wndPtr->rectClient;
-
-	wndPtr->flags &= ~WIN_NEED_SIZE;
-	if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
-	else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
-        WIN_ReleasePtr( wndPtr );
-
-        SendMessageW( hwnd, WM_SIZE, wParam,
-                      MAKELONG( client.right - client.left, client.bottom - client.top ));
-        SendMessageW( hwnd, WM_MOVE, 0, MAKELONG( client.left, client.top ));
-    }
-    else WIN_ReleasePtr( wndPtr );
-
-    return wasVisible;
-}
-
-
 /**********************************************************************
  *		X11DRV_MapNotify
  */
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index eb29a4e..a01ba24 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -679,13 +679,14 @@ extern int X11DRV_check_error(void);
 extern void X11DRV_set_iconic_state( HWND hwnd );
 extern void X11DRV_window_to_X_rect( struct x11drv_win_data *data, RECT *rect );
 extern void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect );
-extern void X11DRV_sync_window_style( Display *display, struct x11drv_win_data *data );
+extern void X11DRV_SyncWindowStyle( HWND hwnd );
 extern void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data,
                                          UINT swp_flags, const RECT *new_client_rect,
                                          const RECT *new_whole_rect );
 extern BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
                                    const RECT *rectClient, UINT swp_flags, const RECT *validRects );
 extern void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data );
+extern void X11DRV_SystrayDockWindow( HWND hwnd );
 extern void xinerama_init(void);
 
 extern void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height );


More information about the wine-patches mailing list