/*
* USER DCE functions
 *
 * Copyright 1993, 2005 Alexandre Julliard
 * Copyright 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
 */

#include "config.h"

#include <assert.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "win.h"
#include "windef.h"
#include "wingdi.h"
#include "wownt32.h"
#include "x11drv.h"
#include "wine/winbase16.h"
#include "wine/wingdi16.h"
#include "wine/server.h"
#include "wine/list.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(dc);

struct dce
{
    struct list entry;         /* entry in global DCE list */
    HDC         hdc;
    HWND        hwnd;
    HRGN        clip_rgn;
    DWORD       flags;
    void       *class_ptr;     /* ptr to identify window class for class DCEs */
    ULONG       count;         /* usage count; 0 or 1 for cache DCEs, always 1 for window DCEs,
                                  always >= 1 for class DCEs */
};

static struct list dce_list = LIST_INIT(dce_list);

static BOOL16 CALLBACK dc_hook( HDC16 hDC, WORD code, DWORD data, LPARAM lParam );

static CRITICAL_SECTION dce_section;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &dce_section,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": dce_section") }
};
static CRITICAL_SECTION dce_section = { &critsect_debug, -1, 0, 0, 0, 0 };

static const WCHAR displayW[] = { 'D','I','S','P','L','A','Y',0 };


/***********************************************************************
 *           dump_cache
 */
static void dump_cache(void)
{
    struct dce *dce;

    EnterCriticalSection( &dce_section );

    LIST_FOR_EACH_ENTRY( dce, &dce_list, struct dce, entry )
    {
        TRACE("%p: hwnd %p dcx %08lx %s %s\n",
              dce, dce->hwnd, dce->flags,
              (dce->flags & DCX_CACHE) ? "Cache" : "Owned",
              dce->count ? "InUse" : "" );
    }

    LeaveCriticalSection( &dce_section );
}


/***********************************************************************
 *		update_visible_region
 *
 * Set the visible region and X11 drawable for the DC associated to
 * a given window.
 */
static void update_visible_region( struct dce *dce )
{
    NTSTATUS status;
    HRGN vis_rgn = 0;
    HWND top = 0;
    struct x11drv_escape_set_drawable escape;
    struct x11drv_win_data *data;
    DWORD flags = dce->flags;
    size_t size = 256;

    /* don't clip siblings if using parent clip region */
    if (flags & DCX_PARENTCLIP) flags &= ~DCX_CLIPSIBLINGS;

    /* fetch the visible region from the server */
    do
    {
        RGNDATA *data = HeapAlloc( GetProcessHeap(), 0, sizeof(*data) + size - 1 );
        if (!data) return;

        SERVER_START_REQ( get_visible_region )
        {
            req->window  = dce->hwnd;
            req->flags   = flags;
            wine_server_set_reply( req, data->Buffer, size );
            if (!(status = wine_server_call( req )))
            {
                size_t reply_size = wine_server_reply_size( reply );
                data->rdh.dwSize   = sizeof(data->rdh);
                data->rdh.iType    = RDH_RECTANGLES;
                data->rdh.nCount   = reply_size / sizeof(RECT);
                data->rdh.nRgnSize = reply_size;
                vis_rgn = ExtCreateRegion( NULL, size, data );

                top = reply->top_win;
                escape.org.x = reply->win_org_x - reply->top_org_x;
                escape.org.y = reply->win_org_y - reply->top_org_y;
                escape.drawable_org.x = reply->top_org_x;
                escape.drawable_org.y = reply->top_org_y;
            }
            else size = reply->total_size;
        }
        SERVER_END_REQ;
        HeapFree( GetProcessHeap(), 0, data );
    } while (status == STATUS_BUFFER_OVERFLOW);

    if (status || !vis_rgn) return;

    if (dce->clip_rgn) CombineRgn( vis_rgn, vis_rgn, dce->clip_rgn,
                                   (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );

    if (top == dce->hwnd && ((data = X11DRV_get_win_data( dce->hwnd )) != NULL) &&
         IsIconic( dce->hwnd ) && data->icon_window)
        escape.drawable = data->icon_window;
    else
        escape.drawable = X11DRV_get_whole_window( top );

    escape.code = X11DRV_SET_DRAWABLE;
    escape.mode = IncludeInferiors;
    ExtEscape( dce->hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );

    /* map region to DC coordinates */
    OffsetRgn( vis_rgn,
               -(escape.drawable_org.x + escape.org.x),
               -(escape.drawable_org.y + escape.org.y) );
    SelectVisRgn16( HDC_16(dce->hdc), HRGN_16(vis_rgn) );
    DeleteObject( vis_rgn );
}


/***********************************************************************
 *		release_dce
 */
static void release_dce( struct dce *dce )
{
    struct x11drv_escape_set_drawable escape;

    if (!dce->hwnd) return;  /* already released */

    if (dce->clip_rgn) DeleteObject( dce->clip_rgn );
    dce->clip_rgn = 0;
    dce->hwnd     = 0;
    dce->flags   &= DCX_CACHE;

    escape.code = X11DRV_SET_DRAWABLE;
    escape.drawable = root_window;
    escape.mode = IncludeInferiors;
    escape.org.x = escape.org.y = 0;
    escape.drawable_org.x = escape.drawable_org.y = 0;
    ExtEscape( dce->hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
}


/***********************************************************************
 *   delete_clip_rgn
 */
static void delete_clip_rgn( struct dce *dce )
{
    if (!dce->clip_rgn) return;  /* nothing to do */

    dce->flags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN);
    DeleteObject( dce->clip_rgn );
    dce->clip_rgn = 0;

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


/***********************************************************************
 *           alloc_cache_dce
 *
 * Allocate a new cache DCE.
 */
static struct dce *alloc_cache_dce(void)
{
    struct x11drv_escape_set_dce escape;
    struct dce *dce;

    if (!(dce = HeapAlloc( GetProcessHeap(), 0, sizeof(*dce) ))) return NULL;
    if (!(dce->hdc = CreateDCW( displayW, NULL, NULL, NULL )))
    {
        HeapFree( GetProcessHeap(), 0, dce );
        return 0;
    }
    SaveDC( dce->hdc );

    /* store DCE handle in DC hook data field */
    SetDCHook( dce->hdc, dc_hook, (DWORD)dce );

    dce->hwnd      = 0;
    dce->clip_rgn  = 0;
    dce->flags     = DCX_CACHE;
    dce->class_ptr = NULL;
    dce->count     = 1;

    EnterCriticalSection( &dce_section );
    list_add_head( &dce_list, &dce->entry );
    LeaveCriticalSection( &dce_section );

    escape.code = X11DRV_SET_DCE;
    escape.dce  = dce;
    ExtEscape( dce->hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, 0, NULL );

    return dce;
}


/***********************************************************************
 *           alloc_window_dce
 *
 * Allocate a DCE for a newly created window if necessary.
 */
void alloc_window_dce( struct x11drv_win_data *data )
{
    struct x11drv_escape_set_dce escape;
    struct dce *dce;
    void *class_ptr = NULL;
    LONG style = GetClassLongW( data->hwnd, GCL_STYLE );

    if (!(style & (CS_CLASSDC|CS_OWNDC))) return;  /* nothing to do */

    if (!(style & CS_OWNDC))  /* class dc */
    {
        /* hack: get the class pointer from the window structure */
        WND *win = WIN_GetPtr( data->hwnd );
        class_ptr = win->class;
        WIN_ReleasePtr( win );

        EnterCriticalSection( &dce_section );
        LIST_FOR_EACH_ENTRY( dce, &dce_list, struct dce, entry )
        {
            if (dce->class_ptr == class_ptr)
            {
                dce->count++;
                data->dce = dce;
                LeaveCriticalSection( &dce_section );
                return;
            }
        }
        LeaveCriticalSection( &dce_section );
    }

    /* now allocate a new one */

    if (!(dce = HeapAlloc( GetProcessHeap(), 0, sizeof(*dce) ))) return;
    if (!(dce->hdc = CreateDCW( displayW, NULL, NULL, NULL )))
    {
        HeapFree( GetProcessHeap(), 0, dce );
        return;
    }

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

    SetDCHook( dce->hdc, dc_hook, (DWORD)dce );

    dce->hwnd      = data->hwnd;
    dce->clip_rgn  = 0;
    dce->flags     = 0;
    dce->class_ptr = class_ptr;
    dce->count     = 1;

    if (style & CS_OWNDC)
    {
        LONG win_style = GetWindowLongW( data->hwnd, GWL_STYLE );
        if (win_style & WS_CLIPCHILDREN) dce->flags |= DCX_CLIPCHILDREN;
        if (win_style & WS_CLIPSIBLINGS) dce->flags |= DCX_CLIPSIBLINGS;
    }
    SetHookFlags16( HDC_16(dce->hdc), DCHF_INVALIDATEVISRGN );

    EnterCriticalSection( &dce_section );
    list_add_tail( &dce_list, &dce->entry );
    LeaveCriticalSection( &dce_section );
    data->dce = dce;

    escape.code = X11DRV_SET_DCE;
    escape.dce  = dce;
    ExtEscape( dce->hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, 0, NULL );
}


/***********************************************************************
 *           free_window_dce
 *
 * Free a class or window DCE.
 */
void free_window_dce( struct x11drv_win_data *data )
{
    struct dce *dce = data->dce;

    if (dce)
    {
        EnterCriticalSection( &dce_section );
        if (!--dce->count)
        {
            list_remove( &dce->entry );
            SetDCHook(dce->hdc, NULL, 0L);
            DeleteDC( dce->hdc );
            if (dce->clip_rgn) DeleteObject( dce->clip_rgn );
            HeapFree( GetProcessHeap(), 0, dce );
        }
        else if (dce->hwnd == data->hwnd)
        {
            release_dce( dce );
        }
        LeaveCriticalSection( &dce_section );
        data->dce = NULL;
    }

    /* now check for cache DCEs */

    EnterCriticalSection( &dce_section );
    LIST_FOR_EACH_ENTRY( dce, &dce_list, struct dce, entry )
    {
        if (dce->hwnd != data->hwnd) continue;
        if (!(dce->flags & DCX_CACHE)) continue;

        if (dce->count) WARN( "GetDC() without ReleaseDC() for window %p\n", data->hwnd );
        release_dce( dce );
        dce->count = 0;
    }
    LeaveCriticalSection( &dce_section );
}


/***********************************************************************
 *   invalidate_dce
 *
 * It is called from SetWindowPos() - 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.
 */
void invalidate_dce( HWND hwnd, const RECT *rect )
{
    HWND hwndScope = GetAncestor( hwnd, GA_PARENT );

    if( hwndScope )
    {
        struct dce *dce;

        TRACE("scope hwnd = %p %s\n", hwndScope, wine_dbgstr_rect(rect) );
        if (TRACE_ON(dc)) dump_cache();

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

        LIST_FOR_EACH_ENTRY( dce, &dce_list, struct dce, entry )
        {
            if (!dce->hwnd) continue;
            if ((dce->hwnd == hwndScope) && !(dce->flags & DCX_CLIPCHILDREN))
                continue;  /* child window positions don't bother us */

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

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

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

                    TRACE("\tpurged %p dce [%p]\n", dce, dce->hwnd);
                    release_dce( dce );
                }
                else
                {
                    /* Set dirty bits in the hDC and DCE structs */

                    TRACE("\tfixed up %p dce [%p]\n", dce, dce->hwnd);
                    SetHookFlags16( HDC_16(dce->hdc), DCHF_INVALIDATEVISRGN );
                }
            }
        } /* dce list */
    }
}


/***********************************************************************
 *		X11DRV_GetDCEx   (X11DRV.@)
 *
 * Unimplemented flags: DCX_LOCKWINDOWUPDATE
 */
HDC X11DRV_GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
{
    static const DWORD clip_flags = DCX_PARENTCLIP | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW;

    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
    struct dce *dce;
    BOOL bUpdateVisRgn = TRUE;
    HWND parent;
    LONG window_style = GetWindowLongW( hwnd, GWL_STYLE );

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

    /* fixup flags */

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

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

        if (window_style & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS;

        if (!(flags & DCX_WINDOW))
        {
            if (GetClassLongW( hwnd, GCL_STYLE ) & CS_PARENTDC) flags |= DCX_PARENTCLIP;

            if (window_style & WS_CLIPCHILDREN && !(window_style & WS_MINIMIZE))
                flags |= DCX_CLIPCHILDREN;
            if (!data || !data->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( (window_style & WS_VISIBLE) && (parent_style & WS_VISIBLE) )
        {
            flags &= ~DCX_CLIPCHILDREN;
            if (parent_style & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS;
        }
    }

    /* find a suitable DCE */

    if (flags & DCX_CACHE)
    {
        struct dce *dceEmpty = NULL, *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.
         */
        EnterCriticalSection( &dce_section );
        LIST_FOR_EACH_ENTRY( dce, &dce_list, struct dce, entry )
        {
            if ((dce->flags & DCX_CACHE) && !dce->count)
            {
                dceUnused = dce;

                if (!dce->hwnd) dceEmpty = dce;
                else if ((dce->hwnd == hwnd) && !((dce->flags ^ flags) & clip_flags))
                {
                    TRACE("\tfound valid %p dce [%p], flags %08lx\n",
                          dce, hwnd, dce->flags );
                    bUpdateVisRgn = FALSE;
                    break;
                }
            }
        }

        if (&dce->entry == &dce_list)  /* nothing found */
            dce = dceEmpty ? dceEmpty : dceUnused;

        if (dce) dce->count = 1;

        LeaveCriticalSection( &dce_section );

        /* if there's no dce empty or unused, allocate a new one */
        if (!dce) dce = alloc_cache_dce();
        if (!dce) return 0;
    }
    else
    {
        flags |= DCX_NORESETATTRS;
        dce = data->dce;
        if (dce->hwnd == hwnd)
        {
            TRACE("\tskipping hVisRgn update\n");
            bUpdateVisRgn = FALSE; /* updated automatically, via DCHook() */
        }
        else
        {
            /* we should free dce->clip_rgn here, but Windows apparently doesn't */
            dce->flags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN);
            dce->clip_rgn = 0;
        }
    }

    if (flags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN))
    {
        /* if the extra clip region has changed, get rid of the old one */
        if (dce->clip_rgn != hrgnClip || ((flags ^ dce->flags) & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)))
            delete_clip_rgn( dce );
        dce->clip_rgn = hrgnClip;
        if (!dce->clip_rgn) dce->clip_rgn = CreateRectRgn( 0, 0, 0, 0 );
        dce->flags |= flags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN);
        bUpdateVisRgn = TRUE;
    }

    dce->hwnd = hwnd;
    dce->flags = (dce->flags & ~clip_flags) | (flags & clip_flags);

    if (SetHookFlags16( HDC_16(dce->hdc), DCHF_VALIDATEVISRGN ))
        bUpdateVisRgn = TRUE;  /* DC was dirty */

    if (bUpdateVisRgn) update_visible_region( dce );

    if (!(flags & DCX_NORESETATTRS))
    {
        RestoreDC( dce->hdc, 1 );  /* initial save level is always 1 */
        SaveDC( dce->hdc );  /* save the state again for next time */
    }

    TRACE("(%p,%p,0x%lx): returning %p\n", hwnd, hrgnClip, flags, dce->hdc);
    return dce->hdc;
}


/***********************************************************************
 *		X11DRV_ReleaseDC  (X11DRV.@)
 */
INT X11DRV_ReleaseDC( HWND hwnd, HDC hdc, BOOL end_paint )
{
    enum x11drv_escape_codes escape = X11DRV_GET_DCE;
    struct dce *dce;
    BOOL ret = FALSE;

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

    EnterCriticalSection( &dce_section );
    if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
                    sizeof(dce), (LPSTR)&dce )) dce = NULL;
    if (dce && dce->count)
    {
        if (end_paint || (dce->flags & DCX_CACHE)) delete_clip_rgn( dce );
        if (dce->flags & DCX_CACHE) dce->count = 0;
        ret = TRUE;
    }
    LeaveCriticalSection( &dce_section );
    return ret;
}

/***********************************************************************
 *		dc_hook
 *
 * See "Undoc. Windows" for hints (DC, SetDCHook, SetHookFlags)..
 */
static BOOL16 CALLBACK dc_hook( HDC16 hDC, WORD code, DWORD data, LPARAM lParam )
{
    BOOL retv = TRUE;
    struct dce *dce = (struct dce *)data;

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

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

    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->count) update_visible_region( dce );
        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->count)
        {
            WARN("Application trying to delete a busy DC %p\n", dce->hdc);
            retv = FALSE;
        }
        else
        {
            EnterCriticalSection( &dce_section );
            list_remove( &dce->entry );
            LeaveCriticalSection( &dce_section );
            if (dce->clip_rgn) DeleteObject( dce->clip_rgn );
            HeapFree( GetProcessHeap(), 0, dce );
        }
        break;
    }
    return retv;
}


/**********************************************************************
 *		WindowFromDC   (X11DRV.@)
 */
HWND X11DRV_WindowFromDC( HDC hdc )
{
    enum x11drv_escape_codes escape = X11DRV_GET_DCE;
    struct dce *dce;
    HWND hwnd = 0;

    EnterCriticalSection( &dce_section );
    if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
                    sizeof(dce), (LPSTR)&dce )) dce = NULL;
    if (dce) hwnd = dce->hwnd;
    LeaveCriticalSection( &dce_section );
    return hwnd;
}
