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