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"
44 * External global variables
47 extern Bool g_fCursor
;
48 extern Bool g_fKeyboardHookLL
;
49 extern Bool g_fSoftwareCursor
;
50 extern Bool g_fButton
[3];
57 static UINT_PTR g_uipMousePollingTimerID
= 0;
64 #define MOUSE_POLLING_INTERVAL 500
65 #define WIN_MULTIWINDOW_SHAPE YES
69 * ConstrainSize - Taken from TWM sources - Respects hints for sizing
71 #define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
73 ConstrainSize (WinXSizeHints hints
, int *widthp
, int *heightp
)
75 int minWidth
, minHeight
, maxWidth
, maxHeight
, xinc
, yinc
, delta
;
76 int baseWidth
, baseHeight
;
77 int dwidth
= *widthp
, dheight
= *heightp
;
79 if (hints
.flags
& PMinSize
)
81 minWidth
= hints
.min_width
;
82 minHeight
= hints
.min_height
;
84 else if (hints
.flags
& PBaseSize
)
86 minWidth
= hints
.base_width
;
87 minHeight
= hints
.base_height
;
90 minWidth
= minHeight
= 1;
92 if (hints
.flags
& PBaseSize
)
94 baseWidth
= hints
.base_width
;
95 baseHeight
= hints
.base_height
;
97 else if (hints
.flags
& PMinSize
)
99 baseWidth
= hints
.min_width
;
100 baseHeight
= hints
.min_height
;
103 baseWidth
= baseHeight
= 0;
105 if (hints
.flags
& PMaxSize
)
107 maxWidth
= hints
.max_width
;
108 maxHeight
= hints
.max_height
;
116 if (hints
.flags
& PResizeInc
)
118 xinc
= hints
.width_inc
;
119 yinc
= hints
.height_inc
;
125 * First, clamp to min and max values
127 if (dwidth
< minWidth
)
129 if (dheight
< minHeight
)
132 if (dwidth
> maxWidth
)
134 if (dheight
> maxHeight
)
138 * Second, fit to base + N * inc
140 dwidth
= ((dwidth
- baseWidth
) / xinc
* xinc
) + baseWidth
;
141 dheight
= ((dheight
- baseHeight
) / yinc
* yinc
) + baseHeight
;
144 * Third, adjust for aspect ratio
148 * The math looks like this:
150 * minAspectX dwidth maxAspectX
151 * ---------- <= ------- <= ----------
152 * minAspectY dheight maxAspectY
154 * If that is multiplied out, then the width and height are
155 * invalid in the following situations:
157 * minAspectX * dheight > minAspectY * dwidth
158 * maxAspectX * dheight < maxAspectY * dwidth
162 if (hints
.flags
& PAspect
)
164 if (hints
.min_aspect
.x
* dheight
> hints
.min_aspect
.y
* dwidth
)
166 delta
= makemult(hints
.min_aspect
.x
* dheight
/ hints
.min_aspect
.y
- dwidth
, xinc
);
167 if (dwidth
+ delta
<= maxWidth
)
171 delta
= makemult(dheight
- dwidth
*hints
.min_aspect
.y
/hints
.min_aspect
.x
, yinc
);
172 if (dheight
- delta
>= minHeight
)
177 if (hints
.max_aspect
.x
* dheight
< hints
.max_aspect
.y
* dwidth
)
179 delta
= makemult(dwidth
* hints
.max_aspect
.y
/ hints
.max_aspect
.x
- dheight
, yinc
);
180 if (dheight
+ delta
<= maxHeight
)
184 delta
= makemult(dwidth
- hints
.max_aspect
.x
*dheight
/hints
.max_aspect
.y
, xinc
);
185 if (dwidth
- delta
>= minWidth
)
191 /* Return computed values */
200 * ValidateSizing - Ensures size request respects hints
203 ValidateSizing (HWND hwnd
, WindowPtr pWin
,
204 WPARAM wParam
, LPARAM lParam
)
206 WinXSizeHints sizeHints
;
210 /* Invalid input checking */
211 if (pWin
==NULL
|| lParam
==0)
214 /* No size hints, no checking */
215 if (!winMultiWindowGetWMNormalHints (pWin
, &sizeHints
))
218 /* Avoid divide-by-zero */
219 if (sizeHints
.flags
& PResizeInc
)
221 if (sizeHints
.width_inc
== 0) sizeHints
.width_inc
= 1;
222 if (sizeHints
.height_inc
== 0) sizeHints
.height_inc
= 1;
225 rect
= (RECT
*)lParam
;
227 iWidth
= rect
->right
- rect
->left
;
228 iHeight
= rect
->bottom
- rect
->top
;
230 /* Now remove size of any borders */
231 iWidth
-= 2 * GetSystemMetrics(SM_CXSIZEFRAME
);
232 iHeight
-= (GetSystemMetrics(SM_CYCAPTION
)
233 + 2 * GetSystemMetrics(SM_CYSIZEFRAME
));
236 /* Constrain the size to legal values */
237 ConstrainSize (sizeHints
, &iWidth
, &iHeight
);
239 /* Add back the borders */
240 iWidth
+= 2 * GetSystemMetrics(SM_CXSIZEFRAME
);
241 iHeight
+= (GetSystemMetrics(SM_CYCAPTION
)
242 + 2 * GetSystemMetrics(SM_CYSIZEFRAME
));
244 /* Adjust size according to where we're dragging from */
249 case WMSZ_BOTTOMRIGHT
:
251 rect
->right
= rect
->left
+ iWidth
;
254 rect
->left
= rect
->right
- iWidth
;
259 case WMSZ_BOTTOMRIGHT
:
260 case WMSZ_BOTTOMLEFT
:
263 rect
->bottom
= rect
->top
+ iHeight
;
266 rect
->top
= rect
->bottom
- iHeight
;
272 extern Bool winInDestroyWindowsWindow
;
273 static Bool winInRaiseWindow
= FALSE
;
274 static void winRaiseWindow(WindowPtr pWin
)
276 if (!winInDestroyWindowsWindow
&& !winInRaiseWindow
)
278 BOOL oldstate
= winInRaiseWindow
;
279 winInRaiseWindow
= TRUE
;
280 /* Call configure window directly to make sure it gets processed
283 XID vlist
[1] = { 0 };
284 ConfigureWindow(pWin
, CWStackMode
, vlist
, serverClient
);
285 winInRaiseWindow
= oldstate
;
291 * winTopLevelWindowProc - Window procedure for all top-level Windows windows.
295 winTopLevelWindowProc (HWND hwnd
, UINT message
,
296 WPARAM wParam
, LPARAM lParam
)
301 WindowPtr pWin
= NULL
;
302 winPrivWinPtr pWinPriv
= NULL
;
303 ScreenPtr s_pScreen
= NULL
;
304 winPrivScreenPtr s_pScreenPriv
= NULL
;
305 winScreenInfo
*s_pScreenInfo
= NULL
;
306 HWND hwndScreen
= NULL
;
307 DrawablePtr pDraw
= NULL
;
308 winWMMessageRec wmMsg
;
309 Bool fWMMsgInitialized
= FALSE
;
310 static Bool s_fTracking
= FALSE
;
311 Bool needRestack
= FALSE
;
315 winDebugWin32Message("winTopLevelWindowProc", hwnd
, message
, wParam
, lParam
);
318 /* Check if the Windows window property for our X window pointer is valid */
319 if ((pWin
= GetProp (hwnd
, WIN_WINDOW_PROP
)) != NULL
)
321 /* Our X window pointer is valid */
323 /* Get pointers to the drawable and the screen */
324 pDraw
= &pWin
->drawable
;
325 s_pScreen
= pWin
->drawable
.pScreen
;
327 /* Get a pointer to our window privates */
328 pWinPriv
= winGetWindowPriv(pWin
);
330 /* Get pointers to our screen privates and screen info */
331 s_pScreenPriv
= pWinPriv
->pScreenPriv
;
332 s_pScreenInfo
= s_pScreenPriv
->pScreenInfo
;
334 /* Get the handle for our screen-sized window */
335 hwndScreen
= s_pScreenPriv
->hwndScreen
;
339 wmMsg
.hwndWindow
= hwnd
;
340 wmMsg
.iWindow
= (Window
)GetProp (hwnd
, WIN_WID_PROP
);
344 wmMsg
.iWidth
= pDraw
->width
;
345 wmMsg
.iHeight
= pDraw
->height
;
347 fWMMsgInitialized
= TRUE
;
351 * Print some debugging information
354 ErrorF ("hWnd %08X\n", hwnd
);
355 ErrorF ("pWin %08X\n", pWin
);
356 ErrorF ("pDraw %08X\n", pDraw
);
357 ErrorF ("\ttype %08X\n", pWin
->drawable
.type
);
358 ErrorF ("\tclass %08X\n", pWin
->drawable
.class);
359 ErrorF ("\tdepth %08X\n", pWin
->drawable
.depth
);
360 ErrorF ("\tbitsPerPixel %08X\n", pWin
->drawable
.bitsPerPixel
);
361 ErrorF ("\tid %08X\n", pWin
->drawable
.id
);
362 ErrorF ("\tx %08X\n", pWin
->drawable
.x
);
363 ErrorF ("\ty %08X\n", pWin
->drawable
.y
);
364 ErrorF ("\twidth %08X\n", pWin
->drawable
.width
);
365 ErrorF ("\thenght %08X\n", pWin
->drawable
.height
);
366 ErrorF ("\tpScreen %08X\n", pWin
->drawable
.pScreen
);
367 ErrorF ("\tserialNumber %08X\n", pWin
->drawable
.serialNumber
);
368 ErrorF ("g_iWindowPrivateIndex %d\n", g_iWindowPrivateIndex
);
369 ErrorF ("pWinPriv %08X\n", pWinPriv
);
370 ErrorF ("s_pScreenPriv %08X\n", s_pScreenPriv
);
371 ErrorF ("s_pScreenInfo %08X\n", s_pScreenInfo
);
372 ErrorF ("hwndScreen %08X\n", hwndScreen
);
376 /* Branch on message type */
384 (HANDLE
)((LPCREATESTRUCT
) lParam
)->lpCreateParams
);
389 (HANDLE
)winGetWindowID (((LPCREATESTRUCT
) lParam
)->lpCreateParams
));
392 * Make X windows' Z orders sync with Windows windows because
393 * there can be AlwaysOnTop windows overlapped on the window
394 * currently being created.
396 winReorderWindowsMultiWindow ();
398 /* Fix a 'round title bar corner background should be transparent not black' problem when first painted */
401 GetWindowRect(hwnd
, &rWindow
);
402 hRgnWindow
= CreateRectRgnIndirect(&rWindow
);
403 SetWindowRgn (hwnd
, hRgnWindow
, TRUE
);
404 DeleteObject(hRgnWindow
);
408 case WM_INIT_SYS_MENU
:
410 * Add whatever the setup file wants to for this window
412 SetupSysMenu ((unsigned long)hwnd
);
417 * Any window menu items go through here
419 if (HandleCustomWM_COMMAND ((unsigned long)hwnd
, LOWORD(wParam
)))
421 /* Don't pass customized menus to DefWindowProc */
424 if (wParam
== SC_RESTORE
|| wParam
== SC_MAXIMIZE
)
426 WINDOWPLACEMENT wndpl
;
427 wndpl
.length
= sizeof(wndpl
);
428 if (GetWindowPlacement(hwnd
, &wndpl
) && wndpl
.showCmd
== SW_SHOWMINIMIZED
)
434 /* Checks/Unchecks any menu items before they are displayed */
435 HandleCustomWM_INITMENU ((unsigned long)hwnd
, wParam
);
439 /* Only paint if our window handle is valid */
440 if (hwndScreen
== NULL
)
443 /* BeginPaint gives us an hdc that clips to the invalidated region */
444 hdcUpdate
= BeginPaint (hwnd
, &ps
);
445 /* Avoid the BitBlt's if the PAINTSTRUCT is bogus */
446 if (ps
.rcPaint
.right
==0 && ps
.rcPaint
.bottom
==0 && ps
.rcPaint
.left
==0 && ps
.rcPaint
.top
==0)
448 EndPaint (hwnd
, &ps
);
452 /* Try to copy from the shadow buffer */
453 if (!BitBlt (hdcUpdate
,
454 ps
.rcPaint
.left
, ps
.rcPaint
.top
,
455 ps
.rcPaint
.right
- ps
.rcPaint
.left
, ps
.rcPaint
.bottom
- ps
.rcPaint
.top
,
456 s_pScreenPriv
->hdcShadow
,
457 ps
.rcPaint
.left
+ pWin
->drawable
.x
, ps
.rcPaint
.top
+ pWin
->drawable
.y
,
462 /* Display a fancy error message */
463 FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
|
464 FORMAT_MESSAGE_FROM_SYSTEM
|
465 FORMAT_MESSAGE_IGNORE_INSERTS
,
468 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
472 ErrorF ("winTopLevelWindowProc - BitBlt failed: %s\n",
474 LocalFree (lpMsgBuf
);
477 /* EndPaint frees the DC */
478 EndPaint (hwnd
, &ps
);
482 /* Unpack the client area mouse coordinates */
483 ptMouse
.x
= GET_X_LPARAM(lParam
);
484 ptMouse
.y
= GET_Y_LPARAM(lParam
);
486 /* Translate the client area mouse coordinates to screen coordinates */
487 ClientToScreen (hwnd
, &ptMouse
);
489 /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
490 ptMouse
.x
-= GetSystemMetrics (SM_XVIRTUALSCREEN
);
491 ptMouse
.y
-= GetSystemMetrics (SM_YVIRTUALSCREEN
);
493 /* We can't do anything without privates */
494 if (s_pScreenPriv
== NULL
|| s_pScreenInfo
->fIgnoreInput
)
497 /* Has the mouse pointer crossed screens? */
498 if (s_pScreen
!= miPointerGetScreen(inputInfo
.pointer
))
499 miPointerSetScreen (inputInfo
.pointer
, s_pScreenInfo
->dwScreen
,
500 ptMouse
.x
- s_pScreenInfo
->dwXOffset
,
501 ptMouse
.y
- s_pScreenInfo
->dwYOffset
);
503 /* Are we tracking yet? */
508 /* Setup data structure */
509 ZeroMemory (&tme
, sizeof (tme
));
510 tme
.cbSize
= sizeof (tme
);
511 tme
.dwFlags
= TME_LEAVE
;
512 tme
.hwndTrack
= hwnd
;
514 /* Call the tracking function */
515 if (!(*g_fpTrackMouseEvent
) (&tme
))
516 ErrorF ("winTopLevelWindowProc - _TrackMouseEvent failed\n");
518 /* Flag that we are tracking now */
522 /* Hide or show the Windows mouse cursor */
523 if (g_fSoftwareCursor
&& g_fCursor
)
525 /* Hide Windows cursor */
530 /* Kill the timer used to poll mouse events */
531 if (g_uipMousePollingTimerID
!= 0)
533 KillTimer (s_pScreenPriv
->hwndScreen
, WIN_POLLING_MOUSE_TIMER_ID
);
534 g_uipMousePollingTimerID
= 0;
537 /* Deliver absolute cursor position to X Server */
538 miPointerAbsoluteCursor (ptMouse
.x
- s_pScreenInfo
->dwXOffset
,
539 ptMouse
.y
- s_pScreenInfo
->dwYOffset
,
540 g_c32LastInputEventTime
= GetTickCount ());
545 * We break instead of returning 0 since we need to call
546 * DefWindowProc to get the mouse cursor changes
547 * and min/max/close button highlighting in Windows XP.
548 * The Platform SDK says that you should return 0 if you
549 * process this message, but it fails to mention that you
550 * will give up any default functionality if you do return 0.
553 /* We can't do anything without privates */
554 if (s_pScreenPriv
== NULL
|| s_pScreenInfo
->fIgnoreInput
)
557 /* Non-client mouse movement, show Windows cursor */
558 if (g_fSoftwareCursor
&& !g_fCursor
)
565 * Timer to poll mouse events. This is needed to make
566 * programs like xeyes follow the mouse properly.
568 if (g_uipMousePollingTimerID
== 0)
569 g_uipMousePollingTimerID
= SetTimer (s_pScreenPriv
->hwndScreen
,
570 WIN_POLLING_MOUSE_TIMER_ID
,
571 MOUSE_POLLING_INTERVAL
,
576 /* Mouse has left our client area */
578 /* Flag that we are no longer tracking */
581 /* Show the mouse cursor, if necessary */
582 if (g_fSoftwareCursor
&& !g_fCursor
)
589 * Timer to poll mouse events. This is needed to make
590 * programs like xeyes follow the mouse properly.
592 if (g_uipMousePollingTimerID
== 0)
593 g_uipMousePollingTimerID
= SetTimer (s_pScreenPriv
->hwndScreen
,
594 WIN_POLLING_MOUSE_TIMER_ID
,
595 MOUSE_POLLING_INTERVAL
,
599 case WM_LBUTTONDBLCLK
:
601 if (s_pScreenPriv
== NULL
|| s_pScreenInfo
->fIgnoreInput
)
604 return winMouseButtonsHandle (s_pScreen
, ButtonPress
, Button1
, wParam
);
607 if (s_pScreenPriv
== NULL
|| s_pScreenInfo
->fIgnoreInput
)
609 g_fButton
[0] = FALSE
;
610 return winMouseButtonsHandle (s_pScreen
, ButtonRelease
, Button1
, wParam
);
612 case WM_MBUTTONDBLCLK
:
614 if (s_pScreenPriv
== NULL
|| s_pScreenInfo
->fIgnoreInput
)
617 return winMouseButtonsHandle (s_pScreen
, ButtonPress
, Button2
, wParam
);
620 if (s_pScreenPriv
== NULL
|| s_pScreenInfo
->fIgnoreInput
)
622 g_fButton
[1] = FALSE
;
623 return winMouseButtonsHandle (s_pScreen
, ButtonRelease
, Button2
, wParam
);
625 case WM_RBUTTONDBLCLK
:
627 if (s_pScreenPriv
== NULL
|| s_pScreenInfo
->fIgnoreInput
)
630 return winMouseButtonsHandle (s_pScreen
, ButtonPress
, Button3
, wParam
);
633 if (s_pScreenPriv
== NULL
|| s_pScreenInfo
->fIgnoreInput
)
635 g_fButton
[2] = FALSE
;
636 return winMouseButtonsHandle (s_pScreen
, ButtonRelease
, Button3
, wParam
);
638 case WM_XBUTTONDBLCLK
:
640 if (s_pScreenPriv
== NULL
|| s_pScreenInfo
->fIgnoreInput
)
642 return winMouseButtonsHandle (s_pScreen
, ButtonPress
, HIWORD(wParam
) + 5, wParam
);
644 if (s_pScreenPriv
== NULL
|| s_pScreenInfo
->fIgnoreInput
)
646 return winMouseButtonsHandle (s_pScreen
, ButtonRelease
, HIWORD(wParam
) + 5, wParam
);
650 /* Pass the message to the root window */
651 SendMessage (hwndScreen
, message
, wParam
, lParam
);
655 if (s_pScreenPriv
== NULL
|| s_pScreenInfo
->fIgnoreInput
)
658 winRestoreModeKeyStates ();
660 /* Add the keyboard hook if possible */
661 if (g_fKeyboardHookLL
)
662 g_fKeyboardHookLL
= winInstallKeyboardHookLL ();
666 /* Pop any pressed keys since we are losing keyboard focus */
667 winKeybdReleaseKeys ();
669 /* Remove our keyboard hook if it is installed */
670 winRemoveKeyboardHookLL ();
676 * NOTE: We do nothing with WM_*CHAR messages,
677 * nor does the root window, so we can just toss these messages.
685 * Don't pass Alt-F4 key combo to root window,
686 * let Windows translate to WM_CLOSE and close this top-level window.
688 * NOTE: We purposely don't check the fUseWinKillKey setting because
689 * it should only apply to the key handling for the root window,
690 * not for top-level window-manager windows.
692 * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
693 * because that is a key combo that no X app should be expecting to
694 * receive, since it has historically been used to shutdown the X server.
695 * Passing Ctrl-Alt-Backspace to the root window preserves that
696 * behavior, assuming that -unixkill has been passed as a parameter.
698 if (wParam
== VK_F4
&& (GetKeyState (VK_MENU
) & 0x8000))
701 #if CYGWINDOWING_DEBUG
702 if (wParam
== VK_ESCAPE
)
704 /* Place for debug: put any tests and dumps here */
705 WINDOWPLACEMENT windPlace
;
709 windPlace
.length
= sizeof (WINDOWPLACEMENT
);
710 GetWindowPlacement (hwnd
, &windPlace
);
711 pRect
= &windPlace
.rcNormalPosition
;
712 ErrorF ("\nCYGWINDOWING Dump:\n"
713 "\tdrawable: (%hd, %hd) - %hdx%hd\n", pDraw
->x
,
714 pDraw
->y
, pDraw
->width
, pDraw
->height
);
715 ErrorF ("\twindPlace: (%ld, %ld) - %ldx%ld\n", pRect
->left
,
716 pRect
->top
, pRect
->right
- pRect
->left
,
717 pRect
->bottom
- pRect
->top
);
718 if (GetClientRect (hwnd
, &rc
))
721 ErrorF ("\tClientRect: (%ld, %ld) - %ldx%ld\n", pRect
->left
,
722 pRect
->top
, pRect
->right
- pRect
->left
,
723 pRect
->bottom
- pRect
->top
);
725 if (GetWindowRect (hwnd
, &rc
))
728 ErrorF ("\tWindowRect: (%ld, %ld) - %ldx%ld\n", pRect
->left
,
729 pRect
->top
, pRect
->right
- pRect
->left
,
730 pRect
->bottom
- pRect
->top
);
736 /* Pass the message to the root window */
737 return winWindowProc(hwndScreen
, message
, wParam
, lParam
);
743 /* Pass the message to the root window */
744 return winWindowProc(hwndScreen
, message
, wParam
, lParam
);
748 /* Pass the message to the root window */
749 SendMessage (hwndScreen
, message
, wParam
, lParam
);
754 /* Pass the message to the root window */
755 SendMessage (hwndScreen
, message
, wParam
, lParam
);
757 if (LOWORD(wParam
) != WA_INACTIVE
)
759 /* Raise the window to the top in Z order */
760 /* ago: Activate does not mean putting it to front! */
762 wmMsg.msg = WM_WM_RAISE;
763 if (fWMMsgInitialized)
764 winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
767 /* Tell our Window Manager thread to activate the window */
768 wmMsg
.msg
= WM_WM_ACTIVATE
;
769 if (fWMMsgInitialized
)
770 if (!pWin
|| !pWin
->overrideRedirect
) /* for OOo menus */
771 winSendMessageToWM (s_pScreenPriv
->pWMInfo
, &wmMsg
);
777 * This message is also sent to the root window
778 * so we do nothing for individual multiwindow windows
783 /* Branch on if the window was killed in X already */
784 if (pWinPriv
->fXKilled
)
786 /* Window was killed, go ahead and destroy the window */
787 DestroyWindow (hwnd
);
791 /* Tell our Window Manager thread to kill the window */
792 wmMsg
.msg
= WM_WM_KILL
;
793 if (fWMMsgInitialized
)
794 winSendMessageToWM (s_pScreenPriv
->pWMInfo
, &wmMsg
);
800 /* Branch on if the window was killed in X already */
801 if (pWinPriv
&& !pWinPriv
->fXKilled
)
803 ErrorF ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n");
805 /* Tell our Window Manager thread to kill the window */
806 wmMsg
.msg
= WM_WM_KILL
;
807 if (fWMMsgInitialized
)
808 winSendMessageToWM (s_pScreenPriv
->pWMInfo
, &wmMsg
);
811 RemoveProp (hwnd
, WIN_WINDOW_PROP
);
812 RemoveProp (hwnd
, WIN_WID_PROP
);
813 RemoveProp (hwnd
, WIN_NEEDMANAGE_PROP
);
818 /* Adjust the X Window to the moved Windows window */
819 winAdjustXWindow (pWin
, hwnd
);
823 /* Bail out if the window is being hidden */
827 /* Tell X to map the window */
828 MapWindow (pWin
, wClient(pWin
));
831 if (!pWin
->overrideRedirect
)
838 /* Flag that this window needs to be made active when clicked */
839 SetProp (hwnd
, WIN_NEEDMANAGE_PROP
, (HANDLE
) 1);
841 /* Get the standard and extended window style information */
842 dwExStyle
= GetWindowLongPtr (hwnd
, GWL_EXSTYLE
);
843 dwStyle
= GetWindowLongPtr (hwnd
, GWL_STYLE
);
846 if (dwExStyle
!= WS_EX_APPWINDOW
)
848 /* Setup a rectangle with the X window position and size */
852 pDraw
->x
+ pDraw
->width
,
853 pDraw
->y
+ pDraw
->height
);
856 ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n",
857 rcNew
.left
, rcNew
.top
,
858 rcNew
.right
, rcNew
.bottom
);
862 AdjustWindowRectEx (&rcNew
,
863 WS_POPUP
| WS_SIZEBOX
| WS_OVERLAPPEDWINDOW
,
867 /* Calculate position deltas */
868 iDx
= pDraw
->x
- rcNew
.left
;
869 iDy
= pDraw
->y
- rcNew
.top
;
871 /* Calculate new rectangle */
878 ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n",
879 rcNew
.left
, rcNew
.top
,
880 rcNew
.right
, rcNew
.bottom
);
883 /* Set the window extended style flags */
884 SetWindowLongPtr (hwnd
, GWL_EXSTYLE
, WS_EX_APPWINDOW
);
886 /* Set the window standard style flags */
887 SetWindowLongPtr (hwnd
, GWL_STYLE
,
888 WS_POPUP
| WS_SIZEBOX
| WS_OVERLAPPEDWINDOW
);
890 /* Position the Windows window */
891 SetWindowPos (hwnd
, HWND_TOP
,
892 rcNew
.left
, rcNew
.top
,
893 rcNew
.right
- rcNew
.left
, rcNew
.bottom
- rcNew
.top
,
894 SWP_NOMOVE
| SWP_FRAMECHANGED
895 | SWP_SHOWWINDOW
| SWP_NOACTIVATE
);
897 /* Bring the Windows window to the foreground */
898 SetForegroundWindow (hwnd
);
901 else /* It is an overridden window so make it top of Z stack */
903 #if CYGWINDOWING_DEBUG
904 ErrorF ("overridden window is shown\n");
906 SetWindowPos (hwnd
, HWND_TOPMOST
, 0, 0, 0, 0,
907 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
910 /* Setup the Window Manager message */
911 wmMsg
.msg
= WM_WM_MAP
;
912 wmMsg
.iWidth
= pDraw
->width
;
913 wmMsg
.iHeight
= pDraw
->height
;
915 /* Tell our Window Manager thread to map the window */
916 if (fWMMsgInitialized
)
917 winSendMessageToWM (s_pScreenPriv
->pWMInfo
, &wmMsg
);
922 /* Need to legalize the size according to WM_NORMAL_HINTS */
923 /* for applications like xterm */
924 return ValidateSizing (hwnd
, pWin
, wParam
, lParam
);
926 case WM_WINDOWPOSCHANGED
:
928 LPWINDOWPOS pWinPos
= (LPWINDOWPOS
) lParam
;
930 if (!(pWinPos
->flags
& SWP_NOZORDER
))
932 #if CYGWINDOWING_DEBUG
933 winDebug ("\twindow z order was changed\n");
935 if (pWinPos
->hwndInsertAfter
== HWND_TOP
936 ||pWinPos
->hwndInsertAfter
== HWND_TOPMOST
937 ||pWinPos
->hwndInsertAfter
== HWND_NOTOPMOST
)
939 #if CYGWINDOWING_DEBUG
940 winDebug ("\traise to top\n");
942 /* Raise the window to the top in Z order */
943 winRaiseWindow(pWin
);
945 else if (pWinPos
->hwndInsertAfter
== HWND_BOTTOM
)
950 /* Check if this window is top of X windows. */
951 HWND hWndAbove
= NULL
;
952 DWORD dwCurrentProcessID
= GetCurrentProcessId ();
953 DWORD dwWindowProcessID
= 0;
955 for (hWndAbove
= pWinPos
->hwndInsertAfter
;
957 hWndAbove
= GetNextWindow (hWndAbove
, GW_HWNDPREV
))
959 /* Ignore other XWin process's window */
960 GetWindowThreadProcessId (hWndAbove
, &dwWindowProcessID
);
962 if ((dwWindowProcessID
== dwCurrentProcessID
)
963 && GetProp (hWndAbove
, WIN_WINDOW_PROP
)
964 && !IsWindowVisible (hWndAbove
)
965 && !IsIconic (hWndAbove
) ) /* ignore minimized windows */
968 /* If this is top of X windows in Windows stack,
969 raise it in X stack. */
970 if (hWndAbove
== NULL
)
972 #if CYGWINDOWING_DEBUG
973 winDebug ("\traise to top\n");
975 winRaiseWindow(pWin
);
981 * Pass the message to DefWindowProc to let the function
982 * break down WM_WINDOWPOSCHANGED to WM_MOVE and WM_SIZE.
987 /* see dix/window.c */
988 #if CYGWINDOWING_DEBUG
994 strcpy(buf
, "SIZE_MINIMIZED");
997 strcpy(buf
, "SIZE_MAXIMIZED");
1000 strcpy(buf
, "SIZE_RESTORED");
1003 strcpy(buf
, "UNKNOWN_FLAG");
1005 ErrorF ("winTopLevelWindowProc - WM_SIZE to %dx%d (%s) - %d ms\n",
1006 (int)LOWORD(lParam
), (int)HIWORD(lParam
), buf
,
1007 (int)(GetTickCount ()));
1010 /* Adjust the X Window to the moved Windows window */
1011 winAdjustXWindow (pWin
, hwnd
);
1012 return 0; /* end of WM_SIZE handler */
1014 case WM_MOUSEACTIVATE
:
1016 /* Check if this window needs to be made active when clicked */
1017 if (!GetProp (pWinPriv
->hWnd
, WIN_NEEDMANAGE_PROP
))
1019 #if CYGMULTIWINDOW_DEBUG
1020 ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - "
1025 return MA_NOACTIVATE
;
1030 if (LOWORD(lParam
) == HTCLIENT
)
1032 if (!g_fSoftwareCursor
) SetCursor (s_pScreenPriv
->cursor
.handle
);
1041 ret
= DefWindowProc (hwnd
, message
, wParam
, lParam
);
1043 * If the window was minized we get the stack change before the window is restored
1044 * and so it gets lost. Ensure there stacking order is correct.
1047 winReorderWindowsMultiWindow();