/*
 * Scroll windows and DCs
 *
 * Copyright  David W. Metcalfe, 1993
 *	      Alex Korobka       1995,1996
 *
 *
 */

#define NO_TRANSITION_TYPES  /* This file is Win32-clean */
#include <stdlib.h>
#include "windows.h"
#include "class.h"
#include "win.h"
#include "gdi.h"
#include "dce.h"
#include "region.h"
#include "graphics.h"
#include "sysmetrics.h"
#include "stddebug.h"
#include "debug.h"

extern HWND32 CARET_GetHwnd();			/* windows/caret.c */
extern void   CARET_GetRect(LPRECT32);
extern void CLIPPING_UpdateGCRegion(DC* );	/* objects/clipping.c */

/*************************************************************************
 *             ScrollWindow16   (USER.61)
 */
void ScrollWindow16( HWND16 hwnd, INT16 dx, INT16 dy, const RECT16 *rect,
                     const RECT16 *clipRect )
{
    RECT32 rect32, clipRect32;

    if (rect) CONV_RECT16TO32( rect, &rect32 );
    if (clipRect) CONV_RECT16TO32( clipRect, &clipRect32 );
    ScrollWindow32( hwnd, dx, dy, rect ? &rect32 : NULL,
                    clipRect ? &clipRect32 : NULL );
}

/*************************************************************************
 *             ScrollWindow32   (USER32.449)
 */
BOOL32 ScrollWindow32( HWND32 hwnd, INT32 dx, INT32 dy, const RECT32 *rect,
                       const RECT32 *clipRect )
{
    HDC32  	hdc;
    HRGN32 	hrgnUpdate,hrgnClip;
    RECT32 	rc, cliprc;
    HWND32 	hCaretWnd = CARET_GetHwnd();
    WND*	wndScroll = WIN_FindWndPtr( hwnd );

    dprintf_scroll(stddeb,"ScrollWindow: hwnd=%04x, dx=%d, dy=%d, lpRect =%p clipRect=%i,%i,%i,%i\n", 
                   hwnd, dx, dy, rect,
                   clipRect ? clipRect->left : 0,
                   clipRect ? clipRect->top : 0,
                   clipRect ? clipRect->right : 0, 
                   clipRect ? clipRect->bottom : 0 );

    if ( !wndScroll || !WIN_IsWindowDrawable( wndScroll, TRUE ) ) return TRUE;

    if ( !rect ) /* do not clip children */
       {
	  GetClientRect32(hwnd, &rc);
	  hrgnClip = CreateRectRgnIndirect32( &rc );

          if ((hCaretWnd == hwnd) || IsChild32(hwnd,hCaretWnd))
              HideCaret(hCaretWnd);
          else hCaretWnd = 0;
 
	  hdc = GetDCEx32(hwnd, hrgnClip, DCX_CACHE | DCX_CLIPSIBLINGS);
          DeleteObject32( hrgnClip );
       }
    else	/* clip children */
       {
	  CopyRect32(&rc, rect);

          if (hCaretWnd == hwnd) HideCaret(hCaretWnd);
          else hCaretWnd = 0;

	  hdc = GetDCEx32( hwnd, 0, DCX_CACHE | DCX_USESTYLE );
       }

    if (clipRect == NULL)
	GetClientRect32(hwnd, &cliprc);
    else
	CopyRect32(&cliprc, clipRect);

    hrgnUpdate = CreateRectRgn32( 0, 0, 0, 0 );
    ScrollDC32( hdc, dx, dy, &rc, &cliprc, hrgnUpdate, NULL );
    ReleaseDC32(hwnd, hdc);

    if( !rect )		/* move child windows and update region */
    { 
      WND*	wndPtr;

      if( wndScroll->hrgnUpdate > 1 )
	OffsetRgn32( wndScroll->hrgnUpdate, dx, dy );

      for (wndPtr = wndScroll->child; wndPtr; wndPtr = wndPtr->next)
        SetWindowPos32(wndPtr->hwndSelf, 0, wndPtr->rectWindow.left + dx,
                       wndPtr->rectWindow.top  + dy, 0,0, SWP_NOZORDER |
                       SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW |
                       SWP_DEFERERASE );
    }

    PAINT_RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_ALLCHILDREN |
			    RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW, RDW_C_USEHRGN );

    DeleteObject32( hrgnUpdate );
    if( hCaretWnd ) 
    {
	POINT32	pt;
	GetCaretPos32(&pt);
	pt.x += dx; pt.y += dy;
	SetCaretPos(pt.x, pt.y);
	ShowCaret(hCaretWnd);
    }
    return TRUE;
}


/*************************************************************************
 *             ScrollDC16   (USER.221)
 */
BOOL16 ScrollDC16( HDC16 hdc, INT16 dx, INT16 dy, const RECT16 *rect,
                   const RECT16 *cliprc, HRGN16 hrgnUpdate, LPRECT16 rcUpdate )
{
    RECT32 rect32, clipRect32, rcUpdate32;
    BOOL16 ret;

    if (rect) CONV_RECT16TO32( rect, &rect32 );
    if (cliprc) CONV_RECT16TO32( cliprc, &clipRect32 );
    ret = ScrollDC32( hdc, dx, dy, rect ? &rect32 : NULL,
                      cliprc ? &clipRect32 : NULL, hrgnUpdate, &rcUpdate32 );
    if (rcUpdate) CONV_RECT32TO16( &rcUpdate32, rcUpdate );
    return ret;
}


/*************************************************************************
 *             ScrollDC32   (USER32.448)
 * 
 * Both 'rc' and 'rLClip' are in logical units but update info is 
 * returned in device coordinates.
 */
BOOL32 ScrollDC32( HDC32 hdc, INT32 dx, INT32 dy, const RECT32 *rc,
                   const RECT32 *prLClip, HRGN32 hrgnUpdate, LPRECT32 rcUpdate )
{
    RECT32 rDClip, rLClip;
    HRGN32 hrgnClip = 0;
    HRGN32 hrgnScrollClip = 0;
    POINT32 src, dest;
    INT32  ldx, ldy;
    DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);

    dprintf_scroll(stddeb,"ScrollDC: %04x %d,%d hrgnUpdate=%04x rcUpdate = %p cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d)\n",
                   (HDC16)hdc, dx, dy, hrgnUpdate, rcUpdate, 
		   prLClip ? prLClip->left : 0, prLClip ? prLClip->top : 0, prLClip ? prLClip->right : 0, prLClip ? prLClip->bottom : 0,
		   rc ? rc->left : 0, rc ? rc->top : 0, rc ? rc->right : 0, rc ? rc->bottom : 0 );

    if ( !dc || !hdc ) return FALSE;

/*
    printf(stddeb,"\t[wndOrgX=%i, wndExtX=%i, vportOrgX=%i, vportExtX=%i]\n",
		  dc->wndOrgX, dc->wndExtX, dc->vportOrgX, dc->vportExtX );
    printf(stddeb,"\t[wndOrgY=%i, wndExtY=%i, vportOrgY=%i, vportExtY=%i]\n",
                  dc->wndOrgY, dc->wndExtY, dc->vportOrgY, dc->vportExtY );
*/

    /* compute device clipping region */

    if ( rc )
    {
	rLClip = *rc;
	rDClip.left = XLPTODP(dc, rc->left); rDClip.right = XLPTODP(dc, rc->right);
	rDClip.top = YLPTODP(dc, rc->top); rDClip.bottom = YLPTODP(dc, rc->bottom);
    }
    else /* maybe we should just return FALSE? */
    {
	GetClipBox32( hdc, &rDClip );
	rLClip.left = XDPTOLP(dc, rDClip.left); rLClip.right = XDPTOLP(dc, rDClip.right);
	rLClip.top = YDPTOLP(dc, rDClip.top); rLClip.bottom = YDPTOLP(dc, rDClip.bottom);
    }

    if (prLClip)
    {
	RECT32 r;

	r.left = XLPTODP(dc, prLClip->left); r.right = XLPTODP(dc, prLClip->right);
	r.top = YLPTODP(dc, prLClip->top); r.bottom = YLPTODP(dc, prLClip->bottom);
	IntersectRect32(&rLClip,&rLClip,prLClip);
	IntersectRect32(&rDClip,&rDClip,&r);
    }

    if( rDClip.left >= rDClip.right || rDClip.top >= rDClip.bottom )
	return FALSE;
    
    hrgnClip = GetClipRgn16(hdc);
    hrgnScrollClip = CreateRectRgnIndirect32(&rDClip);

    if( hrgnClip )
      {
        /* change device clipping region directly */

        CombineRgn32( hrgnScrollClip, hrgnClip, 0, RGN_COPY );
        SetRectRgn( hrgnClip, rDClip.left, rDClip.top,
			      rDClip.right, rDClip.bottom );

	CLIPPING_UpdateGCRegion( dc );
      }
    else
        SelectClipRgn32( hdc, hrgnScrollClip );

    /* translate coordinates */

    ldx = dx * dc->wndExtX / dc->vportExtX;
    ldy = dy * dc->wndExtY / dc->vportExtY;

    if (dx > 0)
	dest.x = (src.x = rLClip.left) + ldx;
    else
	src.x = (dest.x = rLClip.left) - ldx;

    if (dy > 0)
	dest.y = (src.y = rLClip.top) + ldy;
    else
	src.y = (dest.y = rLClip.top) - ldy;

    /* copy bits */

    if( rDClip.right - rDClip.left > dx &&
	rDClip.bottom - rDClip.top > dy )
    {
	ldx = rLClip.right - rLClip.left - ldx;
	ldy = rLClip.bottom - rLClip.top - ldy;

	if (!BitBlt32( hdc, dest.x, dest.y, ldx, ldy,
		       hdc, src.x, src.y, SRCCOPY))
	    return FALSE;
    }

    /* restore clipping region */

    if( hrgnClip )
    {
	CombineRgn32( hrgnClip, hrgnScrollClip, 0, RGN_COPY );
	CLIPPING_UpdateGCRegion( dc );
	SetRectRgn( hrgnScrollClip, rDClip.left, rDClip.top, 
				    rDClip.right, rDClip.bottom );
    }
    else
        SelectClipRgn32( hdc, 0 );

    /* compute update areas */

    if (hrgnUpdate || rcUpdate)
    {
	HRGN32 hrgn = (hrgnUpdate) ? hrgnUpdate : CreateRectRgn32( 0,0,0,0 );

	if( dc->w.hVisRgn )
	{
	  CombineRgn32( hrgn, dc->w.hVisRgn, hrgnScrollClip, RGN_AND );
	  OffsetRgn32( hrgn, dx, dy );
	  CombineRgn32( hrgn, dc->w.hVisRgn, hrgn, RGN_DIFF );
	  CombineRgn32( hrgn, hrgn, hrgnScrollClip, RGN_AND );
	}
	else
	{
	  RECT32 rect;

          rect = rDClip;				/* vertical band */
          if (dx > 0) rect.right = rect.left + dx;
          else if (dx < 0) rect.left = rect.right + dx;
          else SetRectEmpty32( &rect );
          SetRectRgn( hrgn, rect.left, rect.top, rect.right, rect.bottom );

          rect = rDClip;				/* horizontal band */
          if (dy > 0) rect.bottom = rect.top + dy;
          else if (dy < 0) rect.top = rect.bottom + dy;
          else SetRectEmpty32( &rect );

          REGION_UnionRectWithRgn( hrgn, &rect );
	}

	if (rcUpdate) GetRgnBox32( hrgn, rcUpdate );
	if (!hrgnUpdate) DeleteObject32( hrgn );
    }

    DeleteObject32( hrgnScrollClip );     
    return TRUE;
}


/*************************************************************************
 *             ScrollWindowEx16   (USER.319)
 */
INT16 ScrollWindowEx16( HWND16 hwnd, INT16 dx, INT16 dy, const RECT16 *rect,
                        const RECT16 *clipRect, HRGN16 hrgnUpdate,
                        LPRECT16 rcUpdate, UINT16 flags )
{
    RECT32 rect32, clipRect32, rcUpdate32;
    BOOL16 ret;

    if (rect) CONV_RECT16TO32( rect, &rect32 );
    if (clipRect) CONV_RECT16TO32( clipRect, &clipRect32 );
    ret = ScrollWindowEx32( hwnd, dx, dy, rect ? &rect32 : NULL,
                            clipRect ? &clipRect32 : NULL, hrgnUpdate,
                            (rcUpdate) ? &rcUpdate32 : NULL, flags );
    if (rcUpdate) CONV_RECT32TO16( &rcUpdate32, rcUpdate );
    return ret;
}

/*************************************************************************
 *             SCROLL_FixCaret
 */
BOOL32 SCROLL_FixCaret(HWND32 hWnd, LPRECT32 lprc, UINT32 flags)
{
   HWND32 hCaret = CARET_GetHwnd();

   if( hCaret )
   {
       RECT32	rc;
       CARET_GetRect( &rc );
       if( hCaret == hWnd ||
          (flags & SW_SCROLLCHILDREN && IsChild32(hWnd, hCaret)) )
       {
           POINT32     pt;

           pt.x = rc.left; pt.y = rc.top;
           MapWindowPoints32( hCaret, hWnd, (LPPOINT32)&rc, 2 );
           if( IntersectRect32(lprc, lprc, &rc) )
           {
               HideCaret(0);
  	       lprc->left = pt.x; lprc->top = pt.y;
	       return TRUE;
           }
       }
   }
   return FALSE;
}

/*************************************************************************
 *             ScrollWindowEx32   (USER32.450)
 */
INT32 ScrollWindowEx32( HWND32 hwnd, INT32 dx, INT32 dy, const RECT32 *rect,
                        const RECT32 *clipRect, HRGN32 hrgnUpdate,
                        LPRECT32 rcUpdate, UINT32 flags )
{
    INT32  retVal = NULLREGION;
    BOOL32 bCaret = FALSE, bOwnRgn = TRUE;
    RECT32 rc, cliprc;
    WND*   wnd = WIN_FindWndPtr( hwnd );

    if( !wnd || !WIN_IsWindowDrawable( wnd, TRUE )) return ERROR;

    if (rect == NULL) GetClientRect32(hwnd, &rc);
    else rc = *rect;

    if (clipRect) IntersectRect32(&cliprc,&rc,clipRect);
    else cliprc = rc;

    if (!IsRectEmpty32(&cliprc) && (dx || dy))
    {
	DC*	dc;
	HDC32	hDC;
	BOOL32  bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE));
	HRGN32  hrgnClip = CreateRectRgnIndirect32(&cliprc);

dprintf_scroll(stddeb,"ScrollWindowEx: %04x, %d,%d hrgnUpdate=%04x rcUpdate = %p \
cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d) %04x\n",             
(HWND16)hwnd, dx, dy, hrgnUpdate, rcUpdate,
clipRect?clipRect->left:0, clipRect?clipRect->top:0, clipRect?clipRect->right:0, clipRect?clipRect->bottom:0,
rect?rect->left:0, rect?rect->top:0, rect ?rect->right:0, rect ?rect->bottom:0, (UINT16)flags );

	rc = cliprc;
	bCaret = SCROLL_FixCaret(hwnd, &rc, flags);

	if( hrgnUpdate ) bOwnRgn = FALSE;
        else if( bUpdate ) hrgnUpdate = CreateRectRgn32( 0, 0, 0, 0 );

	hDC = GetDCEx32( hwnd, hrgnClip, DCX_CACHE | DCX_USESTYLE | 
		        (flags & SW_SCROLLCHILDREN) ? DCX_NOCLIPCHILDREN : 0 );
	if( (dc = (DC *)GDI_GetObjPtr(hDC, DC_MAGIC)) )
	{
	    POINT32 dst, src;

	    if( dx > 0 ) dst.x = (src.x = dc->w.DCOrgX + cliprc.left) + dx;
	    else src.x = (dst.x = dc->w.DCOrgX + cliprc.left) - dx;

	    if( dy > 0 ) dst.y = (src.y = dc->w.DCOrgY + cliprc.top) + dy;
	    else src.y = (dst.y = dc->w.DCOrgY + cliprc.top) - dy;

	    if( bUpdate )
  		XSetGraphicsExposures( display, dc->u.x.gc, True );
	    XSetFunction( display, dc->u.x.gc, GXcopy );
	    XCopyArea( display, dc->u.x.drawable, dc->u.x.drawable, dc->u.x.gc, 
		       src.x, src.y, cliprc.right - cliprc.left - abs(dx),
		       cliprc.bottom - cliprc.top - abs(dy), dst.x, dst.y );
	    if( bUpdate )
		XSetGraphicsExposures( display, dc->u.x.gc, False );

	    if( dc->w.hVisRgn && bUpdate )
	    {
		CombineRgn32( hrgnUpdate, dc->w.hVisRgn, hrgnClip, RGN_AND );
		OffsetRgn32( hrgnUpdate, dx, dy );
		CombineRgn32( hrgnUpdate, dc->w.hVisRgn, hrgnUpdate, RGN_DIFF );
		CombineRgn32( hrgnUpdate, hrgnUpdate, hrgnClip, RGN_AND );

		if( rcUpdate ) GetRgnBox32( hrgnUpdate, rcUpdate );
	    }
	    ReleaseDC32(hwnd, hDC);
	}

	if( wnd->hrgnUpdate > 1 )
	{
	    if( rect || clipRect )
	    {
		if( (CombineRgn32( hrgnClip, hrgnClip, 
				   wnd->hrgnUpdate, RGN_AND ) != NULLREGION) )
		{
		    CombineRgn32( wnd->hrgnUpdate, wnd->hrgnUpdate, hrgnClip, RGN_DIFF );
		    OffsetRgn32( hrgnClip, dx, dy );
		    CombineRgn32( wnd->hrgnUpdate, wnd->hrgnUpdate, hrgnClip, RGN_OR );
		}
	    }
	    else  
		OffsetRgn32( wnd->hrgnUpdate, dx, dy );
	}

	if( flags & SW_SCROLLCHILDREN )
	{
	    RECT32	r;
	    WND* 	w;
	    for( w = wnd->child; w; w = w->next )
	    {
		 CONV_RECT16TO32( &w->rectWindow, &r );
	         if( IntersectRect32(&r, &r, &cliprc) )
		     SetWindowPos32(w->hwndSelf, 0, w->rectWindow.left + dx,
				    w->rectWindow.top  + dy, 0,0, SWP_NOZORDER |
				    SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW |
				    SWP_DEFERERASE );
	    }
	}

	if( flags & (SW_INVALIDATE | SW_ERASE) )
            PAINT_RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
					((flags & SW_ERASE) ? RDW_ERASENOW : 0), 0 );

	if( bCaret )
	{
	    SetCaretPos( rc.left + dx, rc.top + dy );
	    ShowCaret(0);
	}

	if( bOwnRgn && hrgnUpdate ) DeleteObject32( hrgnUpdate );
	DeleteObject32( hrgnClip );
    }
    return retVal;
}

