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: Dakshinamurthy Karra
29*4882a593Smuzhiyun * Suhaib M Siddiqi
30*4882a593Smuzhiyun * Peter Busch
31*4882a593Smuzhiyun * Harold L Hunt II
32*4882a593Smuzhiyun * MATSUZAKI Kensuke
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 <commctrl.h>
40*4882a593Smuzhiyun #include "winprefs.h"
41*4882a593Smuzhiyun #include "winconfig.h"
42*4882a593Smuzhiyun #include "winmsg.h"
43*4882a593Smuzhiyun #include "winmonitors.h"
44*4882a593Smuzhiyun #include "inputstr.h"
45*4882a593Smuzhiyun #include "winclipboard/winclipboard.h"
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /*
48*4882a593Smuzhiyun * Global variables
49*4882a593Smuzhiyun */
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun Bool g_fCursor = TRUE;
52*4882a593Smuzhiyun Bool g_fButton[3] = { FALSE, FALSE, FALSE };
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun /*
55*4882a593Smuzhiyun * Called by winWakeupHandler
56*4882a593Smuzhiyun * Processes current Windows message
57*4882a593Smuzhiyun */
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun LRESULT CALLBACK
winWindowProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)60*4882a593Smuzhiyun winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
61*4882a593Smuzhiyun {
62*4882a593Smuzhiyun static winPrivScreenPtr s_pScreenPriv = NULL;
63*4882a593Smuzhiyun static winScreenInfo *s_pScreenInfo = NULL;
64*4882a593Smuzhiyun static ScreenPtr s_pScreen = NULL;
65*4882a593Smuzhiyun static HWND s_hwndLastPrivates = NULL;
66*4882a593Smuzhiyun static Bool s_fTracking = FALSE;
67*4882a593Smuzhiyun static unsigned long s_ulServerGeneration = 0;
68*4882a593Smuzhiyun static UINT s_uTaskbarRestart = 0;
69*4882a593Smuzhiyun int iScanCode;
70*4882a593Smuzhiyun int i;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun #if CYGDEBUG
73*4882a593Smuzhiyun winDebugWin32Message("winWindowProc", hwnd, message, wParam, lParam);
74*4882a593Smuzhiyun #endif
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun /* Watch for server regeneration */
77*4882a593Smuzhiyun if (g_ulServerGeneration != s_ulServerGeneration) {
78*4882a593Smuzhiyun /* Store new server generation */
79*4882a593Smuzhiyun s_ulServerGeneration = g_ulServerGeneration;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun /* Only retrieve new privates pointers if window handle is null or changed */
83*4882a593Smuzhiyun if ((s_pScreenPriv == NULL || hwnd != s_hwndLastPrivates)
84*4882a593Smuzhiyun && (s_pScreenPriv = GetProp(hwnd, WIN_SCR_PROP)) != NULL) {
85*4882a593Smuzhiyun #if CYGDEBUG
86*4882a593Smuzhiyun winDebug("winWindowProc - Setting privates handle\n");
87*4882a593Smuzhiyun #endif
88*4882a593Smuzhiyun s_pScreenInfo = s_pScreenPriv->pScreenInfo;
89*4882a593Smuzhiyun s_pScreen = s_pScreenInfo->pScreen;
90*4882a593Smuzhiyun s_hwndLastPrivates = hwnd;
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun else if (s_pScreenPriv == NULL) {
93*4882a593Smuzhiyun /* For safety, handle case that should never happen */
94*4882a593Smuzhiyun s_pScreenInfo = NULL;
95*4882a593Smuzhiyun s_pScreen = NULL;
96*4882a593Smuzhiyun s_hwndLastPrivates = NULL;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun /* Branch on message type */
100*4882a593Smuzhiyun switch (message) {
101*4882a593Smuzhiyun case WM_TRAYICON:
102*4882a593Smuzhiyun return winHandleIconMessage(hwnd, message, wParam, lParam,
103*4882a593Smuzhiyun s_pScreenPriv);
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun case WM_CREATE:
106*4882a593Smuzhiyun #if CYGDEBUG
107*4882a593Smuzhiyun winDebug("winWindowProc - WM_CREATE\n");
108*4882a593Smuzhiyun #endif
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun /*
111*4882a593Smuzhiyun * Add a property to our display window that references
112*4882a593Smuzhiyun * this screens' privates.
113*4882a593Smuzhiyun *
114*4882a593Smuzhiyun * This allows the window procedure to refer to the
115*4882a593Smuzhiyun * appropriate window DC and shadow DC for the window that
116*4882a593Smuzhiyun * it is processing. We use this to repaint exposed
117*4882a593Smuzhiyun * areas of our display window.
118*4882a593Smuzhiyun */
119*4882a593Smuzhiyun s_pScreenPriv = ((LPCREATESTRUCT) lParam)->lpCreateParams;
120*4882a593Smuzhiyun s_pScreenInfo = s_pScreenPriv->pScreenInfo;
121*4882a593Smuzhiyun s_pScreen = s_pScreenInfo->pScreen;
122*4882a593Smuzhiyun s_hwndLastPrivates = hwnd;
123*4882a593Smuzhiyun s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
124*4882a593Smuzhiyun SetProp(hwnd, WIN_SCR_PROP, s_pScreenPriv);
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun /* Setup tray icon */
127*4882a593Smuzhiyun if (!s_pScreenInfo->fNoTrayIcon) {
128*4882a593Smuzhiyun /*
129*4882a593Smuzhiyun * NOTE: The WM_CREATE message is processed before CreateWindowEx
130*4882a593Smuzhiyun * returns, so s_pScreenPriv->hwndScreen is invalid at this point.
131*4882a593Smuzhiyun * We go ahead and copy our hwnd parameter over top of the screen
132*4882a593Smuzhiyun * privates hwndScreen so that we have a valid value for
133*4882a593Smuzhiyun * that member. Otherwise, the tray icon will disappear
134*4882a593Smuzhiyun * the first time you move the mouse over top of it.
135*4882a593Smuzhiyun */
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun s_pScreenPriv->hwndScreen = hwnd;
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun winInitNotifyIcon(s_pScreenPriv);
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun return 0;
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun case WM_DISPLAYCHANGE:
144*4882a593Smuzhiyun /*
145*4882a593Smuzhiyun WM_DISPLAYCHANGE seems to be sent when the monitor layout or
146*4882a593Smuzhiyun any monitor's resolution or depth changes, but it's lParam and
147*4882a593Smuzhiyun wParam always indicate the resolution and bpp for the primary
148*4882a593Smuzhiyun monitor (so ignore that as we could be on any monitor...)
149*4882a593Smuzhiyun */
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /* We cannot handle a display mode change during initialization */
152*4882a593Smuzhiyun if (s_pScreenInfo == NULL)
153*4882a593Smuzhiyun FatalError("winWindowProc - WM_DISPLAYCHANGE - The display "
154*4882a593Smuzhiyun "mode changed while we were intializing. This is "
155*4882a593Smuzhiyun "very bad and unexpected. Exiting.\n");
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun /*
158*4882a593Smuzhiyun * We do not care about display changes with
159*4882a593Smuzhiyun * fullscreen DirectDraw engines, because those engines set
160*4882a593Smuzhiyun * their own mode when they become active.
161*4882a593Smuzhiyun */
162*4882a593Smuzhiyun if (s_pScreenInfo->fFullScreen
163*4882a593Smuzhiyun && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)) {
164*4882a593Smuzhiyun break;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun ErrorF("winWindowProc - WM_DISPLAYCHANGE - new width: %d "
168*4882a593Smuzhiyun "new height: %d new bpp: %d\n",
169*4882a593Smuzhiyun LOWORD(lParam), HIWORD(lParam), (int)wParam);
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun /* 0 bpp has no defined meaning, ignore this message */
172*4882a593Smuzhiyun if (wParam == 0)
173*4882a593Smuzhiyun break;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun /*
176*4882a593Smuzhiyun * Check for a disruptive change in depth.
177*4882a593Smuzhiyun * We can only display a message for a disruptive depth change,
178*4882a593Smuzhiyun * we cannot do anything to correct the situation.
179*4882a593Smuzhiyun */
180*4882a593Smuzhiyun /*
181*4882a593Smuzhiyun XXX: maybe we need to check if GetSystemMetrics(SM_SAMEDISPLAYFORMAT)
182*4882a593Smuzhiyun has changed as well...
183*4882a593Smuzhiyun */
184*4882a593Smuzhiyun if (s_pScreenInfo->dwBPP !=
185*4882a593Smuzhiyun GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL)) {
186*4882a593Smuzhiyun if (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL) {
187*4882a593Smuzhiyun /* Cannot display the visual until the depth is restored */
188*4882a593Smuzhiyun ErrorF("winWindowProc - Disruptive change in depth\n");
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun /* Display depth change dialog */
191*4882a593Smuzhiyun winDisplayDepthChangeDialog(s_pScreenPriv);
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun /* Flag that we have an invalid screen depth */
194*4882a593Smuzhiyun s_pScreenPriv->fBadDepth = TRUE;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun /* Minimize the display window */
197*4882a593Smuzhiyun ShowWindow(hwnd, SW_MINIMIZE);
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun else {
200*4882a593Smuzhiyun /* For GDI, performance may suffer until original depth is restored */
201*4882a593Smuzhiyun ErrorF
202*4882a593Smuzhiyun ("winWindowProc - Performance may be non-optimal after change in depth\n");
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun else {
206*4882a593Smuzhiyun /* Flag that we have a valid screen depth */
207*4882a593Smuzhiyun s_pScreenPriv->fBadDepth = FALSE;
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun /*
211*4882a593Smuzhiyun If we could cheaply check if this WM_DISPLAYCHANGE change
212*4882a593Smuzhiyun affects the monitor(s) which this X screen is displayed on
213*4882a593Smuzhiyun then we should do so here. For the moment, assume it does.
214*4882a593Smuzhiyun (this is probably usually the case so that might be an
215*4882a593Smuzhiyun overoptimization)
216*4882a593Smuzhiyun */
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun /*
219*4882a593Smuzhiyun In rootless modes which are monitor or virtual desktop size
220*4882a593Smuzhiyun use RandR to resize the X screen
221*4882a593Smuzhiyun */
222*4882a593Smuzhiyun if ((!s_pScreenInfo->fUserGaveHeightAndWidth) &&
223*4882a593Smuzhiyun (s_pScreenInfo->iResizeMode == resizeWithRandr) && (FALSE
224*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
225*4882a593Smuzhiyun ||
226*4882a593Smuzhiyun s_pScreenInfo->
227*4882a593Smuzhiyun fMWExtWM
228*4882a593Smuzhiyun #endif
229*4882a593Smuzhiyun ||
230*4882a593Smuzhiyun s_pScreenInfo->
231*4882a593Smuzhiyun fRootless
232*4882a593Smuzhiyun ||
233*4882a593Smuzhiyun s_pScreenInfo->
234*4882a593Smuzhiyun fMultiWindow
235*4882a593Smuzhiyun )) {
236*4882a593Smuzhiyun DWORD dwWidth = 0, dwHeight = 0;
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun if (s_pScreenInfo->fMultipleMonitors) {
239*4882a593Smuzhiyun /* resize to new virtual desktop size */
240*4882a593Smuzhiyun dwWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
241*4882a593Smuzhiyun dwHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun else {
244*4882a593Smuzhiyun /* resize to new size of specified monitor */
245*4882a593Smuzhiyun struct GetMonitorInfoData data;
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun if (QueryMonitor(s_pScreenInfo->iMonitor, &data)) {
248*4882a593Smuzhiyun if (data.bMonitorSpecifiedExists == TRUE) {
249*4882a593Smuzhiyun dwWidth = data.monitorWidth;
250*4882a593Smuzhiyun dwHeight = data.monitorHeight;
251*4882a593Smuzhiyun /*
252*4882a593Smuzhiyun XXX: monitor may have changed position,
253*4882a593Smuzhiyun so we might need to update xinerama data
254*4882a593Smuzhiyun */
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun else {
257*4882a593Smuzhiyun ErrorF("Monitor number %d no longer exists!\n",
258*4882a593Smuzhiyun s_pScreenInfo->iMonitor);
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun }
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun /*
264*4882a593Smuzhiyun XXX: probably a small bug here: we don't compute the work area
265*4882a593Smuzhiyun and allow for task bar
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun XXX: generally, we don't allow for the task bar being moved after
268*4882a593Smuzhiyun the server is started
269*4882a593Smuzhiyun */
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun /* Set screen size to match new size, if it is different to current */
272*4882a593Smuzhiyun if (((dwWidth != 0) && (dwHeight != 0)) &&
273*4882a593Smuzhiyun ((s_pScreenInfo->dwWidth != dwWidth) ||
274*4882a593Smuzhiyun (s_pScreenInfo->dwHeight != dwHeight))) {
275*4882a593Smuzhiyun winDoRandRScreenSetSize(s_pScreen,
276*4882a593Smuzhiyun dwWidth,
277*4882a593Smuzhiyun dwHeight,
278*4882a593Smuzhiyun (dwWidth * 25.4) /
279*4882a593Smuzhiyun monitorResolution,
280*4882a593Smuzhiyun (dwHeight * 25.4) /
281*4882a593Smuzhiyun monitorResolution);
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun else {
285*4882a593Smuzhiyun /*
286*4882a593Smuzhiyun * We can simply recreate the same-sized primary surface when
287*4882a593Smuzhiyun * the display dimensions change.
288*4882a593Smuzhiyun */
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun winDebug
291*4882a593Smuzhiyun ("winWindowProc - WM_DISPLAYCHANGE - Releasing and recreating primary surface\n");
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun /* Release the old primary surface */
294*4882a593Smuzhiyun if (*s_pScreenPriv->pwinReleasePrimarySurface)
295*4882a593Smuzhiyun (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun /* Create the new primary surface */
298*4882a593Smuzhiyun if (*s_pScreenPriv->pwinCreatePrimarySurface)
299*4882a593Smuzhiyun (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen);
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun break;
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun case WM_SIZE:
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun SCROLLINFO si;
308*4882a593Smuzhiyun RECT rcWindow;
309*4882a593Smuzhiyun int iWidth, iHeight;
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun #if CYGDEBUG
312*4882a593Smuzhiyun winDebug("winWindowProc - WM_SIZE\n");
313*4882a593Smuzhiyun #endif
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun /* Break if we do not allow resizing */
316*4882a593Smuzhiyun if ((s_pScreenInfo->iResizeMode == resizeNotAllowed)
317*4882a593Smuzhiyun || !s_pScreenInfo->fDecoration
318*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
319*4882a593Smuzhiyun || s_pScreenInfo->fMWExtWM
320*4882a593Smuzhiyun #endif
321*4882a593Smuzhiyun || s_pScreenInfo->fRootless
322*4882a593Smuzhiyun || s_pScreenInfo->fMultiWindow
323*4882a593Smuzhiyun || s_pScreenInfo->fFullScreen)
324*4882a593Smuzhiyun break;
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun /* No need to resize if we get minimized */
327*4882a593Smuzhiyun if (wParam == SIZE_MINIMIZED)
328*4882a593Smuzhiyun return 0;
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun ErrorF("winWindowProc - WM_SIZE - new client area w: %d h: %d\n",
331*4882a593Smuzhiyun LOWORD(lParam), HIWORD(lParam));
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun if (s_pScreenInfo->iResizeMode == resizeWithRandr) {
334*4882a593Smuzhiyun /* Actual resizing is done on WM_EXITSIZEMOVE */
335*4882a593Smuzhiyun return 0;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun /* Otherwise iResizeMode == resizeWithScrollbars */
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun /*
341*4882a593Smuzhiyun * Get the size of the whole window, including client area,
342*4882a593Smuzhiyun * scrollbars, and non-client area decorations (caption, borders).
343*4882a593Smuzhiyun * We do this because we need to check if the client area
344*4882a593Smuzhiyun * without scrollbars is large enough to display the whole visual.
345*4882a593Smuzhiyun * The new client area size passed by lParam already subtracts
346*4882a593Smuzhiyun * the size of the scrollbars if they are currently displayed.
347*4882a593Smuzhiyun * So checking is LOWORD(lParam) == visual_width and
348*4882a593Smuzhiyun * HIWORD(lParam) == visual_height will never tell us to hide
349*4882a593Smuzhiyun * the scrollbars because the client area would always be too small.
350*4882a593Smuzhiyun * GetClientRect returns the same sizes given by lParam, so we
351*4882a593Smuzhiyun * cannot use GetClientRect either.
352*4882a593Smuzhiyun */
353*4882a593Smuzhiyun GetWindowRect(hwnd, &rcWindow);
354*4882a593Smuzhiyun iWidth = rcWindow.right - rcWindow.left;
355*4882a593Smuzhiyun iHeight = rcWindow.bottom - rcWindow.top;
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun /* Subtract the frame size from the window size. */
358*4882a593Smuzhiyun iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME);
359*4882a593Smuzhiyun iHeight -= (2 * GetSystemMetrics(SM_CYSIZEFRAME)
360*4882a593Smuzhiyun + GetSystemMetrics(SM_CYCAPTION));
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun /*
363*4882a593Smuzhiyun * Update scrollbar page sizes.
364*4882a593Smuzhiyun * NOTE: If page size == range, then the scrollbar is
365*4882a593Smuzhiyun * automatically hidden.
366*4882a593Smuzhiyun */
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun /* Is the naked client area large enough to show the whole visual? */
369*4882a593Smuzhiyun if (iWidth < s_pScreenInfo->dwWidth
370*4882a593Smuzhiyun || iHeight < s_pScreenInfo->dwHeight) {
371*4882a593Smuzhiyun /* Client area too small to display visual, use scrollbars */
372*4882a593Smuzhiyun iWidth -= GetSystemMetrics(SM_CXVSCROLL);
373*4882a593Smuzhiyun iHeight -= GetSystemMetrics(SM_CYHSCROLL);
374*4882a593Smuzhiyun }
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun /* Set the horizontal scrollbar page size */
377*4882a593Smuzhiyun si.cbSize = sizeof(si);
378*4882a593Smuzhiyun si.fMask = SIF_PAGE | SIF_RANGE;
379*4882a593Smuzhiyun si.nMin = 0;
380*4882a593Smuzhiyun si.nMax = s_pScreenInfo->dwWidth - 1;
381*4882a593Smuzhiyun si.nPage = iWidth;
382*4882a593Smuzhiyun SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun /* Set the vertical scrollbar page size */
385*4882a593Smuzhiyun si.cbSize = sizeof(si);
386*4882a593Smuzhiyun si.fMask = SIF_PAGE | SIF_RANGE;
387*4882a593Smuzhiyun si.nMin = 0;
388*4882a593Smuzhiyun si.nMax = s_pScreenInfo->dwHeight - 1;
389*4882a593Smuzhiyun si.nPage = iHeight;
390*4882a593Smuzhiyun SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun /*
393*4882a593Smuzhiyun * NOTE: Scrollbars may have moved if they were at the
394*4882a593Smuzhiyun * far right/bottom, so we query their current position.
395*4882a593Smuzhiyun */
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun /* Get the horizontal scrollbar position and set the offset */
398*4882a593Smuzhiyun si.cbSize = sizeof(si);
399*4882a593Smuzhiyun si.fMask = SIF_POS;
400*4882a593Smuzhiyun GetScrollInfo(hwnd, SB_HORZ, &si);
401*4882a593Smuzhiyun s_pScreenInfo->dwXOffset = -si.nPos;
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun /* Get the vertical scrollbar position and set the offset */
404*4882a593Smuzhiyun si.cbSize = sizeof(si);
405*4882a593Smuzhiyun si.fMask = SIF_POS;
406*4882a593Smuzhiyun GetScrollInfo(hwnd, SB_VERT, &si);
407*4882a593Smuzhiyun s_pScreenInfo->dwYOffset = -si.nPos;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun return 0;
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun case WM_SYSCOMMAND:
412*4882a593Smuzhiyun if (s_pScreenInfo->iResizeMode == resizeWithRandr &&
413*4882a593Smuzhiyun ((wParam & 0xfff0) == SC_MAXIMIZE ||
414*4882a593Smuzhiyun (wParam & 0xfff0) == SC_RESTORE))
415*4882a593Smuzhiyun PostMessage(hwnd, WM_EXITSIZEMOVE, 0, 0);
416*4882a593Smuzhiyun break;
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun case WM_ENTERSIZEMOVE:
419*4882a593Smuzhiyun ErrorF("winWindowProc - WM_ENTERSIZEMOVE\n");
420*4882a593Smuzhiyun break;
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun case WM_EXITSIZEMOVE:
423*4882a593Smuzhiyun ErrorF("winWindowProc - WM_EXITSIZEMOVE\n");
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun if (s_pScreenInfo->iResizeMode == resizeWithRandr) {
426*4882a593Smuzhiyun /* Set screen size to match new client area, if it is different to current */
427*4882a593Smuzhiyun RECT rcClient;
428*4882a593Smuzhiyun DWORD dwWidth, dwHeight;
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun GetClientRect(hwnd, &rcClient);
431*4882a593Smuzhiyun dwWidth = rcClient.right - rcClient.left;
432*4882a593Smuzhiyun dwHeight = rcClient.bottom - rcClient.top;
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun if ((s_pScreenInfo->dwWidth != dwWidth) ||
435*4882a593Smuzhiyun (s_pScreenInfo->dwHeight != dwHeight)) {
436*4882a593Smuzhiyun /* mm = dots * (25.4 mm / inch) / (dots / inch) */
437*4882a593Smuzhiyun winDoRandRScreenSetSize(s_pScreen,
438*4882a593Smuzhiyun dwWidth,
439*4882a593Smuzhiyun dwHeight,
440*4882a593Smuzhiyun (dwWidth * 25.4) / monitorResolution,
441*4882a593Smuzhiyun (dwHeight * 25.4) / monitorResolution);
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun }
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun break;
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun case WM_VSCROLL:
448*4882a593Smuzhiyun {
449*4882a593Smuzhiyun SCROLLINFO si;
450*4882a593Smuzhiyun int iVertPos;
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun #if CYGDEBUG
453*4882a593Smuzhiyun winDebug("winWindowProc - WM_VSCROLL\n");
454*4882a593Smuzhiyun #endif
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun /* Get vertical scroll bar info */
457*4882a593Smuzhiyun si.cbSize = sizeof(si);
458*4882a593Smuzhiyun si.fMask = SIF_ALL;
459*4882a593Smuzhiyun GetScrollInfo(hwnd, SB_VERT, &si);
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun /* Save the vertical position for comparison later */
462*4882a593Smuzhiyun iVertPos = si.nPos;
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun /*
465*4882a593Smuzhiyun * Don't forget:
466*4882a593Smuzhiyun * moving the scrollbar to the DOWN, scroll the content UP
467*4882a593Smuzhiyun */
468*4882a593Smuzhiyun switch (LOWORD(wParam)) {
469*4882a593Smuzhiyun case SB_TOP:
470*4882a593Smuzhiyun si.nPos = si.nMin;
471*4882a593Smuzhiyun break;
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun case SB_BOTTOM:
474*4882a593Smuzhiyun si.nPos = si.nMax - si.nPage + 1;
475*4882a593Smuzhiyun break;
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun case SB_LINEUP:
478*4882a593Smuzhiyun si.nPos -= 1;
479*4882a593Smuzhiyun break;
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun case SB_LINEDOWN:
482*4882a593Smuzhiyun si.nPos += 1;
483*4882a593Smuzhiyun break;
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun case SB_PAGEUP:
486*4882a593Smuzhiyun si.nPos -= si.nPage;
487*4882a593Smuzhiyun break;
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun case SB_PAGEDOWN:
490*4882a593Smuzhiyun si.nPos += si.nPage;
491*4882a593Smuzhiyun break;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun case SB_THUMBTRACK:
494*4882a593Smuzhiyun si.nPos = si.nTrackPos;
495*4882a593Smuzhiyun break;
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun default:
498*4882a593Smuzhiyun break;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun /*
502*4882a593Smuzhiyun * We retrieve the position after setting it,
503*4882a593Smuzhiyun * because Windows may adjust it.
504*4882a593Smuzhiyun */
505*4882a593Smuzhiyun si.fMask = SIF_POS;
506*4882a593Smuzhiyun SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
507*4882a593Smuzhiyun GetScrollInfo(hwnd, SB_VERT, &si);
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun /* Scroll the window if the position has changed */
510*4882a593Smuzhiyun if (si.nPos != iVertPos) {
511*4882a593Smuzhiyun /* Save the new offset for bit block transfers, etc. */
512*4882a593Smuzhiyun s_pScreenInfo->dwYOffset = -si.nPos;
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun /* Change displayed region in the window */
515*4882a593Smuzhiyun ScrollWindowEx(hwnd,
516*4882a593Smuzhiyun 0,
517*4882a593Smuzhiyun iVertPos - si.nPos,
518*4882a593Smuzhiyun NULL, NULL, NULL, NULL, SW_INVALIDATE);
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun /* Redraw the window contents */
521*4882a593Smuzhiyun UpdateWindow(hwnd);
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun }
524*4882a593Smuzhiyun return 0;
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun case WM_HSCROLL:
527*4882a593Smuzhiyun {
528*4882a593Smuzhiyun SCROLLINFO si;
529*4882a593Smuzhiyun int iHorzPos;
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun #if CYGDEBUG
532*4882a593Smuzhiyun winDebug("winWindowProc - WM_HSCROLL\n");
533*4882a593Smuzhiyun #endif
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun /* Get horizontal scroll bar info */
536*4882a593Smuzhiyun si.cbSize = sizeof(si);
537*4882a593Smuzhiyun si.fMask = SIF_ALL;
538*4882a593Smuzhiyun GetScrollInfo(hwnd, SB_HORZ, &si);
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun /* Save the horizontal position for comparison later */
541*4882a593Smuzhiyun iHorzPos = si.nPos;
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun /*
544*4882a593Smuzhiyun * Don't forget:
545*4882a593Smuzhiyun * moving the scrollbar to the RIGHT, scroll the content LEFT
546*4882a593Smuzhiyun */
547*4882a593Smuzhiyun switch (LOWORD(wParam)) {
548*4882a593Smuzhiyun case SB_LEFT:
549*4882a593Smuzhiyun si.nPos = si.nMin;
550*4882a593Smuzhiyun break;
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun case SB_RIGHT:
553*4882a593Smuzhiyun si.nPos = si.nMax - si.nPage + 1;
554*4882a593Smuzhiyun break;
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun case SB_LINELEFT:
557*4882a593Smuzhiyun si.nPos -= 1;
558*4882a593Smuzhiyun break;
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun case SB_LINERIGHT:
561*4882a593Smuzhiyun si.nPos += 1;
562*4882a593Smuzhiyun break;
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun case SB_PAGELEFT:
565*4882a593Smuzhiyun si.nPos -= si.nPage;
566*4882a593Smuzhiyun break;
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun case SB_PAGERIGHT:
569*4882a593Smuzhiyun si.nPos += si.nPage;
570*4882a593Smuzhiyun break;
571*4882a593Smuzhiyun
572*4882a593Smuzhiyun case SB_THUMBTRACK:
573*4882a593Smuzhiyun si.nPos = si.nTrackPos;
574*4882a593Smuzhiyun break;
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun default:
577*4882a593Smuzhiyun break;
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun /*
581*4882a593Smuzhiyun * We retrieve the position after setting it,
582*4882a593Smuzhiyun * because Windows may adjust it.
583*4882a593Smuzhiyun */
584*4882a593Smuzhiyun si.fMask = SIF_POS;
585*4882a593Smuzhiyun SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
586*4882a593Smuzhiyun GetScrollInfo(hwnd, SB_HORZ, &si);
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun /* Scroll the window if the position has changed */
589*4882a593Smuzhiyun if (si.nPos != iHorzPos) {
590*4882a593Smuzhiyun /* Save the new offset for bit block transfers, etc. */
591*4882a593Smuzhiyun s_pScreenInfo->dwXOffset = -si.nPos;
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun /* Change displayed region in the window */
594*4882a593Smuzhiyun ScrollWindowEx(hwnd,
595*4882a593Smuzhiyun iHorzPos - si.nPos,
596*4882a593Smuzhiyun 0, NULL, NULL, NULL, NULL, SW_INVALIDATE);
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun /* Redraw the window contents */
599*4882a593Smuzhiyun UpdateWindow(hwnd);
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun }
602*4882a593Smuzhiyun return 0;
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun case WM_GETMINMAXINFO:
605*4882a593Smuzhiyun {
606*4882a593Smuzhiyun MINMAXINFO *pMinMaxInfo = (MINMAXINFO *) lParam;
607*4882a593Smuzhiyun int iCaptionHeight;
608*4882a593Smuzhiyun int iBorderHeight, iBorderWidth;
609*4882a593Smuzhiyun
610*4882a593Smuzhiyun #if CYGDEBUG
611*4882a593Smuzhiyun winDebug("winWindowProc - WM_GETMINMAXINFO - pScreenInfo: %p\n",
612*4882a593Smuzhiyun s_pScreenInfo);
613*4882a593Smuzhiyun #endif
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun /* Can't do anything without screen info */
616*4882a593Smuzhiyun if (s_pScreenInfo == NULL
617*4882a593Smuzhiyun || (s_pScreenInfo->iResizeMode != resizeWithScrollbars)
618*4882a593Smuzhiyun || s_pScreenInfo->fFullScreen || !s_pScreenInfo->fDecoration
619*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
620*4882a593Smuzhiyun || s_pScreenInfo->fMWExtWM
621*4882a593Smuzhiyun #endif
622*4882a593Smuzhiyun || s_pScreenInfo->fRootless
623*4882a593Smuzhiyun || s_pScreenInfo->fMultiWindow
624*4882a593Smuzhiyun )
625*4882a593Smuzhiyun break;
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun /*
628*4882a593Smuzhiyun * Here we can override the maximum tracking size, which
629*4882a593Smuzhiyun * is the largest size that can be assigned to our window
630*4882a593Smuzhiyun * via the sizing border.
631*4882a593Smuzhiyun */
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun /*
634*4882a593Smuzhiyun * FIXME: Do we only need to do this once, since our visual size
635*4882a593Smuzhiyun * does not change? Does Windows store this value statically
636*4882a593Smuzhiyun * once we have set it once?
637*4882a593Smuzhiyun */
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun /* Get the border and caption sizes */
640*4882a593Smuzhiyun iCaptionHeight = GetSystemMetrics(SM_CYCAPTION);
641*4882a593Smuzhiyun iBorderWidth = 2 * GetSystemMetrics(SM_CXSIZEFRAME);
642*4882a593Smuzhiyun iBorderHeight = 2 * GetSystemMetrics(SM_CYSIZEFRAME);
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun /* Allow the full visual to be displayed */
645*4882a593Smuzhiyun pMinMaxInfo->ptMaxTrackSize.x = s_pScreenInfo->dwWidth + iBorderWidth;
646*4882a593Smuzhiyun pMinMaxInfo->ptMaxTrackSize.y
647*4882a593Smuzhiyun = s_pScreenInfo->dwHeight + iBorderHeight + iCaptionHeight;
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun return 0;
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun case WM_ERASEBKGND:
652*4882a593Smuzhiyun #if CYGDEBUG
653*4882a593Smuzhiyun winDebug("winWindowProc - WM_ERASEBKGND\n");
654*4882a593Smuzhiyun #endif
655*4882a593Smuzhiyun /*
656*4882a593Smuzhiyun * Pretend that we did erase the background but we don't care,
657*4882a593Smuzhiyun * the application uses the full window estate. This avoids some
658*4882a593Smuzhiyun * flickering when resizing.
659*4882a593Smuzhiyun */
660*4882a593Smuzhiyun return TRUE;
661*4882a593Smuzhiyun
662*4882a593Smuzhiyun case WM_PAINT:
663*4882a593Smuzhiyun #if CYGDEBUG
664*4882a593Smuzhiyun winDebug("winWindowProc - WM_PAINT\n");
665*4882a593Smuzhiyun #endif
666*4882a593Smuzhiyun /* Only paint if we have privates and the server is enabled */
667*4882a593Smuzhiyun if (s_pScreenPriv == NULL
668*4882a593Smuzhiyun || !s_pScreenPriv->fEnabled
669*4882a593Smuzhiyun || (s_pScreenInfo->fFullScreen && !s_pScreenPriv->fActive)
670*4882a593Smuzhiyun || s_pScreenPriv->fBadDepth) {
671*4882a593Smuzhiyun /* We don't want to paint */
672*4882a593Smuzhiyun break;
673*4882a593Smuzhiyun }
674*4882a593Smuzhiyun
675*4882a593Smuzhiyun /* Break out here if we don't have a valid paint routine */
676*4882a593Smuzhiyun if (s_pScreenPriv->pwinBltExposedRegions == NULL)
677*4882a593Smuzhiyun break;
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun /* Call the engine dependent repainter */
680*4882a593Smuzhiyun (*s_pScreenPriv->pwinBltExposedRegions) (s_pScreen);
681*4882a593Smuzhiyun return 0;
682*4882a593Smuzhiyun
683*4882a593Smuzhiyun case WM_PALETTECHANGED:
684*4882a593Smuzhiyun {
685*4882a593Smuzhiyun #if CYGDEBUG
686*4882a593Smuzhiyun winDebug("winWindowProc - WM_PALETTECHANGED\n");
687*4882a593Smuzhiyun #endif
688*4882a593Smuzhiyun /*
689*4882a593Smuzhiyun * Don't process if we don't have privates or a colormap,
690*4882a593Smuzhiyun * or if we have an invalid depth.
691*4882a593Smuzhiyun */
692*4882a593Smuzhiyun if (s_pScreenPriv == NULL
693*4882a593Smuzhiyun || s_pScreenPriv->pcmapInstalled == NULL
694*4882a593Smuzhiyun || s_pScreenPriv->fBadDepth)
695*4882a593Smuzhiyun break;
696*4882a593Smuzhiyun
697*4882a593Smuzhiyun /* Return if we caused the palette to change */
698*4882a593Smuzhiyun if ((HWND) wParam == hwnd) {
699*4882a593Smuzhiyun /* Redraw the screen */
700*4882a593Smuzhiyun (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen);
701*4882a593Smuzhiyun return 0;
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun /* Reinstall the windows palette */
705*4882a593Smuzhiyun (*s_pScreenPriv->pwinRealizeInstalledPalette) (s_pScreen);
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun /* Redraw the screen */
708*4882a593Smuzhiyun (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen);
709*4882a593Smuzhiyun return 0;
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun case WM_MOUSEMOVE:
713*4882a593Smuzhiyun /* We can't do anything without privates */
714*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
715*4882a593Smuzhiyun break;
716*4882a593Smuzhiyun
717*4882a593Smuzhiyun /* We can't do anything without g_pwinPointer */
718*4882a593Smuzhiyun if (g_pwinPointer == NULL)
719*4882a593Smuzhiyun break;
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun /* Has the mouse pointer crossed screens? */
722*4882a593Smuzhiyun if (s_pScreen != miPointerGetScreen(g_pwinPointer))
723*4882a593Smuzhiyun miPointerSetScreen(g_pwinPointer, s_pScreenInfo->dwScreen,
724*4882a593Smuzhiyun GET_X_LPARAM(lParam) - s_pScreenInfo->dwXOffset,
725*4882a593Smuzhiyun GET_Y_LPARAM(lParam) - s_pScreenInfo->dwYOffset);
726*4882a593Smuzhiyun
727*4882a593Smuzhiyun /* Are we tracking yet? */
728*4882a593Smuzhiyun if (!s_fTracking) {
729*4882a593Smuzhiyun TRACKMOUSEEVENT tme;
730*4882a593Smuzhiyun
731*4882a593Smuzhiyun /* Setup data structure */
732*4882a593Smuzhiyun ZeroMemory(&tme, sizeof(tme));
733*4882a593Smuzhiyun tme.cbSize = sizeof(tme);
734*4882a593Smuzhiyun tme.dwFlags = TME_LEAVE;
735*4882a593Smuzhiyun tme.hwndTrack = hwnd;
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun /* Call the tracking function */
738*4882a593Smuzhiyun if (!TrackMouseEvent(&tme))
739*4882a593Smuzhiyun ErrorF("winWindowProc - TrackMouseEvent failed\n");
740*4882a593Smuzhiyun
741*4882a593Smuzhiyun /* Flag that we are tracking now */
742*4882a593Smuzhiyun s_fTracking = TRUE;
743*4882a593Smuzhiyun }
744*4882a593Smuzhiyun
745*4882a593Smuzhiyun /* Hide or show the Windows mouse cursor */
746*4882a593Smuzhiyun if (g_fSoftwareCursor && g_fCursor &&
747*4882a593Smuzhiyun (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer)) {
748*4882a593Smuzhiyun /* Hide Windows cursor */
749*4882a593Smuzhiyun g_fCursor = FALSE;
750*4882a593Smuzhiyun ShowCursor(FALSE);
751*4882a593Smuzhiyun }
752*4882a593Smuzhiyun else if (g_fSoftwareCursor && !g_fCursor && !s_pScreenPriv->fActive
753*4882a593Smuzhiyun && !s_pScreenInfo->fLessPointer) {
754*4882a593Smuzhiyun /* Show Windows cursor */
755*4882a593Smuzhiyun g_fCursor = TRUE;
756*4882a593Smuzhiyun ShowCursor(TRUE);
757*4882a593Smuzhiyun }
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun /* Deliver absolute cursor position to X Server */
760*4882a593Smuzhiyun winEnqueueMotion(GET_X_LPARAM(lParam) - s_pScreenInfo->dwXOffset,
761*4882a593Smuzhiyun GET_Y_LPARAM(lParam) - s_pScreenInfo->dwYOffset);
762*4882a593Smuzhiyun return 0;
763*4882a593Smuzhiyun
764*4882a593Smuzhiyun case WM_NCMOUSEMOVE:
765*4882a593Smuzhiyun /*
766*4882a593Smuzhiyun * We break instead of returning 0 since we need to call
767*4882a593Smuzhiyun * DefWindowProc to get the mouse cursor changes
768*4882a593Smuzhiyun * and min/max/close button highlighting in Windows XP.
769*4882a593Smuzhiyun * The Platform SDK says that you should return 0 if you
770*4882a593Smuzhiyun * process this message, but it fails to mention that you
771*4882a593Smuzhiyun * will give up any default functionality if you do return 0.
772*4882a593Smuzhiyun */
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun /* We can't do anything without privates */
775*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
776*4882a593Smuzhiyun break;
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun /* Non-client mouse movement, show Windows cursor */
779*4882a593Smuzhiyun if (g_fSoftwareCursor && !g_fCursor) {
780*4882a593Smuzhiyun g_fCursor = TRUE;
781*4882a593Smuzhiyun ShowCursor(TRUE);
782*4882a593Smuzhiyun }
783*4882a593Smuzhiyun break;
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun case WM_MOUSELEAVE:
786*4882a593Smuzhiyun /* Mouse has left our client area */
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun /* Flag that we are no longer tracking */
789*4882a593Smuzhiyun s_fTracking = FALSE;
790*4882a593Smuzhiyun
791*4882a593Smuzhiyun /* Show the mouse cursor, if necessary */
792*4882a593Smuzhiyun if (g_fSoftwareCursor && !g_fCursor) {
793*4882a593Smuzhiyun g_fCursor = TRUE;
794*4882a593Smuzhiyun ShowCursor(TRUE);
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun return 0;
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun case WM_LBUTTONDBLCLK:
799*4882a593Smuzhiyun case WM_LBUTTONDOWN:
800*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
801*4882a593Smuzhiyun break;
802*4882a593Smuzhiyun if (s_pScreenInfo->fRootless
803*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
804*4882a593Smuzhiyun || s_pScreenInfo->fMWExtWM
805*4882a593Smuzhiyun #endif
806*4882a593Smuzhiyun )
807*4882a593Smuzhiyun SetCapture(hwnd);
808*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonPress, Button1, wParam);
809*4882a593Smuzhiyun
810*4882a593Smuzhiyun case WM_LBUTTONUP:
811*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
812*4882a593Smuzhiyun break;
813*4882a593Smuzhiyun if (s_pScreenInfo->fRootless
814*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
815*4882a593Smuzhiyun || s_pScreenInfo->fMWExtWM
816*4882a593Smuzhiyun #endif
817*4882a593Smuzhiyun )
818*4882a593Smuzhiyun ReleaseCapture();
819*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button1, wParam);
820*4882a593Smuzhiyun
821*4882a593Smuzhiyun case WM_MBUTTONDBLCLK:
822*4882a593Smuzhiyun case WM_MBUTTONDOWN:
823*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
824*4882a593Smuzhiyun break;
825*4882a593Smuzhiyun if (s_pScreenInfo->fRootless
826*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
827*4882a593Smuzhiyun || s_pScreenInfo->fMWExtWM
828*4882a593Smuzhiyun #endif
829*4882a593Smuzhiyun )
830*4882a593Smuzhiyun SetCapture(hwnd);
831*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonPress, Button2, wParam);
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun case WM_MBUTTONUP:
834*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
835*4882a593Smuzhiyun break;
836*4882a593Smuzhiyun if (s_pScreenInfo->fRootless
837*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
838*4882a593Smuzhiyun || s_pScreenInfo->fMWExtWM
839*4882a593Smuzhiyun #endif
840*4882a593Smuzhiyun )
841*4882a593Smuzhiyun ReleaseCapture();
842*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button2, wParam);
843*4882a593Smuzhiyun
844*4882a593Smuzhiyun case WM_RBUTTONDBLCLK:
845*4882a593Smuzhiyun case WM_RBUTTONDOWN:
846*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
847*4882a593Smuzhiyun break;
848*4882a593Smuzhiyun if (s_pScreenInfo->fRootless
849*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
850*4882a593Smuzhiyun || s_pScreenInfo->fMWExtWM
851*4882a593Smuzhiyun #endif
852*4882a593Smuzhiyun )
853*4882a593Smuzhiyun SetCapture(hwnd);
854*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonPress, Button3, wParam);
855*4882a593Smuzhiyun
856*4882a593Smuzhiyun case WM_RBUTTONUP:
857*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
858*4882a593Smuzhiyun break;
859*4882a593Smuzhiyun if (s_pScreenInfo->fRootless
860*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
861*4882a593Smuzhiyun || s_pScreenInfo->fMWExtWM
862*4882a593Smuzhiyun #endif
863*4882a593Smuzhiyun )
864*4882a593Smuzhiyun ReleaseCapture();
865*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button3, wParam);
866*4882a593Smuzhiyun
867*4882a593Smuzhiyun case WM_XBUTTONDBLCLK:
868*4882a593Smuzhiyun case WM_XBUTTONDOWN:
869*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
870*4882a593Smuzhiyun break;
871*4882a593Smuzhiyun if (s_pScreenInfo->fRootless
872*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
873*4882a593Smuzhiyun || s_pScreenInfo->fMWExtWM
874*4882a593Smuzhiyun #endif
875*4882a593Smuzhiyun )
876*4882a593Smuzhiyun SetCapture(hwnd);
877*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonPress, HIWORD(wParam) + 7,
878*4882a593Smuzhiyun wParam);
879*4882a593Smuzhiyun case WM_XBUTTONUP:
880*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
881*4882a593Smuzhiyun break;
882*4882a593Smuzhiyun if (s_pScreenInfo->fRootless
883*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
884*4882a593Smuzhiyun || s_pScreenInfo->fMWExtWM
885*4882a593Smuzhiyun #endif
886*4882a593Smuzhiyun )
887*4882a593Smuzhiyun ReleaseCapture();
888*4882a593Smuzhiyun return winMouseButtonsHandle(s_pScreen, ButtonRelease,
889*4882a593Smuzhiyun HIWORD(wParam) + 7, wParam);
890*4882a593Smuzhiyun
891*4882a593Smuzhiyun case WM_TIMER:
892*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
893*4882a593Smuzhiyun break;
894*4882a593Smuzhiyun
895*4882a593Smuzhiyun /* Branch on the timer id */
896*4882a593Smuzhiyun switch (wParam) {
897*4882a593Smuzhiyun case WIN_E3B_TIMER_ID:
898*4882a593Smuzhiyun /* Send delayed button press */
899*4882a593Smuzhiyun winMouseButtonsSendEvent(ButtonPress,
900*4882a593Smuzhiyun s_pScreenPriv->iE3BCachedPress);
901*4882a593Smuzhiyun
902*4882a593Smuzhiyun /* Kill this timer */
903*4882a593Smuzhiyun KillTimer(s_pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID);
904*4882a593Smuzhiyun
905*4882a593Smuzhiyun /* Clear screen privates flags */
906*4882a593Smuzhiyun s_pScreenPriv->iE3BCachedPress = 0;
907*4882a593Smuzhiyun break;
908*4882a593Smuzhiyun
909*4882a593Smuzhiyun case WIN_POLLING_MOUSE_TIMER_ID:
910*4882a593Smuzhiyun {
911*4882a593Smuzhiyun static POINT last_point;
912*4882a593Smuzhiyun POINT point;
913*4882a593Smuzhiyun WPARAM wL, wM, wR, wShift, wCtrl;
914*4882a593Smuzhiyun LPARAM lPos;
915*4882a593Smuzhiyun
916*4882a593Smuzhiyun /* Get the current position of the mouse cursor */
917*4882a593Smuzhiyun GetCursorPos(&point);
918*4882a593Smuzhiyun
919*4882a593Smuzhiyun /* Map from screen (-X, -Y) to root (0, 0) */
920*4882a593Smuzhiyun point.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
921*4882a593Smuzhiyun point.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
922*4882a593Smuzhiyun
923*4882a593Smuzhiyun /* If the mouse pointer has moved, deliver absolute cursor position to X Server */
924*4882a593Smuzhiyun if (last_point.x != point.x || last_point.y != point.y) {
925*4882a593Smuzhiyun winEnqueueMotion(point.x, point.y);
926*4882a593Smuzhiyun last_point.x = point.x;
927*4882a593Smuzhiyun last_point.y = point.y;
928*4882a593Smuzhiyun }
929*4882a593Smuzhiyun
930*4882a593Smuzhiyun /* Check if a button was released but we didn't see it */
931*4882a593Smuzhiyun GetCursorPos(&point);
932*4882a593Smuzhiyun wL = (GetKeyState(VK_LBUTTON) & 0x8000) ? MK_LBUTTON : 0;
933*4882a593Smuzhiyun wM = (GetKeyState(VK_MBUTTON) & 0x8000) ? MK_MBUTTON : 0;
934*4882a593Smuzhiyun wR = (GetKeyState(VK_RBUTTON) & 0x8000) ? MK_RBUTTON : 0;
935*4882a593Smuzhiyun wShift = (GetKeyState(VK_SHIFT) & 0x8000) ? MK_SHIFT : 0;
936*4882a593Smuzhiyun wCtrl = (GetKeyState(VK_CONTROL) & 0x8000) ? MK_CONTROL : 0;
937*4882a593Smuzhiyun lPos = MAKELPARAM(point.x, point.y);
938*4882a593Smuzhiyun if (g_fButton[0] && !wL)
939*4882a593Smuzhiyun PostMessage(hwnd, WM_LBUTTONUP, wCtrl | wM | wR | wShift, lPos);
940*4882a593Smuzhiyun if (g_fButton[1] && !wM)
941*4882a593Smuzhiyun PostMessage(hwnd, WM_MBUTTONUP, wCtrl | wL | wR | wShift, lPos);
942*4882a593Smuzhiyun if (g_fButton[2] && !wR)
943*4882a593Smuzhiyun PostMessage(hwnd, WM_RBUTTONUP, wCtrl | wL | wM | wShift, lPos);
944*4882a593Smuzhiyun }
945*4882a593Smuzhiyun }
946*4882a593Smuzhiyun return 0;
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun case WM_CTLCOLORSCROLLBAR:
949*4882a593Smuzhiyun FatalError("winWindowProc - WM_CTLCOLORSCROLLBAR - We are not "
950*4882a593Smuzhiyun "supposed to get this message. Exiting.\n");
951*4882a593Smuzhiyun return 0;
952*4882a593Smuzhiyun
953*4882a593Smuzhiyun case WM_MOUSEWHEEL:
954*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
955*4882a593Smuzhiyun break;
956*4882a593Smuzhiyun #if CYGDEBUG
957*4882a593Smuzhiyun winDebug("winWindowProc - WM_MOUSEWHEEL\n");
958*4882a593Smuzhiyun #endif
959*4882a593Smuzhiyun /* Button4 = WheelUp */
960*4882a593Smuzhiyun /* Button5 = WheelDown */
961*4882a593Smuzhiyun winMouseWheel(&(s_pScreenPriv->iDeltaZ), GET_WHEEL_DELTA_WPARAM(wParam), Button4, Button5);
962*4882a593Smuzhiyun break;
963*4882a593Smuzhiyun
964*4882a593Smuzhiyun case WM_MOUSEHWHEEL:
965*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
966*4882a593Smuzhiyun break;
967*4882a593Smuzhiyun #if CYGDEBUG
968*4882a593Smuzhiyun winDebug("winWindowProc - WM_MOUSEHWHEEL\n");
969*4882a593Smuzhiyun #endif
970*4882a593Smuzhiyun /* Button7 = TiltRight */
971*4882a593Smuzhiyun /* Button6 = TiltLeft */
972*4882a593Smuzhiyun winMouseWheel(&(s_pScreenPriv->iDeltaV), GET_WHEEL_DELTA_WPARAM(wParam), 7, 6);
973*4882a593Smuzhiyun break;
974*4882a593Smuzhiyun
975*4882a593Smuzhiyun case WM_SETFOCUS:
976*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
977*4882a593Smuzhiyun break;
978*4882a593Smuzhiyun
979*4882a593Smuzhiyun /* Restore the state of all mode keys */
980*4882a593Smuzhiyun winRestoreModeKeyStates();
981*4882a593Smuzhiyun
982*4882a593Smuzhiyun /* Add the keyboard hook if possible */
983*4882a593Smuzhiyun if (g_fKeyboardHookLL)
984*4882a593Smuzhiyun g_fKeyboardHookLL = winInstallKeyboardHookLL();
985*4882a593Smuzhiyun return 0;
986*4882a593Smuzhiyun
987*4882a593Smuzhiyun case WM_KILLFOCUS:
988*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
989*4882a593Smuzhiyun break;
990*4882a593Smuzhiyun
991*4882a593Smuzhiyun /* Release any pressed keys */
992*4882a593Smuzhiyun winKeybdReleaseKeys();
993*4882a593Smuzhiyun
994*4882a593Smuzhiyun /* Remove our keyboard hook if it is installed */
995*4882a593Smuzhiyun winRemoveKeyboardHookLL();
996*4882a593Smuzhiyun return 0;
997*4882a593Smuzhiyun
998*4882a593Smuzhiyun case WM_SYSKEYDOWN:
999*4882a593Smuzhiyun case WM_KEYDOWN:
1000*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
1001*4882a593Smuzhiyun break;
1002*4882a593Smuzhiyun
1003*4882a593Smuzhiyun /*
1004*4882a593Smuzhiyun * FIXME: Catching Alt-F4 like this is really terrible. This should
1005*4882a593Smuzhiyun * be generalized to handle other Windows keyboard signals. Actually,
1006*4882a593Smuzhiyun * the list keys to catch and the actions to perform when caught should
1007*4882a593Smuzhiyun * be configurable; that way user's can customize the keys that they
1008*4882a593Smuzhiyun * need to have passed through to their window manager or apps, or they
1009*4882a593Smuzhiyun * can remap certain actions to new key codes that do not conflict
1010*4882a593Smuzhiyun * with the X apps that they are using. Yeah, that'll take awhile.
1011*4882a593Smuzhiyun */
1012*4882a593Smuzhiyun if ((s_pScreenInfo->fUseWinKillKey && wParam == VK_F4
1013*4882a593Smuzhiyun && (GetKeyState(VK_MENU) & 0x8000))
1014*4882a593Smuzhiyun || (s_pScreenInfo->fUseUnixKillKey && wParam == VK_BACK
1015*4882a593Smuzhiyun && (GetKeyState(VK_MENU) & 0x8000)
1016*4882a593Smuzhiyun && (GetKeyState(VK_CONTROL) & 0x8000))) {
1017*4882a593Smuzhiyun /*
1018*4882a593Smuzhiyun * Better leave this message here, just in case some unsuspecting
1019*4882a593Smuzhiyun * user enters Alt + F4 and is surprised when the application
1020*4882a593Smuzhiyun * quits.
1021*4882a593Smuzhiyun */
1022*4882a593Smuzhiyun ErrorF("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n");
1023*4882a593Smuzhiyun
1024*4882a593Smuzhiyun /* Display Exit dialog */
1025*4882a593Smuzhiyun winDisplayExitDialog(s_pScreenPriv);
1026*4882a593Smuzhiyun return 0;
1027*4882a593Smuzhiyun }
1028*4882a593Smuzhiyun
1029*4882a593Smuzhiyun /*
1030*4882a593Smuzhiyun * Don't do anything for the Windows keys, as focus will soon
1031*4882a593Smuzhiyun * be returned to Windows. We may be able to trap the Windows keys,
1032*4882a593Smuzhiyun * but we should determine if that is desirable before doing so.
1033*4882a593Smuzhiyun */
1034*4882a593Smuzhiyun if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL)
1035*4882a593Smuzhiyun break;
1036*4882a593Smuzhiyun
1037*4882a593Smuzhiyun /* Discard fake Ctrl_L events that precede AltGR on non-US keyboards */
1038*4882a593Smuzhiyun if (winIsFakeCtrl_L(message, wParam, lParam))
1039*4882a593Smuzhiyun return 0;
1040*4882a593Smuzhiyun
1041*4882a593Smuzhiyun /*
1042*4882a593Smuzhiyun * Discard presses generated from Windows auto-repeat
1043*4882a593Smuzhiyun */
1044*4882a593Smuzhiyun if (lParam & (1 << 30)) {
1045*4882a593Smuzhiyun switch (wParam) {
1046*4882a593Smuzhiyun /* ago: Pressing LControl while RControl is pressed is
1047*4882a593Smuzhiyun * Indicated as repeat. Fix this!
1048*4882a593Smuzhiyun */
1049*4882a593Smuzhiyun case VK_CONTROL:
1050*4882a593Smuzhiyun case VK_SHIFT:
1051*4882a593Smuzhiyun if (winCheckKeyPressed(wParam, lParam))
1052*4882a593Smuzhiyun return 0;
1053*4882a593Smuzhiyun break;
1054*4882a593Smuzhiyun default:
1055*4882a593Smuzhiyun return 0;
1056*4882a593Smuzhiyun }
1057*4882a593Smuzhiyun }
1058*4882a593Smuzhiyun
1059*4882a593Smuzhiyun /* Translate Windows key code to X scan code */
1060*4882a593Smuzhiyun iScanCode = winTranslateKey(wParam, lParam);
1061*4882a593Smuzhiyun
1062*4882a593Smuzhiyun /* Ignore repeats for CapsLock */
1063*4882a593Smuzhiyun if (wParam == VK_CAPITAL)
1064*4882a593Smuzhiyun lParam = 1;
1065*4882a593Smuzhiyun
1066*4882a593Smuzhiyun /* Send the key event(s) */
1067*4882a593Smuzhiyun for (i = 0; i < LOWORD(lParam); ++i)
1068*4882a593Smuzhiyun winSendKeyEvent(iScanCode, TRUE);
1069*4882a593Smuzhiyun return 0;
1070*4882a593Smuzhiyun
1071*4882a593Smuzhiyun case WM_SYSKEYUP:
1072*4882a593Smuzhiyun case WM_KEYUP:
1073*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
1074*4882a593Smuzhiyun break;
1075*4882a593Smuzhiyun
1076*4882a593Smuzhiyun /*
1077*4882a593Smuzhiyun * Don't do anything for the Windows keys, as focus will soon
1078*4882a593Smuzhiyun * be returned to Windows. We may be able to trap the Windows keys,
1079*4882a593Smuzhiyun * but we should determine if that is desirable before doing so.
1080*4882a593Smuzhiyun */
1081*4882a593Smuzhiyun if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL)
1082*4882a593Smuzhiyun break;
1083*4882a593Smuzhiyun
1084*4882a593Smuzhiyun /* Ignore the fake Ctrl_L that follows an AltGr release */
1085*4882a593Smuzhiyun if (winIsFakeCtrl_L(message, wParam, lParam))
1086*4882a593Smuzhiyun return 0;
1087*4882a593Smuzhiyun
1088*4882a593Smuzhiyun /* Enqueue a keyup event */
1089*4882a593Smuzhiyun iScanCode = winTranslateKey(wParam, lParam);
1090*4882a593Smuzhiyun winSendKeyEvent(iScanCode, FALSE);
1091*4882a593Smuzhiyun
1092*4882a593Smuzhiyun /* Release all pressed shift keys */
1093*4882a593Smuzhiyun if (wParam == VK_SHIFT)
1094*4882a593Smuzhiyun winFixShiftKeys(iScanCode);
1095*4882a593Smuzhiyun return 0;
1096*4882a593Smuzhiyun
1097*4882a593Smuzhiyun case WM_ACTIVATE:
1098*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
1099*4882a593Smuzhiyun break;
1100*4882a593Smuzhiyun
1101*4882a593Smuzhiyun /* TODO: Override display of window when we have a bad depth */
1102*4882a593Smuzhiyun if (LOWORD(wParam) != WA_INACTIVE && s_pScreenPriv->fBadDepth) {
1103*4882a593Smuzhiyun ErrorF("winWindowProc - WM_ACTIVATE - Bad depth, trying "
1104*4882a593Smuzhiyun "to override window activation\n");
1105*4882a593Smuzhiyun
1106*4882a593Smuzhiyun /* Minimize the window */
1107*4882a593Smuzhiyun ShowWindow(hwnd, SW_MINIMIZE);
1108*4882a593Smuzhiyun
1109*4882a593Smuzhiyun /* Display dialog box */
1110*4882a593Smuzhiyun if (g_hDlgDepthChange != NULL) {
1111*4882a593Smuzhiyun /* Make the existing dialog box active */
1112*4882a593Smuzhiyun SetActiveWindow(g_hDlgDepthChange);
1113*4882a593Smuzhiyun }
1114*4882a593Smuzhiyun else {
1115*4882a593Smuzhiyun /* TODO: Recreate the dialog box and bring to the top */
1116*4882a593Smuzhiyun ShowWindow(g_hDlgDepthChange, SW_SHOWDEFAULT);
1117*4882a593Smuzhiyun }
1118*4882a593Smuzhiyun
1119*4882a593Smuzhiyun /* Don't do any other processing of this message */
1120*4882a593Smuzhiyun return 0;
1121*4882a593Smuzhiyun }
1122*4882a593Smuzhiyun
1123*4882a593Smuzhiyun #if CYGDEBUG
1124*4882a593Smuzhiyun winDebug("winWindowProc - WM_ACTIVATE\n");
1125*4882a593Smuzhiyun #endif
1126*4882a593Smuzhiyun
1127*4882a593Smuzhiyun /*
1128*4882a593Smuzhiyun * Focus is being changed to another window.
1129*4882a593Smuzhiyun * The other window may or may not belong to
1130*4882a593Smuzhiyun * our process.
1131*4882a593Smuzhiyun */
1132*4882a593Smuzhiyun
1133*4882a593Smuzhiyun /* Clear any lingering wheel delta */
1134*4882a593Smuzhiyun s_pScreenPriv->iDeltaZ = 0;
1135*4882a593Smuzhiyun s_pScreenPriv->iDeltaV = 0;
1136*4882a593Smuzhiyun
1137*4882a593Smuzhiyun /* Reshow the Windows mouse cursor if we are being deactivated */
1138*4882a593Smuzhiyun if (g_fSoftwareCursor && LOWORD(wParam) == WA_INACTIVE && !g_fCursor) {
1139*4882a593Smuzhiyun /* Show Windows cursor */
1140*4882a593Smuzhiyun g_fCursor = TRUE;
1141*4882a593Smuzhiyun ShowCursor(TRUE);
1142*4882a593Smuzhiyun }
1143*4882a593Smuzhiyun return 0;
1144*4882a593Smuzhiyun
1145*4882a593Smuzhiyun case WM_ACTIVATEAPP:
1146*4882a593Smuzhiyun if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
1147*4882a593Smuzhiyun break;
1148*4882a593Smuzhiyun
1149*4882a593Smuzhiyun #if CYGDEBUG || TRUE
1150*4882a593Smuzhiyun winDebug("winWindowProc - WM_ACTIVATEAPP\n");
1151*4882a593Smuzhiyun #endif
1152*4882a593Smuzhiyun
1153*4882a593Smuzhiyun /* Activate or deactivate */
1154*4882a593Smuzhiyun s_pScreenPriv->fActive = wParam;
1155*4882a593Smuzhiyun
1156*4882a593Smuzhiyun /* Reshow the Windows mouse cursor if we are being deactivated */
1157*4882a593Smuzhiyun if (g_fSoftwareCursor && !s_pScreenPriv->fActive && !g_fCursor) {
1158*4882a593Smuzhiyun /* Show Windows cursor */
1159*4882a593Smuzhiyun g_fCursor = TRUE;
1160*4882a593Smuzhiyun ShowCursor(TRUE);
1161*4882a593Smuzhiyun }
1162*4882a593Smuzhiyun
1163*4882a593Smuzhiyun /* Make sure the clipboard chain is ok. */
1164*4882a593Smuzhiyun winFixClipboardChain();
1165*4882a593Smuzhiyun
1166*4882a593Smuzhiyun /* Call engine specific screen activation/deactivation function */
1167*4882a593Smuzhiyun (*s_pScreenPriv->pwinActivateApp) (s_pScreen);
1168*4882a593Smuzhiyun
1169*4882a593Smuzhiyun #ifdef XWIN_MULTIWINDOWEXTWM
1170*4882a593Smuzhiyun if (s_pScreenPriv->fActive) {
1171*4882a593Smuzhiyun /* Restack all window unless using built-in wm. */
1172*4882a593Smuzhiyun if (s_pScreenInfo->fMWExtWM)
1173*4882a593Smuzhiyun winMWExtWMRestackWindows(s_pScreen);
1174*4882a593Smuzhiyun }
1175*4882a593Smuzhiyun #endif
1176*4882a593Smuzhiyun
1177*4882a593Smuzhiyun return 0;
1178*4882a593Smuzhiyun
1179*4882a593Smuzhiyun case WM_COMMAND:
1180*4882a593Smuzhiyun switch (LOWORD(wParam)) {
1181*4882a593Smuzhiyun case ID_APP_EXIT:
1182*4882a593Smuzhiyun /* Display Exit dialog */
1183*4882a593Smuzhiyun winDisplayExitDialog(s_pScreenPriv);
1184*4882a593Smuzhiyun return 0;
1185*4882a593Smuzhiyun
1186*4882a593Smuzhiyun case ID_APP_HIDE_ROOT:
1187*4882a593Smuzhiyun if (s_pScreenPriv->fRootWindowShown)
1188*4882a593Smuzhiyun ShowWindow(s_pScreenPriv->hwndScreen, SW_HIDE);
1189*4882a593Smuzhiyun else
1190*4882a593Smuzhiyun ShowWindow(s_pScreenPriv->hwndScreen, SW_SHOW);
1191*4882a593Smuzhiyun s_pScreenPriv->fRootWindowShown = !s_pScreenPriv->fRootWindowShown;
1192*4882a593Smuzhiyun return 0;
1193*4882a593Smuzhiyun
1194*4882a593Smuzhiyun case ID_APP_MONITOR_PRIMARY:
1195*4882a593Smuzhiyun fPrimarySelection = !fPrimarySelection;
1196*4882a593Smuzhiyun return 0;
1197*4882a593Smuzhiyun
1198*4882a593Smuzhiyun case ID_APP_ABOUT:
1199*4882a593Smuzhiyun /* Display the About box */
1200*4882a593Smuzhiyun winDisplayAboutDialog(s_pScreenPriv);
1201*4882a593Smuzhiyun return 0;
1202*4882a593Smuzhiyun
1203*4882a593Smuzhiyun default:
1204*4882a593Smuzhiyun /* It's probably one of the custom menus... */
1205*4882a593Smuzhiyun if (HandleCustomWM_COMMAND(0, LOWORD(wParam), s_pScreenPriv))
1206*4882a593Smuzhiyun return 0;
1207*4882a593Smuzhiyun }
1208*4882a593Smuzhiyun break;
1209*4882a593Smuzhiyun
1210*4882a593Smuzhiyun case WM_GIVEUP:
1211*4882a593Smuzhiyun /* Tell X that we are giving up */
1212*4882a593Smuzhiyun if (s_pScreenInfo->fMultiWindow)
1213*4882a593Smuzhiyun winDeinitMultiWindowWM();
1214*4882a593Smuzhiyun GiveUp(0);
1215*4882a593Smuzhiyun return 0;
1216*4882a593Smuzhiyun
1217*4882a593Smuzhiyun case WM_CLOSE:
1218*4882a593Smuzhiyun /* Display Exit dialog */
1219*4882a593Smuzhiyun winDisplayExitDialog(s_pScreenPriv);
1220*4882a593Smuzhiyun return 0;
1221*4882a593Smuzhiyun
1222*4882a593Smuzhiyun case WM_SETCURSOR:
1223*4882a593Smuzhiyun if (LOWORD(lParam) == HTCLIENT) {
1224*4882a593Smuzhiyun if (!g_fSoftwareCursor)
1225*4882a593Smuzhiyun SetCursor(s_pScreenPriv->cursor.handle);
1226*4882a593Smuzhiyun return TRUE;
1227*4882a593Smuzhiyun }
1228*4882a593Smuzhiyun break;
1229*4882a593Smuzhiyun
1230*4882a593Smuzhiyun default:
1231*4882a593Smuzhiyun if (message == s_uTaskbarRestart) {
1232*4882a593Smuzhiyun winInitNotifyIcon(s_pScreenPriv);
1233*4882a593Smuzhiyun }
1234*4882a593Smuzhiyun break;
1235*4882a593Smuzhiyun }
1236*4882a593Smuzhiyun
1237*4882a593Smuzhiyun return DefWindowProc(hwnd, message, wParam, lParam);
1238*4882a593Smuzhiyun }
1239