[USER32] Fix GetWindowTextLength() blocking call using the same technique as in GetWi...
[reactos.git] / win32ss / user / user32 / windows / rect.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * PROJECT: ReactOS user32.dll
21 * FILE: win32ss/user/user32/windows/rect.c
22 * PURPOSE: Input
23 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
24 * UPDATE HISTORY:
25 * 09-05-2001 CSH Created
26 */
27
28 #include <user32.h>
29
30 /*
31 * @implemented
32 */
33 BOOL
34 WINAPI
35 CopyRect(LPRECT lprcDst,
36 CONST RECT *lprcSrc)
37 {
38 if (lprcDst == NULL || lprcSrc == NULL)
39 return FALSE;
40
41 *lprcDst = *lprcSrc;
42
43 return TRUE;
44 }
45
46
47 /*
48 * @implemented
49 */
50 BOOL
51 WINAPI
52 EqualRect(CONST RECT *lprc1,
53 CONST RECT *lprc2)
54 {
55 if (lprc1 == NULL || lprc2 == NULL)
56 return FALSE;
57
58 return (lprc1->left == lprc2->left) && (lprc1->top == lprc2->top) &&
59 (lprc1->right == lprc2->right) && (lprc1->bottom == lprc2->bottom);
60 }
61
62
63 /*
64 * @implemented
65 */
66 BOOL
67 WINAPI
68 InflateRect(LPRECT rect,
69 int dx,
70 int dy)
71 {
72 if (rect == NULL)
73 return FALSE;
74
75 rect->left -= dx;
76 rect->top -= dy;
77 rect->right += dx;
78 rect->bottom += dy;
79
80 return TRUE;
81 }
82
83
84 /*
85 * @implemented
86 */
87 BOOL
88 WINAPI
89 IntersectRect(LPRECT lprcDst,
90 CONST RECT *lprcSrc1,
91 CONST RECT *lprcSrc2)
92 {
93 if (lprcDst == NULL || lprcSrc1 == NULL || lprcSrc2 == NULL)
94 return FALSE;
95
96 if (IsRectEmpty(lprcSrc1) || IsRectEmpty(lprcSrc2) ||
97 lprcSrc1->left >= lprcSrc2->right ||
98 lprcSrc2->left >= lprcSrc1->right ||
99 lprcSrc1->top >= lprcSrc2->bottom ||
100 lprcSrc2->top >= lprcSrc1->bottom)
101 {
102 SetRectEmpty(lprcDst);
103 return FALSE;
104 }
105
106 lprcDst->left = max(lprcSrc1->left, lprcSrc2->left);
107 lprcDst->right = min(lprcSrc1->right, lprcSrc2->right);
108 lprcDst->top = max(lprcSrc1->top, lprcSrc2->top);
109 lprcDst->bottom = min(lprcSrc1->bottom, lprcSrc2->bottom);
110
111 return TRUE;
112 }
113
114
115 /*
116 * @implemented
117 */
118 BOOL
119 WINAPI
120 IsRectEmpty(CONST RECT *lprc)
121 {
122 if (lprc == NULL)
123 return TRUE;
124
125 return ((lprc->left >= lprc->right) || (lprc->top >= lprc->bottom));
126 }
127
128
129 /*
130 * @implemented
131 */
132 BOOL
133 WINAPI
134 OffsetRect(LPRECT rect,
135 int dx,
136 int dy)
137 {
138 if (rect == NULL)
139 return FALSE;
140
141 rect->left += dx;
142 rect->top += dy;
143 rect->right += dx;
144 rect->bottom += dy;
145
146 return TRUE;
147 }
148
149
150 /*
151 * @implemented
152 */
153 BOOL
154 WINAPI
155 PtInRect(CONST RECT *lprc,
156 POINT pt)
157 {
158 if (lprc == NULL)
159 return FALSE;
160
161 return((pt.x >= lprc->left) && (pt.x < lprc->right) &&
162 (pt.y >= lprc->top) && (pt.y < lprc->bottom));
163 }
164
165 BOOL
166 WINAPI
167 SetRect(LPRECT lprc,
168 int xLeft,
169 int yTop,
170 int xRight,
171 int yBottom)
172 {
173 if (lprc == NULL)
174 return FALSE;
175
176 lprc->left = xLeft;
177 lprc->top = yTop;
178 lprc->right = xRight;
179 lprc->bottom = yBottom;
180
181 return TRUE;
182 }
183
184
185 /*
186 * @implemented
187 */
188 BOOL
189 WINAPI
190 SetRectEmpty(LPRECT lprc)
191 {
192 if (lprc == NULL)
193 return FALSE;
194
195 lprc->left = lprc->right = lprc->top = lprc->bottom = 0;
196
197 return TRUE;
198 }
199
200
201 /*
202 * @implemented
203 */
204 BOOL
205 WINAPI
206 SubtractRect(LPRECT lprcDst,
207 CONST RECT *lprcSrc1,
208 CONST RECT *lprcSrc2)
209 {
210 RECT tempRect;
211
212 if (lprcDst == NULL || lprcSrc1 == NULL || lprcSrc2 == NULL)
213 return FALSE;
214
215 if (!IntersectRect(&tempRect, lprcSrc1, lprcSrc2))
216 {
217 *lprcDst = *lprcSrc1;
218 return TRUE;
219 }
220
221 if (EqualRect(&tempRect, lprcSrc1))
222 {
223 SetRectEmpty(lprcDst);
224 return FALSE;
225 }
226
227 *lprcDst = *lprcSrc1;
228
229 if (lprcDst->top == tempRect.top && lprcDst->bottom == tempRect.bottom)
230 {
231 if (lprcDst->left == tempRect.left)
232 lprcDst->left = tempRect.right;
233 else if (lprcDst->right == tempRect.right)
234 lprcDst->right = tempRect.left;
235 }
236 else if (lprcDst->left == tempRect.left && lprcDst->right == tempRect.right)
237 {
238 if (lprcDst->top == tempRect.top)
239 lprcDst->top = tempRect.bottom;
240 else if (lprcDst->bottom == tempRect.bottom)
241 lprcDst->bottom = tempRect.top;
242 }
243
244 return TRUE;
245 }
246
247
248 /*
249 * @implemented
250 */
251 BOOL
252 WINAPI
253 UnionRect(LPRECT lprcDst,
254 CONST RECT *lprcSrc1,
255 CONST RECT *lprcSrc2)
256 {
257 if (lprcDst == NULL || lprcSrc1 == NULL || lprcSrc2 == NULL)
258 return FALSE;
259
260 if (IsRectEmpty(lprcSrc1))
261 {
262 if (IsRectEmpty(lprcSrc2))
263 {
264 SetRectEmpty(lprcDst);
265 return FALSE;
266 }
267 else
268 {
269 *lprcDst = *lprcSrc2;
270 }
271 }
272 else
273 {
274 if (IsRectEmpty(lprcSrc2))
275 {
276 *lprcDst = *lprcSrc1;
277 }
278 else
279 {
280 lprcDst->left = min(lprcSrc1->left, lprcSrc2->left);
281 lprcDst->top = min(lprcSrc1->top, lprcSrc2->top);
282 lprcDst->right = max(lprcSrc1->right, lprcSrc2->right);
283 lprcDst->bottom = max(lprcSrc1->bottom, lprcSrc2->bottom);
284 }
285 }
286
287 return TRUE;
288 }