blob: dba6111059fc0b0442ff4b671f492da637b29f92 [file] [log] [blame]
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001/*
2 * Scroll windows and DCs
3 *
4 * Copyright David W. Metcalfe, 1993
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +00005 * Alex Korobka 1995,1996
Alexandre Julliardd4719651995-12-12 18:49:11 +00006 *
Alexandre Julliarde399fc31993-11-24 17:08:56 +00007 *
8 */
9
Alexandre Julliarde399fc31993-11-24 17:08:56 +000010#include <stdlib.h>
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000011
Jeremy Whited3e22d92000-02-10 19:03:02 +000012#include "windef.h"
13#include "wingdi.h"
Patrik Stridvall1ed4ecf1999-06-26 14:58:24 +000014#include "wine/winuser16.h"
Marcus Meissner61afa331999-02-22 10:16:00 +000015#include "winuser.h"
Alexandre Julliardd4719651995-12-12 18:49:11 +000016#include "win.h"
Alexandre Julliarde399fc31993-11-24 17:08:56 +000017#include "gdi.h"
Alexandre Julliard9ea19e51997-01-01 17:29:55 +000018#include "dce.h"
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +000019#include "region.h"
Alexandre Julliarde3fe9f22001-05-10 03:23:59 +000020#include "user.h"
Alexandre Julliard359f497e1999-07-04 16:02:24 +000021#include "debugtools.h"
Alexandre Julliardd4719651995-12-12 18:49:11 +000022
Alexandre Julliard2239abb2000-11-05 02:05:07 +000023DEFAULT_DEBUG_CHANNEL(scroll);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000024
Alexandre Julliarde399fc31993-11-24 17:08:56 +000025/*************************************************************************
Patrik Stridvall0c610282001-01-25 22:22:21 +000026 * ScrollWindow (USER.61)
Alexandre Julliarde399fc31993-11-24 17:08:56 +000027 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +000028void WINAPI ScrollWindow16(HWND16 hwnd, INT16 dx, INT16 dy, const RECT16 *rect,
29 const RECT16 *clipRect )
Alexandre Julliard75d86e11996-11-17 18:59:11 +000030{
Alexandre Julliarda3960291999-02-26 11:11:13 +000031 RECT rect32, clipRect32;
Alexandre Julliard75d86e11996-11-17 18:59:11 +000032
33 if (rect) CONV_RECT16TO32( rect, &rect32 );
34 if (clipRect) CONV_RECT16TO32( clipRect, &clipRect32 );
Alexandre Julliarda3960291999-02-26 11:11:13 +000035 ScrollWindow( hwnd, dx, dy, rect ? &rect32 : NULL,
Alexandre Julliard75d86e11996-11-17 18:59:11 +000036 clipRect ? &clipRect32 : NULL );
37}
38
Alexandre Julliard75d86e11996-11-17 18:59:11 +000039/*************************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +000040 * ScrollWindow (USER32.@)
Alexandre Julliard670cdc41997-08-24 16:00:30 +000041 *
Alexandre Julliard75d86e11996-11-17 18:59:11 +000042 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000043BOOL WINAPI ScrollWindow( HWND hwnd, INT dx, INT dy,
44 const RECT *rect, const RECT *clipRect )
Alexandre Julliarde399fc31993-11-24 17:08:56 +000045{
Jerome Vouillon1da6dba1999-02-14 13:32:13 +000046 return
Alexandre Julliarda3960291999-02-26 11:11:13 +000047 (ERROR != ScrollWindowEx( hwnd, dx, dy, rect, clipRect, 0, NULL,
Jerome Vouillon1da6dba1999-02-14 13:32:13 +000048 (rect ? 0 : SW_SCROLLCHILDREN) |
49 SW_INVALIDATE ));
Alexandre Julliarde399fc31993-11-24 17:08:56 +000050}
51
Alexandre Julliarde399fc31993-11-24 17:08:56 +000052/*************************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +000053 * ScrollDC (USER.221)
Alexandre Julliarde399fc31993-11-24 17:08:56 +000054 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +000055BOOL16 WINAPI ScrollDC16( HDC16 hdc, INT16 dx, INT16 dy, const RECT16 *rect,
56 const RECT16 *cliprc, HRGN16 hrgnUpdate,
57 LPRECT16 rcUpdate )
Alexandre Julliard75d86e11996-11-17 18:59:11 +000058{
Alexandre Julliarda3960291999-02-26 11:11:13 +000059 RECT rect32, clipRect32, rcUpdate32;
Alexandre Julliard75d86e11996-11-17 18:59:11 +000060 BOOL16 ret;
61
62 if (rect) CONV_RECT16TO32( rect, &rect32 );
63 if (cliprc) CONV_RECT16TO32( cliprc, &clipRect32 );
Alexandre Julliarda3960291999-02-26 11:11:13 +000064 ret = ScrollDC( hdc, dx, dy, rect ? &rect32 : NULL,
Alexandre Julliard75d86e11996-11-17 18:59:11 +000065 cliprc ? &clipRect32 : NULL, hrgnUpdate, &rcUpdate32 );
66 if (rcUpdate) CONV_RECT32TO16( &rcUpdate32, rcUpdate );
67 return ret;
68}
69
70
71/*************************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +000072 * ScrollDC (USER32.@)
Alexandre Julliard9ea19e51997-01-01 17:29:55 +000073 *
Pascal Lessard83f39cf1999-02-25 16:35:22 +000074 * Only the hrgnUpdate is return in device coordinate.
75 * rcUpdate must be returned in logical coordinate to comply with win API.
76 *
Alexandre Julliard75d86e11996-11-17 18:59:11 +000077 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000078BOOL WINAPI ScrollDC( HDC hdc, INT dx, INT dy, const RECT *rc,
79 const RECT *prLClip, HRGN hrgnUpdate,
80 LPRECT rcUpdate )
Alexandre Julliarde399fc31993-11-24 17:08:56 +000081{
Alexandre Julliarda3960291999-02-26 11:11:13 +000082 RECT rect, rClip, rSrc;
83 POINT src, dest;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000084 DC *dc = DC_GetDCUpdate( hdc );
Alexandre Julliarde399fc31993-11-24 17:08:56 +000085
Alexandre Julliard359f497e1999-07-04 16:02:24 +000086 TRACE("%04x %d,%d hrgnUpdate=%04x rcUpdate = %p cliprc = (%d,%d-%d,%d), rc=(%d,%d-%d,%d)\n",
Alexandre Julliard9ea19e51997-01-01 17:29:55 +000087 (HDC16)hdc, dx, dy, hrgnUpdate, rcUpdate,
88 prLClip ? prLClip->left : 0, prLClip ? prLClip->top : 0, prLClip ? prLClip->right : 0, prLClip ? prLClip->bottom : 0,
89 rc ? rc->left : 0, rc ? rc->top : 0, rc ? rc->right : 0, rc ? rc->bottom : 0 );
Alexandre Julliarde399fc31993-11-24 17:08:56 +000090
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +000091 if ( !dc || !hdc ) return FALSE;
Alexandre Julliarde399fc31993-11-24 17:08:56 +000092
Alexandre Julliard9ea19e51997-01-01 17:29:55 +000093/*
Alexandre Julliard54c27111998-03-29 19:44:57 +000094 TRACE(scroll,"\t[wndOrgX=%i, wndExtX=%i, vportOrgX=%i, vportExtX=%i]\n",
95 dc->wndOrgX, dc->wndExtX, dc->vportOrgX, dc->vportExtX );
96 TRACE(scroll,"\t[wndOrgY=%i, wndExtY=%i, vportOrgY=%i, vportExtY=%i]\n",
97 dc->wndOrgY, dc->wndExtY, dc->vportOrgY, dc->vportExtY );
Alexandre Julliard9ea19e51997-01-01 17:29:55 +000098*/
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000099
Ulrich Weigand409eb442000-10-23 00:35:28 +0000100 /* compute device clipping region (in device coordinates) */
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000101
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000102 if ( rc )
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000103 rect = *rc;
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000104 else /* maybe we should just return FALSE? */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000105 GetClipBox( hdc, &rect );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000106
Ulrich Weigand409eb442000-10-23 00:35:28 +0000107 LPtoDP( hdc, (LPPOINT)&rect, 2 );
108
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000109 if (prLClip)
Ulrich Weigand409eb442000-10-23 00:35:28 +0000110 {
111 rClip = *prLClip;
112 LPtoDP( hdc, (LPPOINT)&rClip, 2 );
113 IntersectRect( &rClip, &rect, &rClip );
114 }
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000115 else
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000116 rClip = rect;
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000117
Ulrich Weigand409eb442000-10-23 00:35:28 +0000118 dx = XLPTODP ( dc, rect.left + dx ) - XLPTODP ( dc, rect.left );
119 dy = YLPTODP ( dc, rect.top + dy ) - YLPTODP ( dc, rect.top );
120
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000121 rSrc = rClip;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000122 OffsetRect( &rSrc, -dx, -dy );
123 IntersectRect( &rSrc, &rSrc, &rect );
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000124
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000125 if(dc->hVisRgn)
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000126 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000127 if (!IsRectEmpty(&rSrc))
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000128 {
129 dest.x = (src.x = rSrc.left) + dx;
130 dest.y = (src.y = rSrc.top) + dy;
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000131
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000132 /* copy bits */
Ulrich Weigand409eb442000-10-23 00:35:28 +0000133
134 DPtoLP( hdc, (LPPOINT)&rSrc, 2 );
135 DPtoLP( hdc, &src, 1 );
136 DPtoLP( hdc, &dest, 1 );
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000137
Alexandre Julliarda3960291999-02-26 11:11:13 +0000138 if (!BitBlt( hdc, dest.x, dest.y,
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000139 rSrc.right - rSrc.left, rSrc.bottom - rSrc.top,
140 hdc, src.x, src.y, SRCCOPY))
141 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000142 GDI_ReleaseObj( hdc );
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000143 return FALSE;
144 }
145 }
146
147 /* compute update areas */
148
149 if (hrgnUpdate || rcUpdate)
150 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000151 HRGN hrgn =
152 (hrgnUpdate) ? hrgnUpdate : CreateRectRgn( 0,0,0,0 );
153 HRGN hrgn2;
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000154
Alexandre Julliarda3960291999-02-26 11:11:13 +0000155 hrgn2 = CreateRectRgnIndirect( &rect );
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000156 OffsetRgn( hrgn2, dc->DCOrgX, dc->DCOrgY );
157 CombineRgn( hrgn2, hrgn2, dc->hVisRgn, RGN_AND );
158 OffsetRgn( hrgn2, -dc->DCOrgX, -dc->DCOrgY );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000159 SetRectRgn( hrgn, rClip.left, rClip.top,
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000160 rClip.right, rClip.bottom );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000161 CombineRgn( hrgn, hrgn, hrgn2, RGN_AND );
162 OffsetRgn( hrgn2, dx, dy );
163 CombineRgn( hrgn, hrgn, hrgn2, RGN_DIFF );
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000164
Pascal Lessard83f39cf1999-02-25 16:35:22 +0000165 if( rcUpdate )
166 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000167 GetRgnBox( hrgn, rcUpdate );
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000168
Patrik Stridvall0f8bc5b1999-04-22 16:27:50 +0000169 /* Put the rcUpdate in logical coordinate */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000170 DPtoLP( hdc, (LPPOINT)rcUpdate, 2 );
Pascal Lessard83f39cf1999-02-25 16:35:22 +0000171 }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000172 if (!hrgnUpdate) DeleteObject( hrgn );
173 DeleteObject( hrgn2 );
Pascal Lessard83f39cf1999-02-25 16:35:22 +0000174
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000175 }
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000176 }
Jerome Vouillon1da6dba1999-02-14 13:32:13 +0000177 else
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000178 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000179 if (hrgnUpdate) SetRectRgn(hrgnUpdate, 0, 0, 0, 0);
180 if (rcUpdate) SetRectEmpty(rcUpdate);
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000181 }
182
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000183 GDI_ReleaseObj( hdc );
Alexandre Julliard3ed37e01994-11-07 18:20:42 +0000184 return TRUE;
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000185}
186
187
188/*************************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000189 * ScrollWindowEx (USER.319)
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000190 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000191INT16 WINAPI ScrollWindowEx16( HWND16 hwnd, INT16 dx, INT16 dy,
192 const RECT16 *rect, const RECT16 *clipRect,
193 HRGN16 hrgnUpdate, LPRECT16 rcUpdate,
194 UINT16 flags )
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000195{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000196 RECT rect32, clipRect32, rcUpdate32;
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000197 BOOL16 ret;
198
199 if (rect) CONV_RECT16TO32( rect, &rect32 );
200 if (clipRect) CONV_RECT16TO32( clipRect, &clipRect32 );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000201 ret = ScrollWindowEx( hwnd, dx, dy, rect ? &rect32 : NULL,
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000202 clipRect ? &clipRect32 : NULL, hrgnUpdate,
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000203 (rcUpdate) ? &rcUpdate32 : NULL, flags );
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000204 if (rcUpdate) CONV_RECT32TO16( &rcUpdate32, rcUpdate );
205 return ret;
206}
207
208
209/*************************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000210 * ScrollWindowEx (USER32.@)
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000211 *
212 * NOTE: Use this function instead of ScrollWindow32
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000213 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000214INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy,
215 const RECT *rect, const RECT *clipRect,
216 HRGN hrgnUpdate, LPRECT rcUpdate,
217 UINT flags )
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000218{
Alexandre Julliarde3fe9f22001-05-10 03:23:59 +0000219 if (USER_Driver.pScrollWindowEx)
220 return USER_Driver.pScrollWindowEx( hwnd, dx, dy, rect, clipRect,
221 hrgnUpdate, rcUpdate, flags );
222 return ERROR;
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000223}