1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3*4882a593Smuzhiyun *Copyright (C) Colin Harrison 2005-2008
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun *Permission is hereby granted, free of charge, to any person obtaining
6*4882a593Smuzhiyun * a copy of this software and associated documentation files (the
7*4882a593Smuzhiyun *"Software"), to deal in the Software without restriction, including
8*4882a593Smuzhiyun *without limitation the rights to use, copy, modify, merge, publish,
9*4882a593Smuzhiyun *distribute, sublicense, and/or sell copies of the Software, and to
10*4882a593Smuzhiyun *permit persons to whom the Software is furnished to do so, subject to
11*4882a593Smuzhiyun *the following conditions:
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun *The above copyright notice and this permission notice shall be
14*4882a593Smuzhiyun *included in all copies or substantial portions of the Software.
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17*4882a593Smuzhiyun *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18*4882a593Smuzhiyun *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19*4882a593Smuzhiyun *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
20*4882a593Smuzhiyun *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21*4882a593Smuzhiyun *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22*4882a593Smuzhiyun *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23*4882a593Smuzhiyun *
24*4882a593Smuzhiyun *Except as contained in this notice, the name of the XFree86 Project
25*4882a593Smuzhiyun *shall not be used in advertising or otherwise to promote the sale, use
26*4882a593Smuzhiyun *or other dealings in this Software without prior written authorization
27*4882a593Smuzhiyun *from the XFree86 Project.
28*4882a593Smuzhiyun *
29*4882a593Smuzhiyun * Authors: Kensuke Matsuzaki
30*4882a593Smuzhiyun * Earle F. Philhower, III
31*4882a593Smuzhiyun * Harold L Hunt II
32*4882a593Smuzhiyun * Colin Harrison
33*4882a593Smuzhiyun */
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun #ifdef HAVE_XWIN_CONFIG_H
36*4882a593Smuzhiyun #include <xwin-config.h>
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun #include "win.h"
39*4882a593Smuzhiyun #include "dixevents.h"
40*4882a593Smuzhiyun #include "winmultiwindowclass.h"
41*4882a593Smuzhiyun #include "winprefs.h"
42*4882a593Smuzhiyun #include "winmsg.h"
43*4882a593Smuzhiyun #include "inputstr.h"
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun extern void winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /*
48*4882a593Smuzhiyun * Local globals
49*4882a593Smuzhiyun */
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun static UINT_PTR g_uipMousePollingTimerID = 0;
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun /*
54*4882a593Smuzhiyun * Constant defines
55*4882a593Smuzhiyun */
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun #define WIN_MULTIWINDOW_SHAPE YES
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun /*
60*4882a593Smuzhiyun * ConstrainSize - Taken from TWM sources - Respects hints for sizing
61*4882a593Smuzhiyun */
62*4882a593Smuzhiyun #define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
63*4882a593Smuzhiyun static void
ConstrainSize(WinXSizeHints hints,int * widthp,int * heightp)64*4882a593Smuzhiyun ConstrainSize(WinXSizeHints hints, int *widthp, int *heightp)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta;
67*4882a593Smuzhiyun int baseWidth, baseHeight;
68*4882a593Smuzhiyun int dwidth = *widthp, dheight = *heightp;
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun if (hints.flags & PMinSize) {
71*4882a593Smuzhiyun minWidth = hints.min_width;
72*4882a593Smuzhiyun minHeight = hints.min_height;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun else if (hints.flags & PBaseSize) {
75*4882a593Smuzhiyun minWidth = hints.base_width;
76*4882a593Smuzhiyun minHeight = hints.base_height;
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun else
79*4882a593Smuzhiyun minWidth = minHeight = 1;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun if (hints.flags & PBaseSize) {
82*4882a593Smuzhiyun baseWidth = hints.base_width;
83*4882a593Smuzhiyun baseHeight = hints.base_height;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun else if (hints.flags & PMinSize) {
86*4882a593Smuzhiyun baseWidth = hints.min_width;
87*4882a593Smuzhiyun baseHeight = hints.min_height;
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun else
90*4882a593Smuzhiyun baseWidth = baseHeight = 0;
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun if (hints.flags & PMaxSize) {
93*4882a593Smuzhiyun maxWidth = hints.max_width;
94*4882a593Smuzhiyun maxHeight = hints.max_height;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun else {
97*4882a593Smuzhiyun maxWidth = MAXINT;
98*4882a593Smuzhiyun maxHeight = MAXINT;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun if (hints.flags & PResizeInc) {
102*4882a593Smuzhiyun xinc = hints.width_inc;
103*4882a593Smuzhiyun yinc = hints.height_inc;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun else
106*4882a593Smuzhiyun xinc = yinc = 1;
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun /*
109*4882a593Smuzhiyun * First, clamp to min and max values
110*4882a593Smuzhiyun */
111*4882a593Smuzhiyun if (dwidth < minWidth)
112*4882a593Smuzhiyun dwidth = minWidth;
113*4882a593Smuzhiyun if (dheight < minHeight)
114*4882a593Smuzhiyun dheight = minHeight;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun if (dwidth > maxWidth)
117*4882a593Smuzhiyun dwidth = maxWidth;
118*4882a593Smuzhiyun if (dheight > maxHeight)
119*4882a593Smuzhiyun dheight = maxHeight;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun /*
122*4882a593Smuzhiyun * Second, fit to base + N * inc
123*4882a593Smuzhiyun */
124*4882a593Smuzhiyun dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth;
125*4882a593Smuzhiyun dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight;
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun /*
128*4882a593Smuzhiyun * Third, adjust for aspect ratio
129*4882a593Smuzhiyun */
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun /*
132*4882a593Smuzhiyun * The math looks like this:
133*4882a593Smuzhiyun *
134*4882a593Smuzhiyun * minAspectX dwidth maxAspectX
135*4882a593Smuzhiyun * ---------- <= ------- <= ----------
136*4882a593Smuzhiyun * minAspectY dheight maxAspectY
137*4882a593Smuzhiyun *
138*4882a593Smuzhiyun * If that is multiplied out, then the width and height are
139*4882a593Smuzhiyun * invalid in the following situations:
140*4882a593Smuzhiyun *
141*4882a593Smuzhiyun * minAspectX * dheight > minAspectY * dwidth
142*4882a593Smuzhiyun * maxAspectX * dheight < maxAspectY * dwidth
143*4882a593Smuzhiyun *
144*4882a593Smuzhiyun */
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun if (hints.flags & PAspect) {
147*4882a593Smuzhiyun if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth) {
148*4882a593Smuzhiyun delta =
149*4882a593Smuzhiyun makemult(hints.min_aspect.x * dheight / hints.min_aspect.y -
150*4882a593Smuzhiyun dwidth, xinc);
151*4882a593Smuzhiyun if (dwidth + delta <= maxWidth)
152*4882a593Smuzhiyun dwidth += delta;
153*4882a593Smuzhiyun else {
154*4882a593Smuzhiyun delta =
155*4882a593Smuzhiyun makemult(dheight -
156*4882a593Smuzhiyun dwidth * hints.min_aspect.y / hints.min_aspect.x,
157*4882a593Smuzhiyun yinc);
158*4882a593Smuzhiyun if (dheight - delta >= minHeight)
159*4882a593Smuzhiyun dheight -= delta;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth) {
164*4882a593Smuzhiyun delta =
165*4882a593Smuzhiyun makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x -
166*4882a593Smuzhiyun dheight, yinc);
167*4882a593Smuzhiyun if (dheight + delta <= maxHeight)
168*4882a593Smuzhiyun dheight += delta;
169*4882a593Smuzhiyun else {
170*4882a593Smuzhiyun delta =
171*4882a593Smuzhiyun makemult(dwidth -
172*4882a593Smuzhiyun hints.max_aspect.x * dheight / hints.max_aspect.y,
173*4882a593Smuzhiyun xinc);
174*4882a593Smuzhiyun if (dwidth - delta >= minWidth)
175*4882a593Smuzhiyun dwidth -= delta;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun /* Return computed values */
181*4882a593Smuzhiyun *widthp = dwidth;
182*4882a593Smuzhiyun *heightp = dheight;
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun #undef makemult
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun /*
188*4882a593Smuzhiyun * ValidateSizing - Ensures size request respects hints
189*4882a593Smuzhiyun */
190*4882a593Smuzhiyun static int
ValidateSizing(HWND hwnd,WindowPtr pWin,WPARAM wParam,LPARAM lParam)191*4882a593Smuzhiyun ValidateSizing(HWND hwnd, WindowPtr pWin, WPARAM wParam, LPARAM lParam)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun WinXSizeHints sizeHints;
194*4882a593Smuzhiyun RECT *rect;
195*4882a593Smuzhiyun int iWidth, iHeight;
196*4882a593Smuzhiyun RECT rcClient, rcWindow;
197*4882a593Smuzhiyun int iBorderWidthX, iBorderWidthY;
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun /* Invalid input checking */
200*4882a593Smuzhiyun if (pWin == NULL || lParam == 0)
201*4882a593Smuzhiyun return FALSE;
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun /* No size hints, no checking */
204*4882a593Smuzhiyun if (!winMultiWindowGetWMNormalHints(pWin, &sizeHints))
205*4882a593Smuzhiyun return FALSE;
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun /* Avoid divide-by-zero */
208*4882a593Smuzhiyun if (sizeHints.flags & PResizeInc) {
209*4882a593Smuzhiyun if (sizeHints.width_inc == 0)
210*4882a593Smuzhiyun sizeHints.width_inc = 1;
211*4882a593Smuzhiyun if (sizeHints.height_inc == 0)
212*4882a593Smuzhiyun sizeHints.height_inc = 1;
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun rect = (RECT *) lParam;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun iWidth = rect->right - rect->left;
218*4882a593Smuzhiyun iHeight = rect->bottom - rect->top;
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun /* Now remove size of any borders and title bar */
221*4882a593Smuzhiyun GetClientRect(hwnd, &rcClient);
222*4882a593Smuzhiyun GetWindowRect(hwnd, &rcWindow);
223*4882a593Smuzhiyun iBorderWidthX =
224*4882a593Smuzhiyun (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left);
225*4882a593Smuzhiyun iBorderWidthY =
226*4882a593Smuzhiyun (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top);
227*4882a593Smuzhiyun iWidth -= iBorderWidthX;
228*4882a593Smuzhiyun iHeight -= iBorderWidthY;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun /* Constrain the size to legal values */
231*4882a593Smuzhiyun ConstrainSize(sizeHints, &iWidth, &iHeight);
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun /* Add back the size of borders and title bar */
234*4882a593Smuzhiyun iWidth += iBorderWidthX;
235*4882a593Smuzhiyun iHeight += iBorderWidthY;
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun /* Adjust size according to where we're dragging from */
238*4882a593Smuzhiyun switch (wParam) {
239*4882a593Smuzhiyun case WMSZ_TOP:
240*4882a593Smuzhiyun case WMSZ_TOPRIGHT:
241*4882a593Smuzhiyun case WMSZ_BOTTOM:
242*4882a593Smuzhiyun case WMSZ_BOTTOMRIGHT:
243*4882a593Smuzhiyun case WMSZ_RIGHT:
244*4882a593Smuzhiyun rect->right = rect->left + iWidth;
245*4882a593Smuzhiyun break;
246*4882a593Smuzhiyun default:
247*4882a593Smuzhiyun rect->left = rect->right - iWidth;
248*4882a593Smuzhiyun break;
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun switch (wParam) {
251*4882a593Smuzhiyun case WMSZ_BOTTOM:
252*4882a593Smuzhiyun case WMSZ_BOTTOMRIGHT:
253*4882a593Smuzhiyun case WMSZ_BOTTOMLEFT:
254*4882a593Smuzhiyun case WMSZ_RIGHT:
255*4882a593Smuzhiyun case WMSZ_LEFT:
256*4882a593Smuzhiyun rect->bottom = rect->top + iHeight;
257*4882a593Smuzhiyun break;
258*4882a593Smuzhiyun default:
259*4882a593Smuzhiyun rect->top = rect->bottom - iHeight;
260*4882a593Smuzhiyun break;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun return TRUE;
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun extern Bool winInDestroyWindowsWindow;
266*4882a593Smuzhiyun static Bool winInRaiseWindow = FALSE;
267*4882a593Smuzhiyun static void
winRaiseWindow(WindowPtr pWin)268*4882a593Smuzhiyun winRaiseWindow(WindowPtr pWin)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun if (!winInDestroyWindowsWindow && !winInRaiseWindow) {
271*4882a593Smuzhiyun BOOL oldstate = winInRaiseWindow;
272*4882a593Smuzhiyun XID vlist[1] = { 0 };
273*4882a593Smuzhiyun winInRaiseWindow = TRUE;
274*4882a593Smuzhiyun /* Call configure window directly to make sure it gets processed
275*4882a593Smuzhiyun * in time
276*4882a593Smuzhiyun */
277*4882a593Smuzhiyun ConfigureWindow(pWin, CWStackMode, vlist, serverClient);
278*4882a593Smuzhiyun winInRaiseWindow = oldstate;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun static
283*4882a593Smuzhiyun void
winStartMousePolling(winPrivScreenPtr s_pScreenPriv)284*4882a593Smuzhiyun winStartMousePolling(winPrivScreenPtr s_pScreenPriv)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun /*
287*4882a593Smuzhiyun * Timer to poll mouse position. This is needed to make
288*4882a593Smuzhiyun * programs like xeyes follow the mouse properly when the
289*4882a593Smuzhiyun * mouse pointer is outside of any X window.
290*4882a593Smuzhiyun */
291*4882a593Smuzhiyun if (g_uipMousePollingTimerID == 0)
292*4882a593Smuzhiyun g_uipMousePollingTimerID = SetTimer(s_pScreenPriv->hwndScreen,
293*4882a593Smuzhiyun WIN_POLLING_MOUSE_TIMER_ID,
294*4882a593Smuzhiyun MOUSE_POLLING_INTERVAL, NULL);
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun /*
298*4882a593Smuzhiyun * winTopLevelWindowProc - Window procedure for all top-level Windows windows.
299*4882a593Smuzhiyun */
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun LRESULT CALLBACK
winTopLevelWindowProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)302*4882a593Smuzhiyun winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun POINT ptMouse;
305*4882a593Smuzhiyun HDC hdcUpdate;
306*4882a593Smuzhiyun PAINTSTRUCT ps;
307*4882a593Smuzhiyun WindowPtr pWin = NULL;
308*4882a593Smuzhiyun winPrivWinPtr pWinPriv = NULL;
309*4882a593Smuzhiyun ScreenPtr s_pScreen = NULL;
310*4882a593Smuzhiyun winPrivScreenPtr s_pScreenPriv = NULL;
311*4882a593Smuzhiyun winScreenInfo *s_pScreenInfo = NULL;
312*4882a593Smuzhiyun HWND hwndScreen = NULL;
313*4882a593Smuzhiyun DrawablePtr pDraw = NULL;
314*4882a593Smuzhiyun winWMMessageRec wmMsg;
315*4882a593Smuzhiyun Bool fWMMsgInitialized = FALSE;
316*4882a593Smuzhiyun static Bool s_fTracking = FALSE;
317*4882a593Smuzhiyun Bool needRestack = FALSE;
318*4882a593Smuzhiyun LRESULT ret;
319*4882a593Smuzhiyun static Bool hasEnteredSizeMove = FALSE;
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun #if CYGDEBUG
322*4882a593Smuzhiyun winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam,
323*4882a593Smuzhiyun lParam);
324*4882a593Smuzhiyun #endif
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun /* Check if the Windows window property for our X window pointer is valid */
327*4882a593Smuzhiyun if ((pWin = GetProp(hwnd, WIN_WINDOW_PROP)) != NULL) {
328*4882a593Smuzhiyun /* Our X window pointer is valid */
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun /* Get pointers to the drawable and the screen */
331*4882a593Smuzhiyun pDraw = &pWin->drawable;
332*4882a593Smuzhiyun s_pScreen = pWin->drawable.pScreen;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun /* Get a pointer to our window privates */
335*4882a593Smuzhiyun pWinPriv = winGetWindowPriv(pWin);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun /* Get pointers to our screen privates and screen info */
338*4882a593Smuzhiyun s_pScreenPriv = pWinPriv->pScreenPriv;
339*4882a593Smuzhiyun s_pScreenInfo = s_pScreenPriv->pScreenInfo;
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun /* Get the handle for our screen-sized window */
342*4882a593Smuzhiyun hwndScreen = s_pScreenPriv->hwndScreen;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun /* */
345*4882a593Smuzhiyun wmMsg.msg = 0;
346*4882a593Smuzhiyun wmMsg.hwndWindow = hwnd;
347*4882a593Smuzhiyun wmMsg.iWindow = (Window) (INT_PTR) GetProp(hwnd, WIN_WID_PROP);
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun wmMsg.iX = pDraw->x;
350*4882a593Smuzhiyun wmMsg.iY = pDraw->y;
351*4882a593Smuzhiyun wmMsg.iWidth = pDraw->width;
352*4882a593Smuzhiyun wmMsg.iHeight = pDraw->height;
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun fWMMsgInitialized = TRUE;
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun #if 0
357*4882a593Smuzhiyun /*
358*4882a593Smuzhiyun * Print some debugging information
359*4882a593Smuzhiyun */
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun ErrorF("hWnd %08X\n", hwnd);
362*4882a593Smuzhiyun ErrorF("pWin %08X\n", pWin);
363*4882a593Smuzhiyun ErrorF("pDraw %08X\n", pDraw);
364*4882a593Smuzhiyun ErrorF("\ttype %08X\n", pWin->drawable.type);
365*4882a593Smuzhiyun ErrorF("\tclass %08X\n", pWin->drawable.class);
366*4882a593Smuzhiyun ErrorF("\tdepth %08X\n", pWin->drawable.depth);
367*4882a593Smuzhiyun ErrorF("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel);
368*4882a593Smuzhiyun ErrorF("\tid %08X\n", pWin->drawable.id);
369*4882a593Smuzhiyun ErrorF("\tx %08X\n", pWin->drawable.x);
370*4882a593Smuzhiyun ErrorF("\ty %08X\n", pWin->drawable.y);
371*4882a593Smuzhiyun ErrorF("\twidth %08X\n", pWin->drawable.width);
372*4882a593Smuzhiyun ErrorF("\thenght %08X\n", pWin->drawable.height);
373*4882a593Smuzhiyun ErrorF("\tpScreen %08X\n", pWin->drawable.pScreen);
374*4882a593Smuzhiyun ErrorF("\tserialNumber %08X\n", pWin->drawable.serialNumber);
375*4882a593Smuzhiyun ErrorF("g_iWindowPrivateKey %p\n", g_iWindowPrivateKey);
376*4882a593Smuzhiyun ErrorF("pWinPriv %08X\n", pWinPriv);
377*4882a593Smuzhiyun ErrorF("s_pScreenPriv %08X\n", s_pScreenPriv);
378*4882a593Smuzhiyun ErrorF("s_pScreenInfo %08X\n", s_pScreenInfo);
379*4882a593Smuzhiyun ErrorF("hwndScreen %08X\n", hwndScreen);
380*4882a593Smuzhiyun #endif
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun /* Branch on message type */
384*4882a593Smuzhiyun switch (message) {
385*4882a593Smuzhiyun case WM_CREATE:
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun /* */
388*4882a593Smuzhiyun SetProp(hwnd,
389*4882a593Smuzhiyun WIN_WINDOW_PROP,
390*4882a593Smuzhiyun (HANDLE) ((LPCREATESTRUCT) lParam)->lpCreateParams);
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun /* */
393*4882a593Smuzhiyun SetProp(hwnd,
394*4882a593Smuzhiyun WIN_WID_PROP,
395*4882a593Smuzhiyun (HANDLE) (INT_PTR) winGetWindowID(((LPCREATESTRUCT) lParam)->
396*4882a593Smuzhiyun lpCreateParams));
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun /*
399*4882a593Smuzhiyun * Make X windows' Z orders sync with Windows windows because
400*4882a593Smuzhiyun * there can be AlwaysOnTop windows overlapped on the window
401*4882a593Smuzhiyun * currently being created.
402*4882a593Smuzhiyun */
403*4882a593Smuzhiyun winReorderWindowsMultiWindow();
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun /* Fix a 'round title bar corner background should be transparent not black' problem when first painted */
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun RECT rWindow;
408*4882a593Smuzhiyun HRGN hRgnWindow;
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun GetWindowRect(hwnd, &rWindow);
411*4882a593Smuzhiyun hRgnWindow = CreateRectRgnIndirect(&rWindow);
412*4882a593Smuzhiyun SetWindowRgn(hwnd, hRgnWindow, TRUE);
413*4882a593Smuzhiyun DeleteObject(hRgnWindow);
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) XMING_SIGNATURE);
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun return 0;
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun case WM_INIT_SYS_MENU:
421*4882a593Smuzhiyun /*
422*4882a593Smuzhiyun * Add whatever the setup file wants to for this window
423*4882a593Smuzhiyun */
424*4882a593Smuzhiyun SetupSysMenu(hwnd);
425*4882a593Smuzhiyun return 0;
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun case WM_SYSCOMMAND:
428*4882a593Smuzhiyun /*
429*4882a593Smuzhiyun * Any window menu items go through here
430*4882a593Smuzhiyun */
431*4882a593Smuzhiyun if (HandleCustomWM_COMMAND(hwnd, LOWORD(wParam), s_pScreenPriv)) {
432*4882a593Smuzhiyun /* Don't pass customized menus to DefWindowProc */
433*4882a593Smuzhiyun return 0;
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun if (wParam == SC_RESTORE || wParam == SC_MAXIMIZE) {
436*4882a593Smuzhiyun WINDOWPLACEMENT wndpl;
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun wndpl.length = sizeof(wndpl);
439*4882a593Smuzhiyun if (GetWindowPlacement(hwnd, &wndpl) &&
440*4882a593Smuzhiyun wndpl.showCmd == SW_SHOWMINIMIZED)
441*4882a593Smuzhiyun needRestack = TRUE;
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun break;
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun case WM_INITMENU:
446*4882a593Smuzhiyun /* Checks/Unchecks any menu items before they are displayed */
447*4882a593Smuzhiyun HandleCustomWM_INITMENU(hwnd, (HMENU)wParam);
448*4882a593Smuzhiyun break;
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun case WM_ERASEBKGND:
451*4882a593Smuzhiyun /*
452*4882a593Smuzhiyun * Pretend that we did erase the background but we don't care,
453*4882a593Smuzhiyun * since we repaint the entire region anyhow
454*4882a593Smuzhiyun * This avoids some flickering when resizing.
455*4882a593Smuzhiyun */
456*4882a593Smuzhiyun return TRUE;
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun case WM_PAINT:
459*4882a593Smuzhiyun /* Only paint if our window handle is valid */
460*4882a593Smuzhiyun if (hwndScreen == NULL)
461*4882a593Smuzhiyun break;
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun /* BeginPaint gives us an hdc that clips to the invalidated region */
464*4882a593Smuzhiyun hdcUpdate = BeginPaint(hwnd, &ps);
465*4882a593Smuzhiyun /* Avoid the BitBlt's if the PAINTSTRUCT is bogus */
466*4882a593Smuzhiyun if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 &&
467*4882a593Smuzhiyun ps.rcPaint.left == 0 && ps.rcPaint.top == 0) {
468*4882a593Smuzhiyun EndPaint(hwnd, &ps);
469*4882a593Smuzhiyun return 0;
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun #ifdef XWIN_GLX_WINDOWS
473*4882a593Smuzhiyun if (pWinPriv->fWglUsed) {
474*4882a593Smuzhiyun /*
475*4882a593Smuzhiyun For regions which are being drawn by GL, the shadow framebuffer doesn't have the
476*4882a593Smuzhiyun correct bits, so don't bitblt from the shadow framebuffer
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun XXX: For now, just leave it alone, but ideally we want to send an expose event to
479*4882a593Smuzhiyun the window so it really redraws the affected region...
480*4882a593Smuzhiyun */
481*4882a593Smuzhiyun ValidateRect(hwnd, &(ps.rcPaint));
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun else
484*4882a593Smuzhiyun #endif
485*4882a593Smuzhiyun /* Try to copy from the shadow buffer */
486*4882a593Smuzhiyun if (!BitBlt(hdcUpdate,
487*4882a593Smuzhiyun ps.rcPaint.left, ps.rcPaint.top,
488*4882a593Smuzhiyun ps.rcPaint.right - ps.rcPaint.left,
489*4882a593Smuzhiyun ps.rcPaint.bottom - ps.rcPaint.top,
490*4882a593Smuzhiyun s_pScreenPriv->hdcShadow,
491*4882a593Smuzhiyun ps.rcPaint.left + pWin->drawable.x,
492*4882a593Smuzhiyun ps.rcPaint.top + pWin->drawable.y, SRCCOPY)) {
493*4882a593Smuzhiyun LPVOID lpMsgBuf;
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun /* Display a fancy error message */
496*4882a593Smuzhiyun FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
497*4882a593Smuzhiyun FORMAT_MESSAGE_FROM_SYSTEM |
498*4882a593Smuzhiyun FORMAT_MESSAGE_IGNORE_INSERTS,
499*4882a593Smuzhiyun NULL,
500*4882a593Smuzhiyun GetLastError(),
501*4882a593Smuzhiyun MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
502*4882a593Smuzhiyun (LPTSTR) &lpMsgBuf, 0, NULL);
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun ErrorF("winTopLevelWindowProc - BitBlt failed: %s\n",
505*4882a593Smuzhiyun (LPSTR) lpMsgBuf);
506*4882a593Smuzhiyun LocalFree(lpMsgBuf);
507*4882a593Smuzhiyun }
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun /* EndPaint frees the DC */
510*4882a593Smuzhiyun EndPaint(hwnd, &ps);
511*4882a593Smuzhiyun return 0;
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun case WM_MOUSEMOVE:
514*4882a593Smuzhiyun /* Unpack the client area mouse coordinates */
515*4882a593Smuzhiyun ptMouse.x = GET_X_LPARAM(lParam);
516*4882a593Smuzhiyun ptMouse.y = GET_Y_LPARAM(lParam);
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun /* Translate the client area mouse coordinates to screen coordinates */
519*4882a593Smuzhiyun ClientToScreen(hwnd, &ptMouse);
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
522*4882a593Smuzhiyun ptMouse.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
523*4882a593Smuzhiyun ptMouse.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun /* We can't do anything without privates */
526*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
527*4882a593Smuzhiyun break;
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun /* Has the mouse pointer crossed screens? */
530*4882a593Smuzhiyun if (s_pScreen != miPointerGetScreen(g_pwinPointer))
531*4882a593Smuzhiyun miPointerSetScreen(g_pwinPointer, s_pScreenInfo->dwScreen,
532*4882a593Smuzhiyun ptMouse.x - s_pScreenInfo->dwXOffset,
533*4882a593Smuzhiyun ptMouse.y - s_pScreenInfo->dwYOffset);
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun /* Are we tracking yet? */
536*4882a593Smuzhiyun if (!s_fTracking) {
537*4882a593Smuzhiyun TRACKMOUSEEVENT tme;
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun /* Setup data structure */
540*4882a593Smuzhiyun ZeroMemory(&tme, sizeof(tme));
541*4882a593Smuzhiyun tme.cbSize = sizeof(tme);
542*4882a593Smuzhiyun tme.dwFlags = TME_LEAVE;
543*4882a593Smuzhiyun tme.hwndTrack = hwnd;
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun /* Call the tracking function */
546*4882a593Smuzhiyun if (!TrackMouseEvent(&tme))
547*4882a593Smuzhiyun ErrorF("winTopLevelWindowProc - TrackMouseEvent failed\n");
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun /* Flag that we are tracking now */
550*4882a593Smuzhiyun s_fTracking = TRUE;
551*4882a593Smuzhiyun }
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun /* Hide or show the Windows mouse cursor */
554*4882a593Smuzhiyun if (g_fSoftwareCursor && g_fCursor) {
555*4882a593Smuzhiyun /* Hide Windows cursor */
556*4882a593Smuzhiyun g_fCursor = FALSE;
557*4882a593Smuzhiyun ShowCursor(FALSE);
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun /* Kill the timer used to poll mouse events */
561*4882a593Smuzhiyun if (g_uipMousePollingTimerID != 0) {
562*4882a593Smuzhiyun KillTimer(s_pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID);
563*4882a593Smuzhiyun g_uipMousePollingTimerID = 0;
564*4882a593Smuzhiyun }
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun /* Deliver absolute cursor position to X Server */
567*4882a593Smuzhiyun winEnqueueMotion(ptMouse.x - s_pScreenInfo->dwXOffset,
568*4882a593Smuzhiyun ptMouse.y - s_pScreenInfo->dwYOffset);
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun return 0;
571*4882a593Smuzhiyun
572*4882a593Smuzhiyun case WM_NCMOUSEMOVE:
573*4882a593Smuzhiyun /*
574*4882a593Smuzhiyun * We break instead of returning 0 since we need to call
575*4882a593Smuzhiyun * DefWindowProc to get the mouse cursor changes
576*4882a593Smuzhiyun * and min/max/close button highlighting in Windows XP.
577*4882a593Smuzhiyun * The Platform SDK says that you should return 0 if you
578*4882a593Smuzhiyun * process this message, but it fails to mention that you
579*4882a593Smuzhiyun * will give up any default functionality if you do return 0.
580*4882a593Smuzhiyun */
581*4882a593Smuzhiyun
582*4882a593Smuzhiyun /* We can't do anything without privates */
583*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
584*4882a593Smuzhiyun break;
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun /* Non-client mouse movement, show Windows cursor */
587*4882a593Smuzhiyun if (g_fSoftwareCursor && !g_fCursor) {
588*4882a593Smuzhiyun g_fCursor = TRUE;
589*4882a593Smuzhiyun ShowCursor(TRUE);
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun winStartMousePolling(s_pScreenPriv);
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun break;
595*4882a593Smuzhiyun
596*4882a593Smuzhiyun case WM_MOUSELEAVE:
597*4882a593Smuzhiyun /* Mouse has left our client area */
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun /* Flag that we are no longer tracking */
600*4882a593Smuzhiyun s_fTracking = FALSE;
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun /* Show the mouse cursor, if necessary */
603*4882a593Smuzhiyun if (g_fSoftwareCursor && !g_fCursor) {
604*4882a593Smuzhiyun g_fCursor = TRUE;
605*4882a593Smuzhiyun ShowCursor(TRUE);
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun winStartMousePolling(s_pScreenPriv);
609*4882a593Smuzhiyun
610*4882a593Smuzhiyun return 0;
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun case WM_LBUTTONDBLCLK:
613*4882a593Smuzhiyun case WM_LBUTTONDOWN:
614*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
615*4882a593Smuzhiyun break;
616*4882a593Smuzhiyun g_fButton[0] = TRUE;
617*4882a593Smuzhiyun SetCapture(hwnd);
618*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonPress, Button1, wParam);
619*4882a593Smuzhiyun
620*4882a593Smuzhiyun case WM_LBUTTONUP:
621*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
622*4882a593Smuzhiyun break;
623*4882a593Smuzhiyun g_fButton[0] = FALSE;
624*4882a593Smuzhiyun ReleaseCapture();
625*4882a593Smuzhiyun winStartMousePolling(s_pScreenPriv);
626*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button1, wParam);
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun case WM_MBUTTONDBLCLK:
629*4882a593Smuzhiyun case WM_MBUTTONDOWN:
630*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
631*4882a593Smuzhiyun break;
632*4882a593Smuzhiyun g_fButton[1] = TRUE;
633*4882a593Smuzhiyun SetCapture(hwnd);
634*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonPress, Button2, wParam);
635*4882a593Smuzhiyun
636*4882a593Smuzhiyun case WM_MBUTTONUP:
637*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
638*4882a593Smuzhiyun break;
639*4882a593Smuzhiyun g_fButton[1] = FALSE;
640*4882a593Smuzhiyun ReleaseCapture();
641*4882a593Smuzhiyun winStartMousePolling(s_pScreenPriv);
642*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button2, wParam);
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun case WM_RBUTTONDBLCLK:
645*4882a593Smuzhiyun case WM_RBUTTONDOWN:
646*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
647*4882a593Smuzhiyun break;
648*4882a593Smuzhiyun g_fButton[2] = TRUE;
649*4882a593Smuzhiyun SetCapture(hwnd);
650*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonPress, Button3, wParam);
651*4882a593Smuzhiyun
652*4882a593Smuzhiyun case WM_RBUTTONUP:
653*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
654*4882a593Smuzhiyun break;
655*4882a593Smuzhiyun g_fButton[2] = FALSE;
656*4882a593Smuzhiyun ReleaseCapture();
657*4882a593Smuzhiyun winStartMousePolling(s_pScreenPriv);
658*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button3, wParam);
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun case WM_XBUTTONDBLCLK:
661*4882a593Smuzhiyun case WM_XBUTTONDOWN:
662*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
663*4882a593Smuzhiyun break;
664*4882a593Smuzhiyun SetCapture(hwnd);
665*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonPress, HIWORD(wParam) + 7,
666*4882a593Smuzhiyun wParam);
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun case WM_XBUTTONUP:
669*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
670*4882a593Smuzhiyun break;
671*4882a593Smuzhiyun ReleaseCapture();
672*4882a593Smuzhiyun winStartMousePolling(s_pScreenPriv);
673*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonRelease,
674*4882a593Smuzhiyun HIWORD(wParam) + 7, wParam);
675*4882a593Smuzhiyun
676*4882a593Smuzhiyun case WM_MOUSEWHEEL:
677*4882a593Smuzhiyun if (SendMessage
678*4882a593Smuzhiyun (hwnd, WM_NCHITTEST, 0,
679*4882a593Smuzhiyun MAKELONG(GET_X_LPARAM(lParam),
680*4882a593Smuzhiyun GET_Y_LPARAM(lParam))) == HTCLIENT) {
681*4882a593Smuzhiyun /* Pass the message to the root window */
682*4882a593Smuzhiyun SendMessage(hwndScreen, message, wParam, lParam);
683*4882a593Smuzhiyun return 0;
684*4882a593Smuzhiyun }
685*4882a593Smuzhiyun else
686*4882a593Smuzhiyun break;
687*4882a593Smuzhiyun
688*4882a593Smuzhiyun case WM_MOUSEHWHEEL:
689*4882a593Smuzhiyun if (SendMessage
690*4882a593Smuzhiyun (hwnd, WM_NCHITTEST, 0,
691*4882a593Smuzhiyun MAKELONG(GET_X_LPARAM(lParam),
692*4882a593Smuzhiyun GET_Y_LPARAM(lParam))) == HTCLIENT) {
693*4882a593Smuzhiyun /* Pass the message to the root window */
694*4882a593Smuzhiyun SendMessage(hwndScreen, message, wParam, lParam);
695*4882a593Smuzhiyun return 0;
696*4882a593Smuzhiyun }
697*4882a593Smuzhiyun else
698*4882a593Smuzhiyun break;
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun case WM_SETFOCUS:
701*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
702*4882a593Smuzhiyun break;
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun {
705*4882a593Smuzhiyun /* Get the parent window for transient handling */
706*4882a593Smuzhiyun HWND hParent = GetParent(hwnd);
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun if (hParent && IsIconic(hParent))
709*4882a593Smuzhiyun ShowWindow(hParent, SW_RESTORE);
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun winRestoreModeKeyStates();
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun /* Add the keyboard hook if possible */
715*4882a593Smuzhiyun if (g_fKeyboardHookLL)
716*4882a593Smuzhiyun g_fKeyboardHookLL = winInstallKeyboardHookLL();
717*4882a593Smuzhiyun return 0;
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun case WM_KILLFOCUS:
720*4882a593Smuzhiyun /* Pop any pressed keys since we are losing keyboard focus */
721*4882a593Smuzhiyun winKeybdReleaseKeys();
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun /* Remove our keyboard hook if it is installed */
724*4882a593Smuzhiyun winRemoveKeyboardHookLL();
725*4882a593Smuzhiyun
726*4882a593Smuzhiyun /* Revert the X focus as well, but only if the Windows focus is going to another window */
727*4882a593Smuzhiyun if (!wParam && pWin)
728*4882a593Smuzhiyun DeleteWindowFromAnyEvents(pWin, FALSE);
729*4882a593Smuzhiyun
730*4882a593Smuzhiyun return 0;
731*4882a593Smuzhiyun
732*4882a593Smuzhiyun case WM_SYSDEADCHAR:
733*4882a593Smuzhiyun case WM_DEADCHAR:
734*4882a593Smuzhiyun /*
735*4882a593Smuzhiyun * NOTE: We do nothing with WM_*CHAR messages,
736*4882a593Smuzhiyun * nor does the root window, so we can just toss these messages.
737*4882a593Smuzhiyun */
738*4882a593Smuzhiyun return 0;
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun case WM_SYSKEYDOWN:
741*4882a593Smuzhiyun case WM_KEYDOWN:
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun /*
744*4882a593Smuzhiyun * Don't pass Alt-F4 key combo to root window,
745*4882a593Smuzhiyun * let Windows translate to WM_CLOSE and close this top-level window.
746*4882a593Smuzhiyun *
747*4882a593Smuzhiyun * NOTE: We purposely don't check the fUseWinKillKey setting because
748*4882a593Smuzhiyun * it should only apply to the key handling for the root window,
749*4882a593Smuzhiyun * not for top-level window-manager windows.
750*4882a593Smuzhiyun *
751*4882a593Smuzhiyun * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
752*4882a593Smuzhiyun * because that is a key combo that no X app should be expecting to
753*4882a593Smuzhiyun * receive, since it has historically been used to shutdown the X server.
754*4882a593Smuzhiyun * Passing Ctrl-Alt-Backspace to the root window preserves that
755*4882a593Smuzhiyun * behavior, assuming that -unixkill has been passed as a parameter.
756*4882a593Smuzhiyun */
757*4882a593Smuzhiyun if (wParam == VK_F4 && (GetKeyState(VK_MENU) & 0x8000))
758*4882a593Smuzhiyun break;
759*4882a593Smuzhiyun
760*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
761*4882a593Smuzhiyun if (wParam == VK_ESCAPE) {
762*4882a593Smuzhiyun /* Place for debug: put any tests and dumps here */
763*4882a593Smuzhiyun WINDOWPLACEMENT windPlace;
764*4882a593Smuzhiyun RECT rc;
765*4882a593Smuzhiyun LPRECT pRect;
766*4882a593Smuzhiyun
767*4882a593Smuzhiyun windPlace.length = sizeof(WINDOWPLACEMENT);
768*4882a593Smuzhiyun GetWindowPlacement(hwnd, &windPlace);
769*4882a593Smuzhiyun pRect = &windPlace.rcNormalPosition;
770*4882a593Smuzhiyun ErrorF("\nCYGWINDOWING Dump:\n"
771*4882a593Smuzhiyun "\tdrawable: (%hd, %hd) - %hdx%hd\n", pDraw->x,
772*4882a593Smuzhiyun pDraw->y, pDraw->width, pDraw->height);
773*4882a593Smuzhiyun ErrorF("\twindPlace: (%d, %d) - %dx%d\n", (int)pRect->left,
774*4882a593Smuzhiyun (int)pRect->top, (int)(pRect->right - pRect->left),
775*4882a593Smuzhiyun (int)(pRect->bottom - pRect->top));
776*4882a593Smuzhiyun if (GetClientRect(hwnd, &rc)) {
777*4882a593Smuzhiyun pRect = &rc;
778*4882a593Smuzhiyun ErrorF("\tClientRect: (%d, %d) - %dx%d\n", (int)pRect->left,
779*4882a593Smuzhiyun (int)pRect->top, (int)(pRect->right - pRect->left),
780*4882a593Smuzhiyun (int)(pRect->bottom - pRect->top));
781*4882a593Smuzhiyun }
782*4882a593Smuzhiyun if (GetWindowRect(hwnd, &rc)) {
783*4882a593Smuzhiyun pRect = &rc;
784*4882a593Smuzhiyun ErrorF("\tWindowRect: (%d, %d) - %dx%d\n", (int)pRect->left,
785*4882a593Smuzhiyun (int)pRect->top, (int)(pRect->right - pRect->left),
786*4882a593Smuzhiyun (int)(pRect->bottom - pRect->top));
787*4882a593Smuzhiyun }
788*4882a593Smuzhiyun ErrorF("\n");
789*4882a593Smuzhiyun }
790*4882a593Smuzhiyun #endif
791*4882a593Smuzhiyun
792*4882a593Smuzhiyun /* Pass the message to the root window */
793*4882a593Smuzhiyun return winWindowProc(hwndScreen, message, wParam, lParam);
794*4882a593Smuzhiyun
795*4882a593Smuzhiyun case WM_SYSKEYUP:
796*4882a593Smuzhiyun case WM_KEYUP:
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun /* Pass the message to the root window */
799*4882a593Smuzhiyun return winWindowProc(hwndScreen, message, wParam, lParam);
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun case WM_HOTKEY:
802*4882a593Smuzhiyun
803*4882a593Smuzhiyun /* Pass the message to the root window */
804*4882a593Smuzhiyun SendMessage(hwndScreen, message, wParam, lParam);
805*4882a593Smuzhiyun return 0;
806*4882a593Smuzhiyun
807*4882a593Smuzhiyun case WM_ACTIVATE:
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun /* Pass the message to the root window */
810*4882a593Smuzhiyun SendMessage(hwndScreen, message, wParam, lParam);
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun if (LOWORD(wParam) != WA_INACTIVE) {
813*4882a593Smuzhiyun /* Raise the window to the top in Z order */
814*4882a593Smuzhiyun /* ago: Activate does not mean putting it to front! */
815*4882a593Smuzhiyun /*
816*4882a593Smuzhiyun wmMsg.msg = WM_WM_RAISE;
817*4882a593Smuzhiyun if (fWMMsgInitialized)
818*4882a593Smuzhiyun winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
819*4882a593Smuzhiyun */
820*4882a593Smuzhiyun
821*4882a593Smuzhiyun /* Tell our Window Manager thread to activate the window */
822*4882a593Smuzhiyun wmMsg.msg = WM_WM_ACTIVATE;
823*4882a593Smuzhiyun if (fWMMsgInitialized)
824*4882a593Smuzhiyun if (!pWin || !pWin->overrideRedirect) /* for OOo menus */
825*4882a593Smuzhiyun winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun /* Prevent the mouse wheel from stalling when another window is minimized */
828*4882a593Smuzhiyun if (HIWORD(wParam) == 0 && LOWORD(wParam) == WA_ACTIVE &&
829*4882a593Smuzhiyun (HWND) lParam != NULL && (HWND) lParam != GetParent(hwnd))
830*4882a593Smuzhiyun SetFocus(hwnd);
831*4882a593Smuzhiyun return 0;
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun case WM_ACTIVATEAPP:
834*4882a593Smuzhiyun /*
835*4882a593Smuzhiyun * This message is also sent to the root window
836*4882a593Smuzhiyun * so we do nothing for individual multiwindow windows
837*4882a593Smuzhiyun */
838*4882a593Smuzhiyun break;
839*4882a593Smuzhiyun
840*4882a593Smuzhiyun case WM_CLOSE:
841*4882a593Smuzhiyun /* Remove AppUserModelID property */
842*4882a593Smuzhiyun winSetAppUserModelID(hwnd, NULL);
843*4882a593Smuzhiyun /* Branch on if the window was killed in X already */
844*4882a593Smuzhiyun if (pWinPriv->fXKilled) {
845*4882a593Smuzhiyun /* Window was killed, go ahead and destroy the window */
846*4882a593Smuzhiyun DestroyWindow(hwnd);
847*4882a593Smuzhiyun }
848*4882a593Smuzhiyun else {
849*4882a593Smuzhiyun /* Tell our Window Manager thread to kill the window */
850*4882a593Smuzhiyun wmMsg.msg = WM_WM_KILL;
851*4882a593Smuzhiyun if (fWMMsgInitialized)
852*4882a593Smuzhiyun winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);
853*4882a593Smuzhiyun }
854*4882a593Smuzhiyun return 0;
855*4882a593Smuzhiyun
856*4882a593Smuzhiyun case WM_DESTROY:
857*4882a593Smuzhiyun
858*4882a593Smuzhiyun /* Branch on if the window was killed in X already */
859*4882a593Smuzhiyun if (pWinPriv && !pWinPriv->fXKilled) {
860*4882a593Smuzhiyun ErrorF("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n");
861*4882a593Smuzhiyun
862*4882a593Smuzhiyun /* Tell our Window Manager thread to kill the window */
863*4882a593Smuzhiyun wmMsg.msg = WM_WM_KILL;
864*4882a593Smuzhiyun if (fWMMsgInitialized)
865*4882a593Smuzhiyun winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);
866*4882a593Smuzhiyun }
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun RemoveProp(hwnd, WIN_WINDOW_PROP);
869*4882a593Smuzhiyun RemoveProp(hwnd, WIN_WID_PROP);
870*4882a593Smuzhiyun RemoveProp(hwnd, WIN_NEEDMANAGE_PROP);
871*4882a593Smuzhiyun
872*4882a593Smuzhiyun break;
873*4882a593Smuzhiyun
874*4882a593Smuzhiyun case WM_MOVE:
875*4882a593Smuzhiyun /* Adjust the X Window to the moved Windows window */
876*4882a593Smuzhiyun if (!hasEnteredSizeMove)
877*4882a593Smuzhiyun winAdjustXWindow(pWin, hwnd);
878*4882a593Smuzhiyun /* else: Wait for WM_EXITSIZEMOVE */
879*4882a593Smuzhiyun return 0;
880*4882a593Smuzhiyun
881*4882a593Smuzhiyun case WM_SHOWWINDOW:
882*4882a593Smuzhiyun /* Bail out if the window is being hidden */
883*4882a593Smuzhiyun if (!wParam)
884*4882a593Smuzhiyun return 0;
885*4882a593Smuzhiyun
886*4882a593Smuzhiyun /* */
887*4882a593Smuzhiyun if (!pWin->overrideRedirect) {
888*4882a593Smuzhiyun HWND zstyle = HWND_NOTOPMOST;
889*4882a593Smuzhiyun
890*4882a593Smuzhiyun /* Flag that this window needs to be made active when clicked */
891*4882a593Smuzhiyun SetProp(hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1);
892*4882a593Smuzhiyun
893*4882a593Smuzhiyun /* Set the transient style flags */
894*4882a593Smuzhiyun if (GetParent(hwnd))
895*4882a593Smuzhiyun SetWindowLongPtr(hwnd, GWL_STYLE,
896*4882a593Smuzhiyun WS_POPUP | WS_OVERLAPPED | WS_SYSMENU |
897*4882a593Smuzhiyun WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
898*4882a593Smuzhiyun /* Set the window standard style flags */
899*4882a593Smuzhiyun else
900*4882a593Smuzhiyun SetWindowLongPtr(hwnd, GWL_STYLE,
901*4882a593Smuzhiyun (WS_POPUP | WS_OVERLAPPEDWINDOW |
902*4882a593Smuzhiyun WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
903*4882a593Smuzhiyun & ~WS_CAPTION & ~WS_SIZEBOX);
904*4882a593Smuzhiyun
905*4882a593Smuzhiyun winUpdateWindowPosition(hwnd, &zstyle);
906*4882a593Smuzhiyun
907*4882a593Smuzhiyun {
908*4882a593Smuzhiyun WinXWMHints hints;
909*4882a593Smuzhiyun
910*4882a593Smuzhiyun if (winMultiWindowGetWMHints(pWin, &hints)) {
911*4882a593Smuzhiyun /*
912*4882a593Smuzhiyun Give the window focus, unless it has an InputHint
913*4882a593Smuzhiyun which is FALSE (this is used by e.g. glean to
914*4882a593Smuzhiyun avoid every test window grabbing the focus)
915*4882a593Smuzhiyun */
916*4882a593Smuzhiyun if (!((hints.flags & InputHint) && (!hints.input))) {
917*4882a593Smuzhiyun SetForegroundWindow(hwnd);
918*4882a593Smuzhiyun }
919*4882a593Smuzhiyun }
920*4882a593Smuzhiyun }
921*4882a593Smuzhiyun wmMsg.msg = WM_WM_MAP3;
922*4882a593Smuzhiyun }
923*4882a593Smuzhiyun else { /* It is an overridden window so make it top of Z stack */
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun HWND forHwnd = GetForegroundWindow();
926*4882a593Smuzhiyun
927*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
928*4882a593Smuzhiyun ErrorF("overridden window is shown\n");
929*4882a593Smuzhiyun #endif
930*4882a593Smuzhiyun if (forHwnd != NULL) {
931*4882a593Smuzhiyun if (GetWindowLongPtr(forHwnd, GWLP_USERDATA) & (LONG_PTR)
932*4882a593Smuzhiyun XMING_SIGNATURE) {
933*4882a593Smuzhiyun if (GetWindowLongPtr(forHwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
934*4882a593Smuzhiyun SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
935*4882a593Smuzhiyun SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
936*4882a593Smuzhiyun else
937*4882a593Smuzhiyun SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
938*4882a593Smuzhiyun SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
939*4882a593Smuzhiyun }
940*4882a593Smuzhiyun }
941*4882a593Smuzhiyun wmMsg.msg = WM_WM_MAP2;
942*4882a593Smuzhiyun }
943*4882a593Smuzhiyun
944*4882a593Smuzhiyun /* Tell our Window Manager thread to map the window */
945*4882a593Smuzhiyun if (fWMMsgInitialized)
946*4882a593Smuzhiyun winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun winStartMousePolling(s_pScreenPriv);
949*4882a593Smuzhiyun
950*4882a593Smuzhiyun return 0;
951*4882a593Smuzhiyun
952*4882a593Smuzhiyun case WM_SIZING:
953*4882a593Smuzhiyun /* Need to legalize the size according to WM_NORMAL_HINTS */
954*4882a593Smuzhiyun /* for applications like xterm */
955*4882a593Smuzhiyun return ValidateSizing(hwnd, pWin, wParam, lParam);
956*4882a593Smuzhiyun
957*4882a593Smuzhiyun case WM_WINDOWPOSCHANGED:
958*4882a593Smuzhiyun {
959*4882a593Smuzhiyun LPWINDOWPOS pWinPos = (LPWINDOWPOS) lParam;
960*4882a593Smuzhiyun
961*4882a593Smuzhiyun if (!(pWinPos->flags & SWP_NOZORDER)) {
962*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
963*4882a593Smuzhiyun winDebug("\twindow z order was changed\n");
964*4882a593Smuzhiyun #endif
965*4882a593Smuzhiyun if (pWinPos->hwndInsertAfter == HWND_TOP
966*4882a593Smuzhiyun || pWinPos->hwndInsertAfter == HWND_TOPMOST
967*4882a593Smuzhiyun || pWinPos->hwndInsertAfter == HWND_NOTOPMOST) {
968*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
969*4882a593Smuzhiyun winDebug("\traise to top\n");
970*4882a593Smuzhiyun #endif
971*4882a593Smuzhiyun /* Raise the window to the top in Z order */
972*4882a593Smuzhiyun winRaiseWindow(pWin);
973*4882a593Smuzhiyun }
974*4882a593Smuzhiyun else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) {
975*4882a593Smuzhiyun }
976*4882a593Smuzhiyun else {
977*4882a593Smuzhiyun /* Check if this window is top of X windows. */
978*4882a593Smuzhiyun HWND hWndAbove = NULL;
979*4882a593Smuzhiyun DWORD dwCurrentProcessID = GetCurrentProcessId();
980*4882a593Smuzhiyun DWORD dwWindowProcessID = 0;
981*4882a593Smuzhiyun
982*4882a593Smuzhiyun for (hWndAbove = pWinPos->hwndInsertAfter;
983*4882a593Smuzhiyun hWndAbove != NULL;
984*4882a593Smuzhiyun hWndAbove = GetNextWindow(hWndAbove, GW_HWNDPREV)) {
985*4882a593Smuzhiyun /* Ignore other XWin process's window */
986*4882a593Smuzhiyun GetWindowThreadProcessId(hWndAbove, &dwWindowProcessID);
987*4882a593Smuzhiyun
988*4882a593Smuzhiyun if ((dwWindowProcessID == dwCurrentProcessID)
989*4882a593Smuzhiyun && GetProp(hWndAbove, WIN_WINDOW_PROP)
990*4882a593Smuzhiyun && !IsWindowVisible(hWndAbove)
991*4882a593Smuzhiyun && !IsIconic(hWndAbove)) /* ignore minimized windows */
992*4882a593Smuzhiyun break;
993*4882a593Smuzhiyun }
994*4882a593Smuzhiyun /* If this is top of X windows in Windows stack,
995*4882a593Smuzhiyun raise it in X stack. */
996*4882a593Smuzhiyun if (hWndAbove == NULL) {
997*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
998*4882a593Smuzhiyun winDebug("\traise to top\n");
999*4882a593Smuzhiyun #endif
1000*4882a593Smuzhiyun winRaiseWindow(pWin);
1001*4882a593Smuzhiyun }
1002*4882a593Smuzhiyun }
1003*4882a593Smuzhiyun }
1004*4882a593Smuzhiyun }
1005*4882a593Smuzhiyun /*
1006*4882a593Smuzhiyun * Pass the message to DefWindowProc to let the function
1007*4882a593Smuzhiyun * break down WM_WINDOWPOSCHANGED to WM_MOVE and WM_SIZE.
1008*4882a593Smuzhiyun */
1009*4882a593Smuzhiyun break;
1010*4882a593Smuzhiyun
1011*4882a593Smuzhiyun case WM_ENTERSIZEMOVE:
1012*4882a593Smuzhiyun hasEnteredSizeMove = TRUE;
1013*4882a593Smuzhiyun return 0;
1014*4882a593Smuzhiyun
1015*4882a593Smuzhiyun case WM_EXITSIZEMOVE:
1016*4882a593Smuzhiyun /* Adjust the X Window to the moved Windows window */
1017*4882a593Smuzhiyun hasEnteredSizeMove = FALSE;
1018*4882a593Smuzhiyun winAdjustXWindow(pWin, hwnd);
1019*4882a593Smuzhiyun return 0;
1020*4882a593Smuzhiyun
1021*4882a593Smuzhiyun case WM_SIZE:
1022*4882a593Smuzhiyun /* see dix/window.c */
1023*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
1024*4882a593Smuzhiyun {
1025*4882a593Smuzhiyun char buf[64];
1026*4882a593Smuzhiyun
1027*4882a593Smuzhiyun switch (wParam) {
1028*4882a593Smuzhiyun case SIZE_MINIMIZED:
1029*4882a593Smuzhiyun strcpy(buf, "SIZE_MINIMIZED");
1030*4882a593Smuzhiyun break;
1031*4882a593Smuzhiyun case SIZE_MAXIMIZED:
1032*4882a593Smuzhiyun strcpy(buf, "SIZE_MAXIMIZED");
1033*4882a593Smuzhiyun break;
1034*4882a593Smuzhiyun case SIZE_RESTORED:
1035*4882a593Smuzhiyun strcpy(buf, "SIZE_RESTORED");
1036*4882a593Smuzhiyun break;
1037*4882a593Smuzhiyun default:
1038*4882a593Smuzhiyun strcpy(buf, "UNKNOWN_FLAG");
1039*4882a593Smuzhiyun }
1040*4882a593Smuzhiyun ErrorF("winTopLevelWindowProc - WM_SIZE to %dx%d (%s)\n",
1041*4882a593Smuzhiyun (int) LOWORD(lParam), (int) HIWORD(lParam), buf);
1042*4882a593Smuzhiyun }
1043*4882a593Smuzhiyun #endif
1044*4882a593Smuzhiyun if (!hasEnteredSizeMove) {
1045*4882a593Smuzhiyun /* Adjust the X Window to the moved Windows window */
1046*4882a593Smuzhiyun winAdjustXWindow(pWin, hwnd);
1047*4882a593Smuzhiyun }
1048*4882a593Smuzhiyun /* else: wait for WM_EXITSIZEMOVE */
1049*4882a593Smuzhiyun return 0; /* end of WM_SIZE handler */
1050*4882a593Smuzhiyun
1051*4882a593Smuzhiyun case WM_STYLECHANGING:
1052*4882a593Smuzhiyun /*
1053*4882a593Smuzhiyun When the style changes, adjust the Windows window size so the client area remains the same size,
1054*4882a593Smuzhiyun and adjust the Windows window position so that the client area remains in the same place.
1055*4882a593Smuzhiyun */
1056*4882a593Smuzhiyun {
1057*4882a593Smuzhiyun RECT newWinRect;
1058*4882a593Smuzhiyun DWORD dwExStyle;
1059*4882a593Smuzhiyun DWORD dwStyle;
1060*4882a593Smuzhiyun DWORD newStyle = ((STYLESTRUCT *) lParam)->styleNew;
1061*4882a593Smuzhiyun WINDOWINFO wi;
1062*4882a593Smuzhiyun
1063*4882a593Smuzhiyun dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
1064*4882a593Smuzhiyun dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
1065*4882a593Smuzhiyun
1066*4882a593Smuzhiyun winDebug("winTopLevelWindowProc - WM_STYLECHANGING from %08x %08x\n",
1067*4882a593Smuzhiyun (unsigned int)dwStyle, (unsigned int)dwExStyle);
1068*4882a593Smuzhiyun
1069*4882a593Smuzhiyun if (wParam == GWL_EXSTYLE)
1070*4882a593Smuzhiyun dwExStyle = newStyle;
1071*4882a593Smuzhiyun
1072*4882a593Smuzhiyun if (wParam == GWL_STYLE)
1073*4882a593Smuzhiyun dwStyle = newStyle;
1074*4882a593Smuzhiyun
1075*4882a593Smuzhiyun winDebug("winTopLevelWindowProc - WM_STYLECHANGING to %08x %08x\n",
1076*4882a593Smuzhiyun (unsigned int)dwStyle, (unsigned int)dwExStyle);
1077*4882a593Smuzhiyun
1078*4882a593Smuzhiyun /* Get client rect in screen coordinates */
1079*4882a593Smuzhiyun wi.cbSize = sizeof(WINDOWINFO);
1080*4882a593Smuzhiyun GetWindowInfo(hwnd, &wi);
1081*4882a593Smuzhiyun
1082*4882a593Smuzhiyun winDebug
1083*4882a593Smuzhiyun ("winTopLevelWindowProc - WM_STYLECHANGING client area {%d, %d, %d, %d}, {%d x %d}\n",
1084*4882a593Smuzhiyun (int)wi.rcClient.left, (int)wi.rcClient.top, (int)wi.rcClient.right,
1085*4882a593Smuzhiyun (int)wi.rcClient.bottom, (int)(wi.rcClient.right - wi.rcClient.left),
1086*4882a593Smuzhiyun (int)(wi.rcClient.bottom - wi.rcClient.top));
1087*4882a593Smuzhiyun
1088*4882a593Smuzhiyun newWinRect = wi.rcClient;
1089*4882a593Smuzhiyun if (!AdjustWindowRectEx(&newWinRect, dwStyle, FALSE, dwExStyle))
1090*4882a593Smuzhiyun winDebug
1091*4882a593Smuzhiyun ("winTopLevelWindowProc - WM_STYLECHANGING AdjustWindowRectEx failed\n");
1092*4882a593Smuzhiyun
1093*4882a593Smuzhiyun winDebug
1094*4882a593Smuzhiyun ("winTopLevelWindowProc - WM_STYLECHANGING window area should be {%d, %d, %d, %d}, {%d x %d}\n",
1095*4882a593Smuzhiyun (int)newWinRect.left, (int)newWinRect.top, (int)newWinRect.right,
1096*4882a593Smuzhiyun (int)newWinRect.bottom, (int)(newWinRect.right - newWinRect.left),
1097*4882a593Smuzhiyun (int)(newWinRect.bottom - newWinRect.top));
1098*4882a593Smuzhiyun
1099*4882a593Smuzhiyun /*
1100*4882a593Smuzhiyun Style change hasn't happened yet, so we can't adjust the window size yet, as the winAdjustXWindow()
1101*4882a593Smuzhiyun which WM_SIZE does will use the current (unchanged) style. Instead make a note to change it when
1102*4882a593Smuzhiyun WM_STYLECHANGED is received...
1103*4882a593Smuzhiyun */
1104*4882a593Smuzhiyun pWinPriv->hDwp = BeginDeferWindowPos(1);
1105*4882a593Smuzhiyun pWinPriv->hDwp =
1106*4882a593Smuzhiyun DeferWindowPos(pWinPriv->hDwp, hwnd, NULL, newWinRect.left,
1107*4882a593Smuzhiyun newWinRect.top, newWinRect.right - newWinRect.left,
1108*4882a593Smuzhiyun newWinRect.bottom - newWinRect.top,
1109*4882a593Smuzhiyun SWP_NOACTIVATE | SWP_NOZORDER);
1110*4882a593Smuzhiyun }
1111*4882a593Smuzhiyun return 0;
1112*4882a593Smuzhiyun
1113*4882a593Smuzhiyun case WM_STYLECHANGED:
1114*4882a593Smuzhiyun {
1115*4882a593Smuzhiyun if (pWinPriv->hDwp) {
1116*4882a593Smuzhiyun EndDeferWindowPos(pWinPriv->hDwp);
1117*4882a593Smuzhiyun pWinPriv->hDwp = NULL;
1118*4882a593Smuzhiyun }
1119*4882a593Smuzhiyun winDebug("winTopLevelWindowProc - WM_STYLECHANGED done\n");
1120*4882a593Smuzhiyun }
1121*4882a593Smuzhiyun return 0;
1122*4882a593Smuzhiyun
1123*4882a593Smuzhiyun case WM_MOUSEACTIVATE:
1124*4882a593Smuzhiyun
1125*4882a593Smuzhiyun /* Check if this window needs to be made active when clicked */
1126*4882a593Smuzhiyun if (!GetProp(pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) {
1127*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
1128*4882a593Smuzhiyun ErrorF("winTopLevelWindowProc - WM_MOUSEACTIVATE - "
1129*4882a593Smuzhiyun "MA_NOACTIVATE\n");
1130*4882a593Smuzhiyun #endif
1131*4882a593Smuzhiyun
1132*4882a593Smuzhiyun /* */
1133*4882a593Smuzhiyun return MA_NOACTIVATE;
1134*4882a593Smuzhiyun }
1135*4882a593Smuzhiyun break;
1136*4882a593Smuzhiyun
1137*4882a593Smuzhiyun case WM_SETCURSOR:
1138*4882a593Smuzhiyun if (LOWORD(lParam) == HTCLIENT) {
1139*4882a593Smuzhiyun if (!g_fSoftwareCursor)
1140*4882a593Smuzhiyun SetCursor(s_pScreenPriv->cursor.handle);
1141*4882a593Smuzhiyun return TRUE;
1142*4882a593Smuzhiyun }
1143*4882a593Smuzhiyun break;
1144*4882a593Smuzhiyun
1145*4882a593Smuzhiyun default:
1146*4882a593Smuzhiyun break;
1147*4882a593Smuzhiyun }
1148*4882a593Smuzhiyun
1149*4882a593Smuzhiyun ret = DefWindowProc(hwnd, message, wParam, lParam);
1150*4882a593Smuzhiyun /*
1151*4882a593Smuzhiyun * If the window was minized we get the stack change before the window is restored
1152*4882a593Smuzhiyun * and so it gets lost. Ensure there stacking order is correct.
1153*4882a593Smuzhiyun */
1154*4882a593Smuzhiyun if (needRestack)
1155*4882a593Smuzhiyun winReorderWindowsMultiWindow();
1156*4882a593Smuzhiyun return ret;
1157*4882a593Smuzhiyun }
1158