/*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 %08x %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.dc_rect.left = reply->win_rect.left - reply->top_rect.left;
                escape.dc_rect.top = reply->win_rect.top - reply->top_rect.top;
                escape.dc_rect.right = reply->win_rect.right - reply->top_rect.left;
                escape.dc_rect.bottom = reply->win_rect.bottom - reply->top_rect.top;
                escape.drawable_rect.left = reply->top_rect.left;
                escape.drawable_rect.top = reply->top_rect.top;
                escape.drawable_rect.right = reply->top_rect.right;
                escape.drawable_rect.bottom = reply->top_rect.bottom;
            }
            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_rect.left + escape.dc_rect.left),
               -(escape.drawable_rect.top + escape.dc_rect.top) );
    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.drawable_rect = virtual_screen_rect;
    SetRect( &escape.dc_rect, 0, 0, virtual_screen_rect.right - virtual_screen_rect.left,
             virtual_screen_rect.bottom - virtual_screen_rect.top );
    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 %08x\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 %08x\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%x): 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;
}
