Release 941210
[wine] / windows / scroll.c
1 /*
2  * Scroll windows and DCs
3  *
4  * Copyright  David W. Metcalfe, 1993
5  *
6  */
7
8 static char Copyright[] = "Copyright  David W. Metcalfe, 1993";
9
10 #include <stdlib.h>
11 #include "windows.h"
12 #include "gdi.h"
13 #include "scroll.h"
14 #include "stddebug.h"
15 /* #define DEBUG_SCROLL */
16 #include "debug.h"
17
18
19 static int RgnType;
20
21
22 /*************************************************************************
23  *             ScrollWindow         (USER.61)
24  */
25
26 void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect)
27 {
28     HDC hdc;
29     HRGN hrgnUpdate;
30     RECT rc, cliprc;
31
32     dprintf_scroll(stddeb,"ScrollWindow: dx=%d, dy=%d, rect=%d,%d,%d,%d\n", 
33            dx, dy, rect->left, rect->top, rect->right, rect->bottom);
34
35     hdc = GetDC(hwnd);
36
37     if (rect == NULL)
38         GetClientRect(hwnd, &rc);
39     else
40         CopyRect(&rc, rect);
41     if (clipRect == NULL)
42         GetClientRect(hwnd, &cliprc);
43     else
44         CopyRect(&cliprc, clipRect);
45
46     hrgnUpdate = CreateRectRgn(0, 0, 0, 0);
47     ScrollDC(hdc, dx, dy, &rc, &cliprc, hrgnUpdate, NULL);
48     InvalidateRgn(hwnd, hrgnUpdate, TRUE);
49     ReleaseDC(hwnd, hdc);
50 }
51
52
53 /*************************************************************************
54  *             ScrollDC         (USER.221)
55  */
56
57 BOOL ScrollDC(HDC hdc, short dx, short dy, LPRECT rc, LPRECT cliprc,
58               HRGN hrgnUpdate, LPRECT rcUpdate)
59 {
60     HRGN hrgnClip, hrgn1, hrgn2;
61     POINT src, dest;
62     short width, height;
63     DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
64
65     dprintf_scroll(stddeb, "ScrollDC: dx=%d, dy=%d, rc=%d,%d,%d,%d\n", dx, dy,
66            rc->left, rc->top, rc->right, rc->bottom);
67
68     if (rc == NULL)
69         return FALSE;
70
71     if (cliprc)
72     {
73         hrgnClip = CreateRectRgnIndirect(cliprc);
74         SelectClipRgn(hdc, hrgnClip);
75     }
76
77     if (dx > 0)
78     {
79         src.x = XDPTOLP(dc, rc->left);
80         dest.x = XDPTOLP(dc, rc->left + abs(dx));
81     }
82     else
83     {
84         src.x = XDPTOLP(dc, rc->left + abs(dx));
85         dest.x = XDPTOLP(dc, rc->left);
86     }
87     if (dy > 0)
88     {
89         src.y = YDPTOLP(dc, rc->top);
90         dest.y = YDPTOLP(dc, rc->top + abs(dy));
91     }
92     else
93     {
94         src.y = YDPTOLP(dc, rc->top + abs(dy));
95         dest.y = YDPTOLP(dc, rc->top);
96     }
97
98     width = rc->right - rc->left - abs(dx);
99     height = rc->bottom - rc->top - abs(dy);
100
101     if (!BitBlt(hdc, dest.x, dest.y, width, height, hdc, src.x, src.y, 
102                 SRCCOPY))
103         return FALSE;
104
105     if (hrgnUpdate)
106     {
107         if (dx > 0)
108             hrgn1 = CreateRectRgn(rc->left, rc->top, rc->left+dx, rc->bottom);
109         else if (dx < 0)
110             hrgn1 = CreateRectRgn(rc->right+dx, rc->top, rc->right, 
111                                   rc->bottom);
112         else
113             hrgn1 = CreateRectRgn(0, 0, 0, 0);
114
115         if (dy > 0)
116             hrgn2 = CreateRectRgn(rc->left, rc->top, rc->right, rc->top+dy);
117         else if (dy < 0)
118             hrgn2 = CreateRectRgn(rc->left, rc->bottom+dy, rc->right, 
119                                   rc->bottom);
120         else
121             hrgn2 = CreateRectRgn(0, 0, 0, 0);
122
123         RgnType = CombineRgn(hrgnUpdate, hrgn1, hrgn2, RGN_OR);
124     }
125
126     if (rcUpdate) GetRgnBox( hrgnUpdate, rcUpdate );
127     return TRUE;
128 }
129
130
131 /*************************************************************************
132  *             ScrollWindowEx       (USER.319)
133  */
134
135 int ScrollWindowEx(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect,
136                    HRGN hrgnUpdate, LPRECT rcUpdate, WORD flags)
137 {
138     HDC hdc;
139     RECT rc, cliprc;
140
141     dprintf_scroll(stddeb,"ScrollWindowEx: dx=%d, dy=%d, rect=%d,%d,%d,%d\n", 
142            dx, dy, rect->left, rect->top, rect->right, rect->bottom);
143
144     hdc = GetDC(hwnd);
145
146     if (rect == NULL)
147         GetClientRect(hwnd, &rc);
148     else
149         CopyRect(&rc, rect);
150     if (clipRect == NULL)
151         GetClientRect(hwnd, &cliprc);
152     else
153         CopyRect(&cliprc, clipRect);
154
155     ScrollDC(hdc, dx, dy, &rc, &cliprc, hrgnUpdate, rcUpdate);
156
157     if (flags | SW_INVALIDATE)
158     {
159         RedrawWindow(hwnd, NULL, hrgnUpdate,
160                      RDW_INVALIDATE | ((flags & SW_ERASE) ? RDW_ERASENOW : 0));
161     }
162
163     ReleaseDC(hwnd, hdc);
164     return RgnType;
165 }