2
===========================================================================
3
Copyright (C) 1999-2005 Id Software, Inc.
5
This file is part of Quake III Arena source code.
7
Quake III Arena source code is free software; you can redistribute it
8
and/or modify it under the terms of the GNU General Public License as
9
published by the Free Software Foundation; either version 2 of the License,
10
or (at your option) any later version.
12
Quake III Arena source code is distributed in the hope that it will be
13
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with Quake III Arena source code; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
===========================================================================
23
#include "../client/client.h"
24
#include "win_local.h"
29
#define WM_MOUSEWHEEL (WM_MOUSELAST+1) // message that will be supported by the OS
32
static UINT MSH_MOUSEWHEEL;
34
// Console variables that we need to access from this module
35
cvar_t *vid_xpos; // X coordinate of window position
36
cvar_t *vid_ypos; // Y coordinate of window position
39
#define VID_NUM_MODES ( sizeof( vid_modes ) / sizeof( vid_modes[0] ) )
41
LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
43
static qboolean s_alttab_disabled;
45
static void WIN_DisableAltTab( void )
47
if ( s_alttab_disabled )
50
if ( !Q_stricmp( Cvar_VariableString( "arch" ), "winnt" ) )
52
RegisterHotKey( 0, 0, MOD_ALT, VK_TAB );
58
SystemParametersInfo( SPI_SCREENSAVERRUNNING, 1, &old, 0 );
60
s_alttab_disabled = qtrue;
63
static void WIN_EnableAltTab( void )
65
if ( s_alttab_disabled )
67
if ( !Q_stricmp( Cvar_VariableString( "arch" ), "winnt" ) )
69
UnregisterHotKey( 0, 0 );
75
SystemParametersInfo( SPI_SCREENSAVERRUNNING, 0, &old, 0 );
78
s_alttab_disabled = qfalse;
87
static void VID_AppActivate(BOOL fActive, BOOL minimize)
89
g_wv.isMinimized = minimize;
91
Com_DPrintf("VID_AppActivate: %i\n", fActive );
93
Key_ClearStates(); // FIXME!!!
95
// we don't want to act like we're active if we're minimized
96
if (fActive && !g_wv.isMinimized )
98
g_wv.activeApp = qtrue;
102
g_wv.activeApp = qfalse;
105
// minimize/restore mouse-capture on demand
106
if (!g_wv.activeApp )
108
IN_Activate (qfalse);
116
//==========================================================================
118
static byte s_scantokey[128] =
122
0 , 27, '1', '2', '3', '4', '5', '6',
123
'7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0
124
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
125
'o', 'p', '[', ']', 13 , K_CTRL,'a', 's', // 1
126
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
127
'\'' , '`', K_SHIFT,'\\', 'z', 'x', 'c', 'v', // 2
128
'b', 'n', 'm', ',', '.', '/', K_SHIFT,'*',
129
K_ALT,' ', K_CAPSLOCK , K_F1, K_F2, K_F3, K_F4, K_F5, // 3
130
K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, 0 , K_HOME,
131
K_UPARROW,K_PGUP,K_KP_MINUS,K_LEFTARROW,K_KP_5,K_RIGHTARROW, K_KP_PLUS,K_END, //4
132
K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11,
133
K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5
134
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
135
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6
136
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
137
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7
144
Map from windows to quake keynums
147
static int MapKey (int key)
151
qboolean is_extended;
153
// Com_Printf( "0x%x\n", key);
155
modified = ( key >> 16 ) & 255;
157
if ( modified > 127 )
160
if ( key & ( 1 << 24 ) )
166
is_extended = qfalse;
169
result = s_scantokey[modified];
182
return K_KP_LEFTARROW;
184
return K_KP_RIGHTARROW;
188
return K_KP_DOWNARROW;
221
main window procedure
224
extern cvar_t *in_mouse;
225
extern cvar_t *in_logitechbug;
226
LONG WINAPI MainWndProc (
232
static qboolean flip = qtrue;
235
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/mouseinput/aboutmouseinput.asp
236
// Windows 95, Windows NT 3.51 - uses MSH_MOUSEWHEEL
237
// only relevant for non-DI input
239
// NOTE: not sure how reliable this is anymore, might trigger double wheel events
240
if (in_mouse->integer != 1)
242
if ( uMsg == MSH_MOUSEWHEEL )
244
if ( ( ( int ) wParam ) > 0 )
246
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, qtrue, 0, NULL );
247
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, qfalse, 0, NULL );
251
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL );
252
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL );
254
return DefWindowProc (hWnd, uMsg, wParam, lParam);
261
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/mouseinput/aboutmouseinput.asp
262
// Windows 98/Me, Windows NT 4.0 and later - uses WM_MOUSEWHEEL
263
// only relevant for non-DI input and when console is toggled in window mode
264
// if console is toggled in window mode (KEYCATCH_CONSOLE) then mouse is released and DI doesn't see any mouse wheel
265
if (in_mouse->integer != 1 || (!r_fullscreen->integer && (cls.keyCatchers & KEYCATCH_CONSOLE)))
267
// 120 increments, might be 240 and multiples if wheel goes too fast
268
// NOTE Logitech: logitech drivers are screwed and send the message twice?
269
// could add a cvar to interpret the message as successive press/release events
270
zDelta = ( short ) HIWORD( wParam ) / 120;
273
for(i=0; i<zDelta; i++)
275
if (!in_logitechbug->integer)
277
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, qtrue, 0, NULL );
278
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, qfalse, 0, NULL );
282
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, flip, 0, NULL );
289
for(i=0; i<-zDelta; i++)
291
if (!in_logitechbug->integer)
293
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL );
294
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL );
298
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, flip, 0, NULL );
303
// when an application processes the WM_MOUSEWHEEL message, it must return zero
312
vid_xpos = Cvar_Get ("vid_xpos", "3", CVAR_ARCHIVE);
313
vid_ypos = Cvar_Get ("vid_ypos", "22", CVAR_ARCHIVE);
314
r_fullscreen = Cvar_Get ("r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
316
MSH_MOUSEWHEEL = RegisterWindowMessage("MSWHEEL_ROLLMSG");
317
if ( r_fullscreen->integer )
328
case WM_DISPLAYCHANGE:
329
Com_DPrintf( "WM_DISPLAYCHANGE\n" );
330
// we need to force a vid_restart if the user has changed
331
// their desktop resolution while the game is running,
332
// but don't do anything if the message is a result of
333
// our own calling of ChangeDisplaySettings
334
if ( com_insideVidInit ) {
335
break; // we did this on purpose
337
// something else forced a mode change, so restart all our gl stuff
338
Cbuf_AddText( "vid_restart\n" );
342
// let sound and input know about this?
344
if ( r_fullscreen->integer )
351
Cbuf_ExecuteText( EXEC_APPEND, "quit" );
356
int fActive, fMinimized;
358
fActive = LOWORD(wParam);
359
fMinimized = (BOOL) HIWORD(wParam);
361
VID_AppActivate( fActive != WA_INACTIVE, fMinimized);
372
if (!r_fullscreen->integer )
374
xPos = (short) LOWORD(lParam); // horizontal position
375
yPos = (short) HIWORD(lParam); // vertical position
382
style = GetWindowLong( hWnd, GWL_STYLE );
383
AdjustWindowRect( &r, style, FALSE );
385
Cvar_SetValue( "vid_xpos", xPos + r.left);
386
Cvar_SetValue( "vid_ypos", yPos + r.top);
387
vid_xpos->modified = qfalse;
388
vid_ypos->modified = qfalse;
389
if ( g_wv.activeApp )
397
// this is complicated because Win32 seems to pack multiple mouse events into
398
// one update sometimes, so we always check all states and look for events
411
if (wParam & MK_LBUTTON)
414
if (wParam & MK_RBUTTON)
417
if (wParam & MK_MBUTTON)
420
IN_MouseEvent (temp);
425
if ( wParam == SC_SCREENSAVE )
434
Cvar_SetValue( "r_fullscreen", !r_fullscreen->integer );
435
Cbuf_AddText( "vid_restart\n" );
441
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, MapKey( lParam ), qtrue, 0, NULL );
446
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, MapKey( lParam ), qfalse, 0, NULL );
450
Sys_QueEvent( g_wv.sysMsgTime, SE_CHAR, wParam, 0, 0, NULL );
454
return DefWindowProc( hWnd, uMsg, wParam, lParam );