2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
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:
12 *The above copyright notice and this permission notice shall be
13 *included in all copies or substantial portions of the Software.
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.
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.
28 * Authors: Kensuke Matsuzaki
29 * Earle F. Philhower, III
33 #ifdef HAVE_XWIN_CONFIG_H
34 #include <xwin-config.h>
37 #include "dixevents.h"
38 #include "winmultiwindowclass.h"
42 * External global variables
45 extern HWND g_hDlgDepthChange
;
47 extern void winSelectIcons(WindowPtr pWin
, HICON
*pIcon
, HICON
*pSmallIcon
);
50 * Prototypes for local functions
54 winCreateWindowsWindow (WindowPtr pWin
);
57 winDestroyWindowsWindow (WindowPtr pWin
);
60 winUpdateWindowsWindow (WindowPtr pWin
);
63 winFindWindow (pointer value
, XID id
, pointer cdata
);
69 #define MOUSE_POLLING_INTERVAL 500
76 #define SubSend(pWin) \
77 ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
79 #define StrSend(pWin) \
80 ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
82 #define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
86 * CreateWindow - See Porting Layer Definition - p. 37
90 winCreateWindowMultiWindow (WindowPtr pWin
)
93 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
95 winScreenPriv(pScreen
);
97 #if CYGMULTIWINDOW_DEBUG
98 winTrace ("winCreateWindowMultiWindow - pWin: %p\n", pWin
);
101 WIN_UNWRAP(CreateWindow
);
102 fResult
= (*pScreen
->CreateWindow
) (pWin
);
103 WIN_WRAP(CreateWindow
, winCreateWindowMultiWindow
);
105 /* Initialize some privates values */
106 pWinPriv
->hRgn
= NULL
;
107 pWinPriv
->hWnd
= NULL
;
108 pWinPriv
->pScreenPriv
= winGetScreenPriv(pWin
->drawable
.pScreen
);
109 pWinPriv
->fXKilled
= FALSE
;
116 * DestroyWindow - See Porting Layer Definition - p. 37
120 winDestroyWindowMultiWindow (WindowPtr pWin
)
123 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
125 winScreenPriv(pScreen
);
127 #if CYGMULTIWINDOW_DEBUG
128 ErrorF ("winDestroyWindowMultiWindow - pWin: %p\n", pWin
);
131 WIN_UNWRAP(DestroyWindow
);
132 fResult
= (*pScreen
->DestroyWindow
)(pWin
);
133 WIN_WRAP(DestroyWindow
, winDestroyWindowMultiWindow
);
135 /* Flag that the window has been destroyed */
136 pWinPriv
->fXKilled
= TRUE
;
138 /* Kill the MS Windows window associated with this window */
139 winDestroyWindowsWindow (pWin
);
146 * PositionWindow - See Porting Layer Definition - p. 37
148 * This function adjusts the position and size of Windows window
149 * with respect to the underlying X window. This is the inverse
150 * of winAdjustXWindow, which adjusts X window to Windows window.
154 winPositionWindowMultiWindow (WindowPtr pWin
, int x
, int y
)
157 int iX
, iY
, iWidth
, iHeight
;
158 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
160 winScreenPriv(pScreen
);
162 HWND hWnd
= pWinPriv
->hWnd
;
165 #if CYGMULTIWINDOW_DEBUG
172 #if CYGMULTIWINDOW_DEBUG
173 winTrace ("winPositionWindowMultiWindow - pWin: %p\n", pWin
);
176 WIN_UNWRAP(PositionWindow
);
177 fResult
= (*pScreen
->PositionWindow
)(pWin
, x
, y
);
178 WIN_WRAP(PositionWindow
, winPositionWindowMultiWindow
);
180 #if CYGWINDOWING_DEBUG
181 ErrorF ("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n",
185 /* Bail out if the Windows window handle is bad */
188 #if CYGWINDOWING_DEBUG
189 ErrorF ("\timmediately return since hWnd is NULL\n");
194 /* Get the Windows window style and extended style */
195 dwExStyle
= GetWindowLongPtr (hWnd
, GWL_EXSTYLE
);
196 dwStyle
= GetWindowLongPtr (hWnd
, GWL_STYLE
);
198 /* Get the X and Y location of the X window */
199 iX
= pWin
->drawable
.x
+ GetSystemMetrics (SM_XVIRTUALSCREEN
);
200 iY
= pWin
->drawable
.y
+ GetSystemMetrics (SM_YVIRTUALSCREEN
);
202 /* Get the height and width of the X window */
203 iWidth
= pWin
->drawable
.width
;
204 iHeight
= pWin
->drawable
.height
;
206 /* Store the origin, height, and width in a rectangle structure */
207 SetRect (&rcNew
, iX
, iY
, iX
+ iWidth
, iY
+ iHeight
);
209 #if CYGMULTIWINDOW_DEBUG
211 ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n",
212 GetTickCount (), lpRc
->left
, lpRc
->top
, lpRc
->right
, lpRc
->bottom
);
216 * Calculate the required size of the Windows window rectangle,
217 * given the size of the Windows window client area.
219 AdjustWindowRectEx (&rcNew
, dwStyle
, FALSE
, dwExStyle
);
221 /* Get a rectangle describing the old Windows window */
222 GetWindowRect (hWnd
, &rcOld
);
224 #if CYGMULTIWINDOW_DEBUG
225 /* Get a rectangle describing the Windows window client area */
226 GetClientRect (hWnd
, &rcClient
);
229 ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n",
230 GetTickCount (), lpRc
->left
, lpRc
->top
, lpRc
->right
, lpRc
->bottom
);
233 ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n",
234 GetTickCount (), lpRc
->left
, lpRc
->top
, lpRc
->right
, lpRc
->bottom
);
237 ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n",
238 GetTickCount (), lpRc
->left
, lpRc
->top
, lpRc
->right
, lpRc
->bottom
);
241 /* Check if the old rectangle and new rectangle are the same */
242 if (!EqualRect (&rcNew
, &rcOld
))
244 #if CYGMULTIWINDOW_DEBUG
245 ErrorF ("winPositionWindowMultiWindow - Need to move\n");
248 #if CYGWINDOWING_DEBUG
249 ErrorF ("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew
.left
, rcNew
.top
,
250 rcNew
.right
- rcNew
.left
, rcNew
.bottom
- rcNew
.top
);
252 /* Change the position and dimensions of the Windows window */
254 rcNew
.left
, rcNew
.top
,
255 rcNew
.right
- rcNew
.left
, rcNew
.bottom
- rcNew
.top
,
260 #if CYGMULTIWINDOW_DEBUG
261 ErrorF ("winPositionWindowMultiWindow - Not need to move\n");
270 * ChangeWindowAttributes - See Porting Layer Definition - p. 37
274 winChangeWindowAttributesMultiWindow (WindowPtr pWin
, unsigned long mask
)
277 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
279 winScreenPriv(pScreen
);
281 #if CYGMULTIWINDOW_DEBUG
282 ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin
);
285 WIN_UNWRAP(ChangeWindowAttributes
);
286 fResult
= (*pScreen
->ChangeWindowAttributes
)(pWin
, mask
);
287 WIN_WRAP(ChangeWindowAttributes
, winChangeWindowAttributesMultiWindow
);
290 * NOTE: We do not currently need to do anything here.
298 * UnmapWindow - See Porting Layer Definition - p. 37
299 * Also referred to as UnrealizeWindow
303 winUnmapWindowMultiWindow (WindowPtr pWin
)
306 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
308 winScreenPriv(pScreen
);
310 #if CYGMULTIWINDOW_DEBUG
311 ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin
);
314 WIN_UNWRAP(UnrealizeWindow
);
315 fResult
= (*pScreen
->UnrealizeWindow
)(pWin
);
316 WIN_WRAP(UnrealizeWindow
, winUnmapWindowMultiWindow
);
318 /* Flag that the window has been killed */
319 pWinPriv
->fXKilled
= TRUE
;
321 /* Destroy the Windows window associated with this X window */
322 winDestroyWindowsWindow (pWin
);
329 * MapWindow - See Porting Layer Definition - p. 37
330 * Also referred to as RealizeWindow
334 winMapWindowMultiWindow (WindowPtr pWin
)
337 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
339 winScreenPriv(pScreen
);
341 #if CYGMULTIWINDOW_DEBUG
342 ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin
);
345 WIN_UNWRAP(RealizeWindow
);
346 fResult
= (*pScreen
->RealizeWindow
)(pWin
);
347 WIN_WRAP(RealizeWindow
, winMapWindowMultiWindow
);
349 /* Flag that this window has not been destroyed */
350 pWinPriv
->fXKilled
= FALSE
;
352 /* Refresh/redisplay the Windows window associated with this X window */
353 winUpdateWindowsWindow (pWin
);
356 /* Update the Windows window's shape */
357 winReshapeMultiWindow (pWin
);
358 winUpdateRgnMultiWindow (pWin
);
366 * ReparentWindow - See Porting Layer Definition - p. 42
370 winReparentWindowMultiWindow (WindowPtr pWin
, WindowPtr pPriorParent
)
372 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
374 winScreenPriv(pScreen
);
376 #if CYGMULTIWINDOW_DEBUG
377 ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin
);
380 WIN_UNWRAP(ReparentWindow
);
381 if (pScreen
->ReparentWindow
)
382 (*pScreen
->ReparentWindow
)(pWin
, pPriorParent
);
383 WIN_WRAP(ReparentWindow
, winReparentWindowMultiWindow
);
385 /* Update the Windows window associated with this X window */
386 winUpdateWindowsWindow (pWin
);
391 * RestackWindow - Shuffle the z-order of a window
395 winRestackWindowMultiWindow (WindowPtr pWin
, WindowPtr pOldNextSib
)
401 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
403 winScreenPriv(pScreen
);
405 #if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
406 winTrace ("winRestackMultiWindow - %08x\n", pWin
);
409 WIN_UNWRAP(RestackWindow
);
410 if (pScreen
->RestackWindow
)
411 (*pScreen
->RestackWindow
)(pWin
, pOldNextSib
);
412 WIN_WRAP(RestackWindow
, winRestackWindowMultiWindow
);
416 * Calling winReorderWindowsMultiWindow here means our window manager
417 * (i.e. Windows Explorer) has initiative to determine Z order.
419 if (pWin
->nextSib
!= pOldNextSib
)
420 winReorderWindowsMultiWindow ();
422 /* Bail out if no window privates or window handle is invalid */
423 if (!pWinPriv
|| !pWinPriv
->hWnd
)
426 /* Get a pointer to our previous sibling window */
427 pPrevWin
= pWin
->prevSib
;
430 * Look for a sibling window with
431 * valid privates and window handle
434 && !winGetWindowPriv(pPrevWin
)
435 && !winGetWindowPriv(pPrevWin
)->hWnd
)
436 pPrevWin
= pPrevWin
->prevSib
;
438 /* Check if we found a valid sibling */
441 /* Valid sibling - get handle to insert window after */
442 hInsertAfter
= winGetWindowPriv(pPrevWin
)->hWnd
;
443 uFlags
= SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
;
445 hWnd
= GetNextWindow (pWinPriv
->hWnd
, GW_HWNDPREV
);
449 if (GetProp (hWnd
, WIN_WINDOW_PROP
))
451 if (hWnd
== winGetWindowPriv(pPrevWin
)->hWnd
)
453 uFlags
|= SWP_NOZORDER
;
457 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
,
479 * winCreateWindowsWindow - Create a Windows window associated with an X window
483 winCreateWindowsWindow (WindowPtr pWin
)
493 #define CLASS_NAME_LENGTH 512
494 char pszClass
[CLASS_NAME_LENGTH
], pszWindowID
[12];
495 char *res_name
, *res_class
, *res_role
;
496 static int s_iWindowID
= 0;
497 winPrivScreenPtr pScreenPriv
= pWinPriv
->pScreenPriv
;
500 #if CYGMULTIWINDOW_DEBUG
501 ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin
);
504 iX
= pWin
->drawable
.x
+ GetSystemMetrics (SM_XVIRTUALSCREEN
);
505 iY
= pWin
->drawable
.y
+ GetSystemMetrics (SM_YVIRTUALSCREEN
);
507 /* Default positions if none specified */
508 if (!winMultiWindowGetWMNormalHints(pWin
, &hints
))
510 if ( !(hints
.flags
& (USPosition
|PPosition
)) &&
511 !winMultiWindowGetTransientFor (pWin
, NULL
) &&
512 !pWin
->overrideRedirect
)
518 iWidth
= pWin
->drawable
.width
;
519 iHeight
= pWin
->drawable
.height
;
521 winSelectIcons(pWin
, &hIcon
, &hIconSmall
);
523 /* Set standard class name prefix so we can identify window easily */
524 strncpy (pszClass
, WINDOW_CLASS_X
, sizeof(pszClass
));
526 if (winMultiWindowGetClassHint (pWin
, &res_name
, &res_class
))
528 strncat (pszClass
, "-", 1);
529 strncat (pszClass
, res_name
, CLASS_NAME_LENGTH
- strlen (pszClass
));
530 strncat (pszClass
, "-", 1);
531 strncat (pszClass
, res_class
, CLASS_NAME_LENGTH
- strlen (pszClass
));
533 /* Check if a window class is provided by the WM_WINDOW_ROLE property,
534 * if not use the WM_CLASS information.
535 * For further information see:
536 * http://tronche.com/gui/x/icccm/sec-5.html
538 if (winMultiWindowGetWindowRole (pWin
, &res_role
) )
540 strcat (pszClass
, "-");
541 strcat (pszClass
, res_role
);
549 /* Add incrementing window ID to make unique class name */
550 snprintf (pszWindowID
, sizeof(pszWindowID
), "-%x", s_iWindowID
++);
551 pszWindowID
[sizeof(pszWindowID
)-1] = 0;
552 strcat (pszClass
, pszWindowID
);
554 #if CYGMULTIWINDOW_DEBUG
555 ErrorF ("winCreateWindowsWindow - Creating class: %s\n", pszClass
);
558 /* Setup our window class */
559 wc
.cbSize
= sizeof(wc
);
560 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
561 wc
.lpfnWndProc
= winTopLevelWindowProc
;
564 wc
.hInstance
= g_hInstance
;
566 wc
.hIconSm
= hIconSmall
;
568 wc
.hbrBackground
= (HBRUSH
) GetStockObject (WHITE_BRUSH
);
569 wc
.lpszMenuName
= NULL
;
570 wc
.lpszClassName
= pszClass
;
571 RegisterClassEx (&wc
);
573 /* Create the window */
574 /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */
575 /* CW_USEDEFAULT, change back to popup after creation */
576 hWnd
= CreateWindowExA (WS_EX_TOOLWINDOW
, /* Extended styles */
577 pszClass
, /* Class name */
578 WINDOW_TITLE_X
, /* Window name */
579 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
,
580 iX
, /* Horizontal position */
581 iY
, /* Vertical position */
582 iWidth
, /* Right edge */
583 iHeight
, /* Bottom edge */
584 (HWND
) NULL
, /* No parent or owner window */
585 (HMENU
) NULL
, /* No menu */
586 GetModuleHandle (NULL
), /* Instance handle */
587 pWin
); /* ScreenPrivates */
590 ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
591 (int) GetLastError ());
594 /* Change style back to popup, already placed... */
595 SetWindowLong (hWnd
, GWL_STYLE
, WS_POPUP
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
);
596 SetWindowPos (hWnd
, 0, 0, 0, 0, 0,
597 SWP_FRAMECHANGED
| SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
598 /* Make sure it gets the proper system menu for a WS_POPUP, too */
599 GetSystemMenu (hWnd
, TRUE
);
601 pWinPriv
->hWnd
= hWnd
;
603 /* Cause any .XWinrc menus to be added in main WNDPROC */
604 PostMessage (hWnd
, WM_INIT_SYS_MENU
, 0, 0);
606 SetProp (pWinPriv
->hWnd
, WIN_WID_PROP
, (HANDLE
) winGetWindowID(pWin
));
608 /* Flag that this Windows window handles its own activation */
609 SetProp (pWinPriv
->hWnd
, WIN_NEEDMANAGE_PROP
, (HANDLE
) 0);
611 /* Call engine-specific create window procedure */
612 (*pScreenPriv
->pwinFinishCreateWindowsWindow
) (pWin
);
616 Bool winInDestroyWindowsWindow
= FALSE
;
618 * winDestroyWindowsWindow - Destroy a Windows window associated
622 winDestroyWindowsWindow (WindowPtr pWin
)
631 BOOL oldstate
= winInDestroyWindowsWindow
;
633 #if CYGMULTIWINDOW_DEBUG
634 ErrorF ("winDestroyWindowsWindow\n");
637 /* Bail out if the Windows window handle is invalid */
638 if (pWinPriv
->hWnd
== NULL
)
641 winInDestroyWindowsWindow
= TRUE
;
643 /* Store the info we need to destroy after this window is gone */
644 hInstance
= (HINSTANCE
) GetClassLong (pWinPriv
->hWnd
, GCL_HMODULE
);
645 hiconClass
= (HICON
) GetClassLong (pWinPriv
->hWnd
, GCL_HICON
);
646 hiconSmClass
= (HICON
) GetClassLong (pWinPriv
->hWnd
, GCL_HICONSM
);
647 iReturn
= GetClassName (pWinPriv
->hWnd
, pszClass
, 512);
649 SetProp (pWinPriv
->hWnd
, WIN_WINDOW_PROP
, NULL
);
650 /* Destroy the Windows window */
651 DestroyWindow (pWinPriv
->hWnd
);
653 /* Null our handle to the Window so referencing it will cause an error */
654 pWinPriv
->hWnd
= NULL
;
656 /* Process all messages on our queue */
657 while (PeekMessage (&msg
, NULL
, 0, 0, PM_REMOVE
))
659 if (g_hDlgDepthChange
== 0 || !IsDialogMessage (g_hDlgDepthChange
, &msg
))
661 DispatchMessage (&msg
);
665 /* Only if we were able to get the name */
668 #if CYGMULTIWINDOW_DEBUG
669 ErrorF ("winDestroyWindowsWindow - Unregistering %s: ", pszClass
);
671 iReturn
= UnregisterClass (pszClass
, hInstance
);
673 #if CYGMULTIWINDOW_DEBUG
674 ErrorF ("winDestroyWindowsWindow - %d Deleting Icon: ", iReturn
);
677 winDestroyIcon(hiconClass
);
678 winDestroyIcon(hiconSmClass
);
681 winInDestroyWindowsWindow
= oldstate
;
683 #if CYGMULTIWINDOW_DEBUG
684 ErrorF ("-winDestroyWindowsWindow\n");
690 * winUpdateWindowsWindow - Redisplay/redraw a Windows window
691 * associated with an X window
695 winUpdateWindowsWindow (WindowPtr pWin
)
698 HWND hWnd
= pWinPriv
->hWnd
;
700 #if CYGMULTIWINDOW_DEBUG
701 ErrorF ("winUpdateWindowsWindow\n");
704 /* Check if the Windows window's parents have been destroyed */
705 if (pWin
->parent
!= NULL
706 && pWin
->parent
->parent
== NULL
709 /* Create the Windows window if it has been destroyed */
712 winCreateWindowsWindow (pWin
);
713 assert (pWinPriv
->hWnd
!= NULL
);
716 /* Display the window without activating it */
717 ShowWindow (pWinPriv
->hWnd
, SW_SHOWNOACTIVATE
);
719 /* Send first paint message */
720 UpdateWindow (pWinPriv
->hWnd
);
722 else if (hWnd
!= NULL
)
724 /* Destroy the Windows window if its parents are destroyed */
725 winDestroyWindowsWindow (pWin
);
726 assert (pWinPriv
->hWnd
== NULL
);
729 #if CYGMULTIWINDOW_DEBUG
730 ErrorF ("-winUpdateWindowsWindow\n");
740 winGetWindowID (WindowPtr pWin
)
742 WindowIDPairRec wi
= {pWin
, 0};
743 ClientPtr c
= wClient(pWin
);
746 FindClientResourcesByType (c
, RT_WINDOW
, winFindWindow
, &wi
);
748 #if CYGMULTIWINDOW_DEBUG
749 ErrorF ("winGetWindowID - Window ID: %d\n", wi
.id
);
761 winFindWindow (pointer value
, XID id
, pointer cdata
)
763 WindowIDPairPtr wi
= (WindowIDPairPtr
)cdata
;
765 if (value
== wi
->value
)
773 * winReorderWindowsMultiWindow -
777 winReorderWindowsMultiWindow (void)
780 WindowPtr pWin
= NULL
;
781 WindowPtr pWinSib
= NULL
;
783 static Bool fRestacking
= FALSE
; /* Avoid recusive calls to this function */
784 DWORD dwCurrentProcessID
= GetCurrentProcessId ();
785 DWORD dwWindowProcessID
= 0;
787 #if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
788 winTrace ("winReorderWindowsMultiWindow\n");
793 /* It is a recusive call so immediately exit */
794 #if CYGWINDOWING_DEBUG
795 ErrorF ("winReorderWindowsMultiWindow - "
796 "exit because fRestacking == TRUE\n");
802 /* Loop through top level Window windows, descending in Z order */
803 for ( hwnd
= GetTopWindow (NULL
);
805 hwnd
= GetNextWindow (hwnd
, GW_HWNDNEXT
) )
807 /* Don't take care of other Cygwin/X process's windows */
808 GetWindowThreadProcessId (hwnd
, &dwWindowProcessID
);
810 if ( GetProp (hwnd
, WIN_WINDOW_PROP
)
811 && (dwWindowProcessID
== dwCurrentProcessID
)
812 && !IsIconic (hwnd
) ) /* ignore minimized windows */
815 pWin
= GetProp (hwnd
, WIN_WINDOW_PROP
);
818 { /* 1st window - raise to the top */
821 ConfigureWindow (pWin
, CWStackMode
, vlist
, wClient(pWin
));
824 { /* 2nd or deeper windows - just below the previous one */
825 vlist
[0] = winGetWindowID (pWinSib
);
828 ConfigureWindow (pWin
, CWSibling
| CWStackMode
,
829 vlist
, wClient(pWin
));
839 * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE
843 winMinimizeWindow (Window id
)
846 winPrivWinPtr pWinPriv
;
847 #ifdef XWIN_MULTIWINDOWEXTWM
848 win32RootlessWindowPtr pRLWinPriv
;
851 ScreenPtr pScreen
= NULL
;
852 winPrivScreenPtr pScreenPriv
= NULL
;
853 winScreenInfo
*pScreenInfo
= NULL
;
855 #if CYGWINDOWING_DEBUG
856 ErrorF ("winMinimizeWindow\n");
859 pWin
= LookupIDByType (id
, RT_WINDOW
);
862 ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__
);
866 pScreen
= pWin
->drawable
.pScreen
;
867 if (pScreen
) pScreenPriv
= winGetScreenPriv(pScreen
);
868 if (pScreenPriv
) pScreenInfo
= pScreenPriv
->pScreenInfo
;
870 #ifdef XWIN_MULTIWINDOWEXTWM
871 if (pScreenPriv
&& pScreenInfo
->fInternalWM
)
873 pRLWinPriv
= (win32RootlessWindowPtr
) RootlessFrameForWindow (pWin
, FALSE
);
874 hWnd
= pRLWinPriv
->hWnd
;
881 pWinPriv
= winGetWindowPriv (pWin
);
882 hWnd
= pWinPriv
->hWnd
;
885 ShowWindow (hWnd
, SW_MINIMIZE
);
890 * CopyWindow - See Porting Layer Definition - p. 39
893 winCopyWindowMultiWindow (WindowPtr pWin
, DDXPointRec oldpt
,
896 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
898 winScreenPriv(pScreen
);
900 #if CYGWINDOWING_DEBUG
901 ErrorF ("CopyWindowMultiWindow\n");
903 WIN_UNWRAP(CopyWindow
);
904 (*pScreen
->CopyWindow
)(pWin
, oldpt
, oldRegion
);
905 WIN_WRAP(CopyWindow
, winCopyWindowMultiWindow
);
910 * MoveWindow - See Porting Layer Definition - p. 42
913 winMoveWindowMultiWindow (WindowPtr pWin
, int x
, int y
,
914 WindowPtr pSib
, VTKind kind
)
916 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
918 winScreenPriv(pScreen
);
920 #if CYGWINDOWING_DEBUG
921 ErrorF ("MoveWindowMultiWindow to (%d, %d)\n", x
, y
);
924 WIN_UNWRAP(MoveWindow
);
925 (*pScreen
->MoveWindow
)(pWin
, x
, y
, pSib
, kind
);
926 WIN_WRAP(MoveWindow
, winMoveWindowMultiWindow
);
931 * ResizeWindow - See Porting Layer Definition - p. 42
934 winResizeWindowMultiWindow (WindowPtr pWin
, int x
, int y
, unsigned int w
,
935 unsigned int h
, WindowPtr pSib
)
937 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
939 winScreenPriv(pScreen
);
941 #if CYGWINDOWING_DEBUG
942 ErrorF ("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x
, y
, w
, h
);
944 WIN_UNWRAP(ResizeWindow
);
945 (*pScreen
->ResizeWindow
)(pWin
, x
, y
, w
, h
, pSib
);
946 WIN_WRAP(ResizeWindow
, winResizeWindowMultiWindow
);
953 * Move and resize X window with respect to corresponding Windows window.
954 * This is called from WM_MOVE/WM_SIZE handlers when the user performs
955 * any windowing operation (move, resize, minimize, maximize, restore).
957 * The functionality is the inverse of winPositionWindowMultiWindow, which
958 * adjusts Windows window with respect to X window.
961 winAdjustXWindow (WindowPtr pWin
, HWND hwnd
)
963 RECT rcDraw
; /* Rect made from pWin->drawable to be adjusted */
964 RECT rcWin
; /* The source: WindowRect from hwnd */
967 LONG dX
, dY
, dW
, dH
, x
, y
;
968 DWORD dwStyle
, dwExStyle
;
970 #define WIDTH(rc) (rc.right - rc.left)
971 #define HEIGHT(rc) (rc.bottom - rc.top)
973 #if CYGWINDOWING_DEBUG
974 ErrorF ("winAdjustXWindow\n");
979 #if CYGWINDOWING_DEBUG
980 ErrorF ("\timmediately return because the window is iconized\n");
983 * If the Windows window is minimized, its WindowRect has
984 * meaningless values so we don't adjust X window to it.
988 return ConfigureWindow (pWin
, CWX
| CWY
, vlist
, wClient(pWin
));
991 pDraw
= &pWin
->drawable
;
993 /* Calculate the window rect from the drawable */
994 x
= pDraw
->x
+ GetSystemMetrics (SM_XVIRTUALSCREEN
);
995 y
= pDraw
->y
+ GetSystemMetrics (SM_YVIRTUALSCREEN
);
996 SetRect (&rcDraw
, x
, y
, x
+ pDraw
->width
, y
+ pDraw
->height
);
997 #ifdef CYGMULTIWINDOW_DEBUG
998 winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n",
999 rcDraw
.left
, rcDraw
.top
, rcDraw
.right
, rcDraw
.bottom
,
1000 rcDraw
.right
- rcDraw
.left
, rcDraw
.bottom
- rcDraw
.top
);
1002 dwExStyle
= GetWindowLongPtr (hwnd
, GWL_EXSTYLE
);
1003 dwStyle
= GetWindowLongPtr (hwnd
, GWL_STYLE
);
1004 #ifdef CYGMULTIWINDOW_DEBUG
1005 winDebug("\tWindowStyle: %08x %08x\n", dwStyle
, dwExStyle
);
1007 AdjustWindowRectEx (&rcDraw
, dwStyle
, FALSE
, dwExStyle
);
1009 /* The source of adjust */
1010 GetWindowRect (hwnd
, &rcWin
);
1011 #ifdef CYGMULTIWINDOW_DEBUG
1012 winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
1013 rcWin
.left
, rcWin
.top
, rcWin
.right
, rcWin
.bottom
,
1014 rcWin
.right
- rcWin
.left
, rcWin
.bottom
- rcWin
.top
);
1015 winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n",
1016 rcDraw
.left
, rcDraw
.top
, rcDraw
.right
, rcDraw
.bottom
,
1017 rcDraw
.right
- rcDraw
.left
, rcDraw
.bottom
- rcDraw
.top
);
1020 if (EqualRect (&rcDraw
, &rcWin
)) {
1021 /* Bail if no adjust is needed */
1022 #if CYGWINDOWING_DEBUG
1023 ErrorF ("\treturn because already adjusted\n");
1028 /* Calculate delta values */
1029 dX
= rcWin
.left
- rcDraw
.left
;
1030 dY
= rcWin
.top
- rcDraw
.top
;
1031 dW
= WIDTH(rcWin
) - WIDTH(rcDraw
);
1032 dH
= HEIGHT(rcWin
) - HEIGHT(rcDraw
);
1036 * We may only need to move (vlist[0] and [1]), or only resize
1037 * ([2] and [3]) but currently we set all the parameters and leave
1038 * the decision to ConfigureWindow. The reason is code simplicity.
1040 vlist
[0] = pDraw
->x
+ dX
- wBorderWidth(pWin
);
1041 vlist
[1] = pDraw
->y
+ dY
- wBorderWidth(pWin
);
1042 vlist
[2] = pDraw
->width
+ dW
;
1043 vlist
[3] = pDraw
->height
+ dH
;
1044 #if CYGWINDOWING_DEBUG
1045 ErrorF ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist
[0], vlist
[1],
1046 vlist
[2], vlist
[3]);
1048 return ConfigureWindow (pWin
, CWX
| CWY
| CWWidth
| CWHeight
,
1049 vlist
, wClient(pWin
));