Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xwin / winwindow.c
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, pointer data);
43
44 static
45 void
46 winUpdateRgnRootless(WindowPtr pWindow);
47
48 static
49 void
50 winReshapeRootless(WindowPtr pWin);
51
52 #ifdef XWIN_NATIVEGDI
53 /* See Porting Layer Definition - p. 37 */
54 /* See mfb/mfbwindow.c - mfbCreateWindow() */
55
56 Bool
57 winCreateWindowNativeGDI(WindowPtr pWin)
58 {
59 Bool fResult = TRUE;
60 ScreenPtr pScreen = pWin->drawable.pScreen;
61
62 winScreenPriv(pScreen);
63
64 #if CYGDEBUG
65 winTrace("winCreateWindowNativeGDI (%p)\n", pWin);
66 #endif
67
68 WIN_UNWRAP(CreateWindow);
69 fResult = (*pScreen->CreateWindow) (pWin);
70 WIN_WRAP(CreateWindow, winCreateWindowNativeGDI);
71
72 return fResult;
73 }
74
75 /* See Porting Layer Definition - p. 37 */
76 /* See mfb/mfbwindow.c - mfbDestroyWindow() */
77
78 Bool
79 winDestroyWindowNativeGDI(WindowPtr pWin)
80 {
81 Bool fResult = TRUE;
82 ScreenPtr pScreen = pWin->drawable.pScreen;
83
84 winScreenPriv(pScreen);
85
86 #if CYGDEBUG
87 winTrace("winDestroyWindowNativeGDI (%p)\n", pWin);
88 #endif
89
90 WIN_UNWRAP(DestroyWindow);
91 fResult = (*pScreen->DestroyWindow) (pWin);
92 WIN_WRAP(DestroyWindow, winDestroyWindowNativeGDI);
93
94 return fResult;
95 }
96
97 /* See Porting Layer Definition - p. 37 */
98 /* See mfb/mfbwindow.c - mfbPositionWindow() */
99
100 Bool
101 winPositionWindowNativeGDI(WindowPtr pWin, int x, int y)
102 {
103 Bool fResult = TRUE;
104 ScreenPtr pScreen = pWin->drawable.pScreen;
105
106 winScreenPriv(pScreen);
107
108 #if CYGDEBUG
109 winTrace("winPositionWindowNativeGDI (%p)\n", pWin);
110 #endif
111
112 WIN_UNWRAP(PositionWindow);
113 fResult = (*pScreen->PositionWindow) (pWin, x, y);
114 WIN_WRAP(PositionWindow, winPositionWindowNativeGDI);
115
116 return fResult;
117 }
118
119 /* See Porting Layer Definition - p. 39 */
120 /* See mfb/mfbwindow.c - mfbCopyWindow() */
121
122 void
123 winCopyWindowNativeGDI(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
124 {
125 DDXPointPtr pptSrc;
126 DDXPointPtr ppt;
127 RegionPtr prgnDst;
128 BoxPtr pBox;
129 int dx, dy;
130 int i, nbox;
131 BoxPtr pBoxDst;
132 ScreenPtr pScreen = pWin->drawable.pScreen;
133
134 winScreenPriv(pScreen);
135
136 #if 0
137 ErrorF("winCopyWindow\n");
138 #endif
139
140 /* Create a region for the destination */
141 prgnDst = RegionCreate(NULL, 1);
142
143 /* Calculate the shift from the source to the destination */
144 dx = ptOldOrg.x - pWin->drawable.x;
145 dy = ptOldOrg.y - pWin->drawable.y;
146
147 /* Translate the region from the destination to the source? */
148 RegionTranslate(prgnSrc, -dx, -dy);
149 RegionIntersect(prgnDst, &pWin->borderClip, prgnSrc);
150
151 /* Get a pointer to the first box in the region to be copied */
152 pBox = RegionRects(prgnDst);
153
154 /* Get the number of boxes in the region */
155 nbox = RegionNumRects(prgnDst);
156
157 /* Allocate source points for each box */
158 if (!(pptSrc = (DDXPointPtr) malloc(nbox * sizeof(DDXPointRec))))
159 return;
160
161 /* Set an iterator pointer */
162 ppt = pptSrc;
163
164 /* Calculate the source point of each box? */
165 for (i = nbox; --i >= 0; ppt++, pBox++) {
166 ppt->x = pBox->x1 + dx;
167 ppt->y = pBox->y1 + dy;
168 }
169
170 /* Setup loop pointers again */
171 pBoxDst = RegionRects(prgnDst);
172 ppt = pptSrc;
173
174 #if 0
175 ErrorF("winCopyWindow - x1\tx2\ty1\ty2\tx\ty\n");
176 #endif
177
178 /* BitBlt each source to the destination point */
179 for (i = nbox; --i >= 0; pBoxDst++, ppt++) {
180 #if 0
181 ErrorF("winCopyWindow - %d\t%d\t%d\t%d\t%d\t%d\n",
182 pBoxDst->x1, pBoxDst->x2, pBoxDst->y1, pBoxDst->y2,
183 ppt->x, ppt->y);
184 #endif
185
186 BitBlt(pScreenPriv->hdcScreen,
187 pBoxDst->x1, pBoxDst->y1,
188 pBoxDst->x2 - pBoxDst->x1, pBoxDst->y2 - pBoxDst->y1,
189 pScreenPriv->hdcScreen, ppt->x, ppt->y, SRCCOPY);
190 }
191
192 /* Cleanup the regions, etc. */
193 free(pptSrc);
194 RegionDestroy(prgnDst);
195 }
196
197 /* See Porting Layer Definition - p. 37 */
198 /* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */
199
200 Bool
201 winChangeWindowAttributesNativeGDI(WindowPtr pWin, unsigned long mask)
202 {
203 Bool fResult = TRUE;
204 ScreenPtr pScreen = pWin->drawable.pScreen;
205
206 winScreenPriv(pScreen);
207
208 #if CYGDEBUG
209 winTrace("winChangeWindowAttributesNativeGDI (%p)\n", pWin);
210 #endif
211
212 WIN_UNWRAP(ChangeWindowAttributes);
213 fResult = (*pScreen->ChangeWindowAttributes) (pWin, mask);
214 WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesNativeGDI);
215
216 /*
217 * NOTE: We do not currently need to do anything here.
218 */
219
220 return fResult;
221 }
222
223 /* See Porting Layer Definition - p. 37
224 * Also referred to as UnrealizeWindow
225 */
226
227 Bool
228 winUnmapWindowNativeGDI(WindowPtr pWin)
229 {
230 Bool fResult = TRUE;
231 ScreenPtr pScreen = pWin->drawable.pScreen;
232
233 winScreenPriv(pScreen);
234
235 #if CYGDEBUG
236 winTrace("winUnmapWindowNativeGDI (%p)\n", pWin);
237 #endif
238
239 WIN_UNWRAP(UnrealizeWindow);
240 fResult = (*pScreen->UnrealizeWindow) (pWin);
241 WIN_WRAP(UnrealizeWindow, winUnmapWindowNativeGDI);
242
243 return fResult;
244 }
245
246 /* See Porting Layer Definition - p. 37
247 * Also referred to as RealizeWindow
248 */
249
250 Bool
251 winMapWindowNativeGDI(WindowPtr pWin)
252 {
253 Bool fResult = TRUE;
254 ScreenPtr pScreen = pWin->drawable.pScreen;
255
256 winScreenPriv(pScreen);
257
258 #if CYGDEBUG
259 winTrace("winMapWindowNativeGDI (%p)\n", pWin);
260 #endif
261
262 WIN_UNWRAP(RealizeWindow);
263 fResult = (*pScreen->RealizeWindow) (pWin);
264 WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
265
266 return fResult;
267
268 }
269 #endif
270
271 /* See Porting Layer Definition - p. 37 */
272 /* See mfb/mfbwindow.c - mfbCreateWindow() */
273
274 Bool
275 winCreateWindowRootless(WindowPtr pWin)
276 {
277 Bool fResult = FALSE;
278 ScreenPtr pScreen = pWin->drawable.pScreen;
279
280 winWindowPriv(pWin);
281 winScreenPriv(pScreen);
282
283 #if CYGDEBUG
284 winTrace("winCreateWindowRootless (%p)\n", pWin);
285 #endif
286
287 WIN_UNWRAP(CreateWindow);
288 fResult = (*pScreen->CreateWindow) (pWin);
289 WIN_WRAP(CreateWindow, winCreateWindowRootless);
290
291 pWinPriv->hRgn = NULL;
292
293 return fResult;
294 }
295
296 /* See Porting Layer Definition - p. 37 */
297 /* See mfb/mfbwindow.c - mfbDestroyWindow() */
298
299 Bool
300 winDestroyWindowRootless(WindowPtr pWin)
301 {
302 Bool fResult = FALSE;
303 ScreenPtr pScreen = pWin->drawable.pScreen;
304
305 winWindowPriv(pWin);
306 winScreenPriv(pScreen);
307
308 #if CYGDEBUG
309 winTrace("winDestroyWindowRootless (%p)\n", pWin);
310 #endif
311
312 WIN_UNWRAP(DestroyWindow);
313 fResult = (*pScreen->DestroyWindow) (pWin);
314 WIN_WRAP(DestroyWindow, winDestroyWindowRootless);
315
316 if (pWinPriv->hRgn != NULL) {
317 DeleteObject(pWinPriv->hRgn);
318 pWinPriv->hRgn = NULL;
319 }
320
321 winUpdateRgnRootless(pWin);
322
323 return fResult;
324 }
325
326 /* See Porting Layer Definition - p. 37 */
327 /* See mfb/mfbwindow.c - mfbPositionWindow() */
328
329 Bool
330 winPositionWindowRootless(WindowPtr pWin, int x, int y)
331 {
332 Bool fResult = FALSE;
333 ScreenPtr pScreen = pWin->drawable.pScreen;
334
335 winScreenPriv(pScreen);
336
337 #if CYGDEBUG
338 winTrace("winPositionWindowRootless (%p)\n", pWin);
339 #endif
340
341 WIN_UNWRAP(PositionWindow);
342 fResult = (*pScreen->PositionWindow) (pWin, x, y);
343 WIN_WRAP(PositionWindow, winPositionWindowRootless);
344
345 winUpdateRgnRootless(pWin);
346
347 return fResult;
348 }
349
350 /* See Porting Layer Definition - p. 37 */
351 /* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */
352
353 Bool
354 winChangeWindowAttributesRootless(WindowPtr pWin, unsigned long mask)
355 {
356 Bool fResult = FALSE;
357 ScreenPtr pScreen = pWin->drawable.pScreen;
358
359 winScreenPriv(pScreen);
360
361 #if CYGDEBUG
362 winTrace("winChangeWindowAttributesRootless (%p)\n", pWin);
363 #endif
364
365 WIN_UNWRAP(ChangeWindowAttributes);
366 fResult = (*pScreen->ChangeWindowAttributes) (pWin, mask);
367 WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesRootless);
368
369 winUpdateRgnRootless(pWin);
370
371 return fResult;
372 }
373
374 /* See Porting Layer Definition - p. 37
375 * Also referred to as UnrealizeWindow
376 */
377
378 Bool
379 winUnmapWindowRootless(WindowPtr pWin)
380 {
381 Bool fResult = FALSE;
382 ScreenPtr pScreen = pWin->drawable.pScreen;
383
384 winWindowPriv(pWin);
385 winScreenPriv(pScreen);
386
387 #if CYGDEBUG
388 winTrace("winUnmapWindowRootless (%p)\n", pWin);
389 #endif
390
391 WIN_UNWRAP(UnrealizeWindow);
392 fResult = (*pScreen->UnrealizeWindow) (pWin);
393 WIN_WRAP(UnrealizeWindow, winUnmapWindowRootless);
394
395 if (pWinPriv->hRgn != NULL) {
396 DeleteObject(pWinPriv->hRgn);
397 pWinPriv->hRgn = NULL;
398 }
399
400 winUpdateRgnRootless(pWin);
401
402 return fResult;
403 }
404
405 /* See Porting Layer Definition - p. 37
406 * Also referred to as RealizeWindow
407 */
408
409 Bool
410 winMapWindowRootless(WindowPtr pWin)
411 {
412 Bool fResult = FALSE;
413 ScreenPtr pScreen = pWin->drawable.pScreen;
414
415 winScreenPriv(pScreen);
416
417 #if CYGDEBUG
418 winTrace("winMapWindowRootless (%p)\n", pWin);
419 #endif
420
421 WIN_UNWRAP(RealizeWindow);
422 fResult = (*pScreen->RealizeWindow) (pWin);
423 WIN_WRAP(RealizeWindow, winMapWindowRootless);
424
425 winReshapeRootless(pWin);
426
427 winUpdateRgnRootless(pWin);
428
429 return fResult;
430 }
431
432 void
433 winSetShapeRootless(WindowPtr pWin, int kind)
434 {
435 ScreenPtr pScreen = pWin->drawable.pScreen;
436
437 winScreenPriv(pScreen);
438
439 #if CYGDEBUG
440 winTrace("winSetShapeRootless (%p, %i)\n", pWin, kind);
441 #endif
442
443 WIN_UNWRAP(SetShape);
444 (*pScreen->SetShape) (pWin, kind);
445 WIN_WRAP(SetShape, winSetShapeRootless);
446
447 winReshapeRootless(pWin);
448 winUpdateRgnRootless(pWin);
449
450 return;
451 }
452
453 /*
454 * Local function for adding a region to the Windows window region
455 */
456
457 static
458 int
459 winAddRgn(WindowPtr pWin, pointer data)
460 {
461 int iX, iY, iWidth, iHeight, iBorder;
462 HRGN hRgn = *(HRGN *) data;
463 HRGN hRgnWin;
464
465 winWindowPriv(pWin);
466
467 /* If pWin is not Root */
468 if (pWin->parent != NULL) {
469 #if CYGDEBUG
470 winDebug("winAddRgn ()\n");
471 #endif
472 if (pWin->mapped) {
473 iBorder = wBorderWidth(pWin);
474
475 iX = pWin->drawable.x - iBorder;
476 iY = pWin->drawable.y - iBorder;
477
478 iWidth = pWin->drawable.width + iBorder * 2;
479 iHeight = pWin->drawable.height + iBorder * 2;
480
481 hRgnWin = CreateRectRgn(0, 0, iWidth, iHeight);
482
483 if (hRgnWin == NULL) {
484 ErrorF("winAddRgn - CreateRectRgn () failed\n");
485 ErrorF(" Rect %d %d %d %d\n",
486 iX, iY, iX + iWidth, iY + iHeight);
487 }
488
489 if (pWinPriv->hRgn) {
490 if (CombineRgn(hRgnWin, hRgnWin, pWinPriv->hRgn, RGN_AND)
491 == ERROR) {
492 ErrorF("winAddRgn - CombineRgn () failed\n");
493 }
494 }
495
496 OffsetRgn(hRgnWin, iX, iY);
497
498 if (CombineRgn(hRgn, hRgn, hRgnWin, RGN_OR) == ERROR) {
499 ErrorF("winAddRgn - CombineRgn () failed\n");
500 }
501
502 DeleteObject(hRgnWin);
503 }
504 return WT_DONTWALKCHILDREN;
505 }
506 else {
507 return WT_WALKCHILDREN;
508 }
509 }
510
511 /*
512 * Local function to update the Windows window's region
513 */
514
515 static
516 void
517 winUpdateRgnRootless(WindowPtr pWin)
518 {
519 HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
520
521 if (hRgn != NULL) {
522 WalkTree(pWin->drawable.pScreen, winAddRgn, &hRgn);
523 SetWindowRgn(winGetScreenPriv(pWin->drawable.pScreen)->hwndScreen,
524 hRgn, TRUE);
525 }
526 else {
527 ErrorF("winUpdateRgnRootless - CreateRectRgn failed.\n");
528 }
529 }
530
531 static
532 void
533 winReshapeRootless(WindowPtr pWin)
534 {
535 int nRects;
536 RegionRec rrNewShape;
537 BoxPtr pShape, pRects, pEnd;
538 HRGN hRgn, hRgnRect;
539
540 winWindowPriv(pWin);
541
542 #if CYGDEBUG
543 winDebug("winReshapeRootless ()\n");
544 #endif
545
546 /* Bail if the window is the root window */
547 if (pWin->parent == NULL)
548 return;
549
550 /* Bail if the window is not top level */
551 if (pWin->parent->parent != NULL)
552 return;
553
554 /* Free any existing window region stored in the window privates */
555 if (pWinPriv->hRgn != NULL) {
556 DeleteObject(pWinPriv->hRgn);
557 pWinPriv->hRgn = NULL;
558 }
559
560 /* Bail if the window has no bounding region defined */
561 if (!wBoundingShape(pWin))
562 return;
563
564 RegionNull(&rrNewShape);
565 RegionCopy(&rrNewShape, wBoundingShape(pWin));
566 RegionTranslate(&rrNewShape, pWin->borderWidth, pWin->borderWidth);
567
568 nRects = RegionNumRects(&rrNewShape);
569 pShape = RegionRects(&rrNewShape);
570
571 if (nRects > 0) {
572 /* Create initial empty Windows region */
573 hRgn = CreateRectRgn(0, 0, 0, 0);
574
575 /* Loop through all rectangles in the X region */
576 for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) {
577 /* Create a Windows region for the X rectangle */
578 hRgnRect = CreateRectRgn(pRects->x1, pRects->y1,
579 pRects->x2, pRects->y2);
580 if (hRgnRect == NULL) {
581 ErrorF("winReshapeRootless - CreateRectRgn() failed\n");
582 }
583
584 /* Merge the Windows region with the accumulated region */
585 if (CombineRgn(hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) {
586 ErrorF("winReshapeRootless - CombineRgn() failed\n");
587 }
588
589 /* Delete the temporary Windows region */
590 DeleteObject(hRgnRect);
591 }
592
593 /* Save a handle to the composite region in the window privates */
594 pWinPriv->hRgn = hRgn;
595 }
596
597 RegionUninit(&rrNewShape);
598
599 return;
600 }