Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xwin / winwindow.c
CommitLineData
a09e091a
JB
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
41static int
42 winAddRgn(WindowPtr pWindow, pointer data);
43
44static
45 void
46 winUpdateRgnRootless(WindowPtr pWindow);
47
48static
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
56Bool
57winCreateWindowNativeGDI(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
78Bool
79winDestroyWindowNativeGDI(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
100Bool
101winPositionWindowNativeGDI(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
122void
123winCopyWindowNativeGDI(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
200Bool
201winChangeWindowAttributesNativeGDI(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
227Bool
228winUnmapWindowNativeGDI(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
250Bool
251winMapWindowNativeGDI(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
274Bool
275winCreateWindowRootless(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
299Bool
300winDestroyWindowRootless(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
329Bool
330winPositionWindowRootless(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
353Bool
354winChangeWindowAttributesRootless(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
378Bool
379winUnmapWindowRootless(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
409Bool
410winMapWindowRootless(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
432void
433winSetShapeRootless(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
457static
458 int
459winAddRgn(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
515static
516 void
517winUpdateRgnRootless(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
531static
532 void
533winReshapeRootless(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}