/*
 * TTY window driver
 *
 * Copyright 1998,1999 Patrik Stridvall
 */

#include "config.h"

#include "gdi.h"
#include "ttydrv.h"
#include "region.h"
#include "win.h"
#include "winpos.h"
#include "debugtools.h"
#include "hook.h"

DEFAULT_DEBUG_CHANNEL(ttydrv);

#define SWP_AGG_NOGEOMETRYCHANGE \
    (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
#define SWP_AGG_NOPOSCHANGE \
    (SWP_AGG_NOGEOMETRYCHANGE | SWP_NOZORDER)
#define SWP_AGG_STATUSFLAGS \
    (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)

/**********************************************************************
 *		CreateWindow   (TTYDRV.@)
 */
BOOL TTYDRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
{
    BOOL ret;
    HWND hwndLinkAfter;

#ifdef WINE_CURSES
    WND *wndPtr = WIN_FindWndPtr( hwnd );
    WINDOW *window;
    INT cellWidth=8, cellHeight=8; /* FIXME: Hardcoded */

    TRACE("(%x)\n", hwnd);

    /* Only create top-level windows */
    if (!(wndPtr->dwStyle & WS_CHILD))
    {
        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);
        }
        wndPtr->pDriverData = window;
    }
    WIN_ReleaseWndPtr( wndPtr );
#else /* defined(WINE_CURSES) */
    FIXME("(%x): stub\n", hwnd);
#endif /* defined(WINE_CURSES) */

    /* Call the WH_CBT hook */

    hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
 ? HWND_BOTTOM : HWND_TOP;

    if (HOOK_IsHooked( WH_CBT ))
    {
	CBT_CREATEWNDA cbtc;
        LRESULT lret;

	cbtc.lpcs = cs;
	cbtc.hwndInsertAfter = hwndLinkAfter;
        lret = (unicode) ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND,
                                                       (WPARAM)hwnd, (LPARAM)&cbtc)
                        : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND,
                                                       (WPARAM)hwnd, (LPARAM)&cbtc);
        if (lret)
	{
	    TRACE("CBT-hook returned !0\n");
            return FALSE;
	} 
    }

    if (unicode)
    {
        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;
}

/***********************************************************************
 *		DestroyWindow   (TTYDRV.@)
 */
BOOL TTYDRV_DestroyWindow( HWND hwnd )
{
#ifdef WINE_CURSES
    WND *wndPtr = WIN_FindWndPtr( hwnd );
    WINDOW *window = wndPtr->pDriverData;

    TRACE("(%x)\n", hwnd);

    if (window && window != root_window) delwin(window);
    wndPtr->pDriverData = NULL;
    WIN_ReleaseWndPtr( wndPtr );
#else /* defined(WINE_CURSES) */
    FIXME("(%x): stub\n", hwnd);
#endif /* defined(WINE_CURSES) */
    return TRUE;
}


/***********************************************************************
 *           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
 *
 * 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.
 */
static BOOL DCE_GetVisRect( WND *wndPtr, BOOL clientArea, RECT *lprect )
{
    *lprect = clientArea ? wndPtr->rectClient : wndPtr->rectWindow;

    if (wndPtr->dwStyle & WS_VISIBLE)
    {
        INT xoffset = lprect->left;
        INT yoffset = lprect->top;

        while ((wndPtr = WIN_FindWndPtr( GetAncestor(wndPtr->hwndSelf,GA_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;
    }

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 void DCE_AddClipRects( HWND parent, HWND end, HRGN hrgnClip, LPRECT lpRect, int x, int y )
{
    RECT rect;
    WND *pWnd;
    int i;
    HWND *list = WIN_ListChildren( parent );

    if (!list) return;
    for (i = 0; list[i]; i++)
    {
        if (list[i] == end) break;
        if (!(pWnd = WIN_FindWndPtr( list[i] ))) continue;
        if (pWnd->dwStyle & WS_VISIBLE)
        {
            rect.left = pWnd->rectWindow.left + x;
            rect.top = pWnd->rectWindow.top + y;
            rect.right = pWnd->rectWindow.right + x;
            rect.bottom = pWnd->rectWindow.bottom + y;
            if( IntersectRect( &rect, &rect, lpRect ))
            {
                if(!REGION_UnionRectWithRgn( hrgnClip, &rect ))
                {
                    WIN_ReleaseWndPtr( pWnd );
                    break;
                }
            }
        }
        WIN_ReleaseWndPtr( pWnd );
    }
    HeapFree( GetProcessHeap(), 0, list );
}


/***********************************************************************
 *           DCE_GetVisRgn
 *
 * 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.
 */
static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
{
    HRGN hrgnVis = 0;
    RECT rect;
    WND *wndPtr = WIN_FindWndPtr( hwnd );
    WND *childWnd = WIN_FindWndPtr( hwndChild );

    /* Get visible rectangle and create a region with it. */

    if (wndPtr && DCE_GetVisRect(wndPtr, !(flags & DCX_WINDOW), &rect))
    {
        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)
                {
                    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->hwndSelf, 0, 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)
                {
                    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->hwndSelf, 0, 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, wndPtr->hwndSelf,
                                      hrgnClip, &rect, xoffset, yoffset );

                /* Clip siblings of all ancestors that have the
                 * WS_CLIPSIBLINGS style
		 */

                while (wndPtr->parent)
                {
                    WND *ptr = WIN_FindWndPtr( wndPtr->parent );
                    WIN_ReleaseWndPtr( wndPtr );
                    wndPtr = ptr;
                    xoffset -= wndPtr->rectClient.left;
                    yoffset -= wndPtr->rectClient.top;
                    if(wndPtr->dwStyle & WS_CLIPSIBLINGS && wndPtr->parent)
                    {
                        DCE_AddClipRects( wndPtr->parent, wndPtr->hwndSelf,
                                          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;
            }
        }
    }
    else
        hrgnVis = CreateRectRgn(0, 0, 0, 0); /* empty */
    WIN_ReleaseWndPtr(wndPtr);
    WIN_ReleaseWndPtr(childWnd);
    return hrgnVis;
}


/***********************************************************************
 *		GetDC   (TTYDRV.@)
 *
 * Set the drawable, origin and dimensions for the DC associated to
 * a given window.
 */
BOOL TTYDRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
{
    WND *wndPtr = WIN_FindWndPtr(hwnd);
    DC *dc;
    BOOL updateVisRgn;
    HRGN hrgnVisible = 0;

    if (!wndPtr) return FALSE;

    if (!(dc = DC_GetDCPtr( hdc )))
    {
        WIN_ReleaseWndPtr( wndPtr );
        return FALSE;
    }

    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;
    }
    updateVisRgn = (dc->flags & DC_DIRTY) != 0;
    GDI_ReleaseObj( hdc );

    if (updateVisRgn)
    {
        if (flags & DCX_PARENTCLIP)
        {
            WND *parentPtr = WIN_FindWndPtr( 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);
        }
        else
        {
            hrgnVisible = DCE_GetVisRgn( hwnd, flags, 0, 0 );
            DCE_OffsetVisRgn( hdc, hrgnVisible );
        }
        SelectVisRgn16( hdc, hrgnVisible );
    }

    /* apply additional region operation (if any) */

    if( flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) )
    {
        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 );
    }

    if (hrgnVisible) DeleteObject( hrgnVisible );

    WIN_ReleaseWndPtr( wndPtr );
    return TRUE;
}


/***********************************************************************
 *		SetWindowPos   (TTYDRV.@)
 */
BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
{
    WND *wndPtr;
    RECT newWindowRect, newClientRect;
    BOOL retvalue;
    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);

    /* ------------------------------------------------------------------------ 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;
    else
    {
        if (!(winpos->flags & SWP_SHOWWINDOW)) winpos->flags |= SWP_NOREDRAW;
        winpos->flags &= ~SWP_HIDEWINDOW;
    }

    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))
        winpos->flags |= SWP_NOSIZE;    /* Already the right size */

    if ((wndPtr->rectWindow.left == winpos->x) && (wndPtr->rectWindow.top == winpos->y))
        winpos->flags |= SWP_NOMOVE;    /* Already the right position */

    if (winpos->hwnd == hwndActive)
        winpos->flags |= SWP_NOACTIVATE;   /* Already active */
    else if ( (wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD )
    {
        if(!(winpos->flags & SWP_NOACTIVATE)) /* Bring to the top when activating */
        {
            winpos->flags &= ~SWP_NOZORDER;
            winpos->hwndInsertAfter = HWND_TOP;
            goto Pos;
        }
    }

    /* Check hwndInsertAfter */

      /* FIXME: TOPMOST not supported yet */
    if ((winpos->hwndInsertAfter == HWND_TOPMOST) ||
        (winpos->hwndInsertAfter == HWND_NOTOPMOST)) winpos->hwndInsertAfter = HWND_TOP;

    /* hwndInsertAfter must be a sibling of the window */
    if ((winpos->hwndInsertAfter != HWND_TOP) && (winpos->hwndInsertAfter != HWND_BOTTOM))
    {
        WND* wnd = WIN_FindWndPtr(winpos->hwndInsertAfter);

        if( wnd ) {
            if( wnd->parent != wndPtr->parent )
            {
                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 ((winpos->hwnd == winpos->hwndInsertAfter) ||
                (winpos->hwnd == GetWindow( winpos->hwndInsertAfter, GW_HWNDNEXT )))
                winpos->flags |= SWP_NOZORDER;
        }
        WIN_ReleaseWndPtr(wnd);
    }

 Pos:  /* ------------------------------------------------------------------------ MAIN part */

      /* Send WM_WINDOWPOSCHANGING message */

    if (!(winpos->flags & SWP_NOSENDCHANGING))
        SendMessageA( wndPtr->hwndSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM)winpos );

      /* Calculate new position and size */

    newWindowRect = wndPtr->rectWindow;
    newClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
                                                    : wndPtr->rectClient;

    if (!(winpos->flags & SWP_NOSIZE))
    {
        newWindowRect.right  = newWindowRect.left + winpos->cx;
        newWindowRect.bottom = newWindowRect.top + winpos->cy;
    }
    if (!(winpos->flags & SWP_NOMOVE))
    {
        newWindowRect.left    = winpos->x;
        newWindowRect.top     = winpos->y;
        newWindowRect.right  += winpos->x - wndPtr->rectWindow.left;
        newWindowRect.bottom += winpos->y - wndPtr->rectWindow.top;

        OffsetRect( &newClientRect, winpos->x - wndPtr->rectWindow.left,
                    winpos->y - wndPtr->rectWindow.top );
    }

    if( winpos->hwndInsertAfter == HWND_TOP )
    {
        if (GetWindow( wndPtr->hwndSelf, GW_HWNDFIRST ) == wndPtr->hwndSelf)
            winpos->flags |= SWP_NOZORDER;
    }
    else
        if( winpos->hwndInsertAfter == HWND_BOTTOM )
        {
            if (!GetWindow( wndPtr->hwndSelf, GW_HWNDNEXT ))
                winpos->flags |= SWP_NOZORDER;
        }
        else
            if( !(winpos->flags & SWP_NOZORDER) )
                if( GetWindow(winpos->hwndInsertAfter, GW_HWNDNEXT) == wndPtr->hwndSelf )
                    winpos->flags |= SWP_NOZORDER;

    /* Common operations */

      /* Send WM_NCCALCSIZE message to get new client area */
    if( (winpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
    {
        NCCALCSIZE_PARAMS params;
        WINDOWPOS winposCopy;

        params.rgrc[0] = newWindowRect;
        params.rgrc[1] = wndPtr->rectWindow;
        params.rgrc[2] = wndPtr->rectClient;
        params.lppos = &winposCopy;
        winposCopy = *winpos;

        SendMessageW( winpos->hwnd, WM_NCCALCSIZE, TRUE, (LPARAM)&params );

        TRACE( "%d,%d-%d,%d\n", params.rgrc[0].left, params.rgrc[0].top,
               params.rgrc[0].right, params.rgrc[0].bottom );

        /* If the application send back garbage, ignore it */
        if (params.rgrc[0].left <= params.rgrc[0].right &&
            params.rgrc[0].top <= params.rgrc[0].bottom)
            newClientRect = params.rgrc[0];

         /* FIXME: WVR_ALIGNxxx */

        if( newClientRect.left != wndPtr->rectClient.left ||
            newClientRect.top != wndPtr->rectClient.top )
            winpos->flags &= ~SWP_NOCLIENTMOVE;

        if( (newClientRect.right - newClientRect.left !=
             wndPtr->rectClient.right - wndPtr->rectClient.left) ||
            (newClientRect.bottom - newClientRect.top !=
             wndPtr->rectClient.bottom - wndPtr->rectClient.top) )
            winpos->flags &= ~SWP_NOCLIENTSIZE;
    }

    if(!(winpos->flags & SWP_NOZORDER) && winpos->hwnd != winpos->hwndInsertAfter)
    {
        HWND parent = GetAncestor( winpos->hwnd, GA_PARENT );
        if (parent) WIN_LinkWindow( winpos->hwnd, parent, winpos->hwndInsertAfter );
    }

    /* FIXME: actually do something with WVR_VALIDRECTS */

    WIN_SetRectangles( winpos->hwnd, &newWindowRect, &newClientRect );

    if( winpos->flags & SWP_SHOWWINDOW )
        WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle | WS_VISIBLE );
    else if( winpos->flags & SWP_HIDEWINDOW )
        WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle & ~WS_VISIBLE );

    /* ------------------------------------------------------------------------ FINAL */

    /* 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( !(winpos->flags & SWP_NOREDRAW) )
    {
        RedrawWindow( wndPtr->parent, NULL, 0,
                      RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN );
        if (wndPtr->parent == GetDesktopWindow())
            RedrawWindow( wndPtr->parent, NULL, 0,
                          RDW_ERASENOW | RDW_NOCHILDREN );
    }

    if (!(winpos->flags & SWP_NOACTIVATE)) SetActiveWindow( winpos->hwnd );

      /* And last, send the WM_WINDOWPOSCHANGED message */

    TRACE("\tstatus flags = %04x\n", winpos->flags & SWP_AGG_STATUSFLAGS);

    if ((((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) &&
          !(winpos->flags & SWP_NOSENDCHANGING)) )
        SendMessageA( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)winpos );

    retvalue = TRUE;
 END:
    WIN_ReleaseWndPtr(wndPtr);
    return retvalue;
}


/***********************************************************************
 *              WINPOS_MinMaximize   (internal)
 *
 *Lifted from x11 driver	
 */
static UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
{
    WND *wndPtr;
    UINT swpFlags = 0;
    WINDOWPLACEMENT wpl;

    TRACE("0x%04x %u\n", hwnd, cmd );
    FIXME("(%x): stub\n", hwnd);

    wpl.length = sizeof(wpl);
    GetWindowPlacement( hwnd, &wpl );

    /* If I glark this right, yields an immutable window*/
    swpFlags = SWP_NOSIZE | SWP_NOMOVE;

    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;

    /*cmd handling goes here.  see dlls/x1drv/winpos.c*/

    WIN_ReleaseWndPtr( wndPtr );
    return swpFlags;
}

/***********************************************************************
 *              ShowWindow   (TTYDRV.@)
 *
 *Lifted from x11 driver
 *Sets the specified windows' show state.	
 */
BOOL TTYDRV_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;
    hwnd = wndPtr->hwndSelf;  /* make it a full handle */

    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;
    }

    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(hwnd);

        /* 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( hwnd, 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;
}
