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