1 /*
2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3 *
4 *Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 *"Software"), to deal in the Software without restriction, including
7 *without limitation the rights to use, copy, modify, merge, publish,
8 *distribute, sublicense, and/or sell copies of the Software, and to
9 *permit persons to whom the Software is furnished to do so, subject to
10 *the following conditions:
11 *
12 *The above copyright notice and this permission notice shall be
13 *included in all copies or substantial portions of the Software.
14 *
15 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
19 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 *Except as contained in this notice, the name of the XFree86 Project
24 *shall not be used in advertising or otherwise to promote the sale, use
25 *or other dealings in this Software without prior written authorization
26 *from the XFree86 Project.
27 *
28 * Authors: Harold L Hunt II
29 * Kensuke Matsuzaki
30 */
31
32 #ifdef HAVE_XWIN_CONFIG_H
33 #include <xwin-config.h>
34 #endif
35 #include "win.h"
36
37 /*
38 * Prototypes for local functions
39 */
40
41 static int
42 winAddRgn(WindowPtr pWindow, void *data);
43
44 static
45 void
46 winUpdateRgnRootless(WindowPtr pWindow);
47
48 static
49 void
50 winReshapeRootless(WindowPtr pWin);
51
52 /* See Porting Layer Definition - p. 37 */
53 /* See mfb/mfbwindow.c - mfbCreateWindow() */
54
55 Bool
winCreateWindowRootless(WindowPtr pWin)56 winCreateWindowRootless(WindowPtr pWin)
57 {
58 Bool fResult = FALSE;
59 ScreenPtr pScreen = pWin->drawable.pScreen;
60
61 winWindowPriv(pWin);
62 winScreenPriv(pScreen);
63
64 #if CYGDEBUG
65 winTrace("winCreateWindowRootless (%p)\n", pWin);
66 #endif
67
68 WIN_UNWRAP(CreateWindow);
69 fResult = (*pScreen->CreateWindow) (pWin);
70 WIN_WRAP(CreateWindow, winCreateWindowRootless);
71
72 pWinPriv->hRgn = NULL;
73
74 return fResult;
75 }
76
77 /* See Porting Layer Definition - p. 37 */
78 /* See mfb/mfbwindow.c - mfbDestroyWindow() */
79
80 Bool
winDestroyWindowRootless(WindowPtr pWin)81 winDestroyWindowRootless(WindowPtr pWin)
82 {
83 Bool fResult = FALSE;
84 ScreenPtr pScreen = pWin->drawable.pScreen;
85
86 winWindowPriv(pWin);
87 winScreenPriv(pScreen);
88
89 #if CYGDEBUG
90 winTrace("winDestroyWindowRootless (%p)\n", pWin);
91 #endif
92
93 WIN_UNWRAP(DestroyWindow);
94 fResult = (*pScreen->DestroyWindow) (pWin);
95 WIN_WRAP(DestroyWindow, winDestroyWindowRootless);
96
97 if (pWinPriv->hRgn != NULL) {
98 DeleteObject(pWinPriv->hRgn);
99 pWinPriv->hRgn = NULL;
100 }
101
102 winUpdateRgnRootless(pWin);
103
104 return fResult;
105 }
106
107 /* See Porting Layer Definition - p. 37 */
108 /* See mfb/mfbwindow.c - mfbPositionWindow() */
109
110 Bool
winPositionWindowRootless(WindowPtr pWin,int x,int y)111 winPositionWindowRootless(WindowPtr pWin, int x, int y)
112 {
113 Bool fResult = FALSE;
114 ScreenPtr pScreen = pWin->drawable.pScreen;
115
116 winScreenPriv(pScreen);
117
118 #if CYGDEBUG
119 winTrace("winPositionWindowRootless (%p)\n", pWin);
120 #endif
121
122 WIN_UNWRAP(PositionWindow);
123 fResult = (*pScreen->PositionWindow) (pWin, x, y);
124 WIN_WRAP(PositionWindow, winPositionWindowRootless);
125
126 winUpdateRgnRootless(pWin);
127
128 return fResult;
129 }
130
131 /* See Porting Layer Definition - p. 37 */
132 /* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */
133
134 Bool
winChangeWindowAttributesRootless(WindowPtr pWin,unsigned long mask)135 winChangeWindowAttributesRootless(WindowPtr pWin, unsigned long mask)
136 {
137 Bool fResult = FALSE;
138 ScreenPtr pScreen = pWin->drawable.pScreen;
139
140 winScreenPriv(pScreen);
141
142 #if CYGDEBUG
143 winTrace("winChangeWindowAttributesRootless (%p)\n", pWin);
144 #endif
145
146 WIN_UNWRAP(ChangeWindowAttributes);
147 fResult = (*pScreen->ChangeWindowAttributes) (pWin, mask);
148 WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesRootless);
149
150 winUpdateRgnRootless(pWin);
151
152 return fResult;
153 }
154
155 /* See Porting Layer Definition - p. 37
156 * Also referred to as UnrealizeWindow
157 */
158
159 Bool
winUnmapWindowRootless(WindowPtr pWin)160 winUnmapWindowRootless(WindowPtr pWin)
161 {
162 Bool fResult = FALSE;
163 ScreenPtr pScreen = pWin->drawable.pScreen;
164
165 winWindowPriv(pWin);
166 winScreenPriv(pScreen);
167
168 #if CYGDEBUG
169 winTrace("winUnmapWindowRootless (%p)\n", pWin);
170 #endif
171
172 WIN_UNWRAP(UnrealizeWindow);
173 fResult = (*pScreen->UnrealizeWindow) (pWin);
174 WIN_WRAP(UnrealizeWindow, winUnmapWindowRootless);
175
176 if (pWinPriv->hRgn != NULL) {
177 DeleteObject(pWinPriv->hRgn);
178 pWinPriv->hRgn = NULL;
179 }
180
181 winUpdateRgnRootless(pWin);
182
183 return fResult;
184 }
185
186 /* See Porting Layer Definition - p. 37
187 * Also referred to as RealizeWindow
188 */
189
190 Bool
winMapWindowRootless(WindowPtr pWin)191 winMapWindowRootless(WindowPtr pWin)
192 {
193 Bool fResult = FALSE;
194 ScreenPtr pScreen = pWin->drawable.pScreen;
195
196 winScreenPriv(pScreen);
197
198 #if CYGDEBUG
199 winTrace("winMapWindowRootless (%p)\n", pWin);
200 #endif
201
202 WIN_UNWRAP(RealizeWindow);
203 fResult = (*pScreen->RealizeWindow) (pWin);
204 WIN_WRAP(RealizeWindow, winMapWindowRootless);
205
206 winReshapeRootless(pWin);
207
208 winUpdateRgnRootless(pWin);
209
210 return fResult;
211 }
212
213 void
winSetShapeRootless(WindowPtr pWin,int kind)214 winSetShapeRootless(WindowPtr pWin, int kind)
215 {
216 ScreenPtr pScreen = pWin->drawable.pScreen;
217
218 winScreenPriv(pScreen);
219
220 #if CYGDEBUG
221 winTrace("winSetShapeRootless (%p, %i)\n", pWin, kind);
222 #endif
223
224 WIN_UNWRAP(SetShape);
225 (*pScreen->SetShape) (pWin, kind);
226 WIN_WRAP(SetShape, winSetShapeRootless);
227
228 winReshapeRootless(pWin);
229 winUpdateRgnRootless(pWin);
230
231 return;
232 }
233
234 /*
235 * Local function for adding a region to the Windows window region
236 */
237
238 static
239 int
winAddRgn(WindowPtr pWin,void * data)240 winAddRgn(WindowPtr pWin, void *data)
241 {
242 int iX, iY, iWidth, iHeight, iBorder;
243 HRGN hRgn = *(HRGN *) data;
244 HRGN hRgnWin;
245
246 winWindowPriv(pWin);
247
248 /* If pWin is not Root */
249 if (pWin->parent != NULL) {
250 #if CYGDEBUG
251 winDebug("winAddRgn ()\n");
252 #endif
253 if (pWin->mapped) {
254 iBorder = wBorderWidth(pWin);
255
256 iX = pWin->drawable.x - iBorder;
257 iY = pWin->drawable.y - iBorder;
258
259 iWidth = pWin->drawable.width + iBorder * 2;
260 iHeight = pWin->drawable.height + iBorder * 2;
261
262 hRgnWin = CreateRectRgn(0, 0, iWidth, iHeight);
263
264 if (hRgnWin == NULL) {
265 ErrorF("winAddRgn - CreateRectRgn () failed\n");
266 ErrorF(" Rect %d %d %d %d\n",
267 iX, iY, iX + iWidth, iY + iHeight);
268 }
269
270 if (pWinPriv->hRgn) {
271 if (CombineRgn(hRgnWin, hRgnWin, pWinPriv->hRgn, RGN_AND)
272 == ERROR) {
273 ErrorF("winAddRgn - CombineRgn () failed\n");
274 }
275 }
276
277 OffsetRgn(hRgnWin, iX, iY);
278
279 if (CombineRgn(hRgn, hRgn, hRgnWin, RGN_OR) == ERROR) {
280 ErrorF("winAddRgn - CombineRgn () failed\n");
281 }
282
283 DeleteObject(hRgnWin);
284 }
285 return WT_DONTWALKCHILDREN;
286 }
287 else {
288 return WT_WALKCHILDREN;
289 }
290 }
291
292 /*
293 * Local function to update the Windows window's region
294 */
295
296 static
297 void
winUpdateRgnRootless(WindowPtr pWin)298 winUpdateRgnRootless(WindowPtr pWin)
299 {
300 HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
301
302 if (hRgn != NULL) {
303 WalkTree(pWin->drawable.pScreen, winAddRgn, &hRgn);
304 SetWindowRgn(winGetScreenPriv(pWin->drawable.pScreen)->hwndScreen,
305 hRgn, TRUE);
306 }
307 else {
308 ErrorF("winUpdateRgnRootless - CreateRectRgn failed.\n");
309 }
310 }
311
312 static
313 void
winReshapeRootless(WindowPtr pWin)314 winReshapeRootless(WindowPtr pWin)
315 {
316 int nRects;
317 RegionRec rrNewShape;
318 BoxPtr pShape, pRects, pEnd;
319 HRGN hRgn, hRgnRect;
320
321 winWindowPriv(pWin);
322
323 #if CYGDEBUG
324 winDebug("winReshapeRootless ()\n");
325 #endif
326
327 /* Bail if the window is the root window */
328 if (pWin->parent == NULL)
329 return;
330
331 /* Bail if the window is not top level */
332 if (pWin->parent->parent != NULL)
333 return;
334
335 /* Free any existing window region stored in the window privates */
336 if (pWinPriv->hRgn != NULL) {
337 DeleteObject(pWinPriv->hRgn);
338 pWinPriv->hRgn = NULL;
339 }
340
341 /* Bail if the window has no bounding region defined */
342 if (!wBoundingShape(pWin))
343 return;
344
345 RegionNull(&rrNewShape);
346 RegionCopy(&rrNewShape, wBoundingShape(pWin));
347 RegionTranslate(&rrNewShape, pWin->borderWidth, pWin->borderWidth);
348
349 nRects = RegionNumRects(&rrNewShape);
350 pShape = RegionRects(&rrNewShape);
351
352 if (nRects > 0) {
353 /* Create initial empty Windows region */
354 hRgn = CreateRectRgn(0, 0, 0, 0);
355
356 /* Loop through all rectangles in the X region */
357 for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) {
358 /* Create a Windows region for the X rectangle */
359 hRgnRect = CreateRectRgn(pRects->x1, pRects->y1,
360 pRects->x2, pRects->y2);
361 if (hRgnRect == NULL) {
362 ErrorF("winReshapeRootless - CreateRectRgn() failed\n");
363 }
364
365 /* Merge the Windows region with the accumulated region */
366 if (CombineRgn(hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) {
367 ErrorF("winReshapeRootless - CombineRgn() failed\n");
368 }
369
370 /* Delete the temporary Windows region */
371 DeleteObject(hRgnRect);
372 }
373
374 /* Save a handle to the composite region in the window privates */
375 pWinPriv->hRgn = hRgn;
376 }
377
378 RegionUninit(&rrNewShape);
379
380 return;
381 }
382