/*
 * Scroll windows and DCs
 *
 * Copyright 1993  David W. Metcalfe
 * Copyright 1995, 1996 Alex Korobka
 * Copyright 2001 Alexandre Julliard
 *
 * 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 <stdarg.h>
#include <X11/Xlib.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"

#include "x11drv.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(scroll);

static void dump_region( const char *p, HRGN hrgn)
{
    DWORD i, size;
    RGNDATA *data = NULL;
    RECT *rect;

    if (!hrgn) {
        TRACE( "%s null region\n", p );
        return;
    }
    if (!(size = GetRegionData( hrgn, 0, NULL ))) {
        return;
    }
    if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
    GetRegionData( hrgn, size, data );
    TRACE("%s %d rects:", p, data->rdh.nCount );
    for (i = 0, rect = (RECT *)data->Buffer; i<20 && i < data->rdh.nCount; i++, rect++)
        TRACE( " %s", wine_dbgstr_rect( rect));
    TRACE("\n");
    HeapFree( GetProcessHeap(), 0, data );
}

/*************************************************************************
 *		ScrollDC   (X11DRV.@)
 */
BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *lprcScroll,
                      const RECT *lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate )
{
    RECT rcSrc, rcClip, offset;
    INT dxdev, dydev, res;
    HRGN DstRgn, clipRgn, visrgn;
    INT code = X11DRV_START_EXPOSURES;

    TRACE("dx,dy %d,%d rcScroll %s rcClip %s hrgnUpdate %p lprcUpdate %p\n",
            dx, dy, wine_dbgstr_rect(lprcScroll), wine_dbgstr_rect(lprcClip),
            hrgnUpdate, lprcUpdate);
    /* enable X-exposure events */
    if (hrgnUpdate || lprcUpdate)
        ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL );
    /* get the visible region */
    visrgn=CreateRectRgn( 0, 0, 0, 0);
    GetRandomRgn( hdc, visrgn, SYSRGN);
    if( !(GetVersion() & 0x80000000)) {
        /* Window NT/2k/XP */
        POINT org;
        GetDCOrgEx(hdc, &org);
        OffsetRgn( visrgn, -org.x, -org.y);
    }
    /* intersect with the clipping Region if the DC has one */
    clipRgn = CreateRectRgn( 0, 0, 0, 0);
    if (GetClipRgn( hdc, clipRgn) != 1) {
        DeleteObject(clipRgn);
        clipRgn=NULL;
    } else
        CombineRgn( visrgn, visrgn, clipRgn, RGN_AND);
    /* only those pixels in the scroll rectangle that remain in the clipping
     * rect are scrolled. */
    if( lprcClip) 
        rcClip = *lprcClip;
    else
        GetClipBox( hdc, &rcClip);
    rcSrc = rcClip;
    OffsetRect( &rcClip, -dx, -dy);
    IntersectRect( &rcSrc, &rcSrc, &rcClip);
    /* if an scroll rectangle is specified, only the pixels within that
     * rectangle are scrolled */
    if( lprcScroll)
        IntersectRect( &rcSrc, &rcSrc, lprcScroll);
    /* now convert to device coordinates */
    LPtoDP(hdc, (LPPOINT)&rcSrc, 2);
    TRACE("source rect: %s\n", wine_dbgstr_rect(&rcSrc));
    /* also dx and dy */
    SetRect(&offset, 0, 0, dx, dy);
    LPtoDP(hdc, (LPPOINT)&offset, 2);
    dxdev = offset.right - offset.left;
    dydev = offset.bottom - offset.top;
    /* now intersect with the visible region to get the pixels that will
     * actually scroll */
    DstRgn = CreateRectRgnIndirect( &rcSrc);
    res = CombineRgn( DstRgn, DstRgn, visrgn, RGN_AND);
    /* and translate, giving the destination region */
    OffsetRgn( DstRgn, dxdev, dydev);
    if( TRACE_ON( scroll)) dump_region( "Destination scroll region: ", DstRgn);
    /* if there are any, do it */
    if( res > NULLREGION) {
        RECT rect ;
        /* clip to the destination region, so we can BitBlt with a simple
         * bounding rectangle */
        if( clipRgn)
            ExtSelectClipRgn( hdc, DstRgn, RGN_AND);
        else
            SelectClipRgn( hdc, DstRgn);
        GetRgnBox( DstRgn, &rect);
        DPtoLP(hdc, (LPPOINT)&rect, 2);
        TRACE("destination rect: %s\n", wine_dbgstr_rect(&rect));

        BitBlt( hdc, rect.left, rect.top,
                    rect.right - rect.left, rect.bottom - rect.top,
                    hdc, rect.left - dx, rect.top - dy, SRCCOPY);
    }
    /* compute the update areas.  This is the combined clip rectangle
     * minus the scrolled region, and intersected with the visible
     * region. */
    if (hrgnUpdate || lprcUpdate)
    {
        HRGN hrgn = hrgnUpdate;
        HRGN ExpRgn = 0;

        /* collect all the exposures */
        code = X11DRV_END_EXPOSURES;
        ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code,
                sizeof(ExpRgn), (LPSTR)&ExpRgn );
        /* Intersect clip and scroll rectangles, allowing NULL values */ 
        if( lprcScroll)
            if( lprcClip)
                IntersectRect( &rcClip, lprcClip, lprcScroll);
            else
                rcClip = *lprcScroll;
        else
            if( lprcClip)
                rcClip = *lprcClip;
            else
                GetClipBox( hdc, &rcClip);
        /* Convert the combined clip rectangle to device coordinates */
        LPtoDP(hdc, (LPPOINT)&rcClip, 2);
        if( hrgn )
            SetRectRgn( hrgn, rcClip.left, rcClip.top, rcClip.right,
                    rcClip.bottom);
        else
            hrgn = CreateRectRgnIndirect( &rcClip);
        CombineRgn( hrgn, hrgn, visrgn, RGN_AND);
        CombineRgn( hrgn, hrgn, DstRgn, RGN_DIFF);
        /* add the exposures to this */
        if( ExpRgn) {
            if( TRACE_ON( scroll)) dump_region( "Expose region: ", ExpRgn);
            CombineRgn( hrgn, hrgn, ExpRgn, RGN_OR);
            DeleteObject( ExpRgn);
        }
        if( TRACE_ON( scroll)) dump_region( "Update region: ", hrgn);
        if( lprcUpdate) {
            GetRgnBox( hrgn, lprcUpdate );
            /* Put the lprcUpdate in logical coordinates */
            DPtoLP( hdc, (LPPOINT)lprcUpdate, 2 );
            TRACE("returning lprcUpdate %s\n", wine_dbgstr_rect(lprcUpdate));
        }
        if( !hrgnUpdate)
            DeleteObject( hrgn);
    }
    /* restore original clipping region */
    SelectClipRgn( hdc, clipRgn);
    DeleteObject( visrgn);
    DeleteObject( DstRgn);
    if( clipRgn) DeleteObject( clipRgn);
    return TRUE;
}
