/*
 * Window painting functions
 *
 * Copyright 1993 Alexandre Julliard
 */

static char Copyright[] = "Copyright  Alexandre Julliard, 1993";

#include <X11/Xlib.h>

#include "win.h"
#include "message.h"
#include "gdi.h"

  /* Last CTLCOLOR id */
#define CTLCOLOR_MAX   CTLCOLOR_STATIC


/***********************************************************************
 *           BeginPaint    (USER.39)
 */
HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) 
{
    HRGN hrgnUpdate;
    WND * wndPtr = WIN_FindWndPtr( hwnd );
    if (!wndPtr) return 0;

    hrgnUpdate = wndPtr->hrgnUpdate;  /* Save update region */
    if (!hrgnUpdate)    /* Create an empty region */
	if (!(hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ))) return 0;
    
    if (!(lps->hdc = GetDCEx( hwnd, hrgnUpdate,
			      DCX_INTERSECTRGN | DCX_USESTYLE ))) return 0;
    GetRgnBox( InquireVisRgn(lps->hdc), &lps->rcPaint );

    if (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT))
	MSG_DecPaintCount( wndPtr->hmemTaskQ );

    wndPtr->hrgnUpdate = 0;
    wndPtr->flags &= ~(WIN_NEEDS_BEGINPAINT | WIN_INTERNAL_PAINT);

    SendMessage( hwnd, WM_NCPAINT, hrgnUpdate, 0 );
    DeleteObject( hrgnUpdate );

    if (!(wndPtr->flags & WIN_ERASE_UPDATERGN)) lps->fErase = TRUE;
    else lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 );

    return lps->hdc;
}


/***********************************************************************
 *           EndPaint    (USER.40)
 */
void EndPaint( HWND hwnd, LPPAINTSTRUCT lps )
{
    ReleaseDC( hwnd, lps->hdc );
}


/***********************************************************************
 *           FillWindow    (USER.324)
 */
void FillWindow( HWND hwndParent, HWND hwnd, HDC hdc, HBRUSH hbrush )
{
    RECT rect;
    GetClientRect( hwnd, &rect );
    PaintRect( hwndParent, hwnd, hdc, hbrush, &rect );
}


/***********************************************************************
 *           PaintRect    (USER.325)
 */
void PaintRect(HWND hwndParent, HWND hwnd, HDC hdc, HBRUSH hbrush, LPRECT rect)
{
      /* Send WM_CTLCOLOR message if needed */

    if (hbrush <= CTLCOLOR_MAX)
    {
	if (!hwndParent) return;
	hbrush = (HBRUSH)SendMessage( hwndParent, WM_CTLCOLOR,
				      hdc, hwnd | (hbrush << 16) );
    }
    if (hbrush) FillRect( hdc, rect, hbrush );
}


/***********************************************************************
 *           RedrawWindow    (USER.290)
 */
BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
{
    HRGN tmpRgn, hrgn = 0;
    RECT rectClient, rectWindow;
    WND * wndPtr;

    if (!hwnd) hwnd = GetDesktopWindow();
    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
    if (!(wndPtr->dwStyle & WS_VISIBLE) || (wndPtr->flags & WIN_NO_REDRAW))
        return TRUE;  /* No redraw needed */

    /* 
     *	I can't help but feel that this belongs somewhere upstream...
     *
     *  Don't redraw the window if it is iconified and we have an
     *  icon to draw for it
     */
/*    if (IsIconic(hwnd) && wndPtr->hIcon) return FALSE; */

    GetClientRect( hwnd, &rectClient );
    rectWindow = wndPtr->rectWindow;
    OffsetRect(&rectWindow, -wndPtr->rectClient.left, -wndPtr->rectClient.top);

    if (flags & RDW_INVALIDATE)  /* Invalidate */
    {
	if (flags & RDW_ERASE) wndPtr->flags |= WIN_ERASE_UPDATERGN;

	if (hrgnUpdate)  /* Invalidate a region */
	{
	    if (flags & RDW_FRAME) tmpRgn = CreateRectRgnIndirect(&rectWindow);
	    else tmpRgn = CreateRectRgnIndirect( &rectClient );
	    if (!tmpRgn) return FALSE;
	    hrgn = CreateRectRgn( 0, 0, 0, 0 );
	    if (CombineRgn( hrgn, hrgnUpdate, tmpRgn, RGN_AND ) == NULLREGION)
	    {
		DeleteObject( hrgn );
		hrgn = 0;
	    }
	    DeleteObject( tmpRgn );
	}
	else  /* Invalidate a rectangle */
	{
	    RECT rect;
	    if (flags & RDW_FRAME)
	    {
		if (rectUpdate) IntersectRect( &rect, rectUpdate, &rectWindow);
		else rect = rectWindow;
	    }
	    else
	    {
		if (rectUpdate) IntersectRect( &rect, rectUpdate, &rectClient);
		else rect = rectClient;
	    }
	    if (!IsRectEmpty(&rect)) hrgn = CreateRectRgnIndirect( &rect );
	}

	  /* Set update region */

	if (hrgn)
	{
	    if (!wndPtr->hrgnUpdate)
	    {
		wndPtr->hrgnUpdate = hrgn;
		if (!(wndPtr->flags & WIN_INTERNAL_PAINT))
		    MSG_IncPaintCount( wndPtr->hmemTaskQ );
	    }
	    else
	    {
		tmpRgn = CreateRectRgn( 0, 0, 0, 0 );
		CombineRgn( tmpRgn, wndPtr->hrgnUpdate, hrgn, RGN_OR );
		DeleteObject( wndPtr->hrgnUpdate );
		DeleteObject( hrgn );
		wndPtr->hrgnUpdate = tmpRgn;
	    }
	}
	flags |= RDW_FRAME;  /* Force invalidating the frame of children */
    }
    else if (flags & RDW_VALIDATE)  /* Validate */
    {
	if (flags & RDW_NOERASE) wndPtr->flags &= ~WIN_ERASE_UPDATERGN;
	if (!(hrgn = CreateRectRgn( 0, 0, 0, 0 ))) return FALSE;

	  /* Remove frame from update region */

	if (wndPtr->hrgnUpdate && (flags & RDW_NOFRAME))
	{
	    if (!(tmpRgn = CreateRectRgnIndirect( &rectClient )))
		return FALSE;
	    if (CombineRgn(hrgn,tmpRgn,wndPtr->hrgnUpdate,RGN_AND) == NULLREGION)
	    {
		DeleteObject( hrgn );
		hrgn = 0;
	    }
	    DeleteObject( tmpRgn );
	    DeleteObject( wndPtr->hrgnUpdate );
	    wndPtr->hrgnUpdate = hrgn;
	    hrgn = CreateRectRgn( 0, 0, 0, 0 );
	}

	  /* Set update region */

	if (wndPtr->hrgnUpdate)
	{
	    int res;
	    if (hrgnUpdate)  /* Validate a region */
	    {
		res = CombineRgn(hrgn,wndPtr->hrgnUpdate,hrgnUpdate,RGN_DIFF);
	    }
	    else  /* Validate a rectangle */
	    {
		if (rectUpdate) tmpRgn = CreateRectRgnIndirect( rectUpdate );
		else tmpRgn = CreateRectRgnIndirect( &rectWindow );
		res = CombineRgn( hrgn, wndPtr->hrgnUpdate, tmpRgn, RGN_DIFF );
		DeleteObject( tmpRgn );
	    }
	    DeleteObject( wndPtr->hrgnUpdate );
	    if (res == NULLREGION)
	    {
		DeleteObject( hrgn );
		wndPtr->hrgnUpdate = 0;
		if (!(wndPtr->flags & WIN_INTERNAL_PAINT))
		    MSG_DecPaintCount( wndPtr->hmemTaskQ );
	    }
	    else wndPtr->hrgnUpdate = hrgn;
	}
    }

      /* Set/clear internal paint flag */

    if (flags & RDW_INTERNALPAINT)
    {
	if (!wndPtr->hrgnUpdate && !(wndPtr->flags & WIN_INTERNAL_PAINT))
	    MSG_IncPaintCount( wndPtr->hmemTaskQ );
	wndPtr->flags |= WIN_INTERNAL_PAINT;	    
    }
    else if (flags & RDW_NOINTERNALPAINT)
    {
	if (!wndPtr->hrgnUpdate && (wndPtr->flags & WIN_INTERNAL_PAINT))
	    MSG_DecPaintCount( wndPtr->hmemTaskQ );
	wndPtr->flags &= ~WIN_INTERNAL_PAINT;
    }

      /* Erase/update window */

    if (flags & RDW_UPDATENOW) UpdateWindow( hwnd );
    else if (flags & RDW_ERASENOW)
    {
	HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
			   DCX_INTERSECTRGN | DCX_USESTYLE );
	if (hdc)
	{
	    SendMessage( hwnd, WM_NCPAINT, wndPtr->hrgnUpdate, 0 );
	    SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 );
	    ReleaseDC( hwnd, hdc );
	}
    }

      /* Recursively process children */

    if (!(flags & RDW_NOCHILDREN) &&
	((flags && RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)))
    {
	if (hrgnUpdate)
	{
	    HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
	    if (!hrgn) return TRUE;
	    for (hwnd = wndPtr->hwndChild; (hwnd); hwnd = wndPtr->hwndNext)
	    {
		if (!(wndPtr = WIN_FindWndPtr( hwnd ))) break;
		CombineRgn( hrgn, hrgnUpdate, 0, RGN_COPY );
		OffsetRgn( hrgn, -wndPtr->rectClient.left,
			         -wndPtr->rectClient.top );
		RedrawWindow( hwnd, NULL, hrgn, flags );
	    }
	    DeleteObject( hrgn );
	}
	else
	{
	    RECT rect;		
	    for (hwnd = wndPtr->hwndChild; (hwnd); hwnd = wndPtr->hwndNext)
	    {
		if (!(wndPtr = WIN_FindWndPtr( hwnd ))) break;
		if (rectUpdate)
		{
		    rect = *rectUpdate;
		    OffsetRect( &rect, -wndPtr->rectClient.left,
			               -wndPtr->rectClient.top );
		    RedrawWindow( hwnd, &rect, 0, flags );
		}
		else RedrawWindow( hwnd, NULL, 0, flags );
	    }
	}
    }
    return TRUE;
}


/***********************************************************************
 *           UpdateWindow   (USER.124)
 */
void UpdateWindow( HWND hwnd )
{
    if (GetUpdateRect( hwnd, NULL, FALSE )) 
    {
	if (IsWindowVisible( hwnd )) SendMessage( hwnd, WM_PAINT, 0, 0 );
    }
}


/***********************************************************************
 *           InvalidateRgn   (USER.126)
 */
void InvalidateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
{
    RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) );
}


/***********************************************************************
 *           InvalidateRect   (USER.125)
 */
void InvalidateRect( HWND hwnd, LPRECT rect, BOOL erase )
{
    RedrawWindow( hwnd, rect, 0, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) );
}


/***********************************************************************
 *           ValidateRgn   (USER.128)
 */
void ValidateRgn( HWND hwnd, HRGN hrgn )
{
    RedrawWindow( hwnd, NULL, hrgn, RDW_VALIDATE | RDW_NOCHILDREN );
}


/***********************************************************************
 *           ValidateRect   (USER.127)
 */
void ValidateRect( HWND hwnd, LPRECT rect )
{
    RedrawWindow( hwnd, rect, 0, RDW_VALIDATE | RDW_NOCHILDREN );
}


/***********************************************************************
 *           GetUpdateRect   (USER.190)
 */
BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
{
    WND * wndPtr = WIN_FindWndPtr( hwnd );
    if (!wndPtr) return FALSE;

    if (rect)
    {
	if (wndPtr->hrgnUpdate)
	{
	    HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
	    if (GetUpdateRgn( hwnd, hrgn, erase ) == ERROR) return FALSE;
	    GetRgnBox( hrgn, rect );
	    DeleteObject( hrgn );
	}
	else SetRectEmpty( rect );
    }
    return (wndPtr->hrgnUpdate != 0);
}


/***********************************************************************
 *           GetUpdateRgn   (USER.237)
 */
int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
{
    HRGN hrgnClip;
    int retval;
    WND * wndPtr = WIN_FindWndPtr( hwnd );
    if (!wndPtr) return ERROR;

    if (!wndPtr->hrgnUpdate)
    {
	if (!(hrgnClip = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR;
	retval = CombineRgn( hrgn, hrgnClip, 0, RGN_COPY );
    }
    else
    {
	hrgnClip = CreateRectRgn( 0, 0,
			   wndPtr->rectClient.right-wndPtr->rectClient.left,
			   wndPtr->rectClient.bottom-wndPtr->rectClient.top );
	if (!hrgnClip) return ERROR;
	retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, hrgnClip, RGN_AND );
	if (erase)
	{
	    HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
			      DCX_INTERSECTRGN | DCX_USESTYLE );
	    if (hdc)
	    {
		SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 );
		ReleaseDC( hwnd, hdc );
	    }
	}	
    }
    DeleteObject( hrgnClip );
    return retval;
}


/***********************************************************************
 *           ExcludeUpdateRgn   (USER.238)
 */
int ExcludeUpdateRgn( HDC hdc, HWND hwnd )
{
    int retval;
    HRGN hrgn;
    WND * wndPtr;

    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return ERROR;
    if ((hrgn = CreateRectRgn( 0, 0, 0, 0 )) != 0)
    {
	retval = CombineRgn( hrgn, InquireVisRgn(hdc),
			     wndPtr->hrgnUpdate, RGN_DIFF );
	if (retval) SelectVisRgn( hdc, hrgn );
	DeleteObject( hrgn );
    }
    return retval;
}
