2 * Scroll windows and DCs
4 * Copyright 1993 David W. Metcalfe
5 * Copyright 1995, 1996 Alex Korobka
6 * Copyright 2001 Alexandre Julliard
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(scroll
);
40 /*************************************************************************
43 BOOL WINAPI
X11DRV_ScrollDC( HDC hdc
, INT dx
, INT dy
, const RECT
*lprcScroll
,
44 const RECT
*lprcClip
, HRGN hrgnUpdate
, LPRECT lprcUpdate
)
47 RECT rSrc
, rClipped_src
, rClip
, rDst
, offset
;
48 INT code
= X11DRV_START_EXPOSURES
;
50 if (hrgnUpdate
|| lprcUpdate
)
51 ExtEscape( hdc
, X11DRV_ESCAPE
, sizeof(code
), (LPSTR
)&code
, 0, NULL
);
53 /* compute device clipping region (in device coordinates) */
55 if (lprcScroll
) rSrc
= *lprcScroll
;
56 else GetClipBox( hdc
, &rSrc
);
57 LPtoDP(hdc
, (LPPOINT
)&rSrc
, 2);
59 if (lprcClip
) rClip
= *lprcClip
;
60 else GetClipBox( hdc
, &rClip
);
61 LPtoDP(hdc
, (LPPOINT
)&rClip
, 2);
63 IntersectRect( &rClipped_src
, &rSrc
, &rClip
);
64 TRACE("rSrc %s rClip %s clipped rSrc %s\n", wine_dbgstr_rect(&rSrc
),
65 wine_dbgstr_rect(&rClip
), wine_dbgstr_rect(&rClipped_src
));
68 SetRect(&offset
, 0, 0, dx
, dy
);
69 LPtoDP(hdc
, (LPPOINT
)&offset
, 2);
70 OffsetRect( &rDst
, offset
.right
- offset
.left
, offset
.bottom
- offset
.top
);
71 TRACE("rDst before clipping %s\n", wine_dbgstr_rect(&rDst
));
72 IntersectRect( &rDst
, &rDst
, &rClip
);
73 TRACE("rDst after clipping %s\n", wine_dbgstr_rect(&rDst
));
75 if (!IsRectEmpty(&rDst
))
78 RECT rDst_lp
= rDst
, rSrc_lp
= rDst
;
80 OffsetRect( &rSrc_lp
, offset
.left
- offset
.right
, offset
.top
- offset
.bottom
);
81 DPtoLP(hdc
, (LPPOINT
)&rDst_lp
, 2);
82 DPtoLP(hdc
, (LPPOINT
)&rSrc_lp
, 2);
84 if (!BitBlt( hdc
, rDst_lp
.left
, rDst_lp
.top
,
85 rDst_lp
.right
- rDst_lp
.left
, rDst_lp
.bottom
- rDst_lp
.top
,
86 hdc
, rSrc_lp
.left
, rSrc_lp
.top
, SRCCOPY
))
90 /* compute update areas. This is the clipped source or'ed with the unclipped source translated minus the
91 clipped src translated (rDst) all clipped to rClip */
93 if (hrgnUpdate
|| lprcUpdate
)
95 HRGN hrgn
= hrgnUpdate
, hrgn2
, hrgn3
= 0;
97 code
= X11DRV_END_EXPOSURES
;
98 ExtEscape( hdc
, X11DRV_ESCAPE
, sizeof(code
), (LPSTR
)&code
, sizeof(hrgn3
), (LPSTR
)&hrgn3
);
100 if (hrgn
) SetRectRgn( hrgn
, rClipped_src
.left
, rClipped_src
.top
, rClipped_src
.right
, rClipped_src
.bottom
);
101 else hrgn
= CreateRectRgn( rClipped_src
.left
, rClipped_src
.top
, rClipped_src
.right
, rClipped_src
.bottom
);
103 hrgn2
= CreateRectRgnIndirect( &rSrc
);
104 OffsetRgn(hrgn2
, offset
.right
- offset
.left
, offset
.bottom
- offset
.top
);
105 CombineRgn(hrgn
, hrgn
, hrgn2
, RGN_OR
);
107 SetRectRgn( hrgn2
, rDst
.left
, rDst
.top
, rDst
.right
, rDst
.bottom
);
108 CombineRgn( hrgn
, hrgn
, hrgn2
, RGN_DIFF
);
110 SetRectRgn( hrgn2
, rClip
.left
, rClip
.top
, rClip
.right
, rClip
.bottom
);
111 CombineRgn( hrgn
, hrgn
, hrgn2
, RGN_AND
);
115 CombineRgn( hrgn
, hrgn
, hrgn3
, RGN_OR
);
116 DeleteObject( hrgn3
);
121 GetRgnBox( hrgn
, lprcUpdate
);
123 /* Put the lprcUpdate in logical coordinate */
124 DPtoLP( hdc
, (LPPOINT
)lprcUpdate
, 2 );
125 TRACE("returning lprcUpdate %s\n", wine_dbgstr_rect(lprcUpdate
));
127 if (!hrgnUpdate
) DeleteObject( hrgn
);
128 DeleteObject( hrgn2
);