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