2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3 *Copyright (C) Colin Harrison 2005-2008
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:
13 *The above copyright notice and this permission notice shall be
14 *included in all copies or substantial portions of the Software.
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.
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.
29 * Authors: Kensuke Matsuzaki
30 * Earle F. Philhower, III
35 #ifdef HAVE_XWIN_CONFIG_H
36 #include <xwin-config.h>
39 #include "dixevents.h"
40 #include "winmultiwindowclass.h"
43 * Prototypes for local functions
47 winCreateWindowsWindow(WindowPtr pWin
);
50 winDestroyWindowsWindow(WindowPtr pWin
);
53 winUpdateWindowsWindow(WindowPtr pWin
);
56 winFindWindow(pointer value
, XID id
, pointer cdata
);
60 winInitMultiWindowClass(void)
62 static wATOM atomXWinClass
= 0;
65 if (atomXWinClass
== 0) {
66 HICON hIcon
, hIconSmall
;
68 /* Load the default icons */
69 winSelectIcons(&hIcon
, &hIconSmall
);
71 /* Setup our window class */
72 wcx
.cbSize
= sizeof(WNDCLASSEX
);
73 wcx
.style
= CS_HREDRAW
| CS_VREDRAW
| (g_fNativeGl
? CS_OWNDC
: 0);
74 wcx
.lpfnWndProc
= winTopLevelWindowProc
;
77 wcx
.hInstance
= g_hInstance
;
80 wcx
.hbrBackground
= (HBRUSH
) GetStockObject(WHITE_BRUSH
);
81 wcx
.lpszMenuName
= NULL
;
82 wcx
.lpszClassName
= WINDOW_CLASS_X
;
83 wcx
.hIconSm
= hIconSmall
;
85 #if CYGMULTIWINDOW_DEBUG
86 ErrorF("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X
);
89 atomXWinClass
= RegisterClassEx(&wcx
);
94 * CreateWindow - See Porting Layer Definition - p. 37
98 winCreateWindowMultiWindow(WindowPtr pWin
)
101 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
104 winScreenPriv(pScreen
);
106 #if CYGMULTIWINDOW_DEBUG
107 winTrace("winCreateWindowMultiWindow - pWin: %p\n", pWin
);
110 WIN_UNWRAP(CreateWindow
);
111 fResult
= (*pScreen
->CreateWindow
) (pWin
);
112 WIN_WRAP(CreateWindow
, winCreateWindowMultiWindow
);
114 /* Initialize some privates values */
115 pWinPriv
->hRgn
= NULL
;
116 pWinPriv
->hWnd
= NULL
;
117 pWinPriv
->pScreenPriv
= winGetScreenPriv(pWin
->drawable
.pScreen
);
118 pWinPriv
->fXKilled
= FALSE
;
119 #ifdef XWIN_GLX_WINDOWS
120 pWinPriv
->fWglUsed
= FALSE
;
127 * DestroyWindow - See Porting Layer Definition - p. 37
131 winDestroyWindowMultiWindow(WindowPtr pWin
)
134 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
137 winScreenPriv(pScreen
);
139 #if CYGMULTIWINDOW_DEBUG
140 ErrorF("winDestroyWindowMultiWindow - pWin: %p\n", pWin
);
143 WIN_UNWRAP(DestroyWindow
);
144 fResult
= (*pScreen
->DestroyWindow
) (pWin
);
145 WIN_WRAP(DestroyWindow
, winDestroyWindowMultiWindow
);
147 /* Flag that the window has been destroyed */
148 pWinPriv
->fXKilled
= TRUE
;
150 /* Kill the MS Windows window associated with this window */
151 winDestroyWindowsWindow(pWin
);
157 * PositionWindow - See Porting Layer Definition - p. 37
159 * This function adjusts the position and size of Windows window
160 * with respect to the underlying X window. This is the inverse
161 * of winAdjustXWindow, which adjusts X window to Windows window.
165 winPositionWindowMultiWindow(WindowPtr pWin
, int x
, int y
)
168 int iX
, iY
, iWidth
, iHeight
;
169 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
172 winScreenPriv(pScreen
);
174 HWND hWnd
= pWinPriv
->hWnd
;
178 #if CYGMULTIWINDOW_DEBUG
185 #if CYGMULTIWINDOW_DEBUG
186 winTrace("winPositionWindowMultiWindow - pWin: %p\n", pWin
);
189 WIN_UNWRAP(PositionWindow
);
190 fResult
= (*pScreen
->PositionWindow
) (pWin
, x
, y
);
191 WIN_WRAP(PositionWindow
, winPositionWindowMultiWindow
);
193 #if CYGWINDOWING_DEBUG
194 ErrorF("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n", x
, y
);
197 /* Bail out if the Windows window handle is bad */
199 #if CYGWINDOWING_DEBUG
200 ErrorF("\timmediately return since hWnd is NULL\n");
205 /* Get the Windows window style and extended style */
206 dwExStyle
= GetWindowLongPtr(hWnd
, GWL_EXSTYLE
);
207 dwStyle
= GetWindowLongPtr(hWnd
, GWL_STYLE
);
209 /* Get the X and Y location of the X window */
210 iX
= pWin
->drawable
.x
+ GetSystemMetrics(SM_XVIRTUALSCREEN
);
211 iY
= pWin
->drawable
.y
+ GetSystemMetrics(SM_YVIRTUALSCREEN
);
213 /* Get the height and width of the X window */
214 iWidth
= pWin
->drawable
.width
;
215 iHeight
= pWin
->drawable
.height
;
217 /* Store the origin, height, and width in a rectangle structure */
218 SetRect(&rcNew
, iX
, iY
, iX
+ iWidth
, iY
+ iHeight
);
220 #if CYGMULTIWINDOW_DEBUG
222 ErrorF("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n",
223 GetTickCount(), lpRc
->left
, lpRc
->top
, lpRc
->right
, lpRc
->bottom
);
227 * Calculate the required size of the Windows window rectangle,
228 * given the size of the Windows window client area.
230 AdjustWindowRectEx(&rcNew
, dwStyle
, FALSE
, dwExStyle
);
232 /* Get a rectangle describing the old Windows window */
233 GetWindowRect(hWnd
, &rcOld
);
235 #if CYGMULTIWINDOW_DEBUG
236 /* Get a rectangle describing the Windows window client area */
237 GetClientRect(hWnd
, &rcClient
);
240 ErrorF("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n",
241 GetTickCount(), lpRc
->left
, lpRc
->top
, lpRc
->right
, lpRc
->bottom
);
244 ErrorF("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n",
245 GetTickCount(), lpRc
->left
, lpRc
->top
, lpRc
->right
, lpRc
->bottom
);
248 ErrorF("(%d ms)rcClient (%d, %d)-(%d, %d)\n",
249 GetTickCount(), lpRc
->left
, lpRc
->top
, lpRc
->right
, lpRc
->bottom
);
252 /* Check if the old rectangle and new rectangle are the same */
253 if (!EqualRect(&rcNew
, &rcOld
)) {
254 #if CYGMULTIWINDOW_DEBUG
255 ErrorF("winPositionWindowMultiWindow - Need to move\n");
258 #if CYGWINDOWING_DEBUG
259 ErrorF("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew
.left
, rcNew
.top
,
260 rcNew
.right
- rcNew
.left
, rcNew
.bottom
- rcNew
.top
);
262 /* Change the position and dimensions of the Windows window */
264 rcNew
.left
, rcNew
.top
,
265 rcNew
.right
- rcNew
.left
, rcNew
.bottom
- rcNew
.top
, TRUE
);
268 #if CYGMULTIWINDOW_DEBUG
269 ErrorF("winPositionWindowMultiWindow - Not need to move\n");
277 * ChangeWindowAttributes - See Porting Layer Definition - p. 37
281 winChangeWindowAttributesMultiWindow(WindowPtr pWin
, unsigned long mask
)
284 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
286 winScreenPriv(pScreen
);
288 #if CYGMULTIWINDOW_DEBUG
289 ErrorF("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin
);
292 WIN_UNWRAP(ChangeWindowAttributes
);
293 fResult
= (*pScreen
->ChangeWindowAttributes
) (pWin
, mask
);
294 WIN_WRAP(ChangeWindowAttributes
, winChangeWindowAttributesMultiWindow
);
297 * NOTE: We do not currently need to do anything here.
304 * UnmapWindow - See Porting Layer Definition - p. 37
305 * Also referred to as UnrealizeWindow
309 winUnmapWindowMultiWindow(WindowPtr pWin
)
312 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
315 winScreenPriv(pScreen
);
317 #if CYGMULTIWINDOW_DEBUG
318 ErrorF("winUnmapWindowMultiWindow - pWin: %08x\n", pWin
);
321 WIN_UNWRAP(UnrealizeWindow
);
322 fResult
= (*pScreen
->UnrealizeWindow
) (pWin
);
323 WIN_WRAP(UnrealizeWindow
, winUnmapWindowMultiWindow
);
325 /* Flag that the window has been killed */
326 pWinPriv
->fXKilled
= TRUE
;
328 /* Destroy the Windows window associated with this X window */
329 winDestroyWindowsWindow(pWin
);
335 * MapWindow - See Porting Layer Definition - p. 37
336 * Also referred to as RealizeWindow
340 winMapWindowMultiWindow(WindowPtr pWin
)
343 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
346 winScreenPriv(pScreen
);
348 #if CYGMULTIWINDOW_DEBUG
349 ErrorF("winMapWindowMultiWindow - pWin: %08x\n", pWin
);
352 WIN_UNWRAP(RealizeWindow
);
353 fResult
= (*pScreen
->RealizeWindow
) (pWin
);
354 WIN_WRAP(RealizeWindow
, winMapWindowMultiWindow
);
356 /* Flag that this window has not been destroyed */
357 pWinPriv
->fXKilled
= FALSE
;
359 /* Refresh/redisplay the Windows window associated with this X window */
360 winUpdateWindowsWindow(pWin
);
362 /* Update the Windows window's shape */
363 winReshapeMultiWindow(pWin
);
364 winUpdateRgnMultiWindow(pWin
);
370 * ReparentWindow - See Porting Layer Definition - p. 42
374 winReparentWindowMultiWindow(WindowPtr pWin
, WindowPtr pPriorParent
)
376 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
378 winScreenPriv(pScreen
);
381 ("winReparentMultiWindow - pWin:%08x XID:0x%x, reparent from pWin:%08x XID:0x%x to pWin:%08x XID:0x%x\n",
382 pWin
, pWin
->drawable
.id
, pPriorParent
, pPriorParent
->drawable
.id
,
383 pWin
->parent
, pWin
->parent
->drawable
.id
);
385 WIN_UNWRAP(ReparentWindow
);
386 if (pScreen
->ReparentWindow
)
387 (*pScreen
->ReparentWindow
) (pWin
, pPriorParent
);
388 WIN_WRAP(ReparentWindow
, winReparentWindowMultiWindow
);
390 /* Update the Windows window associated with this X window */
391 winUpdateWindowsWindow(pWin
);
395 * RestackWindow - Shuffle the z-order of a window
399 winRestackWindowMultiWindow(WindowPtr pWin
, WindowPtr pOldNextSib
)
407 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
409 winScreenPriv(pScreen
);
411 #if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
412 winTrace("winRestackMultiWindow - %08x\n", pWin
);
415 WIN_UNWRAP(RestackWindow
);
416 if (pScreen
->RestackWindow
)
417 (*pScreen
->RestackWindow
) (pWin
, pOldNextSib
);
418 WIN_WRAP(RestackWindow
, winRestackWindowMultiWindow
);
422 * Calling winReorderWindowsMultiWindow here means our window manager
423 * (i.e. Windows Explorer) has initiative to determine Z order.
425 if (pWin
->nextSib
!= pOldNextSib
)
426 winReorderWindowsMultiWindow();
428 /* Bail out if no window privates or window handle is invalid */
429 if (!pWinPriv
|| !pWinPriv
->hWnd
)
432 /* Get a pointer to our previous sibling window */
433 pPrevWin
= pWin
->prevSib
;
436 * Look for a sibling window with
437 * valid privates and window handle
439 while (pPrevWin
&& !winGetWindowPriv(pPrevWin
)
440 && !winGetWindowPriv(pPrevWin
)->hWnd
)
441 pPrevWin
= pPrevWin
->prevSib
;
443 /* Check if we found a valid sibling */
445 /* Valid sibling - get handle to insert window after */
446 hInsertAfter
= winGetWindowPriv(pPrevWin
)->hWnd
;
447 uFlags
= SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
;
449 hWnd
= GetNextWindow(pWinPriv
->hWnd
, GW_HWNDPREV
);
452 if (GetProp(hWnd
, WIN_WINDOW_PROP
)) {
453 if (hWnd
== winGetWindowPriv(pPrevWin
)->hWnd
) {
454 uFlags
|= SWP_NOZORDER
;
458 hWnd
= GetNextWindow(hWnd
, GW_HWNDPREV
);
463 /* No valid sibling - make this window the top window */
464 hInsertAfter
= HWND_TOP
;
465 uFlags
= SWP_NOMOVE
| SWP_NOSIZE
;
468 /* Perform the restacking operation in Windows */
469 SetWindowPos(pWinPriv
->hWnd
, hInsertAfter
, 0, 0, 0, 0, uFlags
);
474 * winCreateWindowsWindow - Create a Windows window associated with an X window
478 winCreateWindowsWindow(WindowPtr pWin
)
487 winPrivScreenPtr pScreenPriv
= pWinPriv
->pScreenPriv
;
490 DWORD dwStyle
, dwExStyle
;
493 winInitMultiWindowClass();
495 winDebug("winCreateWindowsTopLevelWindow - pWin:%08x XID:0x%x \n", pWin
,
498 iX
= pWin
->drawable
.x
+ GetSystemMetrics(SM_XVIRTUALSCREEN
);
499 iY
= pWin
->drawable
.y
+ GetSystemMetrics(SM_YVIRTUALSCREEN
);
501 iWidth
= pWin
->drawable
.width
;
502 iHeight
= pWin
->drawable
.height
;
504 /* If it's an InputOutput window, and so is going to end up being made visible,
505 make sure the window actually ends up somewhere where it will be visible */
506 if (pWin
->drawable
.class != InputOnly
) {
507 if ((iX
< GetSystemMetrics(SM_XVIRTUALSCREEN
)) ||
508 (iX
> GetSystemMetrics(SM_CXVIRTUALSCREEN
)))
511 if ((iY
< GetSystemMetrics(SM_YVIRTUALSCREEN
)) ||
512 (iY
> GetSystemMetrics(SM_CYVIRTUALSCREEN
)))
516 winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth
, iHeight
, iX
,
519 if (winMultiWindowGetTransientFor(pWin
, &daddyId
)) {
521 hFore
= GetForegroundWindow();
522 if (hFore
&& (daddyId
!= (Window
) (INT_PTR
) GetProp(hFore
, WIN_WID_PROP
)))
527 /* Default positions if none specified */
528 if (!winMultiWindowGetWMNormalHints(pWin
, &hints
))
530 if (!(hints
.flags
& (USPosition
| PPosition
)) &&
531 !pWin
->overrideRedirect
) {
537 /* Make it WS_OVERLAPPED in create call since WS_POPUP doesn't support */
538 /* CW_USEDEFAULT, change back to popup after creation */
539 dwStyle
= WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
;
540 dwExStyle
= WS_EX_TOOLWINDOW
;
543 Calculate the window coordinates containing the requested client area,
544 being careful to preseve CW_USEDEFAULT
546 rc
.top
= (iY
!= CW_USEDEFAULT
) ? iY
: 0;
547 rc
.left
= (iX
!= CW_USEDEFAULT
) ? iX
: 0;
548 rc
.bottom
= rc
.top
+ iHeight
;
549 rc
.right
= rc
.left
+ iWidth
;
550 AdjustWindowRectEx(&rc
, dwStyle
, FALSE
, dwExStyle
);
551 if (iY
!= CW_USEDEFAULT
)
553 if (iX
!= CW_USEDEFAULT
)
555 iHeight
= rc
.bottom
- rc
.top
;
556 iWidth
= rc
.right
- rc
.left
;
558 winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth
, iHeight
, iX
,
561 /* Create the window */
562 hWnd
= CreateWindowExA(dwExStyle
, /* Extended styles */
563 WINDOW_CLASS_X
, /* Class name */
564 WINDOW_TITLE_X
, /* Window name */
565 dwStyle
, /* Styles */
566 iX
, /* Horizontal position */
567 iY
, /* Vertical position */
568 iWidth
, /* Right edge */
569 iHeight
, /* Bottom edge */
570 hFore
, /* Null or Parent window if transient */
571 (HMENU
) NULL
, /* No menu */
572 GetModuleHandle(NULL
), /* Instance handle */
573 pWin
); /* ScreenPrivates */
575 ErrorF("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
576 (int) GetLastError());
578 pWinPriv
->hWnd
= hWnd
;
580 /* Change style back to popup, already placed... */
581 SetWindowLongPtr(hWnd
, GWL_STYLE
,
582 WS_POPUP
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
);
583 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
584 SWP_FRAMECHANGED
| SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOSIZE
|
587 /* Adjust the X window to match the window placement we actually got... */
588 winAdjustXWindow(pWin
, hWnd
);
590 /* Make sure it gets the proper system menu for a WS_POPUP, too */
591 GetSystemMenu(hWnd
, TRUE
);
593 /* Cause any .XWinrc menus to be added in main WNDPROC */
594 PostMessage(hWnd
, WM_INIT_SYS_MENU
, 0, 0);
596 SetProp(hWnd
, WIN_WID_PROP
, (HANDLE
) (INT_PTR
) winGetWindowID(pWin
));
598 /* Flag that this Windows window handles its own activation */
599 SetProp(hWnd
, WIN_NEEDMANAGE_PROP
, (HANDLE
) 0);
601 /* Call engine-specific create window procedure */
602 (*pScreenPriv
->pwinFinishCreateWindowsWindow
) (pWin
);
605 Bool winInDestroyWindowsWindow
= FALSE
;
608 * winDestroyWindowsWindow - Destroy a Windows window associated
612 winDestroyWindowsWindow(WindowPtr pWin
)
617 BOOL oldstate
= winInDestroyWindowsWindow
;
621 winDebug("winDestroyWindowsWindow - pWin:%08x XID:0x%x \n", pWin
,
624 /* Bail out if the Windows window handle is invalid */
625 if (pWinPriv
->hWnd
== NULL
)
628 winInDestroyWindowsWindow
= TRUE
;
630 /* Store the info we need to destroy after this window is gone */
631 hIcon
= (HICON
) SendMessage(pWinPriv
->hWnd
, WM_GETICON
, ICON_BIG
, 0);
632 hIconSm
= (HICON
) SendMessage(pWinPriv
->hWnd
, WM_GETICON
, ICON_SMALL
, 0);
634 /* Destroy the Windows window */
635 DestroyWindow(pWinPriv
->hWnd
);
637 /* Null our handle to the Window so referencing it will cause an error */
638 pWinPriv
->hWnd
= NULL
;
640 /* Destroy any icons we created for this window */
641 winDestroyIcon(hIcon
);
642 winDestroyIcon(hIconSm
);
644 #ifdef XWIN_GLX_WINDOWS
645 /* No longer note WGL used on this window */
646 pWinPriv
->fWglUsed
= FALSE
;
649 /* Process all messages on our queue */
650 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
)) {
651 if (g_hDlgDepthChange
== 0 || !IsDialogMessage(g_hDlgDepthChange
, &msg
)) {
652 DispatchMessage(&msg
);
656 winInDestroyWindowsWindow
= oldstate
;
658 winDebug("winDestroyWindowsWindow - done\n");
662 * winUpdateWindowsWindow - Redisplay/redraw a Windows window
663 * associated with an X window
667 winUpdateWindowsWindow(WindowPtr pWin
)
670 HWND hWnd
= pWinPriv
->hWnd
;
672 #if CYGMULTIWINDOW_DEBUG
673 ErrorF("winUpdateWindowsWindow\n");
676 /* Check if the Windows window's parents have been destroyed */
677 if (pWin
->parent
!= NULL
&& pWin
->parent
->parent
== NULL
&& pWin
->mapped
) {
678 /* Create the Windows window if it has been destroyed */
680 winCreateWindowsWindow(pWin
);
681 assert(pWinPriv
->hWnd
!= NULL
);
684 /* Display the window without activating it */
685 if (pWin
->drawable
.class != InputOnly
)
686 ShowWindow(pWinPriv
->hWnd
, SW_SHOWNOACTIVATE
);
688 /* Send first paint message */
689 UpdateWindow(pWinPriv
->hWnd
);
691 else if (hWnd
!= NULL
) {
692 /* Destroy the Windows window if its parents are destroyed */
693 winDestroyWindowsWindow(pWin
);
694 assert(pWinPriv
->hWnd
== NULL
);
697 #if CYGMULTIWINDOW_DEBUG
698 ErrorF("-winUpdateWindowsWindow\n");
707 winGetWindowID(WindowPtr pWin
)
709 WindowIDPairRec wi
= { pWin
, 0 };
710 ClientPtr c
= wClient(pWin
);
713 FindClientResourcesByType(c
, RT_WINDOW
, winFindWindow
, &wi
);
715 #if CYGMULTIWINDOW_DEBUG
716 ErrorF("winGetWindowID - Window ID: %d\n", wi
.id
);
727 winFindWindow(pointer value
, XID id
, pointer cdata
)
729 WindowIDPairPtr wi
= (WindowIDPairPtr
) cdata
;
731 if (value
== wi
->value
) {
737 * winReorderWindowsMultiWindow -
741 winReorderWindowsMultiWindow(void)
744 WindowPtr pWin
= NULL
;
745 WindowPtr pWinSib
= NULL
;
747 static Bool fRestacking
= FALSE
; /* Avoid recusive calls to this function */
748 DWORD dwCurrentProcessID
= GetCurrentProcessId();
749 DWORD dwWindowProcessID
= 0;
751 #if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
752 winTrace("winReorderWindowsMultiWindow\n");
756 /* It is a recusive call so immediately exit */
757 #if CYGWINDOWING_DEBUG
758 ErrorF("winReorderWindowsMultiWindow - "
759 "exit because fRestacking == TRUE\n");
765 /* Loop through top level Window windows, descending in Z order */
766 for (hwnd
= GetTopWindow(NULL
);
767 hwnd
; hwnd
= GetNextWindow(hwnd
, GW_HWNDNEXT
)) {
768 /* Don't take care of other Cygwin/X process's windows */
769 GetWindowThreadProcessId(hwnd
, &dwWindowProcessID
);
771 if (GetProp(hwnd
, WIN_WINDOW_PROP
)
772 && (dwWindowProcessID
== dwCurrentProcessID
)
773 && !IsIconic(hwnd
)) { /* ignore minimized windows */
775 pWin
= GetProp(hwnd
, WIN_WINDOW_PROP
);
777 if (!pWinSib
) { /* 1st window - raise to the top */
780 ConfigureWindow(pWin
, CWStackMode
, vlist
, wClient(pWin
));
782 else { /* 2nd or deeper windows - just below the previous one */
783 vlist
[0] = winGetWindowID(pWinSib
);
786 ConfigureWindow(pWin
, CWSibling
| CWStackMode
,
787 vlist
, wClient(pWin
));
796 * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE
800 winMinimizeWindow(Window id
)
803 winPrivWinPtr pWinPriv
;
805 #ifdef XWIN_MULTIWINDOWEXTWM
806 win32RootlessWindowPtr pRLWinPriv
;
809 ScreenPtr pScreen
= NULL
;
810 winPrivScreenPtr pScreenPriv
= NULL
;
812 #if CYGWINDOWING_DEBUG
813 ErrorF("winMinimizeWindow\n");
816 dixLookupResourceByType((pointer
) &pWin
, id
, RT_WINDOW
, NullClient
,
819 ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__
);
823 pScreen
= pWin
->drawable
.pScreen
;
825 pScreenPriv
= winGetScreenPriv(pScreen
);
827 #ifdef XWIN_MULTIWINDOWEXTWM
828 if (pScreenPriv
&& pScreenPriv
->pScreenInfo
->fInternalWM
) {
830 (win32RootlessWindowPtr
) RootlessFrameForWindow(pWin
, FALSE
);
831 hWnd
= pRLWinPriv
->hWnd
;
838 pWinPriv
= winGetWindowPriv(pWin
);
839 hWnd
= pWinPriv
->hWnd
;
842 ShowWindow(hWnd
, SW_MINIMIZE
);
846 * CopyWindow - See Porting Layer Definition - p. 39
849 winCopyWindowMultiWindow(WindowPtr pWin
, DDXPointRec oldpt
, RegionPtr oldRegion
)
851 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
853 winScreenPriv(pScreen
);
855 #if CYGWINDOWING_DEBUG
856 ErrorF("CopyWindowMultiWindow\n");
858 WIN_UNWRAP(CopyWindow
);
859 (*pScreen
->CopyWindow
) (pWin
, oldpt
, oldRegion
);
860 WIN_WRAP(CopyWindow
, winCopyWindowMultiWindow
);
864 * MoveWindow - See Porting Layer Definition - p. 42
867 winMoveWindowMultiWindow(WindowPtr pWin
, int x
, int y
,
868 WindowPtr pSib
, VTKind kind
)
870 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
872 winScreenPriv(pScreen
);
874 #if CYGWINDOWING_DEBUG
875 ErrorF("MoveWindowMultiWindow to (%d, %d)\n", x
, y
);
878 WIN_UNWRAP(MoveWindow
);
879 (*pScreen
->MoveWindow
) (pWin
, x
, y
, pSib
, kind
);
880 WIN_WRAP(MoveWindow
, winMoveWindowMultiWindow
);
884 * ResizeWindow - See Porting Layer Definition - p. 42
887 winResizeWindowMultiWindow(WindowPtr pWin
, int x
, int y
, unsigned int w
,
888 unsigned int h
, WindowPtr pSib
)
890 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
892 winScreenPriv(pScreen
);
894 #if CYGWINDOWING_DEBUG
895 ErrorF("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x
, y
, w
, h
);
897 WIN_UNWRAP(ResizeWindow
);
898 (*pScreen
->ResizeWindow
) (pWin
, x
, y
, w
, h
, pSib
);
899 WIN_WRAP(ResizeWindow
, winResizeWindowMultiWindow
);
905 * Move and resize X window with respect to corresponding Windows window.
906 * This is called from WM_MOVE/WM_SIZE handlers when the user performs
907 * any windowing operation (move, resize, minimize, maximize, restore).
909 * The functionality is the inverse of winPositionWindowMultiWindow, which
910 * adjusts Windows window with respect to X window.
913 winAdjustXWindow(WindowPtr pWin
, HWND hwnd
)
915 RECT rcDraw
; /* Rect made from pWin->drawable to be adjusted */
916 RECT rcWin
; /* The source: WindowRect from hwnd */
919 LONG dX
, dY
, dW
, dH
, x
, y
;
920 DWORD dwStyle
, dwExStyle
;
922 #define WIDTH(rc) (rc.right - rc.left)
923 #define HEIGHT(rc) (rc.bottom - rc.top)
925 #if CYGWINDOWING_DEBUG
926 ErrorF("winAdjustXWindow\n");
929 if (IsIconic(hwnd
)) {
930 #if CYGWINDOWING_DEBUG
931 ErrorF("\timmediately return because the window is iconized\n");
934 * If the Windows window is minimized, its WindowRect has
935 * meaningless values so we don't adjust X window to it.
939 return ConfigureWindow(pWin
, CWX
| CWY
, vlist
, wClient(pWin
));
942 pDraw
= &pWin
->drawable
;
944 /* Calculate the window rect from the drawable */
945 x
= pDraw
->x
+ GetSystemMetrics(SM_XVIRTUALSCREEN
);
946 y
= pDraw
->y
+ GetSystemMetrics(SM_YVIRTUALSCREEN
);
947 SetRect(&rcDraw
, x
, y
, x
+ pDraw
->width
, y
+ pDraw
->height
);
948 #ifdef CYGMULTIWINDOW_DEBUG
949 winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n",
950 rcDraw
.left
, rcDraw
.top
, rcDraw
.right
, rcDraw
.bottom
,
951 rcDraw
.right
- rcDraw
.left
, rcDraw
.bottom
- rcDraw
.top
);
953 dwExStyle
= GetWindowLongPtr(hwnd
, GWL_EXSTYLE
);
954 dwStyle
= GetWindowLongPtr(hwnd
, GWL_STYLE
);
955 #ifdef CYGMULTIWINDOW_DEBUG
956 winDebug("\tWindowStyle: %08x %08x\n", dwStyle
, dwExStyle
);
958 AdjustWindowRectEx(&rcDraw
, dwStyle
, FALSE
, dwExStyle
);
960 /* The source of adjust */
961 GetWindowRect(hwnd
, &rcWin
);
962 #ifdef CYGMULTIWINDOW_DEBUG
963 winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
964 rcWin
.left
, rcWin
.top
, rcWin
.right
, rcWin
.bottom
,
965 rcWin
.right
- rcWin
.left
, rcWin
.bottom
- rcWin
.top
);
966 winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n",
967 rcDraw
.left
, rcDraw
.top
, rcDraw
.right
, rcDraw
.bottom
,
968 rcDraw
.right
- rcDraw
.left
, rcDraw
.bottom
- rcDraw
.top
);
971 if (EqualRect(&rcDraw
, &rcWin
)) {
972 /* Bail if no adjust is needed */
973 #if CYGWINDOWING_DEBUG
974 ErrorF("\treturn because already adjusted\n");
979 /* Calculate delta values */
980 dX
= rcWin
.left
- rcDraw
.left
;
981 dY
= rcWin
.top
- rcDraw
.top
;
982 dW
= WIDTH(rcWin
) - WIDTH(rcDraw
);
983 dH
= HEIGHT(rcWin
) - HEIGHT(rcDraw
);
987 * We may only need to move (vlist[0] and [1]), or only resize
988 * ([2] and [3]) but currently we set all the parameters and leave
989 * the decision to ConfigureWindow. The reason is code simplicity.
991 vlist
[0] = pDraw
->x
+ dX
- wBorderWidth(pWin
);
992 vlist
[1] = pDraw
->y
+ dY
- wBorderWidth(pWin
);
993 vlist
[2] = pDraw
->width
+ dW
;
994 vlist
[3] = pDraw
->height
+ dH
;
995 #if CYGWINDOWING_DEBUG
996 ErrorF("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist
[0], vlist
[1],
999 return ConfigureWindow(pWin
, CWX
| CWY
| CWWidth
| CWHeight
,
1000 vlist
, wClient(pWin
));