1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun *Permission is hereby granted, free of charge, to any person obtaining
5*4882a593Smuzhiyun * a copy of this software and associated documentation files (the
6*4882a593Smuzhiyun *"Software"), to deal in the Software without restriction, including
7*4882a593Smuzhiyun *without limitation the rights to use, copy, modify, merge, publish,
8*4882a593Smuzhiyun *distribute, sublicense, and/or sell copies of the Software, and to
9*4882a593Smuzhiyun *permit persons to whom the Software is furnished to do so, subject to
10*4882a593Smuzhiyun *the following conditions:
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun *The above copyright notice and this permission notice shall be
13*4882a593Smuzhiyun *included in all copies or substantial portions of the Software.
14*4882a593Smuzhiyun *
15*4882a593Smuzhiyun *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*4882a593Smuzhiyun *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*4882a593Smuzhiyun *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18*4882a593Smuzhiyun *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
19*4882a593Smuzhiyun *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20*4882a593Smuzhiyun *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21*4882a593Smuzhiyun *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun *Except as contained in this notice, the name of the XFree86 Project
24*4882a593Smuzhiyun *shall not be used in advertising or otherwise to promote the sale, use
25*4882a593Smuzhiyun *or other dealings in this Software without prior written authorization
26*4882a593Smuzhiyun *from the XFree86 Project.
27*4882a593Smuzhiyun *
28*4882a593Smuzhiyun * Authors: Kensuke Matsuzaki
29*4882a593Smuzhiyun * Earle F. Philhower, III
30*4882a593Smuzhiyun * Harold L Hunt II
31*4882a593Smuzhiyun */
32*4882a593Smuzhiyun #ifdef HAVE_XWIN_CONFIG_H
33*4882a593Smuzhiyun #include <xwin-config.h>
34*4882a593Smuzhiyun #endif
35*4882a593Smuzhiyun #include "win.h"
36*4882a593Smuzhiyun #include <winuser.h>
37*4882a593Smuzhiyun #define _WINDOWSWM_SERVER_
38*4882a593Smuzhiyun #include <X11/extensions/windowswmstr.h>
39*4882a593Smuzhiyun #include "dixevents.h"
40*4882a593Smuzhiyun #include "propertyst.h"
41*4882a593Smuzhiyun #include <X11/Xatom.h>
42*4882a593Smuzhiyun #include "winmultiwindowclass.h"
43*4882a593Smuzhiyun #include "winmsg.h"
44*4882a593Smuzhiyun #include "inputstr.h"
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun /*
47*4882a593Smuzhiyun * Constant defines
48*4882a593Smuzhiyun */
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun #define MOUSE_ACTIVATE_DEFAULT TRUE
51*4882a593Smuzhiyun #define RAISE_ON_CLICK_DEFAULT FALSE
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun /*
54*4882a593Smuzhiyun * Local globals
55*4882a593Smuzhiyun */
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun static UINT_PTR g_uipMousePollingTimerID = 0;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun /*
60*4882a593Smuzhiyun * Local function
61*4882a593Smuzhiyun */
62*4882a593Smuzhiyun
DEFINE_ATOM_HELPER(AtmWindowsWMMouseActivate,WINDOWSWM_MOUSE_ACTIVATE)63*4882a593Smuzhiyun DEFINE_ATOM_HELPER(AtmWindowsWMMouseActivate, WINDOWSWM_MOUSE_ACTIVATE)
64*4882a593Smuzhiyun /* DEFINE_ATOM_HELPER(AtmWindowsWMClientWindow, WINDOWSWM_CLIENT_WINDOW) */
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun /*
67*4882a593Smuzhiyun * ConstrainSize - Taken from TWM sources - Respects hints for sizing
68*4882a593Smuzhiyun */
69*4882a593Smuzhiyun #define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
70*4882a593Smuzhiyun static void
71*4882a593Smuzhiyun ConstrainSize(WinXSizeHints hints, int *widthp, int *heightp)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta;
74*4882a593Smuzhiyun int baseWidth, baseHeight;
75*4882a593Smuzhiyun int dwidth = *widthp, dheight = *heightp;
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun if (hints.flags & PMinSize) {
78*4882a593Smuzhiyun minWidth = hints.min_width;
79*4882a593Smuzhiyun minHeight = hints.min_height;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun else if (hints.flags & PBaseSize) {
82*4882a593Smuzhiyun minWidth = hints.base_width;
83*4882a593Smuzhiyun minHeight = hints.base_height;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun else
86*4882a593Smuzhiyun minWidth = minHeight = 1;
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun if (hints.flags & PBaseSize) {
89*4882a593Smuzhiyun baseWidth = hints.base_width;
90*4882a593Smuzhiyun baseHeight = hints.base_height;
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun else if (hints.flags & PMinSize) {
93*4882a593Smuzhiyun baseWidth = hints.min_width;
94*4882a593Smuzhiyun baseHeight = hints.min_height;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun else
97*4882a593Smuzhiyun baseWidth = baseHeight = 0;
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun if (hints.flags & PMaxSize) {
100*4882a593Smuzhiyun maxWidth = hints.max_width;
101*4882a593Smuzhiyun maxHeight = hints.max_height;
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun else {
104*4882a593Smuzhiyun maxWidth = MAXINT;
105*4882a593Smuzhiyun maxHeight = MAXINT;
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun if (hints.flags & PResizeInc) {
109*4882a593Smuzhiyun xinc = hints.width_inc;
110*4882a593Smuzhiyun yinc = hints.height_inc;
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun else
113*4882a593Smuzhiyun xinc = yinc = 1;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun /*
116*4882a593Smuzhiyun * First, clamp to min and max values
117*4882a593Smuzhiyun */
118*4882a593Smuzhiyun if (dwidth < minWidth)
119*4882a593Smuzhiyun dwidth = minWidth;
120*4882a593Smuzhiyun if (dheight < minHeight)
121*4882a593Smuzhiyun dheight = minHeight;
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun if (dwidth > maxWidth)
124*4882a593Smuzhiyun dwidth = maxWidth;
125*4882a593Smuzhiyun if (dheight > maxHeight)
126*4882a593Smuzhiyun dheight = maxHeight;
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun /*
129*4882a593Smuzhiyun * Second, fit to base + N * inc
130*4882a593Smuzhiyun */
131*4882a593Smuzhiyun dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth;
132*4882a593Smuzhiyun dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun /*
135*4882a593Smuzhiyun * Third, adjust for aspect ratio
136*4882a593Smuzhiyun */
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun /*
139*4882a593Smuzhiyun * The math looks like this:
140*4882a593Smuzhiyun *
141*4882a593Smuzhiyun * minAspectX dwidth maxAspectX
142*4882a593Smuzhiyun * ---------- <= ------- <= ----------
143*4882a593Smuzhiyun * minAspectY dheight maxAspectY
144*4882a593Smuzhiyun *
145*4882a593Smuzhiyun * If that is multiplied out, then the width and height are
146*4882a593Smuzhiyun * invalid in the following situations:
147*4882a593Smuzhiyun *
148*4882a593Smuzhiyun * minAspectX * dheight > minAspectY * dwidth
149*4882a593Smuzhiyun * maxAspectX * dheight < maxAspectY * dwidth
150*4882a593Smuzhiyun *
151*4882a593Smuzhiyun */
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun if (hints.flags & PAspect) {
154*4882a593Smuzhiyun if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth) {
155*4882a593Smuzhiyun delta =
156*4882a593Smuzhiyun makemult(hints.min_aspect.x * dheight / hints.min_aspect.y -
157*4882a593Smuzhiyun dwidth, xinc);
158*4882a593Smuzhiyun if (dwidth + delta <= maxWidth)
159*4882a593Smuzhiyun dwidth += delta;
160*4882a593Smuzhiyun else {
161*4882a593Smuzhiyun delta =
162*4882a593Smuzhiyun makemult(dheight -
163*4882a593Smuzhiyun dwidth * hints.min_aspect.y / hints.min_aspect.x,
164*4882a593Smuzhiyun yinc);
165*4882a593Smuzhiyun if (dheight - delta >= minHeight)
166*4882a593Smuzhiyun dheight -= delta;
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth) {
171*4882a593Smuzhiyun delta =
172*4882a593Smuzhiyun makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x -
173*4882a593Smuzhiyun dheight, yinc);
174*4882a593Smuzhiyun if (dheight + delta <= maxHeight)
175*4882a593Smuzhiyun dheight += delta;
176*4882a593Smuzhiyun else {
177*4882a593Smuzhiyun delta =
178*4882a593Smuzhiyun makemult(dwidth -
179*4882a593Smuzhiyun hints.max_aspect.x * dheight / hints.max_aspect.y,
180*4882a593Smuzhiyun xinc);
181*4882a593Smuzhiyun if (dwidth - delta >= minWidth)
182*4882a593Smuzhiyun dwidth -= delta;
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun /* Return computed values */
188*4882a593Smuzhiyun *widthp = dwidth;
189*4882a593Smuzhiyun *heightp = dheight;
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun #undef makemult
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun /*
195*4882a593Smuzhiyun * ValidateSizing - Ensures size request respects hints
196*4882a593Smuzhiyun */
197*4882a593Smuzhiyun static int
ValidateSizing(HWND hwnd,WindowPtr pWin,WPARAM wParam,LPARAM lParam)198*4882a593Smuzhiyun ValidateSizing(HWND hwnd, WindowPtr pWin, WPARAM wParam, LPARAM lParam)
199*4882a593Smuzhiyun {
200*4882a593Smuzhiyun WinXSizeHints sizeHints;
201*4882a593Smuzhiyun RECT *rect;
202*4882a593Smuzhiyun int iWidth, iHeight, iTopBorder;
203*4882a593Smuzhiyun POINT pt;
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun /* Invalid input checking */
206*4882a593Smuzhiyun if (pWin == NULL || lParam == 0) {
207*4882a593Smuzhiyun ErrorF("Invalid input checking\n");
208*4882a593Smuzhiyun return FALSE;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun /* No size hints, no checking */
212*4882a593Smuzhiyun if (!winMultiWindowGetWMNormalHints(pWin, &sizeHints)) {
213*4882a593Smuzhiyun ErrorF("No size hints, no checking\n");
214*4882a593Smuzhiyun return FALSE;
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun /* Avoid divide-by-zero */
218*4882a593Smuzhiyun if (sizeHints.flags & PResizeInc) {
219*4882a593Smuzhiyun if (sizeHints.width_inc == 0)
220*4882a593Smuzhiyun sizeHints.width_inc = 1;
221*4882a593Smuzhiyun if (sizeHints.height_inc == 0)
222*4882a593Smuzhiyun sizeHints.height_inc = 1;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun rect = (RECT *) lParam;
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun iWidth = rect->right - rect->left;
228*4882a593Smuzhiyun iHeight = rect->bottom - rect->top;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun /* Get title bar height, there must be an easier way?! */
231*4882a593Smuzhiyun pt.x = pt.y = 0;
232*4882a593Smuzhiyun ClientToScreen(hwnd, &pt);
233*4882a593Smuzhiyun iTopBorder = pt.y - rect->top;
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun /* Now remove size of any borders */
236*4882a593Smuzhiyun iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME);
237*4882a593Smuzhiyun iHeight -= GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun /* Constrain the size to legal values */
240*4882a593Smuzhiyun ConstrainSize(sizeHints, &iWidth, &iHeight);
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun /* Add back the borders */
243*4882a593Smuzhiyun iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME);
244*4882a593Smuzhiyun iHeight += GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun /* Adjust size according to where we're dragging from */
247*4882a593Smuzhiyun switch (wParam) {
248*4882a593Smuzhiyun case WMSZ_TOP:
249*4882a593Smuzhiyun case WMSZ_TOPRIGHT:
250*4882a593Smuzhiyun case WMSZ_BOTTOM:
251*4882a593Smuzhiyun case WMSZ_BOTTOMRIGHT:
252*4882a593Smuzhiyun case WMSZ_RIGHT:
253*4882a593Smuzhiyun rect->right = rect->left + iWidth;
254*4882a593Smuzhiyun break;
255*4882a593Smuzhiyun default:
256*4882a593Smuzhiyun rect->left = rect->right - iWidth;
257*4882a593Smuzhiyun break;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun switch (wParam) {
260*4882a593Smuzhiyun case WMSZ_BOTTOM:
261*4882a593Smuzhiyun case WMSZ_BOTTOMRIGHT:
262*4882a593Smuzhiyun case WMSZ_BOTTOMLEFT:
263*4882a593Smuzhiyun case WMSZ_RIGHT:
264*4882a593Smuzhiyun case WMSZ_LEFT:
265*4882a593Smuzhiyun rect->bottom = rect->top + iHeight;
266*4882a593Smuzhiyun break;
267*4882a593Smuzhiyun default:
268*4882a593Smuzhiyun rect->top = rect->bottom - iHeight;
269*4882a593Smuzhiyun break;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun return TRUE;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun /*
275*4882a593Smuzhiyun * IsMouseActive
276*4882a593Smuzhiyun */
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun static Bool
IsMouseActive(WindowPtr pWin)279*4882a593Smuzhiyun IsMouseActive(WindowPtr pWin)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun struct _Window *pwin;
283*4882a593Smuzhiyun struct _Property *prop;
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun /* XXX We're getting inputInfo.poniter here, but this might be really wrong.
286*4882a593Smuzhiyun * Which pointer's current window do we want? */
287*4882a593Smuzhiyun WindowPtr pRoot = GetCurrentRootWindow(inputInfo.pointer);
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun if (!pWin) {
290*4882a593Smuzhiyun ErrorF("IsMouseActive - pWin was NULL use default value:%d\n",
291*4882a593Smuzhiyun MOUSE_ACTIVATE_DEFAULT);
292*4882a593Smuzhiyun return MOUSE_ACTIVATE_DEFAULT;
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun pwin = (struct _Window *) pWin;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun if (pwin->optional)
298*4882a593Smuzhiyun prop = (struct _Property *) pwin->optional->userProps;
299*4882a593Smuzhiyun else
300*4882a593Smuzhiyun prop = NULL;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun while (prop) {
303*4882a593Smuzhiyun if (prop->propertyName == AtmWindowsWMMouseActivate()
304*4882a593Smuzhiyun && prop->type == XA_INTEGER && prop->format == 32) {
305*4882a593Smuzhiyun return *(int *) prop->data;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun else
308*4882a593Smuzhiyun prop = prop->next;
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun if (pWin != pRoot) {
312*4882a593Smuzhiyun return IsMouseActive(pRoot);
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun else {
315*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
316*4882a593Smuzhiyun winDebug("IsMouseActive - no prop use default value:%d\n",
317*4882a593Smuzhiyun MOUSE_ACTIVATE_DEFAULT);
318*4882a593Smuzhiyun #endif
319*4882a593Smuzhiyun return MOUSE_ACTIVATE_DEFAULT;
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun /*
324*4882a593Smuzhiyun * winMWExtWMWindowProc - Window procedure
325*4882a593Smuzhiyun */
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun LRESULT CALLBACK
winMWExtWMWindowProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)328*4882a593Smuzhiyun winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
329*4882a593Smuzhiyun {
330*4882a593Smuzhiyun WindowPtr pWin = NULL;
331*4882a593Smuzhiyun win32RootlessWindowPtr pRLWinPriv = NULL;
332*4882a593Smuzhiyun ScreenPtr pScreen = NULL;
333*4882a593Smuzhiyun winPrivScreenPtr pScreenPriv = NULL;
334*4882a593Smuzhiyun winScreenInfo *pScreenInfo = NULL;
335*4882a593Smuzhiyun HWND hwndScreen = NULL;
336*4882a593Smuzhiyun POINT ptMouse;
337*4882a593Smuzhiyun static Bool s_fTracking = FALSE;
338*4882a593Smuzhiyun HDC hdcUpdate;
339*4882a593Smuzhiyun PAINTSTRUCT ps;
340*4882a593Smuzhiyun LPWINDOWPOS pWinPos = NULL;
341*4882a593Smuzhiyun RECT rcClient;
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun /* Check if the Windows window property for our X window pointer is valid */
344*4882a593Smuzhiyun if ((pRLWinPriv =
345*4882a593Smuzhiyun (win32RootlessWindowPtr) GetProp(hwnd, WIN_WINDOW_PROP)) != NULL) {
346*4882a593Smuzhiyun pWin = pRLWinPriv->pFrame->win;
347*4882a593Smuzhiyun pScreen = pWin->drawable.pScreen;
348*4882a593Smuzhiyun if (pScreen)
349*4882a593Smuzhiyun pScreenPriv = winGetScreenPriv(pScreen);
350*4882a593Smuzhiyun if (pScreenPriv)
351*4882a593Smuzhiyun pScreenInfo = pScreenPriv->pScreenInfo;
352*4882a593Smuzhiyun if (pScreenPriv)
353*4882a593Smuzhiyun hwndScreen = pScreenPriv->hwndScreen;
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun #if CYGDEBUG
356*4882a593Smuzhiyun winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam,
357*4882a593Smuzhiyun lParam);
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun winDebug("\thWnd %p\n", hwnd);
360*4882a593Smuzhiyun winDebug("\tpScreenPriv %p\n", pScreenPriv);
361*4882a593Smuzhiyun winDebug("\tpScreenInfo %p\n", pScreenInfo);
362*4882a593Smuzhiyun winDebug("\thwndScreen %p\n", hwndScreen);
363*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc (%p) %08x %08x %08x\n",
364*4882a593Smuzhiyun pRLWinPriv, message, (int)wParam, (int)lParam);
365*4882a593Smuzhiyun #endif
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun /* Branch on message type */
368*4882a593Smuzhiyun switch (message) {
369*4882a593Smuzhiyun case WM_CREATE:
370*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
371*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_CREATE\n");
372*4882a593Smuzhiyun #endif
373*4882a593Smuzhiyun /* */
374*4882a593Smuzhiyun SetProp(hwnd,
375*4882a593Smuzhiyun WIN_WINDOW_PROP,
376*4882a593Smuzhiyun (HANDLE) ((LPCREATESTRUCT) lParam)->lpCreateParams);
377*4882a593Smuzhiyun return 0;
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun case WM_CLOSE:
380*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
381*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_CLOSE %d\n", pRLWinPriv->fClose);
382*4882a593Smuzhiyun #endif
383*4882a593Smuzhiyun /* Tell window-manager to close window */
384*4882a593Smuzhiyun if (pRLWinPriv->fClose) {
385*4882a593Smuzhiyun DestroyWindow(hwnd);
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun else {
388*4882a593Smuzhiyun winWindowsWMSendEvent(WindowsWMControllerNotify,
389*4882a593Smuzhiyun WindowsWMControllerNotifyMask,
390*4882a593Smuzhiyun 1,
391*4882a593Smuzhiyun WindowsWMCloseWindow,
392*4882a593Smuzhiyun pWin->drawable.id, 0, 0, 0, 0);
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun return 0;
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun case WM_DESTROY:
397*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
398*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_DESTROY\n");
399*4882a593Smuzhiyun #endif
400*4882a593Smuzhiyun /* Free the shaodw DC; which allows the bitmap to be freed */
401*4882a593Smuzhiyun DeleteDC(pRLWinPriv->hdcShadow);
402*4882a593Smuzhiyun pRLWinPriv->hdcShadow = NULL;
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun /* Free the shadow bitmap */
405*4882a593Smuzhiyun DeleteObject(pRLWinPriv->hbmpShadow);
406*4882a593Smuzhiyun pRLWinPriv->hbmpShadow = NULL;
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun /* Free the screen DC */
409*4882a593Smuzhiyun ReleaseDC(pRLWinPriv->hWnd, pRLWinPriv->hdcScreen);
410*4882a593Smuzhiyun pRLWinPriv->hdcScreen = NULL;
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun /* Free shadow buffer info header */
413*4882a593Smuzhiyun free(pRLWinPriv->pbmihShadow);
414*4882a593Smuzhiyun pRLWinPriv->pbmihShadow = NULL;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun pRLWinPriv->fResized = FALSE;
417*4882a593Smuzhiyun pRLWinPriv->pfb = NULL;
418*4882a593Smuzhiyun free(pRLWinPriv);
419*4882a593Smuzhiyun RemoveProp(hwnd, WIN_WINDOW_PROP);
420*4882a593Smuzhiyun break;
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun case WM_MOUSEMOVE:
423*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG && 0
424*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_MOUSEMOVE\n");
425*4882a593Smuzhiyun #endif
426*4882a593Smuzhiyun /* Unpack the client area mouse coordinates */
427*4882a593Smuzhiyun ptMouse.x = GET_X_LPARAM(lParam);
428*4882a593Smuzhiyun ptMouse.y = GET_Y_LPARAM(lParam);
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun /* Translate the client area mouse coordinates to screen coordinates */
431*4882a593Smuzhiyun ClientToScreen(hwnd, &ptMouse);
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
434*4882a593Smuzhiyun ptMouse.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
435*4882a593Smuzhiyun ptMouse.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun /* We can't do anything without privates */
438*4882a593Smuzhiyun if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
439*4882a593Smuzhiyun break;
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun /* Has the mouse pointer crossed screens? */
442*4882a593Smuzhiyun if (pScreen != miPointerGetScreen(inputInfo.pointer))
443*4882a593Smuzhiyun miPointerSetScreen(inputInfo.pointer, pScreenInfo->dwScreen,
444*4882a593Smuzhiyun ptMouse.x - pScreenInfo->dwXOffset,
445*4882a593Smuzhiyun ptMouse.y - pScreenInfo->dwYOffset);
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun /* Are we tracking yet? */
448*4882a593Smuzhiyun if (!s_fTracking) {
449*4882a593Smuzhiyun TRACKMOUSEEVENT tme;
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun /* Setup data structure */
452*4882a593Smuzhiyun ZeroMemory(&tme, sizeof(tme));
453*4882a593Smuzhiyun tme.cbSize = sizeof(tme);
454*4882a593Smuzhiyun tme.dwFlags = TME_LEAVE;
455*4882a593Smuzhiyun tme.hwndTrack = hwnd;
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun /* Call the tracking function */
458*4882a593Smuzhiyun if (!TrackMouseEvent(&tme))
459*4882a593Smuzhiyun ErrorF("winMWExtWMWindowProc - TrackMouseEvent failed\n");
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun /* Flag that we are tracking now */
462*4882a593Smuzhiyun s_fTracking = TRUE;
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun /* Kill the timer used to poll mouse events */
466*4882a593Smuzhiyun if (g_uipMousePollingTimerID != 0) {
467*4882a593Smuzhiyun KillTimer(pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID);
468*4882a593Smuzhiyun g_uipMousePollingTimerID = 0;
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun /* Deliver absolute cursor position to X Server */
472*4882a593Smuzhiyun winEnqueueMotion(ptMouse.x - pScreenInfo->dwXOffset,
473*4882a593Smuzhiyun ptMouse.y - pScreenInfo->dwYOffset);
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun return 0;
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun case WM_NCMOUSEMOVE:
478*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG && 0
479*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_NCMOUSEMOVE\n");
480*4882a593Smuzhiyun #endif
481*4882a593Smuzhiyun /*
482*4882a593Smuzhiyun * We break instead of returning 0 since we need to call
483*4882a593Smuzhiyun * DefWindowProc to get the mouse cursor changes
484*4882a593Smuzhiyun * and min/max/close button highlighting in Windows XP.
485*4882a593Smuzhiyun * The Platform SDK says that you should return 0 if you
486*4882a593Smuzhiyun * process this message, but it fails to mention that you
487*4882a593Smuzhiyun * will give up any default functionality if you do return 0.
488*4882a593Smuzhiyun */
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun /* We can't do anything without privates */
491*4882a593Smuzhiyun if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
492*4882a593Smuzhiyun break;
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun /*
495*4882a593Smuzhiyun * Timer to poll mouse events. This is needed to make
496*4882a593Smuzhiyun * programs like xeyes follow the mouse properly.
497*4882a593Smuzhiyun */
498*4882a593Smuzhiyun if (g_uipMousePollingTimerID == 0)
499*4882a593Smuzhiyun g_uipMousePollingTimerID = SetTimer(pScreenPriv->hwndScreen,
500*4882a593Smuzhiyun WIN_POLLING_MOUSE_TIMER_ID,
501*4882a593Smuzhiyun MOUSE_POLLING_INTERVAL, NULL);
502*4882a593Smuzhiyun break;
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun case WM_MOUSELEAVE:
505*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
506*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_MOUSELEAVE\n");
507*4882a593Smuzhiyun #endif
508*4882a593Smuzhiyun /* Mouse has left our client area */
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun /* Flag that we are no longer tracking */
511*4882a593Smuzhiyun s_fTracking = FALSE;
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun /*
514*4882a593Smuzhiyun * Timer to poll mouse events. This is needed to make
515*4882a593Smuzhiyun * programs like xeyes follow the mouse properly.
516*4882a593Smuzhiyun */
517*4882a593Smuzhiyun if (g_uipMousePollingTimerID == 0)
518*4882a593Smuzhiyun g_uipMousePollingTimerID = SetTimer(pScreenPriv->hwndScreen,
519*4882a593Smuzhiyun WIN_POLLING_MOUSE_TIMER_ID,
520*4882a593Smuzhiyun MOUSE_POLLING_INTERVAL, NULL);
521*4882a593Smuzhiyun return 0;
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun case WM_LBUTTONDBLCLK:
524*4882a593Smuzhiyun case WM_LBUTTONDOWN:
525*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
526*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_LBUTTONDBLCLK\n");
527*4882a593Smuzhiyun #endif
528*4882a593Smuzhiyun if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
529*4882a593Smuzhiyun break;
530*4882a593Smuzhiyun SetCapture(hwnd);
531*4882a593Smuzhiyun return winMouseButtonsHandle(pScreen, ButtonPress, Button1, wParam);
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun case WM_LBUTTONUP:
534*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
535*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_LBUTTONUP\n");
536*4882a593Smuzhiyun #endif
537*4882a593Smuzhiyun if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
538*4882a593Smuzhiyun break;
539*4882a593Smuzhiyun ReleaseCapture();
540*4882a593Smuzhiyun return winMouseButtonsHandle(pScreen, ButtonRelease, Button1, wParam);
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun case WM_MBUTTONDBLCLK:
543*4882a593Smuzhiyun case WM_MBUTTONDOWN:
544*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
545*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_MBUTTONDBLCLK\n");
546*4882a593Smuzhiyun #endif
547*4882a593Smuzhiyun if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
548*4882a593Smuzhiyun break;
549*4882a593Smuzhiyun SetCapture(hwnd);
550*4882a593Smuzhiyun return winMouseButtonsHandle(pScreen, ButtonPress, Button2, wParam);
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun case WM_MBUTTONUP:
553*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
554*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_MBUTTONUP\n");
555*4882a593Smuzhiyun #endif
556*4882a593Smuzhiyun if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
557*4882a593Smuzhiyun break;
558*4882a593Smuzhiyun ReleaseCapture();
559*4882a593Smuzhiyun return winMouseButtonsHandle(pScreen, ButtonRelease, Button2, wParam);
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun case WM_RBUTTONDBLCLK:
562*4882a593Smuzhiyun case WM_RBUTTONDOWN:
563*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
564*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_RBUTTONDBLCLK\n");
565*4882a593Smuzhiyun #endif
566*4882a593Smuzhiyun if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
567*4882a593Smuzhiyun break;
568*4882a593Smuzhiyun SetCapture(hwnd);
569*4882a593Smuzhiyun return winMouseButtonsHandle(pScreen, ButtonPress, Button3, wParam);
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun case WM_RBUTTONUP:
572*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
573*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_RBUTTONUP\n");
574*4882a593Smuzhiyun #endif
575*4882a593Smuzhiyun if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
576*4882a593Smuzhiyun break;
577*4882a593Smuzhiyun ReleaseCapture();
578*4882a593Smuzhiyun return winMouseButtonsHandle(pScreen, ButtonRelease, Button3, wParam);
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun case WM_XBUTTONDBLCLK:
581*4882a593Smuzhiyun case WM_XBUTTONDOWN:
582*4882a593Smuzhiyun if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
583*4882a593Smuzhiyun break;
584*4882a593Smuzhiyun SetCapture(hwnd);
585*4882a593Smuzhiyun return winMouseButtonsHandle(pScreen, ButtonPress, HIWORD(wParam) + 7,
586*4882a593Smuzhiyun wParam);
587*4882a593Smuzhiyun case WM_XBUTTONUP:
588*4882a593Smuzhiyun if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
589*4882a593Smuzhiyun break;
590*4882a593Smuzhiyun ReleaseCapture();
591*4882a593Smuzhiyun return winMouseButtonsHandle(pScreen, ButtonRelease, HIWORD(wParam) + 7,
592*4882a593Smuzhiyun wParam);
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun case WM_MOUSEWHEEL:
595*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
596*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_MOUSEWHEEL\n");
597*4882a593Smuzhiyun #endif
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun /* Pass the message to the root window */
600*4882a593Smuzhiyun SendMessage(hwndScreen, message, wParam, lParam);
601*4882a593Smuzhiyun return 0;
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun case WM_MOUSEHWHEEL:
604*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
605*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_MOUSEHWHEEL\n");
606*4882a593Smuzhiyun #endif
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun /* Pass the message to the root window */
609*4882a593Smuzhiyun SendMessage(hwndScreen, message, wParam, lParam);
610*4882a593Smuzhiyun return 0;
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun case WM_MOUSEACTIVATE:
613*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
614*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n");
615*4882a593Smuzhiyun #endif
616*4882a593Smuzhiyun if (!IsMouseActive(pWin))
617*4882a593Smuzhiyun return MA_NOACTIVATE;
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun break;
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun case WM_KILLFOCUS:
622*4882a593Smuzhiyun /* Pop any pressed keys since we are losing keyboard focus */
623*4882a593Smuzhiyun winKeybdReleaseKeys();
624*4882a593Smuzhiyun return 0;
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun case WM_SYSDEADCHAR:
627*4882a593Smuzhiyun case WM_DEADCHAR:
628*4882a593Smuzhiyun /*
629*4882a593Smuzhiyun * NOTE: We do nothing with WM_*CHAR messages,
630*4882a593Smuzhiyun * nor does the root window, so we can just toss these messages.
631*4882a593Smuzhiyun */
632*4882a593Smuzhiyun return 0;
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun case WM_SYSKEYDOWN:
635*4882a593Smuzhiyun case WM_KEYDOWN:
636*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
637*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_*KEYDOWN\n");
638*4882a593Smuzhiyun #endif
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun /*
641*4882a593Smuzhiyun * Don't pass Alt-F4 key combo to root window,
642*4882a593Smuzhiyun * let Windows translate to WM_CLOSE and close this top-level window.
643*4882a593Smuzhiyun *
644*4882a593Smuzhiyun * NOTE: We purposely don't check the fUseWinKillKey setting because
645*4882a593Smuzhiyun * it should only apply to the key handling for the root window,
646*4882a593Smuzhiyun * not for top-level window-manager windows.
647*4882a593Smuzhiyun *
648*4882a593Smuzhiyun * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
649*4882a593Smuzhiyun * because that is a key combo that no X app should be expecting to
650*4882a593Smuzhiyun * receive, since it has historically been used to shutdown the X server.
651*4882a593Smuzhiyun * Passing Ctrl-Alt-Backspace to the root window preserves that
652*4882a593Smuzhiyun * behavior, assuming that -unixkill has been passed as a parameter.
653*4882a593Smuzhiyun */
654*4882a593Smuzhiyun if (wParam == VK_F4 && (GetKeyState(VK_MENU) & 0x8000))
655*4882a593Smuzhiyun break;
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun /* Pass the message to the root window */
658*4882a593Smuzhiyun SendMessage(hwndScreen, message, wParam, lParam);
659*4882a593Smuzhiyun return 0;
660*4882a593Smuzhiyun
661*4882a593Smuzhiyun case WM_SYSKEYUP:
662*4882a593Smuzhiyun case WM_KEYUP:
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
665*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_*KEYUP\n");
666*4882a593Smuzhiyun #endif
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun /* Pass the message to the root window */
669*4882a593Smuzhiyun SendMessage(hwndScreen, message, wParam, lParam);
670*4882a593Smuzhiyun return 0;
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun case WM_HOTKEY:
673*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
674*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_HOTKEY\n");
675*4882a593Smuzhiyun #endif
676*4882a593Smuzhiyun
677*4882a593Smuzhiyun /* Pass the message to the root window */
678*4882a593Smuzhiyun SendMessage(hwndScreen, message, wParam, lParam);
679*4882a593Smuzhiyun return 0;
680*4882a593Smuzhiyun
681*4882a593Smuzhiyun case WM_ERASEBKGND:
682*4882a593Smuzhiyun #if CYGDEBUG
683*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_ERASEBKGND\n");
684*4882a593Smuzhiyun #endif
685*4882a593Smuzhiyun /*
686*4882a593Smuzhiyun * Pretend that we did erase the background but we don't care,
687*4882a593Smuzhiyun * since we repaint the entire region anyhow
688*4882a593Smuzhiyun * This avoids some flickering when resizing.
689*4882a593Smuzhiyun */
690*4882a593Smuzhiyun return TRUE;
691*4882a593Smuzhiyun
692*4882a593Smuzhiyun case WM_PAINT:
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun /* BeginPaint gives us an hdc that clips to the invalidated region */
695*4882a593Smuzhiyun hdcUpdate = BeginPaint(hwnd, &ps);
696*4882a593Smuzhiyun
697*4882a593Smuzhiyun /* Try to copy from the shadow buffer */
698*4882a593Smuzhiyun if (!BitBlt(hdcUpdate,
699*4882a593Smuzhiyun ps.rcPaint.left, ps.rcPaint.top,
700*4882a593Smuzhiyun ps.rcPaint.right - ps.rcPaint.left,
701*4882a593Smuzhiyun ps.rcPaint.bottom - ps.rcPaint.top,
702*4882a593Smuzhiyun pRLWinPriv->hdcShadow,
703*4882a593Smuzhiyun ps.rcPaint.left, ps.rcPaint.top, SRCCOPY)) {
704*4882a593Smuzhiyun LPVOID lpMsgBuf;
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun /* Display a fancy error message */
707*4882a593Smuzhiyun FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
708*4882a593Smuzhiyun FORMAT_MESSAGE_FROM_SYSTEM |
709*4882a593Smuzhiyun FORMAT_MESSAGE_IGNORE_INSERTS,
710*4882a593Smuzhiyun NULL,
711*4882a593Smuzhiyun GetLastError(),
712*4882a593Smuzhiyun MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
713*4882a593Smuzhiyun (LPTSTR) &lpMsgBuf, 0, NULL);
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun ErrorF("winMWExtWMWindowProc - BitBlt failed: %s\n",
716*4882a593Smuzhiyun (LPSTR) lpMsgBuf);
717*4882a593Smuzhiyun LocalFree(lpMsgBuf);
718*4882a593Smuzhiyun }
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun /* EndPaint frees the DC */
721*4882a593Smuzhiyun EndPaint(hwnd, &ps);
722*4882a593Smuzhiyun break;
723*4882a593Smuzhiyun
724*4882a593Smuzhiyun case WM_ACTIVATE:
725*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
726*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_ACTIVATE\n");
727*4882a593Smuzhiyun #endif
728*4882a593Smuzhiyun if (LOWORD(wParam) != WA_INACTIVE) {
729*4882a593Smuzhiyun winWindowsWMSendEvent(WindowsWMControllerNotify,
730*4882a593Smuzhiyun WindowsWMControllerNotifyMask,
731*4882a593Smuzhiyun 1,
732*4882a593Smuzhiyun WindowsWMActivateWindow,
733*4882a593Smuzhiyun pWin->drawable.id, 0, 0, 0, 0);
734*4882a593Smuzhiyun }
735*4882a593Smuzhiyun return 0;
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun #if 1
738*4882a593Smuzhiyun case WM_WINDOWPOSCHANGING:
739*4882a593Smuzhiyun pWinPos = (LPWINDOWPOS) lParam;
740*4882a593Smuzhiyun if (!(pWinPos->flags & SWP_NOZORDER)) {
741*4882a593Smuzhiyun if (pRLWinPriv->fRestackingNow || pScreenPriv->fRestacking) {
742*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
743*4882a593Smuzhiyun winDebug("Win %p is now restacking.\n",
744*4882a593Smuzhiyun pRLWinPriv);
745*4882a593Smuzhiyun #endif
746*4882a593Smuzhiyun break;
747*4882a593Smuzhiyun }
748*4882a593Smuzhiyun
749*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
750*4882a593Smuzhiyun winDebug("Win %p forbid to change z order (%p).\n",
751*4882a593Smuzhiyun pRLWinPriv,
752*4882a593Smuzhiyun pWinPos->hwndInsertAfter);
753*4882a593Smuzhiyun #endif
754*4882a593Smuzhiyun pWinPos->flags |= SWP_NOZORDER;
755*4882a593Smuzhiyun }
756*4882a593Smuzhiyun break;
757*4882a593Smuzhiyun #endif
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun case WM_MOVE:
760*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
761*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_MOVE\n");
762*4882a593Smuzhiyun #endif
763*4882a593Smuzhiyun if (g_fNoConfigureWindow)
764*4882a593Smuzhiyun break;
765*4882a593Smuzhiyun #if 0
766*4882a593Smuzhiyun /* Bail if Windows window is not actually moving */
767*4882a593Smuzhiyun if (pRLWinPriv->dwX == (short) LOWORD(lParam)
768*4882a593Smuzhiyun && pRLWinPriv->dwY == (short) HIWORD(lParam))
769*4882a593Smuzhiyun break;
770*4882a593Smuzhiyun
771*4882a593Smuzhiyun /* Also bail if we're maximizing, we'll do the whole thing in WM_SIZE */
772*4882a593Smuzhiyun {
773*4882a593Smuzhiyun WINDOWPLACEMENT windPlace;
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun windPlace.length = sizeof(WINDOWPLACEMENT);
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun /* Get current window placement */
778*4882a593Smuzhiyun GetWindowPlacement(hwnd, &windPlace);
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun /* Bail if maximizing */
781*4882a593Smuzhiyun if (windPlace.showCmd == SW_MAXIMIZE
782*4882a593Smuzhiyun || windPlace.showCmd == SW_SHOWMAXIMIZED)
783*4882a593Smuzhiyun break;
784*4882a593Smuzhiyun }
785*4882a593Smuzhiyun #endif
786*4882a593Smuzhiyun
787*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
788*4882a593Smuzhiyun winDebug("\t(%d, %d)\n", (short) LOWORD(lParam),
789*4882a593Smuzhiyun (short) HIWORD(lParam));
790*4882a593Smuzhiyun #endif
791*4882a593Smuzhiyun if (!pRLWinPriv->fMovingOrSizing) {
792*4882a593Smuzhiyun winMWExtWMMoveXWindow(pWin, (LOWORD(lParam) - wBorderWidth(pWin)
793*4882a593Smuzhiyun - GetSystemMetrics(SM_XVIRTUALSCREEN)),
794*4882a593Smuzhiyun (HIWORD(lParam) - wBorderWidth(pWin)
795*4882a593Smuzhiyun - GetSystemMetrics(SM_YVIRTUALSCREEN)));
796*4882a593Smuzhiyun }
797*4882a593Smuzhiyun return 0;
798*4882a593Smuzhiyun
799*4882a593Smuzhiyun case WM_SHOWWINDOW:
800*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG || TRUE
801*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_SHOWWINDOW\n");
802*4882a593Smuzhiyun #endif
803*4882a593Smuzhiyun /* Bail out if the window is being hidden */
804*4882a593Smuzhiyun if (!wParam)
805*4882a593Smuzhiyun return 0;
806*4882a593Smuzhiyun
807*4882a593Smuzhiyun winMWExtWMUpdateWindowDecoration(pRLWinPriv, pScreenInfo);
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun break;
810*4882a593Smuzhiyun
811*4882a593Smuzhiyun case WM_SIZING:
812*4882a593Smuzhiyun /* Need to legalize the size according to WM_NORMAL_HINTS */
813*4882a593Smuzhiyun /* for applications like xterm */
814*4882a593Smuzhiyun return ValidateSizing(hwnd, pWin, wParam, lParam);
815*4882a593Smuzhiyun
816*4882a593Smuzhiyun case WM_WINDOWPOSCHANGED:
817*4882a593Smuzhiyun {
818*4882a593Smuzhiyun pWinPos = (LPWINDOWPOS) lParam;
819*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
820*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED\n");
821*4882a593Smuzhiyun winDebug("\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n",
822*4882a593Smuzhiyun (pWinPos->flags & SWP_DRAWFRAME) ? "SWP_DRAWFRAME " : "",
823*4882a593Smuzhiyun (pWinPos->flags & SWP_FRAMECHANGED) ? "SWP_FRAMECHANGED " : "",
824*4882a593Smuzhiyun (pWinPos->flags & SWP_HIDEWINDOW) ? "SWP_HIDEWINDOW " : "",
825*4882a593Smuzhiyun (pWinPos->flags & SWP_NOACTIVATE) ? "SWP_NOACTIVATE " : "",
826*4882a593Smuzhiyun (pWinPos->flags & SWP_NOCOPYBITS) ? "SWP_NOCOPYBITS " : "",
827*4882a593Smuzhiyun (pWinPos->flags & SWP_NOMOVE) ? "SWP_NOMOVE " : "",
828*4882a593Smuzhiyun (pWinPos->
829*4882a593Smuzhiyun flags & SWP_NOOWNERZORDER) ? "SWP_NOOWNERZORDER " : "",
830*4882a593Smuzhiyun (pWinPos->flags & SWP_NOSIZE) ? "SWP_NOSIZE " : "",
831*4882a593Smuzhiyun (pWinPos->flags & SWP_NOREDRAW) ? "SWP_NOREDRAW " : "",
832*4882a593Smuzhiyun (pWinPos->
833*4882a593Smuzhiyun flags & SWP_NOSENDCHANGING) ? "SWP_NOSENDCHANGING " : "",
834*4882a593Smuzhiyun (pWinPos->flags & SWP_NOZORDER) ? "SWP_NOZORDER " : "",
835*4882a593Smuzhiyun (pWinPos->flags & SWP_SHOWWINDOW) ? "SWP_SHOWWINDOW " : "");
836*4882a593Smuzhiyun winDebug("\tno_configure: %s\n", (g_fNoConfigureWindow ? "Yes" : "No"));
837*4882a593Smuzhiyun winDebug("\textend: (%d, %d, %d, %d)\n",
838*4882a593Smuzhiyun pWinPos->x, pWinPos->y, pWinPos->cx, pWinPos->cy);
839*4882a593Smuzhiyun
840*4882a593Smuzhiyun #endif
841*4882a593Smuzhiyun if (pWinPos->flags & SWP_HIDEWINDOW)
842*4882a593Smuzhiyun break;
843*4882a593Smuzhiyun
844*4882a593Smuzhiyun if (!(pWinPos->flags & SWP_NOSIZE)) {
845*4882a593Smuzhiyun if (IsIconic(hwnd)) {
846*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
847*4882a593Smuzhiyun winDebug("\tIconic -> MINIMIZED\n");
848*4882a593Smuzhiyun #endif
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun winWindowsWMSendEvent(WindowsWMControllerNotify,
851*4882a593Smuzhiyun WindowsWMControllerNotifyMask,
852*4882a593Smuzhiyun 1,
853*4882a593Smuzhiyun WindowsWMMinimizeWindow,
854*4882a593Smuzhiyun pWin->drawable.id, 0, 0, 0, 0);
855*4882a593Smuzhiyun }
856*4882a593Smuzhiyun else if (IsZoomed(hwnd)) {
857*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
858*4882a593Smuzhiyun winDebug("\tZoomed -> MAXIMIZED\n");
859*4882a593Smuzhiyun #endif
860*4882a593Smuzhiyun winWindowsWMSendEvent(WindowsWMControllerNotify,
861*4882a593Smuzhiyun WindowsWMControllerNotifyMask,
862*4882a593Smuzhiyun 1,
863*4882a593Smuzhiyun WindowsWMMaximizeWindow,
864*4882a593Smuzhiyun pWin->drawable.id, 0, 0, 0, 0);
865*4882a593Smuzhiyun }
866*4882a593Smuzhiyun else {
867*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
868*4882a593Smuzhiyun winDebug("\tnone -> RESTORED\n");
869*4882a593Smuzhiyun #endif
870*4882a593Smuzhiyun winWindowsWMSendEvent(WindowsWMControllerNotify,
871*4882a593Smuzhiyun WindowsWMControllerNotifyMask,
872*4882a593Smuzhiyun 1,
873*4882a593Smuzhiyun WindowsWMRestoreWindow,
874*4882a593Smuzhiyun pWin->drawable.id, 0, 0, 0, 0);
875*4882a593Smuzhiyun }
876*4882a593Smuzhiyun }
877*4882a593Smuzhiyun if (!g_fNoConfigureWindow) {
878*4882a593Smuzhiyun
879*4882a593Smuzhiyun if (!pRLWinPriv->fMovingOrSizing
880*4882a593Smuzhiyun /*&& (pWinPos->flags & SWP_SHOWWINDOW) */ ) {
881*4882a593Smuzhiyun GetClientRect(hwnd, &rcClient);
882*4882a593Smuzhiyun MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT) &rcClient, 2);
883*4882a593Smuzhiyun
884*4882a593Smuzhiyun if (!(pWinPos->flags & SWP_NOMOVE)
885*4882a593Smuzhiyun && !(pWinPos->flags & SWP_NOSIZE)) {
886*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
887*4882a593Smuzhiyun winDebug("\tmove & resize\n");
888*4882a593Smuzhiyun #endif
889*4882a593Smuzhiyun
890*4882a593Smuzhiyun winMWExtWMMoveResizeXWindow(pWin,
891*4882a593Smuzhiyun rcClient.left -
892*4882a593Smuzhiyun wBorderWidth(pWin)
893*4882a593Smuzhiyun -
894*4882a593Smuzhiyun GetSystemMetrics
895*4882a593Smuzhiyun (SM_XVIRTUALSCREEN),
896*4882a593Smuzhiyun rcClient.top -
897*4882a593Smuzhiyun wBorderWidth(pWin)
898*4882a593Smuzhiyun -
899*4882a593Smuzhiyun GetSystemMetrics
900*4882a593Smuzhiyun (SM_YVIRTUALSCREEN),
901*4882a593Smuzhiyun rcClient.right - rcClient.left -
902*4882a593Smuzhiyun wBorderWidth(pWin) * 2,
903*4882a593Smuzhiyun rcClient.bottom - rcClient.top -
904*4882a593Smuzhiyun wBorderWidth(pWin) * 2);
905*4882a593Smuzhiyun }
906*4882a593Smuzhiyun else if (!(pWinPos->flags & SWP_NOMOVE)) {
907*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
908*4882a593Smuzhiyun winDebug("\tmove\n");
909*4882a593Smuzhiyun #endif
910*4882a593Smuzhiyun
911*4882a593Smuzhiyun winMWExtWMMoveResizeXWindow(pWin,
912*4882a593Smuzhiyun rcClient.left -
913*4882a593Smuzhiyun wBorderWidth(pWin)
914*4882a593Smuzhiyun -
915*4882a593Smuzhiyun GetSystemMetrics
916*4882a593Smuzhiyun (SM_XVIRTUALSCREEN),
917*4882a593Smuzhiyun rcClient.top -
918*4882a593Smuzhiyun wBorderWidth(pWin)
919*4882a593Smuzhiyun -
920*4882a593Smuzhiyun GetSystemMetrics
921*4882a593Smuzhiyun (SM_YVIRTUALSCREEN),
922*4882a593Smuzhiyun rcClient.right - rcClient.left -
923*4882a593Smuzhiyun wBorderWidth(pWin) * 2,
924*4882a593Smuzhiyun rcClient.bottom - rcClient.top -
925*4882a593Smuzhiyun wBorderWidth(pWin) * 2);
926*4882a593Smuzhiyun }
927*4882a593Smuzhiyun else if (!(pWinPos->flags & SWP_NOMOVE)) {
928*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
929*4882a593Smuzhiyun winDebug("\tmove\n");
930*4882a593Smuzhiyun #endif
931*4882a593Smuzhiyun
932*4882a593Smuzhiyun winMWExtWMMoveXWindow(pWin,
933*4882a593Smuzhiyun rcClient.left - wBorderWidth(pWin)
934*4882a593Smuzhiyun - GetSystemMetrics(SM_XVIRTUALSCREEN),
935*4882a593Smuzhiyun rcClient.top - wBorderWidth(pWin)
936*4882a593Smuzhiyun -
937*4882a593Smuzhiyun GetSystemMetrics(SM_YVIRTUALSCREEN));
938*4882a593Smuzhiyun }
939*4882a593Smuzhiyun else if (!(pWinPos->flags & SWP_NOSIZE)) {
940*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
941*4882a593Smuzhiyun winDebug("\tresize\n");
942*4882a593Smuzhiyun #endif
943*4882a593Smuzhiyun
944*4882a593Smuzhiyun winMWExtWMResizeXWindow(pWin,
945*4882a593Smuzhiyun rcClient.right - rcClient.left
946*4882a593Smuzhiyun - wBorderWidth(pWin) * 2,
947*4882a593Smuzhiyun rcClient.bottom - rcClient.top
948*4882a593Smuzhiyun - wBorderWidth(pWin) * 2);
949*4882a593Smuzhiyun }
950*4882a593Smuzhiyun }
951*4882a593Smuzhiyun }
952*4882a593Smuzhiyun }
953*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
954*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED - done.\n");
955*4882a593Smuzhiyun #endif
956*4882a593Smuzhiyun return 0;
957*4882a593Smuzhiyun
958*4882a593Smuzhiyun case WM_SIZE:
959*4882a593Smuzhiyun /* see dix/window.c */
960*4882a593Smuzhiyun /* FIXME: Maximize/Restore? */
961*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
962*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_SIZE\n");
963*4882a593Smuzhiyun #endif
964*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
965*4882a593Smuzhiyun winDebug("\t(%d, %d) %d\n", (short) LOWORD(lParam),
966*4882a593Smuzhiyun (short) HIWORD(lParam), g_fNoConfigureWindow);
967*4882a593Smuzhiyun #endif
968*4882a593Smuzhiyun if (g_fNoConfigureWindow)
969*4882a593Smuzhiyun break;
970*4882a593Smuzhiyun
971*4882a593Smuzhiyun /* Branch on type of resizing occurring */
972*4882a593Smuzhiyun switch (wParam) {
973*4882a593Smuzhiyun case SIZE_MINIMIZED:
974*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
975*4882a593Smuzhiyun winDebug("\tSIZE_MINIMIZED\n");
976*4882a593Smuzhiyun #endif
977*4882a593Smuzhiyun
978*4882a593Smuzhiyun winWindowsWMSendEvent(WindowsWMControllerNotify,
979*4882a593Smuzhiyun WindowsWMControllerNotifyMask,
980*4882a593Smuzhiyun 1,
981*4882a593Smuzhiyun WindowsWMMinimizeWindow,
982*4882a593Smuzhiyun pWin->drawable.id,
983*4882a593Smuzhiyun 0, 0, LOWORD(lParam), HIWORD(lParam));
984*4882a593Smuzhiyun break;
985*4882a593Smuzhiyun
986*4882a593Smuzhiyun case SIZE_RESTORED:
987*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
988*4882a593Smuzhiyun winDebug("\tSIZE_RESTORED\n");
989*4882a593Smuzhiyun #endif
990*4882a593Smuzhiyun winWindowsWMSendEvent(WindowsWMControllerNotify,
991*4882a593Smuzhiyun WindowsWMControllerNotifyMask,
992*4882a593Smuzhiyun 1,
993*4882a593Smuzhiyun WindowsWMRestoreWindow,
994*4882a593Smuzhiyun pWin->drawable.id,
995*4882a593Smuzhiyun 0, 0, LOWORD(lParam), HIWORD(lParam));
996*4882a593Smuzhiyun break;
997*4882a593Smuzhiyun
998*4882a593Smuzhiyun case SIZE_MAXIMIZED:
999*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
1000*4882a593Smuzhiyun winDebug("\tSIZE_MAXIMIZED\n");
1001*4882a593Smuzhiyun #endif
1002*4882a593Smuzhiyun winWindowsWMSendEvent(WindowsWMControllerNotify,
1003*4882a593Smuzhiyun WindowsWMControllerNotifyMask,
1004*4882a593Smuzhiyun 1,
1005*4882a593Smuzhiyun WindowsWMMaximizeWindow,
1006*4882a593Smuzhiyun pWin->drawable.id,
1007*4882a593Smuzhiyun 0, 0, LOWORD(lParam), HIWORD(lParam));
1008*4882a593Smuzhiyun break;
1009*4882a593Smuzhiyun }
1010*4882a593Smuzhiyun
1011*4882a593Smuzhiyun /* Perform the resize and notify the X client */
1012*4882a593Smuzhiyun if (!pRLWinPriv->fMovingOrSizing) {
1013*4882a593Smuzhiyun winMWExtWMResizeXWindow(pWin, (short) LOWORD(lParam)
1014*4882a593Smuzhiyun - wBorderWidth(pWin) * 2,
1015*4882a593Smuzhiyun (short) HIWORD(lParam)
1016*4882a593Smuzhiyun - wBorderWidth(pWin) * 2);
1017*4882a593Smuzhiyun }
1018*4882a593Smuzhiyun break;
1019*4882a593Smuzhiyun
1020*4882a593Smuzhiyun case WM_ACTIVATEAPP:
1021*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
1022*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_ACTIVATEAPP\n");
1023*4882a593Smuzhiyun #endif
1024*4882a593Smuzhiyun if (wParam) {
1025*4882a593Smuzhiyun winWindowsWMSendEvent(WindowsWMActivationNotify,
1026*4882a593Smuzhiyun WindowsWMActivationNotifyMask,
1027*4882a593Smuzhiyun 1,
1028*4882a593Smuzhiyun WindowsWMIsActive,
1029*4882a593Smuzhiyun pWin->drawable.id, 0, 0, 0, 0);
1030*4882a593Smuzhiyun }
1031*4882a593Smuzhiyun else {
1032*4882a593Smuzhiyun winWindowsWMSendEvent(WindowsWMActivationNotify,
1033*4882a593Smuzhiyun WindowsWMActivationNotifyMask,
1034*4882a593Smuzhiyun 1,
1035*4882a593Smuzhiyun WindowsWMIsInactive,
1036*4882a593Smuzhiyun pWin->drawable.id, 0, 0, 0, 0);
1037*4882a593Smuzhiyun }
1038*4882a593Smuzhiyun break;
1039*4882a593Smuzhiyun
1040*4882a593Smuzhiyun case WM_SETCURSOR:
1041*4882a593Smuzhiyun if (LOWORD(lParam) == HTCLIENT) {
1042*4882a593Smuzhiyun if (!g_fSoftwareCursor)
1043*4882a593Smuzhiyun SetCursor(pScreenPriv->cursor.handle);
1044*4882a593Smuzhiyun return TRUE;
1045*4882a593Smuzhiyun }
1046*4882a593Smuzhiyun break;
1047*4882a593Smuzhiyun
1048*4882a593Smuzhiyun case WM_ENTERSIZEMOVE:
1049*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
1050*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_ENTERSIZEMOVE\n");
1051*4882a593Smuzhiyun #endif
1052*4882a593Smuzhiyun pRLWinPriv->fMovingOrSizing = TRUE;
1053*4882a593Smuzhiyun break;
1054*4882a593Smuzhiyun
1055*4882a593Smuzhiyun case WM_EXITSIZEMOVE:
1056*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
1057*4882a593Smuzhiyun winDebug("winMWExtWMWindowProc - WM_EXITSIZEMOVE\n");
1058*4882a593Smuzhiyun #endif
1059*4882a593Smuzhiyun pRLWinPriv->fMovingOrSizing = FALSE;
1060*4882a593Smuzhiyun
1061*4882a593Smuzhiyun GetClientRect(hwnd, &rcClient);
1062*4882a593Smuzhiyun
1063*4882a593Smuzhiyun MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT) &rcClient, 2);
1064*4882a593Smuzhiyun
1065*4882a593Smuzhiyun winMWExtWMMoveResizeXWindow(pWin, rcClient.left - wBorderWidth(pWin)
1066*4882a593Smuzhiyun - GetSystemMetrics(SM_XVIRTUALSCREEN),
1067*4882a593Smuzhiyun rcClient.top - wBorderWidth(pWin)
1068*4882a593Smuzhiyun - GetSystemMetrics(SM_YVIRTUALSCREEN),
1069*4882a593Smuzhiyun rcClient.right - rcClient.left
1070*4882a593Smuzhiyun - wBorderWidth(pWin) * 2,
1071*4882a593Smuzhiyun rcClient.bottom - rcClient.top
1072*4882a593Smuzhiyun - wBorderWidth(pWin) * 2);
1073*4882a593Smuzhiyun break;
1074*4882a593Smuzhiyun
1075*4882a593Smuzhiyun default:
1076*4882a593Smuzhiyun break;
1077*4882a593Smuzhiyun }
1078*4882a593Smuzhiyun
1079*4882a593Smuzhiyun return DefWindowProc(hwnd, message, wParam, lParam);
1080*4882a593Smuzhiyun }
1081