/*
 * USER DCE functions
 *
 * Copyright 1993 Alexandre Julliard
 *	     1996,1997 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
 *
 *
 * Note: Visible regions of CS_OWNDC/CS_CLASSDC window DCs
 * have to be updated dynamically.
 *
 * Internal DCX flags:
 *
 * DCX_DCEEMPTY    - dce is uninitialized
 * DCX_DCEBUSY     - dce is in use
 * DCX_DCEDIRTY    - ReleaseDC() should wipe instead of caching
 * DCX_KEEPCLIPRGN - ReleaseDC() should not delete the clipping region
 * DCX_WINDOWPAINT - BeginPaint() is in effect
 */

#include <assert.h>
#include "dce.h"
#include "win.h"
#include "gdi.h"
#include "user.h"
#include "wine/debug.h"
#include "windef.h"
#include "wingdi.h"
#include "wownt32.h"
#include "wine/winbase16.h"
#include "wine/winuser16.h"

WINE_DEFAULT_DEBUG_CHANNEL(dc);

static DCE *firstDCE;
static HDC16 defaultDCstate;

static void DCE_DeleteClipRgn( DCE* );
static INT DCE_ReleaseDC( DCE* );


/***********************************************************************
 *           DCE_DumpCache
 */
static void DCE_DumpCache(void)
{
    DCE *dce;

    USER_Lock();
    dce = firstDCE;

    DPRINTF("DCE:\n");
    while( dce )
    {
	DPRINTF("\t[0x%08x] hWnd %p, dcx %08x, %s %s\n",
	     (unsigned)dce, dce->hwndCurrent, (unsigned)dce->DCXflags,
	     (dce->DCXflags & DCX_CACHE) ? "Cache" : "Owned",
	     (dce->DCXflags & DCX_DCEBUSY) ? "InUse" : "" );
	dce = dce->next;
    }

    USER_Unlock();
}

/***********************************************************************
 *           DCE_AllocDCE
 *
 * Allocate a new DCE.
 */
DCE *DCE_AllocDCE( HWND hWnd, DCE_TYPE type )
{
    DCE * dce;

    if (!(dce = HeapAlloc( GetProcessHeap(), 0, sizeof(DCE) ))) return NULL;
    if (!(dce->hDC = CreateDCA( "DISPLAY", NULL, NULL, NULL )))
    {
        HeapFree( GetProcessHeap(), 0, dce );
	return 0;
    }
    if (!defaultDCstate) defaultDCstate = GetDCState16( HDC_16(dce->hDC) );

    /* store DCE handle in DC hook data field */

    SetDCHook( dce->hDC, DCHook16, (DWORD)dce );

    dce->hwndCurrent = WIN_GetFullHandle( hWnd );
    dce->hClipRgn    = 0;

    if( type != DCE_CACHE_DC ) /* owned or class DC */
    {
	dce->DCXflags = DCX_DCEBUSY;
	if( hWnd )
	{
            LONG style = GetWindowLongW( hWnd, GWL_STYLE );
            if (style & WS_CLIPCHILDREN) dce->DCXflags |= DCX_CLIPCHILDREN;
            if (style & WS_CLIPSIBLINGS) dce->DCXflags |= DCX_CLIPSIBLINGS;
	}
        SetHookFlags16( HDC_16(dce->hDC), DCHF_INVALIDATEVISRGN );
    }
    else dce->DCXflags = DCX_CACHE | DCX_DCEEMPTY;

    USER_Lock();
    dce->next = firstDCE;
    firstDCE = dce;
    USER_Unlock();
    return dce;
}


/***********************************************************************
 *           DCE_FreeDCE
 */
DCE* DCE_FreeDCE( DCE *dce )
{
    DCE **ppDCE, *ret;

    if (!dce) return NULL;

    USER_Lock();

    ppDCE = &firstDCE;

    while (*ppDCE && (*ppDCE != dce)) ppDCE = &(*ppDCE)->next;
    if (*ppDCE == dce) *ppDCE = dce->next;
    ret = *ppDCE;
    USER_Unlock();

    SetDCHook(dce->hDC, NULL, 0L);

    DeleteDC( dce->hDC );
    if( dce->hClipRgn && !(dce->DCXflags & DCX_KEEPCLIPRGN) )
	DeleteObject(dce->hClipRgn);
    HeapFree( GetProcessHeap(), 0, dce );

    return ret;
}

/***********************************************************************
 *           DCE_FreeWindowDCE
 *
 * Remove owned DCE and reset unreleased cache DCEs.
 */
void DCE_FreeWindowDCE( HWND hwnd )
{
    DCE *pDCE;
    WND *pWnd = WIN_GetPtr( hwnd );

    pDCE = firstDCE;
    while( pDCE )
    {
	if( pDCE->hwndCurrent == hwnd )
	{
	    if( pDCE == pWnd->dce ) /* owned or Class DCE*/
	    {
                if (pWnd->clsStyle & CS_OWNDC)	/* owned DCE*/
		{
                    pDCE = DCE_FreeDCE( pDCE );
                    pWnd->dce = NULL;
                    continue;
                }
		else if( pDCE->DCXflags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN) )	/* Class DCE*/
		{
                    if (USER_Driver.pReleaseDC)
                        USER_Driver.pReleaseDC( pDCE->hwndCurrent, pDCE->hDC );
                    DCE_DeleteClipRgn( pDCE );
                    pDCE->hwndCurrent = 0;
		}
	    }
	    else
	    {
		if( pDCE->DCXflags & DCX_DCEBUSY ) /* shared cache DCE */
		{
                    /* FIXME: AFAICS we are doing the right thing here so
                     * this should be a WARN. But this is best left as an ERR
                     * because the 'application error' is likely to come from
                     * another part of Wine (i.e. it's our fault after all).
                     * We should change this to WARN when Wine is more stable
                     * (for 1.0?).
                     */
		    ERR("[%p] GetDC() without ReleaseDC()!\n",hwnd);
		    DCE_ReleaseDC( pDCE );
		}

                if (pDCE->hwndCurrent && USER_Driver.pReleaseDC)
                    USER_Driver.pReleaseDC( pDCE->hwndCurrent, pDCE->hDC );
		pDCE->DCXflags &= DCX_CACHE;
		pDCE->DCXflags |= DCX_DCEEMPTY;
		pDCE->hwndCurrent = 0;
	    }
	}
	pDCE = pDCE->next;
    }
    WIN_ReleasePtr( pWnd );
}


/***********************************************************************
 *   DCE_DeleteClipRgn
 */
static void DCE_DeleteClipRgn( DCE* dce )
{
    dce->DCXflags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN | DCX_WINDOWPAINT);

    if( dce->DCXflags & DCX_KEEPCLIPRGN )
	dce->DCXflags &= ~DCX_KEEPCLIPRGN;
    else
	if( dce->hClipRgn > (HRGN)1 )
	    DeleteObject( dce->hClipRgn );

    dce->hClipRgn = 0;

    /* make it dirty so that the vis rgn gets recomputed next time */
    dce->DCXflags |= DCX_DCEDIRTY;
    SetHookFlags16( HDC_16(dce->hDC), DCHF_INVALIDATEVISRGN );
}


/***********************************************************************
 *   DCE_ReleaseDC
 */
static INT DCE_ReleaseDC( DCE* dce )
{
    if ((dce->DCXflags & (DCX_DCEEMPTY | DCX_DCEBUSY)) != DCX_DCEBUSY) return 0;

    /* restore previous visible region */

    if ((dce->DCXflags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) &&
        (dce->DCXflags & (DCX_CACHE | DCX_WINDOWPAINT)) )
        DCE_DeleteClipRgn( dce );

    if (dce->DCXflags & DCX_CACHE)
    {
        /* make the DC clean so that SetDCState doesn't try to update the vis rgn */
        SetHookFlags16( HDC_16(dce->hDC), DCHF_VALIDATEVISRGN );
        SetDCState16( HDC_16(dce->hDC), defaultDCstate );
        dce->DCXflags &= ~DCX_DCEBUSY;
	if (dce->DCXflags & DCX_DCEDIRTY)
	{
	    /* don't keep around invalidated entries
	     * because SetDCState() disables hVisRgn updates
	     * by removing dirty bit. */
            if (dce->hwndCurrent && USER_Driver.pReleaseDC)
                USER_Driver.pReleaseDC( dce->hwndCurrent, dce->hDC );
	    dce->hwndCurrent = 0;
	    dce->DCXflags &= DCX_CACHE;
	    dce->DCXflags |= DCX_DCEEMPTY;
	}
    }
    return 1;
}


/***********************************************************************
 *   DCE_InvalidateDCE
 *
 * It is called from SetWindowPos() and EVENT_MapNotify - we have to
 * mark as dirty all busy DCEs for windows that have pWnd->parent as
 * an ancestor and whose client rect intersects with specified update
 * rectangle. In addition, pWnd->parent DCEs may need to be updated if
 * DCX_CLIPCHILDREN flag is set.  */
BOOL DCE_InvalidateDCE(HWND hwnd, const RECT* pRectUpdate)
{
    HWND hwndScope = GetAncestor( hwnd, GA_PARENT );
    BOOL bRet = FALSE;

    if( hwndScope )
    {
	DCE *dce;

        TRACE("scope hwnd = %p, (%i,%i - %i,%i)\n",
              hwndScope, pRectUpdate->left,pRectUpdate->top,
              pRectUpdate->right,pRectUpdate->bottom);
	if(TRACE_ON(dc))
	  DCE_DumpCache();

 	/* walk all DCEs and fixup non-empty entries */

	for (dce = firstDCE; (dce); dce = dce->next)
	{
            if (dce->DCXflags & DCX_DCEEMPTY) continue;
            if ((dce->hwndCurrent == hwndScope) && !(dce->DCXflags & DCX_CLIPCHILDREN))
                continue;  /* child window positions don't bother us */

            /* check if DCE window is within the z-order scope */

            if (hwndScope == dce->hwndCurrent || IsChild( hwndScope, dce->hwndCurrent ))
            {
                if (hwnd != dce->hwndCurrent)
                {
                    /* check if the window rectangle intersects this DCE window */
                    RECT rect;
                    GetWindowRect( dce->hwndCurrent, &rect );
                    MapWindowPoints( 0, hwndScope, (POINT *)&rect, 2 );
                    if (!IntersectRect( &rect, &rect, pRectUpdate )) continue;

                }
                if( !(dce->DCXflags & DCX_DCEBUSY) )
                {
                    /* Don't bother with visible regions of unused DCEs */

                    TRACE("\tpurged %p dce [%p]\n", dce, dce->hwndCurrent);
                    if (dce->hwndCurrent && USER_Driver.pReleaseDC)
                        USER_Driver.pReleaseDC( dce->hwndCurrent, dce->hDC );
                    dce->hwndCurrent = 0;
                    dce->DCXflags &= DCX_CACHE;
                    dce->DCXflags |= DCX_DCEEMPTY;
                }
                else
                {
                    /* Set dirty bits in the hDC and DCE structs */

                    TRACE("\tfixed up %p dce [%p]\n", dce, dce->hwndCurrent);
                    dce->DCXflags |= DCX_DCEDIRTY;
                    SetHookFlags16( HDC_16(dce->hDC), DCHF_INVALIDATEVISRGN );
                    bRet = TRUE;
                }
            }
	} /* dce list */
    }
    return bRet;
}


/***********************************************************************
 *           DCE_ExcludeRgn
 *
 *  Translate given region from the wnd client to the DC coordinates
 *  and add it to the clipping region.
 */
INT DCE_ExcludeRgn( HDC hDC, HWND hwnd, HRGN hRgn )
{
  POINT  pt = {0, 0};
  DCE     *dce = firstDCE;

  while (dce && (dce->hDC != hDC)) dce = dce->next;
  if (!dce) return ERROR;

  MapWindowPoints( hwnd, dce->hwndCurrent, &pt, 1);
  if( dce->DCXflags & DCX_WINDOW )
  {
      WND *wnd = WIN_FindWndPtr(dce->hwndCurrent);
      pt.x += wnd->rectClient.left - wnd->rectWindow.left;
      pt.y += wnd->rectClient.top - wnd->rectWindow.top;
      WIN_ReleaseWndPtr(wnd);
  }
  OffsetRgn(hRgn, pt.x, pt.y);

  return ExtSelectClipRgn( hDC, hRgn, RGN_DIFF );
}


/***********************************************************************
 *		GetDCEx (USER32.@)
 *
 * Unimplemented flags: DCX_LOCKWINDOWUPDATE
 *
 * FIXME: Full support for hrgnClip == 1 (alias for entire window).
 */
HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
{
    HDC 	hdc = 0;
    DCE * 	dce;
    WND * 	wndPtr;
    DWORD 	dcxFlags = 0;
    BOOL	bUpdateVisRgn = TRUE;
    BOOL	bUpdateClipOrigin = FALSE;
    HWND parent, full;

    TRACE("hwnd %p, hrgnClip %p, flags %08lx\n", hwnd, hrgnClip, flags);

    if (!hwnd) hwnd = GetDesktopWindow();
    if (!(full = WIN_IsCurrentProcess( hwnd )))
    {
        FIXME( "not supported yet on other process window %p\n", hwnd );
        return 0;
    }
    hwnd = full;
    if (!(wndPtr = WIN_GetPtr( hwnd ))) return 0;

    /* fixup flags */

    if (flags & (DCX_WINDOW | DCX_PARENTCLIP)) flags |= DCX_CACHE;

    if (flags & DCX_USESTYLE)
    {
	flags &= ~( DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS | DCX_PARENTCLIP);

        if( wndPtr->dwStyle & WS_CLIPSIBLINGS )
            flags |= DCX_CLIPSIBLINGS;

	if ( !(flags & DCX_WINDOW) )
	{
            if (wndPtr->clsStyle & CS_PARENTDC) flags |= DCX_PARENTCLIP;

	    if (wndPtr->dwStyle & WS_CLIPCHILDREN &&
                     !(wndPtr->dwStyle & WS_MINIMIZE) ) flags |= DCX_CLIPCHILDREN;
            if (!wndPtr->dce) flags |= DCX_CACHE;
	}
    }

    if (flags & DCX_WINDOW) flags &= ~DCX_CLIPCHILDREN;

    parent = GetAncestor( hwnd, GA_PARENT );
    if (!parent || (parent == GetDesktopWindow()))
        flags = (flags & ~DCX_PARENTCLIP) | DCX_CLIPSIBLINGS;

    /* it seems parent clip is ignored when clipping siblings or children */
    if (flags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN)) flags &= ~DCX_PARENTCLIP;

    if( flags & DCX_PARENTCLIP )
    {
        LONG parent_style = GetWindowLongW( parent, GWL_STYLE );
        if( (wndPtr->dwStyle & WS_VISIBLE) && (parent_style & WS_VISIBLE) )
        {
            flags &= ~DCX_CLIPCHILDREN;
            if (parent_style & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS;
        }
    }

    /* find a suitable DCE */

    dcxFlags = flags & (DCX_PARENTCLIP | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
		        DCX_CACHE | DCX_WINDOW);

    if (flags & DCX_CACHE)
    {
	DCE*	dceEmpty;
	DCE*	dceUnused;

	dceEmpty = dceUnused = NULL;

	/* Strategy: First, we attempt to find a non-empty but unused DCE with
	 * compatible flags. Next, we look for an empty entry. If the cache is
	 * full we have to purge one of the unused entries.
	 */

	for (dce = firstDCE; (dce); dce = dce->next)
	{
	    if ((dce->DCXflags & (DCX_CACHE | DCX_DCEBUSY)) == DCX_CACHE )
	    {
		dceUnused = dce;

		if (dce->DCXflags & DCX_DCEEMPTY)
		    dceEmpty = dce;
		else
		if ((dce->hwndCurrent == hwnd) &&
		   ((dce->DCXflags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
				      DCX_CACHE | DCX_WINDOW | DCX_PARENTCLIP)) == dcxFlags))
		{
		    TRACE("\tfound valid %p dce [%p], flags %08lx\n",
                          dce, hwnd, dcxFlags );
		    bUpdateVisRgn = FALSE;
		    bUpdateClipOrigin = TRUE;
		    break;
		}
	    }
	}

	if (!dce) dce = (dceEmpty) ? dceEmpty : dceUnused;

        /* if there's no dce empty or unused, allocate a new one */
        if (!dce)
        {
            dce = DCE_AllocDCE( 0, DCE_CACHE_DC );
        }
    }
    else
    {
        dce = wndPtr->dce;
        if (dce && dce->hwndCurrent == hwnd)
	{
	    TRACE("\tskipping hVisRgn update\n");
	    bUpdateVisRgn = FALSE; /* updated automatically, via DCHook() */
	}
    }
    if (!dce)
    {
        hdc = 0;
        goto END;
    }

    if (!(flags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN))) hrgnClip = 0;

    if (((flags ^ dce->DCXflags) & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) &&
        (dce->hClipRgn != hrgnClip))
    {
        /* if the extra clip region has changed, get rid of the old one */
        DCE_DeleteClipRgn( dce );
    }

    dce->hwndCurrent = hwnd;
    dce->hClipRgn = hrgnClip;
    dce->DCXflags = flags & (DCX_PARENTCLIP | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
                             DCX_CACHE | DCX_WINDOW | DCX_WINDOWPAINT |
                             DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_EXCLUDERGN);
    dce->DCXflags |= DCX_DCEBUSY;
    dce->DCXflags &= ~DCX_DCEDIRTY;
    hdc = dce->hDC;

    if (bUpdateVisRgn) SetHookFlags16( HDC_16(hdc), DCHF_INVALIDATEVISRGN ); /* force update */

    if (!USER_Driver.pGetDC( hwnd, hdc, hrgnClip, flags )) hdc = 0;

    TRACE("(%p,%p,0x%lx): returning %p\n", hwnd, hrgnClip, flags, hdc);
END:
    WIN_ReleasePtr(wndPtr);
    return hdc;
}


/***********************************************************************
 *		GetDC (USER32.@)
 * RETURNS
 *	:Handle to DC
 *	NULL: Failure
 */
HDC WINAPI GetDC(
	     HWND hwnd /* [in] handle of window */
) {
    if (!hwnd)
        return GetDCEx( 0, 0, DCX_CACHE | DCX_WINDOW );
    return GetDCEx( hwnd, 0, DCX_USESTYLE );
}


/***********************************************************************
 *		GetWindowDC (USER32.@)
 */
HDC WINAPI GetWindowDC( HWND hwnd )
{
    return GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
}


/***********************************************************************
 *		ReleaseDC (USER32.@)
 *
 * RETURNS
 *	1: Success
 *	0: Failure
 */
INT WINAPI ReleaseDC(
             HWND hwnd /* [in] Handle of window - ignored */,
             HDC hdc   /* [in] Handle of device context */
) {
    DCE * dce;
    INT nRet = 0;

    USER_Lock();
    dce = firstDCE;

    TRACE("%p %p\n", hwnd, hdc );

    while (dce && (dce->hDC != hdc)) dce = dce->next;

    if ( dce )
	if ( dce->DCXflags & DCX_DCEBUSY )
            nRet = DCE_ReleaseDC( dce );

    USER_Unlock();

    return nRet;
}

/***********************************************************************
 *		DCHook (USER.362)
 *
 * See "Undoc. Windows" for hints (DC, SetDCHook, SetHookFlags)..
 */
BOOL16 WINAPI DCHook16( HDC16 hDC, WORD code, DWORD data, LPARAM lParam )
{
    BOOL retv = TRUE;
    DCE *dce = (DCE *)data;

    TRACE("hDC = %04x, %i\n", hDC, code);

    if (!dce) return 0;
    assert( HDC_16(dce->hDC) == hDC );

    /* Grab the windows lock before doing anything else  */
    USER_Lock();

    switch( code )
    {
      case DCHC_INVALIDVISRGN:
	   /* GDI code calls this when it detects that the
	    * DC is dirty (usually after SetHookFlags()). This
	    * means that we have to recompute the visible region.
	    */
           if( dce->DCXflags & DCX_DCEBUSY )
           {
               /* Dirty bit has been cleared by caller, set it again so that
                * pGetDC recomputes the visible region. */
               SetHookFlags16( hDC, DCHF_INVALIDATEVISRGN );
               USER_Driver.pGetDC( dce->hwndCurrent, dce->hDC, dce->hClipRgn, dce->DCXflags );
           }
           else /* non-fatal but shouldn't happen */
	     WARN("DC is not in use!\n");
	   break;

      case DCHC_DELETEDC:
           /*
            * Windows will not let you delete a DC that is busy
            * (between GetDC and ReleaseDC)
            */

           if ( dce->DCXflags & DCX_DCEBUSY )
           {
               WARN("Application trying to delete a busy DC\n");
               retv = FALSE;
           }
           else DCE_FreeDCE( dce );
	   break;

      default:
	   FIXME("unknown code\n");
    }

  USER_Unlock();  /* Release the wnd lock */
  return retv;
}


/**********************************************************************
 *		WindowFromDC (USER32.@)
 */
HWND WINAPI WindowFromDC( HDC hDC )
{
    DCE *dce;
    HWND hwnd;

    USER_Lock();
    dce = firstDCE;

    while (dce && (dce->hDC != hDC)) dce = dce->next;

    hwnd = dce ? dce->hwndCurrent : 0;
    USER_Unlock();

    return hwnd;
}


/***********************************************************************
 *		LockWindowUpdate (USER32.@)
 */
BOOL WINAPI LockWindowUpdate( HWND hwnd )
{
    static HWND lockedWnd;

    FIXME("(%p), partial stub!\n",hwnd);

    USER_Lock();
    if (lockedWnd)
    {
        if (!hwnd)
        {
            /* Unlock lockedWnd */
            /* FIXME: Do something */
        }
        else
        {
            /* Attempted to lock a second window */
            /* Return FALSE and do nothing */
            USER_Unlock();
            return FALSE;
        }
    }
    lockedWnd = hwnd;
    USER_Unlock();
    return TRUE;
}
