winmultiwindowwindow.c revision 6747b715
1/* 2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3 *Copyright (C) Colin Harrison 2005-2008 4 * 5 *Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 *"Software"), to deal in the Software without restriction, including 8 *without limitation the rights to use, copy, modify, merge, publish, 9 *distribute, sublicense, and/or sell copies of the Software, and to 10 *permit persons to whom the Software is furnished to do so, subject to 11 *the following conditions: 12 * 13 *The above copyright notice and this permission notice shall be 14 *included in all copies or substantial portions of the Software. 15 * 16 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR 20 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 21 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 *Except as contained in this notice, the name of the XFree86 Project 25 *shall not be used in advertising or otherwise to promote the sale, use 26 *or other dealings in this Software without prior written authorization 27 *from the XFree86 Project. 28 * 29 * Authors: Kensuke Matsuzaki 30 * Earle F. Philhower, III 31 * Harold L Hunt II 32 * Colin Harrison 33 */ 34 35#ifdef HAVE_XWIN_CONFIG_H 36#include <xwin-config.h> 37#endif 38#include "win.h" 39#include "dixevents.h" 40#include "winmultiwindowclass.h" 41#include "winprefs.h" 42 43/* 44 * External global variables 45 */ 46 47extern HICON g_hIconX; 48extern HICON g_hSmallIconX; 49extern HWND g_hDlgDepthChange; 50extern Bool g_fNativeGl; 51 52/* 53 * Prototypes for local functions 54 */ 55 56void 57winCreateWindowsWindow (WindowPtr pWin); 58 59static void 60winDestroyWindowsWindow (WindowPtr pWin); 61 62static void 63winUpdateWindowsWindow (WindowPtr pWin); 64 65static void 66winFindWindow (pointer value, XID id, pointer cdata); 67 68static 69void winInitMultiWindowClass(void) 70{ 71 static wATOM atomXWinClass=0; 72 WNDCLASSEX wcx; 73 74 if (atomXWinClass==0) 75 { 76 /* Setup our window class */ 77 wcx.cbSize=sizeof(WNDCLASSEX); 78 wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0); 79 wcx.lpfnWndProc = winTopLevelWindowProc; 80 wcx.cbClsExtra = 0; 81 wcx.cbWndExtra = 0; 82 wcx.hInstance = g_hInstance; 83 wcx.hIcon = g_hIconX; 84 wcx.hCursor = 0; 85 wcx.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); 86 wcx.lpszMenuName = NULL; 87 wcx.lpszClassName = WINDOW_CLASS_X; 88 wcx.hIconSm = g_hSmallIconX; 89 90#if CYGMULTIWINDOW_DEBUG 91 ErrorF ("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X); 92#endif 93 94 atomXWinClass = RegisterClassEx (&wcx); 95 } 96} 97 98/* 99 * CreateWindow - See Porting Layer Definition - p. 37 100 */ 101 102Bool 103winCreateWindowMultiWindow (WindowPtr pWin) 104{ 105 Bool fResult = TRUE; 106 ScreenPtr pScreen = pWin->drawable.pScreen; 107 winWindowPriv(pWin); 108 winScreenPriv(pScreen); 109 110#if CYGMULTIWINDOW_DEBUG 111 winTrace ("winCreateWindowMultiWindow - pWin: %p\n", pWin); 112#endif 113 114 WIN_UNWRAP(CreateWindow); 115 fResult = (*pScreen->CreateWindow) (pWin); 116 WIN_WRAP(CreateWindow, winCreateWindowMultiWindow); 117 118 /* Initialize some privates values */ 119 pWinPriv->hRgn = NULL; 120 pWinPriv->hWnd = NULL; 121 pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen); 122 pWinPriv->fXKilled = FALSE; 123 124 return fResult; 125} 126 127 128/* 129 * DestroyWindow - See Porting Layer Definition - p. 37 130 */ 131 132Bool 133winDestroyWindowMultiWindow (WindowPtr pWin) 134{ 135 Bool fResult = TRUE; 136 ScreenPtr pScreen = pWin->drawable.pScreen; 137 winWindowPriv(pWin); 138 winScreenPriv(pScreen); 139 140#if CYGMULTIWINDOW_DEBUG 141 ErrorF ("winDestroyWindowMultiWindow - pWin: %p\n", pWin); 142#endif 143 144 WIN_UNWRAP(DestroyWindow); 145 fResult = (*pScreen->DestroyWindow)(pWin); 146 WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow); 147 148 /* Flag that the window has been destroyed */ 149 pWinPriv->fXKilled = TRUE; 150 151 /* Kill the MS Windows window associated with this window */ 152 winDestroyWindowsWindow (pWin); 153 154 return fResult; 155} 156 157 158/* 159 * PositionWindow - See Porting Layer Definition - p. 37 160 * 161 * This function adjusts the position and size of Windows window 162 * with respect to the underlying X window. This is the inverse 163 * of winAdjustXWindow, which adjusts X window to Windows window. 164 */ 165 166Bool 167winPositionWindowMultiWindow (WindowPtr pWin, int x, int y) 168{ 169 Bool fResult = TRUE; 170 int iX, iY, iWidth, iHeight; 171 ScreenPtr pScreen = pWin->drawable.pScreen; 172 winWindowPriv(pWin); 173 winScreenPriv(pScreen); 174 175 HWND hWnd = pWinPriv->hWnd; 176 RECT rcNew; 177 RECT rcOld; 178#if CYGMULTIWINDOW_DEBUG 179 RECT rcClient; 180 RECT *lpRc; 181#endif 182 DWORD dwExStyle; 183 DWORD dwStyle; 184 185#if CYGMULTIWINDOW_DEBUG 186 winTrace ("winPositionWindowMultiWindow - pWin: %p\n", pWin); 187#endif 188 189 WIN_UNWRAP(PositionWindow); 190 fResult = (*pScreen->PositionWindow)(pWin, x, y); 191 WIN_WRAP(PositionWindow, winPositionWindowMultiWindow); 192 193#if CYGWINDOWING_DEBUG 194 ErrorF ("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n", 195 x, y); 196#endif 197 198 /* Bail out if the Windows window handle is bad */ 199 if (!hWnd) 200 { 201#if CYGWINDOWING_DEBUG 202 ErrorF ("\timmediately return since hWnd is NULL\n"); 203#endif 204 return fResult; 205 } 206 207 /* Get the Windows window style and extended style */ 208 dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE); 209 dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE); 210 211 /* Get the X and Y location of the X window */ 212 iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); 213 iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); 214 215 /* Get the height and width of the X window */ 216 iWidth = pWin->drawable.width; 217 iHeight = pWin->drawable.height; 218 219 /* Store the origin, height, and width in a rectangle structure */ 220 SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); 221 222#if CYGMULTIWINDOW_DEBUG 223 lpRc = &rcNew; 224 ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n", 225 GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); 226#endif 227 228 /* 229 * Calculate the required size of the Windows window rectangle, 230 * given the size of the Windows window client area. 231 */ 232 AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); 233 234 /* Get a rectangle describing the old Windows window */ 235 GetWindowRect (hWnd, &rcOld); 236 237#if CYGMULTIWINDOW_DEBUG 238 /* Get a rectangle describing the Windows window client area */ 239 GetClientRect (hWnd, &rcClient); 240 241 lpRc = &rcNew; 242 ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n", 243 GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); 244 245 lpRc = &rcOld; 246 ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n", 247 GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); 248 249 lpRc = &rcClient; 250 ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n", 251 GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); 252#endif 253 254 /* Check if the old rectangle and new rectangle are the same */ 255 if (!EqualRect (&rcNew, &rcOld)) 256 { 257#if CYGMULTIWINDOW_DEBUG 258 ErrorF ("winPositionWindowMultiWindow - Need to move\n"); 259#endif 260 261#if CYGWINDOWING_DEBUG 262 ErrorF ("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew.left, rcNew.top, 263 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); 264#endif 265 /* Change the position and dimensions of the Windows window */ 266 MoveWindow (hWnd, 267 rcNew.left, rcNew.top, 268 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, 269 TRUE); 270 } 271 else 272 { 273#if CYGMULTIWINDOW_DEBUG 274 ErrorF ("winPositionWindowMultiWindow - Not need to move\n"); 275#endif 276 } 277 278 return fResult; 279} 280 281 282/* 283 * ChangeWindowAttributes - See Porting Layer Definition - p. 37 284 */ 285 286Bool 287winChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask) 288{ 289 Bool fResult = TRUE; 290 ScreenPtr pScreen = pWin->drawable.pScreen; 291 winScreenPriv(pScreen); 292 293#if CYGMULTIWINDOW_DEBUG 294 ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin); 295#endif 296 297 WIN_UNWRAP(ChangeWindowAttributes); 298 fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask); 299 WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow); 300 301 /* 302 * NOTE: We do not currently need to do anything here. 303 */ 304 305 return fResult; 306} 307 308 309/* 310 * UnmapWindow - See Porting Layer Definition - p. 37 311 * Also referred to as UnrealizeWindow 312 */ 313 314Bool 315winUnmapWindowMultiWindow (WindowPtr pWin) 316{ 317 Bool fResult = TRUE; 318 ScreenPtr pScreen = pWin->drawable.pScreen; 319 winWindowPriv(pWin); 320 winScreenPriv(pScreen); 321 322#if CYGMULTIWINDOW_DEBUG 323 ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin); 324#endif 325 326 WIN_UNWRAP(UnrealizeWindow); 327 fResult = (*pScreen->UnrealizeWindow)(pWin); 328 WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow); 329 330 /* Flag that the window has been killed */ 331 pWinPriv->fXKilled = TRUE; 332 333 /* Destroy the Windows window associated with this X window */ 334 winDestroyWindowsWindow (pWin); 335 336 return fResult; 337} 338 339 340/* 341 * MapWindow - See Porting Layer Definition - p. 37 342 * Also referred to as RealizeWindow 343 */ 344 345Bool 346winMapWindowMultiWindow (WindowPtr pWin) 347{ 348 Bool fResult = TRUE; 349 ScreenPtr pScreen = pWin->drawable.pScreen; 350 winWindowPriv(pWin); 351 winScreenPriv(pScreen); 352 353#if CYGMULTIWINDOW_DEBUG 354 ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin); 355#endif 356 357 WIN_UNWRAP(RealizeWindow); 358 fResult = (*pScreen->RealizeWindow)(pWin); 359 WIN_WRAP(RealizeWindow, winMapWindowMultiWindow); 360 361 /* Flag that this window has not been destroyed */ 362 pWinPriv->fXKilled = FALSE; 363 364 /* Refresh/redisplay the Windows window associated with this X window */ 365 winUpdateWindowsWindow (pWin); 366 367 /* Update the Windows window's shape */ 368 winReshapeMultiWindow (pWin); 369 winUpdateRgnMultiWindow (pWin); 370 371 return fResult; 372} 373 374 375/* 376 * ReparentWindow - See Porting Layer Definition - p. 42 377 */ 378 379void 380winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent) 381{ 382 ScreenPtr pScreen = pWin->drawable.pScreen; 383 winScreenPriv(pScreen); 384 385#if CYGMULTIWINDOW_DEBUG 386 ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin); 387#endif 388 389 WIN_UNWRAP(ReparentWindow); 390 if (pScreen->ReparentWindow) 391 (*pScreen->ReparentWindow)(pWin, pPriorParent); 392 WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow); 393 394 /* Update the Windows window associated with this X window */ 395 winUpdateWindowsWindow (pWin); 396} 397 398 399/* 400 * RestackWindow - Shuffle the z-order of a window 401 */ 402 403void 404winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) 405{ 406#if 0 407 WindowPtr pPrevWin; 408 UINT uFlags; 409 HWND hInsertAfter; 410 HWND hWnd = NULL; 411#endif 412 ScreenPtr pScreen = pWin->drawable.pScreen; 413 winScreenPriv(pScreen); 414 415#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG 416 winTrace ("winRestackMultiWindow - %08x\n", pWin); 417#endif 418 419 WIN_UNWRAP(RestackWindow); 420 if (pScreen->RestackWindow) 421 (*pScreen->RestackWindow)(pWin, pOldNextSib); 422 WIN_WRAP(RestackWindow, winRestackWindowMultiWindow); 423 424#if 1 425 /* 426 * Calling winReorderWindowsMultiWindow here means our window manager 427 * (i.e. Windows Explorer) has initiative to determine Z order. 428 */ 429 if (pWin->nextSib != pOldNextSib) 430 winReorderWindowsMultiWindow (); 431#else 432 /* Bail out if no window privates or window handle is invalid */ 433 if (!pWinPriv || !pWinPriv->hWnd) 434 return; 435 436 /* Get a pointer to our previous sibling window */ 437 pPrevWin = pWin->prevSib; 438 439 /* 440 * Look for a sibling window with 441 * valid privates and window handle 442 */ 443 while (pPrevWin 444 && !winGetWindowPriv(pPrevWin) 445 && !winGetWindowPriv(pPrevWin)->hWnd) 446 pPrevWin = pPrevWin->prevSib; 447 448 /* Check if we found a valid sibling */ 449 if (pPrevWin) 450 { 451 /* Valid sibling - get handle to insert window after */ 452 hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd; 453 uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; 454 455 hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV); 456 457 do 458 { 459 if (GetProp (hWnd, WIN_WINDOW_PROP)) 460 { 461 if (hWnd == winGetWindowPriv(pPrevWin)->hWnd) 462 { 463 uFlags |= SWP_NOZORDER; 464 } 465 break; 466 } 467 hWnd = GetNextWindow (hWnd, GW_HWNDPREV); 468 } 469 while (hWnd); 470 } 471 else 472 { 473 /* No valid sibling - make this window the top window */ 474 hInsertAfter = HWND_TOP; 475 uFlags = SWP_NOMOVE | SWP_NOSIZE; 476 } 477 478 /* Perform the restacking operation in Windows */ 479 SetWindowPos (pWinPriv->hWnd, 480 hInsertAfter, 481 0, 0, 482 0, 0, 483 uFlags); 484#endif 485} 486 487 488/* 489 * winCreateWindowsWindow - Create a Windows window associated with an X window 490 */ 491 492void 493winCreateWindowsWindow (WindowPtr pWin) 494{ 495 int iX, iY; 496 int iWidth; 497 int iHeight; 498 HWND hWnd; 499 HWND hFore = NULL; 500 winWindowPriv(pWin); 501 HICON hIcon; 502 HICON hIconSmall; 503 winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv; 504 WinXSizeHints hints; 505 WindowPtr pDaddy; 506 507 winInitMultiWindowClass(); 508 509#if CYGMULTIWINDOW_DEBUG 510 ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin); 511#endif 512 513 iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); 514 iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); 515 516 iWidth = pWin->drawable.width; 517 iHeight = pWin->drawable.height; 518 519 /* ensure window actually ends up somewhere visible */ 520 if (iX > GetSystemMetrics (SM_CXVIRTUALSCREEN)) 521 iX = CW_USEDEFAULT; 522 523 if (iY > GetSystemMetrics (SM_CYVIRTUALSCREEN)) 524 iY = CW_USEDEFAULT; 525 526 if (winMultiWindowGetTransientFor (pWin, &pDaddy)) 527 { 528 if (pDaddy) 529 { 530 hFore = GetForegroundWindow(); 531 if (hFore && (pDaddy != (WindowPtr)GetProp(hFore, WIN_WID_PROP))) hFore = NULL; 532 } 533 } 534 else 535 { 536 /* Default positions if none specified */ 537 if (!winMultiWindowGetWMNormalHints(pWin, &hints)) 538 hints.flags = 0; 539 if (!(hints.flags & (USPosition|PPosition)) && 540 !pWin->overrideRedirect) 541 { 542 iX = CW_USEDEFAULT; 543 iY = CW_USEDEFAULT; 544 } 545 } 546 547 /* Create the window */ 548 /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */ 549 /* CW_USEDEFAULT, change back to popup after creation */ 550 hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ 551 WINDOW_CLASS_X, /* Class name */ 552 WINDOW_TITLE_X, /* Window name */ 553 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 554 iX, /* Horizontal position */ 555 iY, /* Vertical position */ 556 iWidth, /* Right edge */ 557 iHeight, /* Bottom edge */ 558 hFore, /* Null or Parent window if transient*/ 559 (HMENU) NULL, /* No menu */ 560 GetModuleHandle (NULL), /* Instance handle */ 561 pWin); /* ScreenPrivates */ 562 if (hWnd == NULL) 563 { 564 ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n", 565 (int) GetLastError ()); 566 } 567 pWinPriv->hWnd = hWnd; 568 569 /* Set application or .XWinrc defined Icons */ 570 winSelectIcons(pWin, &hIcon, &hIconSmall); 571 if (hIcon) SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon); 572 if (hIconSmall) SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); 573 574 /* Change style back to popup, already placed... */ 575 SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); 576 SetWindowPos (hWnd, 0, 0, 0, 0, 0, 577 SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 578 /* Make sure it gets the proper system menu for a WS_POPUP, too */ 579 GetSystemMenu (hWnd, TRUE); 580 581 /* Cause any .XWinrc menus to be added in main WNDPROC */ 582 PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0); 583 584 SetProp (hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin)); 585 586 /* Flag that this Windows window handles its own activation */ 587 SetProp (hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0); 588 589 /* Call engine-specific create window procedure */ 590 (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin); 591} 592 593 594Bool winInDestroyWindowsWindow = FALSE; 595/* 596 * winDestroyWindowsWindow - Destroy a Windows window associated 597 * with an X window 598 */ 599static void 600winDestroyWindowsWindow (WindowPtr pWin) 601{ 602 MSG msg; 603 winWindowPriv(pWin); 604 BOOL oldstate = winInDestroyWindowsWindow; 605 606#if CYGMULTIWINDOW_DEBUG 607 ErrorF ("winDestroyWindowsWindow\n"); 608#endif 609 610 /* Bail out if the Windows window handle is invalid */ 611 if (pWinPriv->hWnd == NULL) 612 return; 613 614 winInDestroyWindowsWindow = TRUE; 615 616 SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL); 617 /* Destroy the Windows window */ 618 DestroyWindow (pWinPriv->hWnd); 619 620 /* Null our handle to the Window so referencing it will cause an error */ 621 pWinPriv->hWnd = NULL; 622 623 /* Process all messages on our queue */ 624 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) 625 { 626 if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg)) 627 { 628 DispatchMessage (&msg); 629 } 630 } 631 632 winInDestroyWindowsWindow = oldstate; 633 634#if CYGMULTIWINDOW_DEBUG 635 ErrorF ("-winDestroyWindowsWindow\n"); 636#endif 637} 638 639 640/* 641 * winUpdateWindowsWindow - Redisplay/redraw a Windows window 642 * associated with an X window 643 */ 644 645static void 646winUpdateWindowsWindow (WindowPtr pWin) 647{ 648 winWindowPriv(pWin); 649 HWND hWnd = pWinPriv->hWnd; 650 651#if CYGMULTIWINDOW_DEBUG 652 ErrorF ("winUpdateWindowsWindow\n"); 653#endif 654 655 /* Check if the Windows window's parents have been destroyed */ 656 if (pWin->parent != NULL 657 && pWin->parent->parent == NULL 658 && pWin->mapped) 659 { 660 /* Create the Windows window if it has been destroyed */ 661 if (hWnd == NULL) 662 { 663 winCreateWindowsWindow (pWin); 664 assert (pWinPriv->hWnd != NULL); 665 } 666 667 /* Display the window without activating it */ 668 ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE); 669 670 /* Send first paint message */ 671 UpdateWindow (pWinPriv->hWnd); 672 } 673 else if (hWnd != NULL) 674 { 675 /* Destroy the Windows window if its parents are destroyed */ 676 winDestroyWindowsWindow (pWin); 677 assert (pWinPriv->hWnd == NULL); 678 } 679 680#if CYGMULTIWINDOW_DEBUG 681 ErrorF ("-winUpdateWindowsWindow\n"); 682#endif 683} 684 685 686/* 687 * winGetWindowID - 688 */ 689 690XID 691winGetWindowID (WindowPtr pWin) 692{ 693 WindowIDPairRec wi = {pWin, 0}; 694 ClientPtr c = wClient(pWin); 695 696 /* */ 697 FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi); 698 699#if CYGMULTIWINDOW_DEBUG 700 ErrorF ("winGetWindowID - Window ID: %d\n", wi.id); 701#endif 702 703 return wi.id; 704} 705 706 707/* 708 * winFindWindow - 709 */ 710 711static void 712winFindWindow (pointer value, XID id, pointer cdata) 713{ 714 WindowIDPairPtr wi = (WindowIDPairPtr)cdata; 715 716 if (value == wi->value) 717 { 718 wi->id = id; 719 } 720} 721 722 723/* 724 * winReorderWindowsMultiWindow - 725 */ 726 727void 728winReorderWindowsMultiWindow (void) 729{ 730 HWND hwnd = NULL; 731 WindowPtr pWin = NULL; 732 WindowPtr pWinSib = NULL; 733 XID vlist[2]; 734 static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */ 735 DWORD dwCurrentProcessID = GetCurrentProcessId (); 736 DWORD dwWindowProcessID = 0; 737 738#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG 739 winTrace ("winReorderWindowsMultiWindow\n"); 740#endif 741 742 if (fRestacking) 743 { 744 /* It is a recusive call so immediately exit */ 745#if CYGWINDOWING_DEBUG 746 ErrorF ("winReorderWindowsMultiWindow - " 747 "exit because fRestacking == TRUE\n"); 748#endif 749 return; 750 } 751 fRestacking = TRUE; 752 753 /* Loop through top level Window windows, descending in Z order */ 754 for ( hwnd = GetTopWindow (NULL); 755 hwnd; 756 hwnd = GetNextWindow (hwnd, GW_HWNDNEXT) ) 757 { 758 /* Don't take care of other Cygwin/X process's windows */ 759 GetWindowThreadProcessId (hwnd, &dwWindowProcessID); 760 761 if ( GetProp (hwnd, WIN_WINDOW_PROP) 762 && (dwWindowProcessID == dwCurrentProcessID) 763 && !IsIconic (hwnd) ) /* ignore minimized windows */ 764 { 765 pWinSib = pWin; 766 pWin = GetProp (hwnd, WIN_WINDOW_PROP); 767 768 if (!pWinSib) 769 { /* 1st window - raise to the top */ 770 vlist[0] = Above; 771 772 ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin)); 773 } 774 else 775 { /* 2nd or deeper windows - just below the previous one */ 776 vlist[0] = winGetWindowID (pWinSib); 777 vlist[1] = Below; 778 779 ConfigureWindow (pWin, CWSibling | CWStackMode, 780 vlist, wClient(pWin)); 781 } 782 } 783 } 784 785 fRestacking = FALSE; 786} 787 788 789/* 790 * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE 791 */ 792 793void 794winMinimizeWindow (Window id) 795{ 796 WindowPtr pWin; 797 winPrivWinPtr pWinPriv; 798#ifdef XWIN_MULTIWINDOWEXTWM 799 win32RootlessWindowPtr pRLWinPriv; 800#endif 801 HWND hWnd; 802 ScreenPtr pScreen = NULL; 803 winPrivScreenPtr pScreenPriv = NULL; 804 winScreenInfo *pScreenInfo = NULL; 805 806#if CYGWINDOWING_DEBUG 807 ErrorF ("winMinimizeWindow\n"); 808#endif 809 810 dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess); 811 if (!pWin) 812 { 813 ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__); 814 return; 815 } 816 817 pScreen = pWin->drawable.pScreen; 818 if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); 819 if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; 820 821#ifdef XWIN_MULTIWINDOWEXTWM 822 if (pScreenPriv && pScreenInfo->fInternalWM) 823 { 824 pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); 825 hWnd = pRLWinPriv->hWnd; 826 } 827 else 828#else 829 if (pScreenPriv) 830#endif 831 { 832 pWinPriv = winGetWindowPriv (pWin); 833 hWnd = pWinPriv->hWnd; 834 } 835 836 ShowWindow (hWnd, SW_MINIMIZE); 837} 838 839 840/* 841 * CopyWindow - See Porting Layer Definition - p. 39 842 */ 843void 844winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt, 845 RegionPtr oldRegion) 846{ 847 ScreenPtr pScreen = pWin->drawable.pScreen; 848 winScreenPriv(pScreen); 849 850#if CYGWINDOWING_DEBUG 851 ErrorF ("CopyWindowMultiWindow\n"); 852#endif 853 WIN_UNWRAP(CopyWindow); 854 (*pScreen->CopyWindow)(pWin, oldpt, oldRegion); 855 WIN_WRAP(CopyWindow, winCopyWindowMultiWindow); 856} 857 858 859/* 860 * MoveWindow - See Porting Layer Definition - p. 42 861 */ 862void 863winMoveWindowMultiWindow (WindowPtr pWin, int x, int y, 864 WindowPtr pSib, VTKind kind) 865{ 866 ScreenPtr pScreen = pWin->drawable.pScreen; 867 winScreenPriv(pScreen); 868 869#if CYGWINDOWING_DEBUG 870 ErrorF ("MoveWindowMultiWindow to (%d, %d)\n", x, y); 871#endif 872 873 WIN_UNWRAP(MoveWindow); 874 (*pScreen->MoveWindow)(pWin, x, y, pSib, kind); 875 WIN_WRAP(MoveWindow, winMoveWindowMultiWindow); 876} 877 878 879/* 880 * ResizeWindow - See Porting Layer Definition - p. 42 881 */ 882void 883winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w, 884 unsigned int h, WindowPtr pSib) 885{ 886 ScreenPtr pScreen = pWin->drawable.pScreen; 887 winScreenPriv(pScreen); 888 889#if CYGWINDOWING_DEBUG 890 ErrorF ("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h); 891#endif 892 WIN_UNWRAP(ResizeWindow); 893 (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib); 894 WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow); 895} 896 897 898/* 899 * winAdjustXWindow 900 * 901 * Move and resize X window with respect to corresponding Windows window. 902 * This is called from WM_MOVE/WM_SIZE handlers when the user performs 903 * any windowing operation (move, resize, minimize, maximize, restore). 904 * 905 * The functionality is the inverse of winPositionWindowMultiWindow, which 906 * adjusts Windows window with respect to X window. 907 */ 908int 909winAdjustXWindow (WindowPtr pWin, HWND hwnd) 910{ 911 RECT rcDraw; /* Rect made from pWin->drawable to be adjusted */ 912 RECT rcWin; /* The source: WindowRect from hwnd */ 913 DrawablePtr pDraw; 914 XID vlist[4]; 915 LONG dX, dY, dW, dH, x, y; 916 DWORD dwStyle, dwExStyle; 917 918#define WIDTH(rc) (rc.right - rc.left) 919#define HEIGHT(rc) (rc.bottom - rc.top) 920 921#if CYGWINDOWING_DEBUG 922 ErrorF ("winAdjustXWindow\n"); 923#endif 924 925 if (IsIconic (hwnd)) 926 { 927#if CYGWINDOWING_DEBUG 928 ErrorF ("\timmediately return because the window is iconized\n"); 929#endif 930 /* 931 * If the Windows window is minimized, its WindowRect has 932 * meaningless values so we don't adjust X window to it. 933 */ 934 vlist[0] = 0; 935 vlist[1] = 0; 936 return ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin)); 937 } 938 939 pDraw = &pWin->drawable; 940 941 /* Calculate the window rect from the drawable */ 942 x = pDraw->x + GetSystemMetrics (SM_XVIRTUALSCREEN); 943 y = pDraw->y + GetSystemMetrics (SM_YVIRTUALSCREEN); 944 SetRect (&rcDraw, x, y, x + pDraw->width, y + pDraw->height); 945#ifdef CYGMULTIWINDOW_DEBUG 946 winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n", 947 rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom, 948 rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top); 949#endif 950 dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); 951 dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); 952#ifdef CYGMULTIWINDOW_DEBUG 953 winDebug("\tWindowStyle: %08x %08x\n", dwStyle, dwExStyle); 954#endif 955 AdjustWindowRectEx (&rcDraw, dwStyle, FALSE, dwExStyle); 956 957 /* The source of adjust */ 958 GetWindowRect (hwnd, &rcWin); 959#ifdef CYGMULTIWINDOW_DEBUG 960 winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n", 961 rcWin.left, rcWin.top, rcWin.right, rcWin.bottom, 962 rcWin.right - rcWin.left, rcWin.bottom - rcWin.top); 963 winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n", 964 rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom, 965 rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top); 966#endif 967 968 if (EqualRect (&rcDraw, &rcWin)) { 969 /* Bail if no adjust is needed */ 970#if CYGWINDOWING_DEBUG 971 ErrorF ("\treturn because already adjusted\n"); 972#endif 973 return 0; 974 } 975 976 /* Calculate delta values */ 977 dX = rcWin.left - rcDraw.left; 978 dY = rcWin.top - rcDraw.top; 979 dW = WIDTH(rcWin) - WIDTH(rcDraw); 980 dH = HEIGHT(rcWin) - HEIGHT(rcDraw); 981 982 /* 983 * Adjust. 984 * We may only need to move (vlist[0] and [1]), or only resize 985 * ([2] and [3]) but currently we set all the parameters and leave 986 * the decision to ConfigureWindow. The reason is code simplicity. 987 */ 988 vlist[0] = pDraw->x + dX - wBorderWidth(pWin); 989 vlist[1] = pDraw->y + dY - wBorderWidth(pWin); 990 vlist[2] = pDraw->width + dW; 991 vlist[3] = pDraw->height + dH; 992#if CYGWINDOWING_DEBUG 993 ErrorF ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist[0], vlist[1], 994 vlist[2], vlist[3]); 995#endif 996 return ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, 997 vlist, wClient(pWin)); 998 999#undef WIDTH 1000#undef HEIGHT 1001} 1002 1003