/*
 * Window painting functions
 *
 * Copyright 1993, 1994, 1995 Alexandre Julliard
 *			 1999 Alex Korobka
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <string.h>
#include "windef.h"
#include "wingdi.h"
#include "wine/winuser16.h"
#include "wine/unicode.h"
#include "wine/server.h"
#include "region.h"
#include "user.h"
#include "win.h"
#include "queue.h"
#include "dce.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(win);
WINE_DECLARE_DEBUG_CHANNEL(nonclient);

/* client rect in window coordinates */

#define GETCLIENTRECTW( wnd, r )	(r).left = (wnd)->rectClient.left - (wnd)->rectWindow.left; \
					(r).top = (wnd)->rectClient.top - (wnd)->rectWindow.top; \
					(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


/* ### start build ### */
extern WORD CALLBACK PAINTING_CallTo16_word_wlwww(DRAWSTATEPROC16,WORD,LONG,WORD,WORD,WORD);
/* ### stop build ### */

struct draw_state_info
{
    DRAWSTATEPROC16 proc;
    LPARAM          param;
};

/* callback for 16-bit DrawState functions */
static BOOL CALLBACK draw_state_callback( HDC hdc, LPARAM lparam, WPARAM wparam, int cx, int cy )
{
    const struct draw_state_info *info = (struct draw_state_info *)lparam;
    return PAINTING_CallTo16_word_wlwww( info->proc, hdc, info->param, wparam, cx, cy );
}


/***********************************************************************
 *           add_paint_count
 *
 * Add an increment (normally 1 or -1) to the current paint count of a window.
 */
static void add_paint_count( HWND hwnd, int incr )
{
    SERVER_START_REQ( inc_window_paint_count )
    {
        req->handle = hwnd;
        req->incr   = incr;
        wine_server_call( req );
    }
    SERVER_END_REQ;
}


/***********************************************************************
 *           WIN_HaveToDelayNCPAINT
 *
 * Currently, in the Wine painting mechanism, the WM_NCPAINT message
 * is generated as soon as a region intersecting the non-client area 
 * of a window is invalidated.
 *
 * This technique will work fine for all windows whose parents
 * have the WS_CLIPCHILDREN style. When the parents have that style,
 * they are not going to override the contents of their children.
 * However, when the parent doesn't have that style, Windows relies
 * on a "painter's algorithm" to display the contents of the windows.
 * That is, windows are painted from back to front. This includes the
 * non-client area.
 *
 * This method looks at the current state of a window to determine
 * if the sending of the WM_NCPAINT message should be delayed until 
 * the BeginPaint call.
 *
 * PARAMS:
 *   wndPtr   - A Locked window pointer to the window we're
 *              examining.
 *   uncFlags - This is the flag passed to the WIN_UpdateNCRgn
 *              function. This is a shortcut for the cases when
 *              we already know when to avoid scanning all the
 *              parents of a window. If you already know that this
 *              window's NCPAINT should be delayed, set the 
 *              UNC_DELAY_NCPAINT flag for this parameter. 
 *
 *              This shortcut behavior is implemented in the
 *              RDW_Paint() method.
 * 
 */
static BOOL WIN_HaveToDelayNCPAINT( HWND hwnd, UINT uncFlags)
{
  /*
   * Test the shortcut first. (duh)
   */
  if (uncFlags & UNC_DELAY_NCPAINT)
    return TRUE;

  /*
   * The UNC_IN_BEGINPAINT flag is set in the BeginPaint
   * method only. This is another shortcut to avoid going
   * up the parent's chain of the window to finally
   * figure-out that none of them has an invalid region.
   */
  if (uncFlags & UNC_IN_BEGINPAINT)
    return FALSE;

  /*
   * Scan all the parents of this window to find a window
   * that doesn't have the WS_CLIPCHILDREN style and that
   * has an invalid region. 
   */
  while ((hwnd = GetAncestor( hwnd, GA_PARENT )))
  {
      WND* parentWnd = WIN_FindWndPtr( hwnd );
      if (!(parentWnd->dwStyle & WS_CLIPCHILDREN) && parentWnd->hrgnUpdate)
      {
          WIN_ReleaseWndPtr( parentWnd );
          return TRUE;
      }
      WIN_ReleaseWndPtr( parentWnd );
  }
  return FALSE;
}

/***********************************************************************
 *           WIN_UpdateNCRgn
 *
 *  Things to do:
 *	Send WM_NCPAINT if required (when nonclient is invalid or UNC_ENTIRE flag is set)
 *	Crop hrgnUpdate to a client rect, especially if it 1.
 *	If UNC_REGION is set return update region for the client rect.
 *
 *  NOTE: UNC_REGION is mainly for the RDW_Paint() chunk that sends WM_ERASEBKGND message.
 *	  The trick is that when the returned region handle may be different from hRgn.
 *	  In this case the old hRgn must be considered gone. BUT, if the returned value
 *	  is 1 then the hRgn is preserved and RDW_Paint() will have to get 
 *	  a DC without extra clipping region.
 */
static HRGN WIN_UpdateNCRgn(WND* wnd, HRGN hRgn, UINT uncFlags )
{
    RECT  r;
    HRGN  hClip = 0;
    HRGN  hrgnRet = 0;

    TRACE_(nonclient)("hwnd %04x [%04x] hrgn %04x, unc %04x, ncf %i\n", 
                      wnd->hwndSelf, wnd->hrgnUpdate, hRgn, uncFlags, wnd->flags & WIN_NEEDS_NCPAINT);

    /* desktop window doesn't have a nonclient area */
    if(wnd->hwndSelf == GetDesktopWindow())
    {
        wnd->flags &= ~WIN_NEEDS_NCPAINT;
	if( wnd->hrgnUpdate > 1 )
	    hrgnRet = REGION_CropRgn( hRgn, wnd->hrgnUpdate, NULL, NULL );
	else 
	{
	    hrgnRet = wnd->hrgnUpdate;
	}
        return hrgnRet;
    }

    if ((wnd->hwndSelf == GetForegroundWindow()) &&
        !(wnd->flags & WIN_NCACTIVATED) )
    {
	wnd->flags |= WIN_NCACTIVATED;
	uncFlags |= UNC_ENTIRE; 
    }

    /*
     * If the window's non-client area needs to be painted, 
     */
    if ( ( wnd->flags & WIN_NEEDS_NCPAINT ) &&
	 !WIN_HaveToDelayNCPAINT(wnd->hwndSelf, uncFlags) )
    {
	    RECT r2, r3;

	    wnd->flags &= ~WIN_NEEDS_NCPAINT;  
	    GETCLIENTRECTW( wnd, r );

	    TRACE_(nonclient)( "\tclient box (%i,%i-%i,%i), hrgnUpdate %04x\n", 
				r.left, r.top, r.right, r.bottom, wnd->hrgnUpdate );
	    if( wnd->hrgnUpdate > 1 )
	    {
		/* Check if update rgn overlaps with nonclient area */

		GetRgnBox( wnd->hrgnUpdate, &r2 );
		UnionRect( &r3, &r2, &r );
		if( r3.left != r.left || r3.top != r.top || 
		    r3.right != r.right || r3.bottom != r.bottom ) /* it does */
		{
		    /* crop hrgnUpdate, save old one in hClip - the only
		     * case that places a valid region handle in hClip */

		    hClip = wnd->hrgnUpdate;
		    wnd->hrgnUpdate = REGION_CropRgn( hRgn, hClip, &r, NULL );
		    if( uncFlags & UNC_REGION ) hrgnRet = hClip;
		}

		if( uncFlags & UNC_CHECK )
		{
		    GetRgnBox( wnd->hrgnUpdate, &r3 );
		    if( IsRectEmpty( &r3 ) )
		    {
			/* delete the update region since all invalid 
			 * parts were in the nonclient area */

			DeleteObject( wnd->hrgnUpdate );
			wnd->hrgnUpdate = 0;
			if(!(wnd->flags & WIN_INTERNAL_PAINT))
			    add_paint_count( wnd->hwndSelf, -1 );

			wnd->flags &= ~WIN_NEEDS_ERASEBKGND;
		    }
		}

		if(!hClip && wnd->hrgnUpdate ) goto copyrgn;
	    }
	    else 
	    if( wnd->hrgnUpdate == 1 )/* entire window */
	    {
		if( uncFlags & UNC_UPDATE ) wnd->hrgnUpdate = CreateRectRgnIndirect( &r );
		if( uncFlags & UNC_REGION ) hrgnRet = 1;
		uncFlags |= UNC_ENTIRE;
	    }
    }
    else /* no WM_NCPAINT unless forced */
    {
	if( wnd->hrgnUpdate >  1 )
	{
copyrgn:
	    if( uncFlags & UNC_REGION )
		hrgnRet = REGION_CropRgn( hRgn, wnd->hrgnUpdate, NULL, NULL );
	}
	else
	if( wnd->hrgnUpdate == 1 && (uncFlags & UNC_UPDATE) )
	{
	    GETCLIENTRECTW( wnd, r ); 
	    wnd->hrgnUpdate = CreateRectRgnIndirect( &r );
	    if( uncFlags & UNC_REGION ) hrgnRet = 1;
	}
    }

    if(!hClip && (uncFlags & UNC_ENTIRE) )
    {
	/* still don't do anything if there is no nonclient area */
	hClip = (memcmp( &wnd->rectWindow, &wnd->rectClient, sizeof(RECT) ) != 0);
    }

    if( hClip ) /* NOTE: WM_NCPAINT allows wParam to be 1 */
    {
        if ( hClip == hrgnRet && hrgnRet > 1 ) {
	    hClip = CreateRectRgn( 0, 0, 0, 0 );
	    CombineRgn( hClip, hrgnRet, 0, RGN_COPY );
	}

	SendMessageA( wnd->hwndSelf, WM_NCPAINT, hClip, 0L );
	if( (hClip > 1) && (hClip != hRgn) && (hClip != hrgnRet) )
	    DeleteObject( hClip );
	/*
         * Since all Window locks are suspended while processing the WM_NCPAINT
         * we want to make sure the window still exists before continuing.
	 */
        if (!IsWindow(wnd->hwndSelf))
        {
	  DeleteObject(hrgnRet);
	  hrgnRet=0;
        }
    }

    TRACE_(nonclient)("returning %04x (hClip = %04x, hrgnUpdate = %04x)\n", hrgnRet, hClip, wnd->hrgnUpdate );

    return hrgnRet;
}


/***********************************************************************
 * 		RDW_ValidateParent [RDW_UpdateRgns() helper] 
 *
 *  Validate the portions of parents that are covered by a validated child
 *  wndPtr = child
 */
static void RDW_ValidateParent(WND *wndChild)
{
    HWND parent;
    HRGN hrg;

    if (wndChild->hrgnUpdate == 1 ) {
        RECT r;
        r.left = 0;
        r.top = 0;
        r.right = wndChild->rectWindow.right - wndChild->rectWindow.left;
        r.bottom = wndChild->rectWindow.bottom - wndChild->rectWindow.top;
        hrg = CreateRectRgnIndirect( &r );
    } else
        hrg = wndChild->hrgnUpdate;

    parent = GetAncestor( wndChild->hwndSelf, GA_PARENT );
    while (parent && parent != GetDesktopWindow())
    {
        WND *wndParent = WIN_FindWndPtr( parent );
        if (!(wndParent->dwStyle & WS_CLIPCHILDREN))
        {
            if (wndParent->hrgnUpdate != 0)
            {
                POINT ptOffset;
                RECT rect, rectParent;
                if( wndParent->hrgnUpdate == 1 )
                {
                   RECT r;

                   r.left = 0;
                   r.top = 0;
                   r.right = wndParent->rectWindow.right - wndParent->rectWindow.left;
                   r.bottom = wndParent->rectWindow.bottom - wndParent->rectWindow.top;

                   wndParent->hrgnUpdate = CreateRectRgnIndirect( &r );
                }
                /* we must offset the child region by the offset of the child rect in the parent */
                GetWindowRect(wndParent->hwndSelf, &rectParent);
                GetWindowRect(wndChild->hwndSelf, &rect);
                ptOffset.x = rect.left - rectParent.left;
                ptOffset.y = rect.top - rectParent.top;
                OffsetRgn( hrg, ptOffset.x, ptOffset.y );
                CombineRgn( wndParent->hrgnUpdate, wndParent->hrgnUpdate, hrg, RGN_DIFF );
                OffsetRgn( hrg, -ptOffset.x, -ptOffset.y );
            }
        }
        WIN_ReleaseWndPtr( wndParent );
        parent = GetAncestor( parent, GA_PARENT );
    }
    if (hrg != wndChild->hrgnUpdate) DeleteObject( hrg );
}

/***********************************************************************
 * 		RDW_UpdateRgns [RedrawWindow() helper] 
 *
 *  Walks the window tree and adds/removes parts of the hRgn to/from update
 *  regions of windows that overlap it. Also, manages internal paint flags.
 *
 *  NOTE: Walks the window tree so the caller must lock it.
 *	  MUST preserve hRgn (can modify but then has to restore).
 */
static void RDW_UpdateRgns( WND* wndPtr, HRGN hRgn, UINT flags, BOOL firstRecursLevel )
{
    /* 
     * Called only when one of the following is set:
     * (RDW_INVALIDATE | RDW_VALIDATE | RDW_INTERNALPAINT | RDW_NOINTERNALPAINT)
     */

    BOOL bHadOne =  wndPtr->hrgnUpdate && hRgn;
    BOOL bChildren =  (!(flags & RDW_NOCHILDREN) && !(wndPtr->dwStyle & WS_MINIMIZE) &&
                       ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) );
    RECT r;

    r.left = 0;
    r.top = 0;
    r.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
    r.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;

    TRACE("\thwnd %04x [%04x] -> hrgn [%04x], flags [%04x]\n", wndPtr->hwndSelf, wndPtr->hrgnUpdate, hRgn, flags );

    if( flags & RDW_INVALIDATE )
    {
	if( hRgn > 1 )
	{
	    switch( wndPtr->hrgnUpdate )
	    {
		default:
			CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate, hRgn, RGN_OR );
			/* fall through */
		case 0:
			wndPtr->hrgnUpdate = REGION_CropRgn( wndPtr->hrgnUpdate, 
							     wndPtr->hrgnUpdate ? wndPtr->hrgnUpdate : hRgn, 
							     &r, NULL );
			if( !bHadOne )
			{
			    GetRgnBox( wndPtr->hrgnUpdate, &r );
			    if( IsRectEmpty( &r ) )
			    {
				DeleteObject( wndPtr->hrgnUpdate );
				wndPtr->hrgnUpdate = 0;
			        goto end;
			    }
			}
			break;
		case 1:	/* already an entire window */
		        break;
	    }
	}
	else if( hRgn == 1 )
	{
	    if( wndPtr->hrgnUpdate > 1 )
		DeleteObject( wndPtr->hrgnUpdate );
	    wndPtr->hrgnUpdate = 1;
	}
	else
	    hRgn = wndPtr->hrgnUpdate;	/* this is a trick that depends on code in PAINT_RedrawWindow() */

	if( !bHadOne && !(wndPtr->flags & WIN_INTERNAL_PAINT) )
            add_paint_count( wndPtr->hwndSelf, 1 );

	if (flags & RDW_FRAME) wndPtr->flags |= WIN_NEEDS_NCPAINT;
	if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
	flags    |= RDW_FRAME;
    }
    else if( flags & RDW_VALIDATE )
    {
	if( wndPtr->hrgnUpdate )
	{
	    if( hRgn > 1 )
	    {
		if( wndPtr->hrgnUpdate == 1 )
		    wndPtr->hrgnUpdate = CreateRectRgnIndirect( &r );

		if( CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate, hRgn, RGN_DIFF )
		    == NULLREGION )
                {
                    DeleteObject( wndPtr->hrgnUpdate );
                    wndPtr->hrgnUpdate = 0;
                }
	    }
	    else /* validate everything */
	    {
		if( wndPtr->hrgnUpdate > 1 ) DeleteObject( wndPtr->hrgnUpdate );
		wndPtr->hrgnUpdate = 0;
	    }

	    if( !wndPtr->hrgnUpdate )
	    {
		wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
		if( !(wndPtr->flags & WIN_INTERNAL_PAINT) )
                    add_paint_count( wndPtr->hwndSelf, -1 );
	    }
	}

	if (flags & RDW_NOFRAME) wndPtr->flags &= ~WIN_NEEDS_NCPAINT;
	if (flags & RDW_NOERASE) wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;

    }

    if ((firstRecursLevel) && (wndPtr->hrgnUpdate != 0) && (flags & RDW_UPDATENOW))
        RDW_ValidateParent(wndPtr); /* validate parent covered by region */

    /* in/validate child windows that intersect with the region if it
     * is a valid handle. */

    if( flags & (RDW_INVALIDATE | RDW_VALIDATE) )
    {
        HWND *list;
	if( hRgn > 1 && bChildren && (list = WIN_ListChildren( wndPtr->hwndSelf )))
	{
	    POINT ptTotal, prevOrigin = {0,0};
            POINT ptClient;
            INT i;

            ptClient.x = wndPtr->rectClient.left - wndPtr->rectWindow.left;
            ptClient.y = wndPtr->rectClient.top - wndPtr->rectWindow.top;

            for(i = ptTotal.x = ptTotal.y = 0; list[i]; i++)
            {
                WND *wnd = WIN_FindWndPtr( list[i] );
                if (!wnd) continue;
                if( wnd->dwStyle & WS_VISIBLE )
                {
                    POINT ptOffset;

                    r.left = wnd->rectWindow.left + ptClient.x;
                    r.right = wnd->rectWindow.right + ptClient.x;
                    r.top = wnd->rectWindow.top + ptClient.y;
                    r.bottom = wnd->rectWindow.bottom + ptClient.y;

                    ptOffset.x = r.left - prevOrigin.x;
                    ptOffset.y = r.top - prevOrigin.y;
                    OffsetRect( &r, -ptTotal.x, -ptTotal.y );

                    if( RectInRegion( hRgn, &r ) )
                    {
                        OffsetRgn( hRgn, -ptOffset.x, -ptOffset.y );
                        RDW_UpdateRgns( wnd, hRgn, flags, FALSE );
                        prevOrigin.x = r.left + ptTotal.x;
                        prevOrigin.y = r.top + ptTotal.y;
                        ptTotal.x += ptOffset.x;
                        ptTotal.y += ptOffset.y;
                    }
                }
                WIN_ReleaseWndPtr( wnd );
            }
            HeapFree( GetProcessHeap(), 0, list );
            OffsetRgn( hRgn, ptTotal.x, ptTotal.y );
            bChildren = 0;
	}
    }

    /* handle hRgn == 1 (alias for entire window) and/or internal paint recursion */

    if( bChildren )
    {
        HWND *list;
        if ((list = WIN_ListChildren( wndPtr->hwndSelf )))
        {
            INT i;
            for (i = 0; list[i]; i++)
            {
                WND *wnd = WIN_FindWndPtr( list[i] );
                if (!wnd) continue;
                if( wnd->dwStyle & WS_VISIBLE )
                    RDW_UpdateRgns( wnd, hRgn, flags, FALSE );
                WIN_ReleaseWndPtr( wnd );
            }
            HeapFree( GetProcessHeap(), 0, list );
        }
    }

end:

    /* Set/clear internal paint flag */

    if (flags & RDW_INTERNALPAINT)
    {
        if ( !wndPtr->hrgnUpdate && !(wndPtr->flags & WIN_INTERNAL_PAINT))
            add_paint_count( wndPtr->hwndSelf, 1 );
        wndPtr->flags |= WIN_INTERNAL_PAINT;
    }
    else if (flags & RDW_NOINTERNALPAINT)
    {
        if ( !wndPtr->hrgnUpdate && (wndPtr->flags & WIN_INTERNAL_PAINT))
            add_paint_count( wndPtr->hwndSelf, -1 );
        wndPtr->flags &= ~WIN_INTERNAL_PAINT;
    }
}

/***********************************************************************
 *           RDW_Paint [RedrawWindow() helper]
 *
 * Walks the window tree and paints/erases windows that have
 * nonzero update regions according to redraw flags. hrgn is a scratch
 * region passed down during recursion. Must not be 1.
 *
 */
static HRGN RDW_Paint( WND* wndPtr, HRGN hrgn, UINT flags, UINT ex )
{
/* NOTE: wndPtr is locked by caller.
 * 
 * FIXME: Windows uses WM_SYNCPAINT to cut down the number of intertask
 * SendMessage() calls. This is a comment inside DefWindowProc() source
 * from 16-bit SDK:
 *
 *   This message avoids lots of inter-app message traffic
 *   by switching to the other task and continuing the
 *   recursion there.
 *
 * wParam         = flags
 * LOWORD(lParam) = hrgnClip
 * HIWORD(lParam) = hwndSkip  (not used; always NULL)
 *
 */
    HDC  hDC;
    HWND hWnd = wndPtr->hwndSelf;
    BOOL bIcon = ((wndPtr->dwStyle & WS_MINIMIZE) && GetClassLongA(hWnd, GCL_HICON));

      /* Erase/update the window itself ... */

    TRACE("\thwnd %04x [%04x] -> hrgn [%04x], flags [%04x]\n", hWnd, wndPtr->hrgnUpdate, hrgn, flags );

    /*
     * Check if this window should delay it's processing of WM_NCPAINT.
     * See WIN_HaveToDelayNCPAINT for a description of the mechanism
     */
    if ((ex & RDW_EX_DELAY_NCPAINT) || WIN_HaveToDelayNCPAINT(wndPtr->hwndSelf, 0) )
	ex |= RDW_EX_DELAY_NCPAINT;

    if (flags & RDW_UPDATENOW)
    {
        if (wndPtr->hrgnUpdate) /* wm_painticon wparam is 1 */
            SendMessageW( hWnd, (bIcon) ? WM_PAINTICON : WM_PAINT, bIcon, 0 );
    }
    else if (flags & RDW_ERASENOW)
    {
	UINT dcx = DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN | DCX_WINDOWPAINT | DCX_CACHE;
	HRGN hrgnRet;

	hrgnRet = WIN_UpdateNCRgn(wndPtr, 
				  hrgn, 
				  UNC_REGION | UNC_CHECK | 
				  ((ex & RDW_EX_DELAY_NCPAINT) ? UNC_DELAY_NCPAINT : 0) ); 

        if( hrgnRet )
	{
	    if( hrgnRet > 1 ) hrgn = hrgnRet; else hrgnRet = 0; /* entire client */
	    if( wndPtr->flags & WIN_NEEDS_ERASEBKGND )
	    {
		if( bIcon ) dcx |= DCX_WINDOW;
		else 
		if( hrgnRet )
		    OffsetRgn( hrgnRet, wndPtr->rectWindow.left - wndPtr->rectClient.left, 
			                wndPtr->rectWindow.top  - wndPtr->rectClient.top);
		else
		    dcx &= ~DCX_INTERSECTRGN;
		if (( hDC = GetDCEx( hWnd, hrgnRet, dcx )) )
		{
		    if (SendMessageW( hWnd, (bIcon) ? WM_ICONERASEBKGND : WM_ERASEBKGND,
                                      (WPARAM)hDC, 0 ))
		    wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
		    ReleaseDC( hWnd, hDC );
		}
            }
        }
    }

    if( !IsWindow(hWnd) ) return hrgn;

      /* ... and its child windows */

    if(!(flags & RDW_NOCHILDREN) && !(wndPtr->dwStyle & WS_MINIMIZE) &&
       ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) )
    {
        HWND *list, *phwnd;

	if( (list = WIN_ListChildren( wndPtr->hwndSelf )) )
	{
	    for (phwnd = list; *phwnd; phwnd++)
	    {
                if (!(wndPtr = WIN_FindWndPtr( *phwnd ))) continue;
                if ( (wndPtr->dwStyle & WS_VISIBLE) &&
                     (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT)) )
                    hrgn = RDW_Paint( wndPtr, hrgn, flags, ex );
                WIN_ReleaseWndPtr(wndPtr);
	    }
            HeapFree( GetProcessHeap(), 0, list );
	}
    }

    return hrgn;
}


/***********************************************************************
 *		RedrawWindow (USER32.@)
 */
BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rectUpdate,
                              HRGN hrgnUpdate, UINT flags )
{
    HRGN hRgn = 0;
    RECT r, r2;
    POINT pt;
    WND* wndPtr;

    if (!hwnd) hwnd = GetDesktopWindow();

    /* check if the window or its parents are visible/not minimized */

    if (!WIN_IsWindowDrawable( hwnd, !(flags & RDW_FRAME) )) return TRUE;

    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
    if (TRACE_ON(win))
    {
	if( hrgnUpdate )
	{
	    GetRgnBox( hrgnUpdate, &r );
            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
	{
	    if( rectUpdate )
		r = *rectUpdate;
	    else
		SetRectEmpty( &r );
	    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 );
	}
    }


    /* process pending events and messages before painting */
    if (flags & RDW_UPDATENOW)
        MsgWaitForMultipleObjects( 0, NULL, FALSE, 0, QS_ALLINPUT );

    /* prepare an update region in window coordinates */

    if( flags & RDW_FRAME )
	r = wndPtr->rectWindow;
    else
	r = wndPtr->rectClient;

    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 */
    {
	/* If the window doesn't have hrgnUpdate we leave hRgn zero
	 * and put a new region straight into wndPtr->hrgnUpdate
	 * so that RDW_UpdateRgns() won't have to do any extra work.
	 */

	if( hrgnUpdate )
	{
	    if( wndPtr->hrgnUpdate )
	        hRgn = REGION_CropRgn( 0, hrgnUpdate, NULL, &pt );
	    else 
		wndPtr->hrgnUpdate = REGION_CropRgn( 0, hrgnUpdate, &r, &pt ); 
	}
	else if( rectUpdate )
	{
	    if( !IntersectRect( &r2, &r, rectUpdate ) ) goto END;
	    OffsetRect( &r2, pt.x, pt.y );
	    if( wndPtr->hrgnUpdate == 0 )
		wndPtr->hrgnUpdate = CreateRectRgnIndirect( &r2 );
	    else
		hRgn = CreateRectRgnIndirect( &r2 );
	}
	else /* entire window or client depending on RDW_FRAME */
	{
	    if( flags & RDW_FRAME )
	    {
                if (wndPtr->hrgnUpdate) hRgn = 1;
                else wndPtr->hrgnUpdate = 1;
	    }
	    else
	    {
		GETCLIENTRECTW( wndPtr, r2 );
                if( wndPtr->hrgnUpdate == 0 )
                    wndPtr->hrgnUpdate = CreateRectRgnIndirect( &r2 );
                else
                    hRgn = CreateRectRgnIndirect( &r2 );
	    }
	}
    }
    else if (flags & RDW_VALIDATE)  /* ------------------------- Validate */
    {
	/* In this we cannot leave with zero hRgn */
	if( hrgnUpdate )
	{
	    hRgn = REGION_CropRgn( hRgn, hrgnUpdate,  &r, &pt );
	    GetRgnBox( hRgn, &r2 );
	    if( IsRectEmpty( &r2 ) ) goto END;
	}
	else if( rectUpdate )
	{
	    if( !IntersectRect( &r2, &r, rectUpdate ) ) goto END;
		OffsetRect( &r2, pt.x, pt.y );
	    hRgn = CreateRectRgnIndirect( &r2 );
	}
	else /* entire window or client depending on RDW_FRAME */
        {
	    if( flags & RDW_FRAME ) 
		hRgn = 1;
	    else
	    {
		GETCLIENTRECTW( wndPtr, r2 );
                hRgn = CreateRectRgnIndirect( &r2 );
            }
        }
    }

    /* At this point hRgn is either an update region in window coordinates or 1 or 0 */

    RDW_UpdateRgns( wndPtr, hRgn, flags, TRUE );

    /* Erase/update windows, from now on hRgn is a scratch region */

    hRgn = RDW_Paint( wndPtr, (hRgn == 1) ? 0 : hRgn, flags, 0 );

END:
    if( hRgn > 1 && (hRgn != hrgnUpdate) )
	DeleteObject(hRgn );
    WIN_ReleaseWndPtr(wndPtr);
    return TRUE;
}


/***********************************************************************
 *		UpdateWindow (USER32.@)
 */
void WINAPI UpdateWindow( HWND hwnd )
{
    RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
}


/***********************************************************************
 *		InvalidateRgn (USER32.@)
 */
BOOL WINAPI InvalidateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
{
    return RedrawWindow(hwnd, NULL, hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) );
}


/***********************************************************************
 *		InvalidateRect (USER32.@)
 */
BOOL WINAPI InvalidateRect( HWND hwnd, const RECT *rect, BOOL erase )
{
    return RedrawWindow( hwnd, rect, 0, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) );
}


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


/***********************************************************************
 *		ValidateRect (USER32.@)
 */
void WINAPI ValidateRect( HWND hwnd, const RECT *rect )
{
    RedrawWindow( hwnd, rect, 0, RDW_VALIDATE | RDW_NOCHILDREN );
}


/***********************************************************************
 *		GetUpdateRect (USER32.@)
 */
BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
{
    BOOL retvalue;
    WND * wndPtr = WIN_FindWndPtr( hwnd );
    if (!wndPtr) return FALSE;

    if (rect)
    {
	if (wndPtr->hrgnUpdate > 1)
	{
	    HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
            if (GetUpdateRgn( hwnd, hrgn, erase ) == ERROR)
            {
                retvalue = FALSE;
                goto END;
            }
	    GetRgnBox( hrgn, rect );
	    DeleteObject( hrgn );
	    if (GetClassLongA(wndPtr->hwndSelf, GCL_STYLE) & CS_OWNDC)
	    {
		if (GetMapMode(wndPtr->dce->hDC) != MM_TEXT)
		{
		    DPtoLP (wndPtr->dce->hDC, (LPPOINT)rect,  2);
		}
	    }
	}
	else
	if( wndPtr->hrgnUpdate == 1 )
	{
	    GetClientRect( hwnd, rect );
	    if (erase) RedrawWindow( hwnd, NULL, 0, RDW_FRAME | RDW_ERASENOW | RDW_NOCHILDREN );
	}
	else 
	    SetRectEmpty( rect );
    }
    retvalue = (wndPtr->hrgnUpdate >= 1);
END:
    WIN_ReleaseWndPtr(wndPtr);
    return retvalue;
}


/***********************************************************************
 *		GetUpdateRgn (USER32.@)
 */
INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
{
    INT retval;
    WND * wndPtr = WIN_FindWndPtr( hwnd );
    if (!wndPtr) return ERROR;

    if (wndPtr->hrgnUpdate == 0)
    {
        SetRectRgn( hrgn, 0, 0, 0, 0 );
        retval = NULLREGION;
        goto END;
    }
    else
    if (wndPtr->hrgnUpdate == 1)
    {
	SetRectRgn( hrgn, 0, 0, wndPtr->rectClient.right - wndPtr->rectClient.left,
				wndPtr->rectClient.bottom - wndPtr->rectClient.top );
	retval = SIMPLEREGION;
    }
    else
    {
	retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY );
	OffsetRgn( hrgn, wndPtr->rectWindow.left - wndPtr->rectClient.left,
			 wndPtr->rectWindow.top - wndPtr->rectClient.top );
    }
    if (erase) RedrawWindow( hwnd, NULL, 0, RDW_ERASENOW | RDW_NOCHILDREN );
END:
    WIN_ReleaseWndPtr(wndPtr);
    return retval;
}


/***********************************************************************
 *		ExcludeUpdateRgn (USER32.@)
 */
INT WINAPI ExcludeUpdateRgn( HDC hdc, HWND hwnd )
{
    RECT rect;
    WND * wndPtr;

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

    if (wndPtr->hrgnUpdate)
    {
	INT ret;
	HRGN hrgn = CreateRectRgn(wndPtr->rectWindow.left - wndPtr->rectClient.left,
				      wndPtr->rectWindow.top - wndPtr->rectClient.top,
				      wndPtr->rectWindow.right - wndPtr->rectClient.left,
				      wndPtr->rectWindow.bottom - wndPtr->rectClient.top);
	if( wndPtr->hrgnUpdate > 1 )
	{
	    CombineRgn(hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY);
	    OffsetRgn(hrgn, wndPtr->rectWindow.left - wndPtr->rectClient.left, 
			    wndPtr->rectWindow.top - wndPtr->rectClient.top );
	}

	/* do ugly coordinate translations in dce.c */

	ret = DCE_ExcludeRgn( hdc, hwnd, hrgn );
	DeleteObject( hrgn );
        WIN_ReleaseWndPtr(wndPtr);
	return ret;
    } 
    WIN_ReleaseWndPtr(wndPtr);
    return GetClipBox( hdc, &rect );
}



/***********************************************************************
 *		FillRect (USER.81)
 * NOTE
 *   The Win16 variant doesn't support special color brushes like
 *   the Win32 one, despite the fact that Win16, as well as Win32,
 *   supports special background brushes for a window class.
 */
INT16 WINAPI FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
{
    HBRUSH prevBrush;

    /* coordinates are logical so we cannot fast-check 'rect',
     * it will be done later in the PatBlt().
     */

    if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
    PatBlt( hdc, rect->left, rect->top,
              rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
    SelectObject( hdc, prevBrush );
    return 1;
}


/***********************************************************************
 *		FillRect (USER32.@)
 */
INT WINAPI FillRect( HDC hdc, const RECT *rect, HBRUSH hbrush )
{
    HBRUSH prevBrush;

    if (hbrush <= (HBRUSH) (COLOR_MAX + 1)) {
	hbrush = GetSysColorBrush( (INT) hbrush - 1 );
    }

    if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
    PatBlt( hdc, rect->left, rect->top,
              rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
    SelectObject( hdc, prevBrush );
    return 1;
}


/***********************************************************************
 *		InvertRect (USER.82)
 */
void WINAPI InvertRect16( HDC16 hdc, const RECT16 *rect )
{
    PatBlt( hdc, rect->left, rect->top,
              rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
}


/***********************************************************************
 *		InvertRect (USER32.@)
 */
BOOL WINAPI InvertRect( HDC hdc, const RECT *rect )
{
    return PatBlt( hdc, rect->left, rect->top,
		     rect->right - rect->left, rect->bottom - rect->top, 
		     DSTINVERT );
}


/***********************************************************************
 *		FrameRect (USER32.@)
 */
INT WINAPI FrameRect( HDC hdc, const RECT *rect, HBRUSH hbrush )
{
    HBRUSH prevBrush;
    RECT r = *rect;

    if ( (r.right <= r.left) || (r.bottom <= r.top) ) return 0;
    if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
    
    PatBlt( hdc, r.left, r.top, 1,
	      r.bottom - r.top, PATCOPY );
    PatBlt( hdc, r.right - 1, r.top, 1,
	      r.bottom - r.top, PATCOPY );
    PatBlt( hdc, r.left, r.top,
	      r.right - r.left, 1, PATCOPY );
    PatBlt( hdc, r.left, r.bottom - 1,
	      r.right - r.left, 1, PATCOPY );

    SelectObject( hdc, prevBrush );
    return TRUE;
}


/***********************************************************************
 *		FrameRect (USER.83)
 */
INT16 WINAPI FrameRect16( HDC16 hdc, const RECT16 *rect16, HBRUSH16 hbrush )
{
    RECT rect;
    CONV_RECT16TO32( rect16, &rect );
    return FrameRect( hdc, &rect, hbrush );
}


/***********************************************************************
 *		DrawFocusRect (USER.466)
 */
void WINAPI DrawFocusRect16( HDC16 hdc, const RECT16* rc )
{
    RECT rect32;
    CONV_RECT16TO32( rc, &rect32 );
    DrawFocusRect( hdc, &rect32 );
}


/***********************************************************************
 *		DrawFocusRect (USER32.@)
 *
 * FIXME: PatBlt(PATINVERT) with background brush.
 */
BOOL WINAPI DrawFocusRect( HDC hdc, const RECT* rc )
{
    HBRUSH hOldBrush;
    HPEN hOldPen, hNewPen;
    INT oldDrawMode, oldBkMode;

    hOldBrush = SelectObject(hdc, GetStockObject(NULL_BRUSH));
    hNewPen = CreatePen(PS_ALTERNATE, 1, GetSysColor(COLOR_WINDOWTEXT));
    hOldPen = SelectObject(hdc, hNewPen);
    oldDrawMode = SetROP2(hdc, R2_XORPEN);
    oldBkMode = SetBkMode(hdc, TRANSPARENT);

    Rectangle(hdc, rc->left, rc->top, rc->right, rc->bottom);

    SetBkMode(hdc, oldBkMode);
    SetROP2(hdc, oldDrawMode);
    SelectObject(hdc, hOldPen);
    DeleteObject(hNewPen);
    SelectObject(hdc, hOldBrush);

    return TRUE;
}


/**********************************************************************
 *		DrawAnimatedRects (USER32.@)
 */
BOOL WINAPI DrawAnimatedRects( HWND hwnd, INT idAni,
                                   const RECT* lprcFrom,
                                   const RECT* lprcTo )
{
    FIXME_(win)("(0x%x,%d,%p,%p): stub\n",hwnd,idAni,lprcFrom,lprcTo);
    return TRUE;
}


/**********************************************************************
 *          PAINTING_DrawStateJam
 *
 * Jams in the requested type in the dc
 */
static BOOL PAINTING_DrawStateJam(HDC hdc, UINT opcode,
                                  DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
                                  LPRECT rc, UINT dtflags, BOOL unicode )
{
    HDC memdc;
    HBITMAP hbmsave;
    BOOL retval;
    INT cx = rc->right - rc->left;
    INT cy = rc->bottom - rc->top;
    
    switch(opcode)
    {
    case DST_TEXT:
    case DST_PREFIXTEXT:
        if(unicode)
            return DrawTextW(hdc, (LPWSTR)lp, (INT)wp, rc, dtflags);
        else
            return DrawTextA(hdc, (LPSTR)lp, (INT)wp, rc, dtflags);

    case DST_ICON:
        return DrawIcon(hdc, rc->left, rc->top, (HICON)lp);

    case DST_BITMAP:
        memdc = CreateCompatibleDC(hdc);
        if(!memdc) return FALSE;
        hbmsave = (HBITMAP)SelectObject(memdc, (HBITMAP)lp);
        if(!hbmsave) 
        {
            DeleteDC(memdc);
            return FALSE;
        }
        retval = BitBlt(hdc, rc->left, rc->top, cx, cy, memdc, 0, 0, SRCCOPY);
        SelectObject(memdc, hbmsave);
        DeleteDC(memdc);
        return retval;
            
    case DST_COMPLEX:
        if(func) {
	    BOOL bRet;
	    /* DRAWSTATEPROC assumes that it draws at the center of coordinates  */

	    OffsetViewportOrgEx(hdc, rc->left, rc->top, NULL);
            bRet = func(hdc, lp, wp, cx, cy);
	    /* Restore origin */
	    OffsetViewportOrgEx(hdc, -rc->left, -rc->top, NULL);
	    return bRet;
	} else
            return FALSE;
    }
    return FALSE;
}

/**********************************************************************
 *      PAINTING_DrawState()
 */
static BOOL PAINTING_DrawState(HDC hdc, HBRUSH hbr, DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
                               INT x, INT y, INT cx, INT cy, UINT flags, BOOL unicode )
{
    HBITMAP hbm, hbmsave;
    HFONT hfsave;
    HBRUSH hbsave, hbrtmp = 0;
    HDC memdc;
    RECT rc;
    UINT dtflags = DT_NOCLIP;
    COLORREF fg, bg;
    UINT opcode = flags & 0xf;
    INT len = wp;
    BOOL retval, tmp;

    if((opcode == DST_TEXT || opcode == DST_PREFIXTEXT) && !len)    /* The string is '\0' terminated */
    {
        if(unicode)
            len = strlenW((LPWSTR)lp);
        else
            len = strlen((LPSTR)lp);
    }

    /* Find out what size the image has if not given by caller */
    if(!cx || !cy)
    {
        SIZE s;
        CURSORICONINFO *ici;
	BITMAP bm;

        switch(opcode)
        {
        case DST_TEXT:
        case DST_PREFIXTEXT:
            if(unicode)
                retval = GetTextExtentPoint32W(hdc, (LPWSTR)lp, len, &s);
            else
                retval = GetTextExtentPoint32A(hdc, (LPSTR)lp, len, &s);
            if(!retval) return FALSE;
            break;
            
        case DST_ICON:
            ici = (CURSORICONINFO *)GlobalLock16((HGLOBAL16)lp);
            if(!ici) return FALSE;
            s.cx = ici->nWidth;
            s.cy = ici->nHeight;
            GlobalUnlock16((HGLOBAL16)lp);
            break;            

        case DST_BITMAP:
	    if(!GetObjectA((HBITMAP)lp, sizeof(bm), &bm))
	        return FALSE;
            s.cx = bm.bmWidth;
            s.cy = bm.bmHeight;
            break;
            
        case DST_COMPLEX: /* cx and cy must be set in this mode */
            return FALSE;
	}
	            
        if(!cx) cx = s.cx;
        if(!cy) cy = s.cy;
    }

    rc.left   = x;
    rc.top    = y;
    rc.right  = x + cx;
    rc.bottom = y + cy;

    if(flags & DSS_RIGHT)    /* This one is not documented in the win32.hlp file */
        dtflags |= DT_RIGHT;
    if(opcode == DST_TEXT)
        dtflags |= DT_NOPREFIX;

    /* For DSS_NORMAL we just jam in the image and return */
    if((flags & 0x7ff0) == DSS_NORMAL)
    {
        return PAINTING_DrawStateJam(hdc, opcode, func, lp, len, &rc, dtflags, unicode);
    }

    /* For all other states we need to convert the image to B/W in a local bitmap */
    /* before it is displayed */
    fg = SetTextColor(hdc, RGB(0, 0, 0));
    bg = SetBkColor(hdc, RGB(255, 255, 255));
    hbm = (HBITMAP)NULL; hbmsave = (HBITMAP)NULL;
    memdc = (HDC)NULL; hbsave = (HBRUSH)NULL;
    retval = FALSE; /* assume failure */
    
    /* From here on we must use "goto cleanup" when something goes wrong */
    hbm     = CreateBitmap(cx, cy, 1, 1, NULL);
    if(!hbm) goto cleanup;
    memdc   = CreateCompatibleDC(hdc);
    if(!memdc) goto cleanup;
    hbmsave = (HBITMAP)SelectObject(memdc, hbm);
    if(!hbmsave) goto cleanup;
    rc.left = rc.top = 0;
    rc.right = cx;
    rc.bottom = cy;
    if(!FillRect(memdc, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH))) goto cleanup;
    SetBkColor(memdc, RGB(255, 255, 255));
    SetTextColor(memdc, RGB(0, 0, 0));
    hfsave  = (HFONT)SelectObject(memdc, GetCurrentObject(hdc, OBJ_FONT));

    /* DST_COMPLEX may draw text as well,
     * so we must be sure that correct font is selected
     */
    if(!hfsave && (opcode <= DST_PREFIXTEXT)) goto cleanup;
    tmp = PAINTING_DrawStateJam(memdc, opcode, func, lp, len, &rc, dtflags, unicode);
    if(hfsave) SelectObject(memdc, hfsave);
    if(!tmp) goto cleanup;
    
    /* This state cause the image to be dithered */
    if(flags & DSS_UNION)
    {
        hbsave = (HBRUSH)SelectObject(memdc, CACHE_GetPattern55AABrush());
        if(!hbsave) goto cleanup;
        tmp = PatBlt(memdc, 0, 0, cx, cy, 0x00FA0089);
        SelectObject(memdc, hbsave);
        if(!tmp) goto cleanup;
    }

    if (flags & DSS_DISABLED)
       hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
    else if (flags & DSS_DEFAULT)
       hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));

    /* Draw light or dark shadow */
    if (flags & (DSS_DISABLED|DSS_DEFAULT))
    {
       if(!hbrtmp) goto cleanup;
       hbsave = (HBRUSH)SelectObject(hdc, hbrtmp);
       if(!hbsave) goto cleanup;
       if(!BitBlt(hdc, x+1, y+1, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
       SelectObject(hdc, hbsave);
       DeleteObject(hbrtmp);
       hbrtmp = 0;
    }

    if (flags & DSS_DISABLED)
    {
       hbr = hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
       if(!hbrtmp) goto cleanup;
    }
    else if (!hbr)
    {
       hbr = (HBRUSH)GetStockObject(BLACK_BRUSH);
    }

    hbsave = (HBRUSH)SelectObject(hdc, hbr);
    
    if(!BitBlt(hdc, x, y, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
    
    retval = TRUE; /* We succeeded */
    
cleanup:    
    SetTextColor(hdc, fg);
    SetBkColor(hdc, bg);

    if(hbsave)  SelectObject(hdc, hbsave);
    if(hbmsave) SelectObject(memdc, hbmsave);
    if(hbrtmp)  DeleteObject(hbrtmp);
    if(hbm)     DeleteObject(hbm);
    if(memdc)   DeleteDC(memdc);

    return retval;
}

/**********************************************************************
 *		DrawStateA (USER32.@)
 */
BOOL WINAPI DrawStateA(HDC hdc, HBRUSH hbr,
                   DRAWSTATEPROC func, LPARAM ldata, WPARAM wdata,
                   INT x, INT y, INT cx, INT cy, UINT flags)
{
    return PAINTING_DrawState(hdc, hbr, func, ldata, wdata, x, y, cx, cy, flags, FALSE);
}

/**********************************************************************
 *		DrawStateW (USER32.@)
 */
BOOL WINAPI DrawStateW(HDC hdc, HBRUSH hbr,
                   DRAWSTATEPROC func, LPARAM ldata, WPARAM wdata,
                   INT x, INT y, INT cx, INT cy, UINT flags)
{
    return PAINTING_DrawState(hdc, hbr, func, ldata, wdata, x, y, cx, cy, flags, TRUE);
}


/**********************************************************************
 *	     DrawState    (USER.449)
 */
BOOL16 WINAPI DrawState16( HDC16 hdc, HBRUSH16 hbr, DRAWSTATEPROC16 func, LPARAM ldata,
                           WPARAM16 wdata, INT16 x, INT16 y, INT16 cx, INT16 cy, UINT16 flags )
{
    struct draw_state_info info;
    UINT opcode = flags & 0xf;

    if (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)
    {
        /* make sure DrawStateA doesn't try to use ldata as a pointer */
        if (!wdata) wdata = strlen( MapSL(ldata) );
        if (!cx || !cy)
        {
            SIZE s;
            if (!GetTextExtentPoint32A( hdc, MapSL(ldata), wdata, &s )) return FALSE;
            if (!cx) cx = s.cx;
            if (!cy) cy = s.cy;
        }
    }
    info.proc  = func;
    info.param = ldata;
    return DrawStateA( hdc, hbr, draw_state_callback, (LPARAM)&info, wdata, x, y, cx, cy, flags );
}


/***********************************************************************
 *		SelectPalette (USER.282)
 */
HPALETTE16 WINAPI SelectPalette16( HDC16 hDC, HPALETTE16 hPal,
                                   BOOL16 bForceBackground )
{
    WORD wBkgPalette = 1;

    if (!bForceBackground && (hPal != GetStockObject(DEFAULT_PALETTE)))
    {
        HWND hwnd = WindowFromDC( hDC );
        if (hwnd)
        {
            HWND hForeground = GetForegroundWindow();
            /* set primary palette if it's related to current active */
            if (hForeground == hwnd || IsChild(hForeground,hwnd)) wBkgPalette = 0;
        }
    }
    return GDISelectPalette16( hDC, hPal, wBkgPalette);
}


/***********************************************************************
 *		RealizePalette (USER.283)
 */
UINT16 WINAPI RealizePalette16( HDC16 hDC )
{
    UINT16 realized = GDIRealizePalette16( hDC );

    /* do not send anything if no colors were changed */
    if (realized && IsDCCurrentPalette16( hDC ))
    {
        /* send palette change notification */
        HWND hWnd = WindowFromDC( hDC );
        if (hWnd) SendMessageA( HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hWnd, 0L);
    }
    return realized;
}


/***********************************************************************
 *		UserRealizePalette (USER32.@)
 */
UINT WINAPI UserRealizePalette( HDC hDC )
{
    return RealizePalette16( hDC );
}
