mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2025-04-07 01:41:21 +00:00
627 lines
17 KiB
C++
627 lines
17 KiB
C++
/*
|
|
===========================================================================
|
|
Copyright (C) 1999-2005 Id Software, Inc.
|
|
|
|
This file is part of Quake III Arena source code.
|
|
|
|
Quake III Arena source code is free software; you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
or (at your option) any later version.
|
|
|
|
Quake III Arena source code is distributed in the hope that it will be
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Quake III Arena source code; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
===========================================================================
|
|
*/
|
|
|
|
#include "../client/client.h"
|
|
#include "win_local.h"
|
|
|
|
|
|
#define DEBUG_KEYPRESS 0
|
|
|
|
|
|
static cvar_t* vid_xpos; // X coordinate of window position
|
|
static cvar_t* vid_ypos; // Y coordinate of window position
|
|
static cvar_t* in_qwerty; // forces the QWERTY layout for key bindings
|
|
cvar_t* r_fullscreen;
|
|
|
|
|
|
static void WIN_AppActivate( BOOL fActive, BOOL fMinimized )
|
|
{
|
|
const qbool active = fActive && !fMinimized;
|
|
|
|
if ( r_fullscreen->integer )
|
|
SetWindowPos( g_wv.hWnd, active ? HWND_TOPMOST : HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
|
|
|
|
Key_ClearStates();
|
|
|
|
// we don't want to act like we're active if we're minimized
|
|
g_wv.activeApp = active;
|
|
}
|
|
|
|
|
|
#if DEBUG_KEYPRESS
|
|
static const char* GetKeyName( int q3key )
|
|
{
|
|
switch ( q3key )
|
|
{
|
|
case K_TAB: return "TAB";
|
|
case K_ENTER: return "ENTER";
|
|
case K_ESCAPE: return "ESCAPE";
|
|
case K_SPACE: return "SPACE";
|
|
case K_BACKSPACE: return "BACKSPACE";
|
|
case K_COMMAND: return "COMMAND";
|
|
case K_CAPSLOCK: return "CAPSLOCK";
|
|
case K_POWER: return "POWER";
|
|
case K_PAUSE: return "PAUSE";
|
|
case K_UPARROW: return "UPARROW";
|
|
case K_DOWNARROW: return "DOWNARROW";
|
|
case K_LEFTARROW: return "LEFTARROW";
|
|
case K_RIGHTARROW: return "RIGHTARROW";
|
|
case K_ALT: return "ALT";
|
|
case K_CTRL: return "CTRL";
|
|
case K_SHIFT: return "SHIFT";
|
|
case K_INS: return "INS";
|
|
case K_DEL: return "DEL";
|
|
case K_PGDN: return "PGDN";
|
|
case K_PGUP: return "PGUP";
|
|
case K_HOME: return "HOME";
|
|
case K_END: return "END";
|
|
case K_F1: return "F1";
|
|
case K_F2: return "F2";
|
|
case K_F3: return "F3";
|
|
case K_F4: return "F4";
|
|
case K_F5: return "F5";
|
|
case K_F6: return "F6";
|
|
case K_F7: return "F7";
|
|
case K_F8: return "F8";
|
|
case K_F9: return "F9";
|
|
case K_F10: return "F10";
|
|
case K_F11: return "F11";
|
|
case K_F12: return "F12";
|
|
case K_F13: return "F13";
|
|
case K_F14: return "F14";
|
|
case K_F15: return "F15";
|
|
case K_KP_HOME: return "KP_HOME";
|
|
case K_KP_UPARROW: return "KP_UPARROW";
|
|
case K_KP_PGUP: return "KP_PGUP";
|
|
case K_KP_LEFTARROW: return "KP_LEFTARROW";
|
|
case K_KP_5: return "KP_5";
|
|
case K_KP_RIGHTARROW: return "KP_RIGHTARROW";
|
|
case K_KP_END: return "KP_END";
|
|
case K_KP_DOWNARROW: return "KP_DOWNARROW";
|
|
case K_KP_PGDN: return "KP_PGDN";
|
|
case K_KP_ENTER: return "KP_ENTER";
|
|
case K_KP_INS: return "KP_INS";
|
|
case K_KP_DEL: return "KP_DEL";
|
|
case K_KP_SLASH: return "KP_SLASH";
|
|
case K_KP_MINUS: return "KP_MINUS";
|
|
case K_KP_PLUS: return "KP_PLUS";
|
|
case K_KP_NUMLOCK: return "KP_NUMLOCK";
|
|
case K_KP_STAR: return "KP_STAR";
|
|
case K_KP_EQUALS: return "KP_EQUALS";
|
|
case K_MOUSE1: return "MOUSE1";
|
|
case K_MOUSE2: return "MOUSE2";
|
|
case K_MOUSE3: return "MOUSE3";
|
|
case K_MOUSE4: return "MOUSE4";
|
|
case K_MOUSE5: return "MOUSE5";
|
|
case K_MWHEELDOWN: return "MWHEELDOWN";
|
|
case K_MWHEELUP: return "MWHEELUP";
|
|
case K_JOY1: return "JOY1";
|
|
case K_JOY2: return "JOY2";
|
|
case K_JOY3: return "JOY3";
|
|
case K_JOY4: return "JOY4";
|
|
case K_JOY5: return "JOY5";
|
|
case K_JOY6: return "JOY6";
|
|
case K_JOY7: return "JOY7";
|
|
case K_JOY8: return "JOY8";
|
|
case K_JOY9: return "JOY9";
|
|
case K_JOY10: return "JOY10";
|
|
case K_JOY11: return "JOY11";
|
|
case K_JOY12: return "JOY12";
|
|
case K_JOY13: return "JOY13";
|
|
case K_JOY14: return "JOY14";
|
|
case K_JOY15: return "JOY15";
|
|
case K_JOY16: return "JOY16";
|
|
case K_JOY17: return "JOY17";
|
|
case K_JOY18: return "JOY18";
|
|
case K_JOY19: return "JOY19";
|
|
case K_JOY20: return "JOY20";
|
|
case K_JOY21: return "JOY21";
|
|
case K_JOY22: return "JOY22";
|
|
case K_JOY23: return "JOY23";
|
|
case K_JOY24: return "JOY24";
|
|
case K_JOY25: return "JOY25";
|
|
case K_JOY26: return "JOY26";
|
|
case K_JOY27: return "JOY27";
|
|
case K_JOY28: return "JOY28";
|
|
case K_JOY29: return "JOY29";
|
|
case K_JOY30: return "JOY30";
|
|
case K_JOY31: return "JOY31";
|
|
case K_JOY32: return "JOY32";
|
|
case K_AUX1: return "AUX1";
|
|
case K_AUX2: return "AUX2";
|
|
case K_AUX3: return "AUX3";
|
|
case K_AUX4: return "AUX4";
|
|
case K_AUX5: return "AUX5";
|
|
case K_AUX6: return "AUX6";
|
|
case K_AUX7: return "AUX7";
|
|
case K_AUX8: return "AUX8";
|
|
case K_AUX9: return "AUX9";
|
|
case K_AUX10: return "AUX10";
|
|
case K_AUX11: return "AUX11";
|
|
case K_AUX12: return "AUX12";
|
|
case K_AUX13: return "AUX13";
|
|
case K_AUX14: return "AUX14";
|
|
case K_AUX15: return "AUX15";
|
|
case K_AUX16: return "AUX16";
|
|
case K_MOUSE6: return "MOUSE6";
|
|
case K_MOUSE7: return "MOUSE7";
|
|
case K_MOUSE8: return "MOUSE8";
|
|
case K_MOUSE9: return "MOUSE9";
|
|
case K_WIN: return "WIN";
|
|
case K_MENU: return "MENU";
|
|
case K_BACKSLASH: return "BACKSLASH";
|
|
case K_F16: return "F16";
|
|
case K_F17: return "F17";
|
|
case K_F18: return "F18";
|
|
case K_F19: return "F19";
|
|
case K_F20: return "F20";
|
|
case K_F21: return "F21";
|
|
case K_F22: return "F22";
|
|
case K_F23: return "F23";
|
|
case K_F24: return "F24";
|
|
default: return "???";
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
|
|
static const byte s_scantokey[128] =
|
|
{
|
|
// 0 1 2 3 4 5 6 7
|
|
// 8 9 A B C D E F
|
|
0 , 27, '1', '2', '3', '4', '5', '6',
|
|
'7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0
|
|
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
|
|
'o', 'p', '[', ']', 13 , K_CTRL,'a', 's', // 1
|
|
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
|
|
'\'' , '`', K_SHIFT,'\\', 'z', 'x', 'c', 'v', // 2
|
|
'b', 'n', 'm', ',', '.', '/', K_SHIFT,'*',
|
|
K_ALT,' ', K_CAPSLOCK , K_F1, K_F2, K_F3, K_F4, K_F5, // 3
|
|
K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, 0 , K_HOME,
|
|
K_UPARROW,K_PGUP,K_KP_MINUS,K_LEFTARROW,K_KP_5,K_RIGHTARROW, K_KP_PLUS,K_END, //4
|
|
K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11,
|
|
K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5
|
|
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
|
|
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6
|
|
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
|
|
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7
|
|
};
|
|
|
|
|
|
static byte s_winVKeyToQ3Key[256];
|
|
static qbool s_keyTableValid = qfalse;
|
|
|
|
static void InitKeyMap()
|
|
{
|
|
if ( s_keyTableValid )
|
|
{
|
|
return;
|
|
}
|
|
|
|
for ( int c = '0'; c <= '9'; c++ )
|
|
{
|
|
s_winVKeyToQ3Key[c] = c;
|
|
}
|
|
|
|
for ( int c = 'A'; c <= 'Z'; c++ )
|
|
{
|
|
s_winVKeyToQ3Key[c] = c + 32;
|
|
}
|
|
|
|
struct keyMap_t
|
|
{
|
|
byte winKey;
|
|
byte quakeKey;
|
|
};
|
|
|
|
#define KEY(WinKey, QuakeKey) { WinKey, QuakeKey }
|
|
static const keyMap_t keys[] =
|
|
{
|
|
KEY(VK_TAB, K_TAB),
|
|
KEY(VK_RETURN, K_ENTER),
|
|
KEY(VK_ESCAPE, K_ESCAPE),
|
|
KEY(VK_SPACE, K_SPACE),
|
|
KEY(VK_BACK, K_BACKSPACE),
|
|
KEY(VK_CAPITAL, K_CAPSLOCK),
|
|
KEY(VK_PAUSE, K_PAUSE),
|
|
KEY(VK_UP, K_UPARROW),
|
|
KEY(VK_DOWN, K_DOWNARROW),
|
|
KEY(VK_LEFT, K_LEFTARROW),
|
|
KEY(VK_RIGHT, K_RIGHTARROW),
|
|
KEY(VK_MENU, K_ALT),
|
|
KEY(VK_CONTROL, K_CTRL),
|
|
KEY(VK_SHIFT, K_SHIFT),
|
|
KEY(VK_INSERT, K_INS),
|
|
KEY(VK_DELETE, K_DEL),
|
|
KEY(VK_NEXT, K_PGDN),
|
|
KEY(VK_PRIOR, K_PGUP),
|
|
KEY(VK_HOME, K_HOME),
|
|
KEY(VK_END, K_END),
|
|
KEY(VK_F1, K_F1),
|
|
KEY(VK_F2, K_F2),
|
|
KEY(VK_F3, K_F3),
|
|
KEY(VK_F4, K_F4),
|
|
KEY(VK_F5, K_F5),
|
|
KEY(VK_F6, K_F6),
|
|
KEY(VK_F7, K_F7),
|
|
KEY(VK_F8, K_F8),
|
|
KEY(VK_F9, K_F9),
|
|
KEY(VK_F10, K_F10),
|
|
KEY(VK_F11, K_F11),
|
|
KEY(VK_F12, K_F12),
|
|
KEY(VK_F13, K_F13),
|
|
KEY(VK_F14, K_F14),
|
|
KEY(VK_F15, K_F15),
|
|
KEY(VK_NUMPAD7, K_KP_HOME),
|
|
KEY(VK_NUMPAD8, K_KP_UPARROW),
|
|
KEY(VK_NUMPAD9, K_KP_PGUP),
|
|
KEY(VK_NUMPAD4, K_KP_LEFTARROW),
|
|
KEY(VK_NUMPAD5, K_KP_5),
|
|
KEY(VK_NUMPAD6, K_KP_RIGHTARROW),
|
|
KEY(VK_NUMPAD1, K_KP_END),
|
|
KEY(VK_NUMPAD2, K_KP_DOWNARROW),
|
|
KEY(VK_NUMPAD3, K_KP_PGDN),
|
|
KEY(VK_NUMPAD0, K_KP_INS),
|
|
KEY(VK_NUMLOCK, K_KP_DEL),
|
|
KEY(VK_DIVIDE, K_KP_SLASH),
|
|
KEY(VK_SUBTRACT, K_KP_MINUS),
|
|
KEY(VK_ADD, K_KP_PLUS),
|
|
KEY(VK_DECIMAL, K_KP_NUMLOCK),
|
|
KEY(VK_MULTIPLY, K_KP_STAR),
|
|
KEY(VK_LBUTTON, K_MOUSE1),
|
|
KEY(VK_RBUTTON, K_MOUSE2),
|
|
KEY(VK_MBUTTON, K_MOUSE3),
|
|
KEY(VK_XBUTTON1, K_MOUSE4),
|
|
KEY(VK_XBUTTON2, K_MOUSE5),
|
|
KEY(VK_F16, K_F16),
|
|
KEY(VK_F17, K_F17),
|
|
KEY(VK_F18, K_F18),
|
|
KEY(VK_F19, K_F19),
|
|
KEY(VK_F20, K_F20),
|
|
KEY(VK_F21, K_F21),
|
|
KEY(VK_F22, K_F22),
|
|
KEY(VK_F23, K_F23),
|
|
KEY(VK_F24, K_F24)
|
|
#if 0 // not handled
|
|
K_COMMAND
|
|
K_POWER
|
|
K_BACKSLASH
|
|
K_MOUSE6
|
|
K_MOUSE7
|
|
K_MOUSE8
|
|
K_MOUSE9
|
|
K_KP_ENTER
|
|
K_KP_EQUALS
|
|
K_WIN
|
|
K_MENU
|
|
#endif
|
|
};
|
|
#undef KEY
|
|
|
|
for ( int i = 0; i < ARRAY_LEN(keys); i++ )
|
|
{
|
|
const byte winKey = keys[i].winKey;
|
|
const byte quakeKey = keys[i].quakeKey;
|
|
s_winVKeyToQ3Key[winKey] = quakeKey;
|
|
}
|
|
|
|
s_keyTableValid = qtrue;
|
|
}
|
|
|
|
|
|
/*
|
|
=======
|
|
MapKey
|
|
|
|
Map from windows to quake keynums
|
|
=======
|
|
*/
|
|
static int MapKey( int wParam, int lParam )
|
|
{
|
|
// this is needed for the in_qwerty 1 case
|
|
// the K_F13 to K_F24 values are *not* contiguous for mod compatibility reasons
|
|
switch ( wParam )
|
|
{
|
|
case VK_F13: return K_F13;
|
|
case VK_F14: return K_F14;
|
|
case VK_F15: return K_F15;
|
|
case VK_F16: return K_F16;
|
|
case VK_F17: return K_F17;
|
|
case VK_F18: return K_F18;
|
|
case VK_F19: return K_F19;
|
|
case VK_F20: return K_F20;
|
|
case VK_F21: return K_F21;
|
|
case VK_F22: return K_F22;
|
|
case VK_F23: return K_F23;
|
|
case VK_F24: return K_F24;
|
|
default: break;
|
|
}
|
|
|
|
#if DEBUG_KEYPRESS
|
|
char keyName[64];
|
|
if ( GetKeyNameTextA((LONG)lParam, keyName, (int)sizeof(keyName)) > 0 )
|
|
{
|
|
Sys_DebugPrintf( "Key: Win32 %d %s\n", wParam, keyName );
|
|
}
|
|
#endif
|
|
|
|
Q_assert( in_qwerty != NULL );
|
|
const qbool qwerty = in_qwerty != NULL && in_qwerty->integer != 0;
|
|
if ( !qwerty && wParam < ARRAY_LEN(s_winVKeyToQ3Key) )
|
|
{
|
|
const int q3key = s_winVKeyToQ3Key[wParam];
|
|
if ( q3key > 0 )
|
|
{
|
|
#if DEBUG_KEYPRESS
|
|
Sys_DebugPrintf( "Mapped key: Win32 %d -> Q3 %d (%c, %s)\n",
|
|
wParam, q3key, (char)q3key, GetKeyName(q3key) );
|
|
#endif
|
|
return q3key;
|
|
}
|
|
}
|
|
|
|
const int scanCode = ( lParam >> 16 ) & 255;
|
|
if ( scanCode > 127 )
|
|
return 0; // why?
|
|
|
|
const qbool isExtended = (lParam & ( 1 << 24 )) != 0;
|
|
const int result = s_scantokey[scanCode];
|
|
|
|
if ( !isExtended )
|
|
{
|
|
switch ( result )
|
|
{
|
|
case K_HOME:
|
|
return K_KP_HOME;
|
|
case K_UPARROW:
|
|
return K_KP_UPARROW;
|
|
case K_PGUP:
|
|
return K_KP_PGUP;
|
|
case K_LEFTARROW:
|
|
return K_KP_LEFTARROW;
|
|
case K_RIGHTARROW:
|
|
return K_KP_RIGHTARROW;
|
|
case K_END:
|
|
return K_KP_END;
|
|
case K_DOWNARROW:
|
|
return K_KP_DOWNARROW;
|
|
case K_PGDN:
|
|
return K_KP_PGDN;
|
|
case K_INS:
|
|
return K_KP_INS;
|
|
case K_DEL:
|
|
return K_KP_DEL;
|
|
case '*':
|
|
return K_KP_STAR;
|
|
case 0x00:
|
|
return K_BACKSLASH;
|
|
default:
|
|
return result;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch ( result )
|
|
{
|
|
case K_PAUSE:
|
|
return K_KP_NUMLOCK;
|
|
case 0x0D:
|
|
return K_KP_ENTER;
|
|
case 0x2F:
|
|
return K_KP_SLASH;
|
|
case 0xAF:
|
|
return K_KP_PLUS;
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
====================
|
|
MainWndProc
|
|
|
|
main window procedure
|
|
====================
|
|
*/
|
|
|
|
LRESULT CALLBACK MainWndProc (
|
|
HWND hWnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
static qbool draggingWindow = qfalse;
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_CREATE:
|
|
|
|
g_wv.hWnd = hWnd;
|
|
|
|
vid_xpos = Cvar_Get( "vid_xpos", "3", CVAR_ARCHIVE );
|
|
vid_ypos = Cvar_Get( "vid_ypos", "22", CVAR_ARCHIVE );
|
|
r_fullscreen = Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
|
Cvar_Get( "r_monitor", "0", CVAR_ARCHIVE | CVAR_LATCH ); // 1-based monitor index, 0 means primary
|
|
in_qwerty = Cvar_Get( "in_qwerty", "1", CVAR_ARCHIVE );
|
|
Cvar_SetRange( "in_qwerty", CVART_BOOL, NULL, NULL );
|
|
Cvar_SetHelp( "in_qwerty", "forces the QWERTY layout for key bindings" );
|
|
|
|
WIN_RegisterLastValidHotKey();
|
|
|
|
InitKeyMap();
|
|
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
WIN_UnregisterHotKey();
|
|
g_wv.hWnd = NULL;
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
Cbuf_AddText( "quit\n" );
|
|
break;
|
|
|
|
case WM_ACTIVATE:
|
|
WIN_AppActivate( (LOWORD(wParam) != WA_INACTIVE), !!(BOOL)HIWORD(wParam) );
|
|
WIN_S_Mute( !g_wv.activeApp );
|
|
break;
|
|
|
|
case WM_MOVING:
|
|
draggingWindow = qtrue;
|
|
break;
|
|
|
|
case WM_MOVE:
|
|
{
|
|
WIN_UpdateMonitorIndexFromMainWindow();
|
|
|
|
if ( !r_fullscreen->integer )
|
|
{
|
|
RECT r;
|
|
r.left = 0;
|
|
r.top = 0;
|
|
r.right = 1;
|
|
r.bottom = 1;
|
|
AdjustWindowRect( &r, GetWindowLong( hWnd, GWL_STYLE ), FALSE );
|
|
|
|
const RECT& monRect = g_wv.monitorRects[g_wv.monitor];
|
|
const int x = (int)(short)LOWORD( lParam );
|
|
const int y = (int)(short)HIWORD( lParam );
|
|
Cvar_SetValue( "vid_xpos", x + r.left - monRect.left );
|
|
Cvar_SetValue( "vid_ypos", y + r.top - monRect.top );
|
|
vid_xpos->modified = qfalse;
|
|
vid_ypos->modified = qfalse;
|
|
}
|
|
|
|
draggingWindow = qfalse;
|
|
}
|
|
break;
|
|
|
|
case WM_SIZE:
|
|
if ( wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED )
|
|
{
|
|
WIN_UpdateMonitorIndexFromMainWindow();
|
|
|
|
// note that WM_SIZE can be called with no actual size change
|
|
const int w = (int)LOWORD( lParam );
|
|
const int h = (int)HIWORD( lParam );
|
|
if ( g_wv.duringCreateWindow )
|
|
WIN_UpdateResolution( w, h );
|
|
}
|
|
break;
|
|
|
|
case WM_WINDOWPOSCHANGED:
|
|
{
|
|
const int prevMon = g_wv.monitor;
|
|
WIN_UpdateMonitorIndexFromMainWindow();
|
|
const int currMon = g_wv.monitor;
|
|
|
|
if ( !g_wv.duringCreateWindow && !draggingWindow && currMon != prevMon )
|
|
Cbuf_AddText( "vid_restart\n" );
|
|
}
|
|
break;
|
|
|
|
case WM_SYSCOMMAND:
|
|
if ( wParam == SC_SCREENSAVE )
|
|
return 0;
|
|
break;
|
|
|
|
case WM_SYSKEYDOWN:
|
|
if ( wParam == VK_RETURN )
|
|
{
|
|
if ( r_fullscreen )
|
|
{
|
|
Cvar_SetValue( "r_fullscreen", !r_fullscreen->integer );
|
|
Cbuf_AddText( "vid_restart\n" );
|
|
}
|
|
return 0;
|
|
}
|
|
// fall through
|
|
case WM_KEYDOWN:
|
|
WIN_QueEvent( g_wv.sysMsgTime, SE_KEY, MapKey( wParam, lParam ), qtrue, 0, NULL );
|
|
break;
|
|
|
|
case WM_SYSKEYUP:
|
|
case WM_KEYUP:
|
|
WIN_QueEvent( g_wv.sysMsgTime, SE_KEY, MapKey( wParam, lParam ), qfalse, 0, NULL );
|
|
break;
|
|
|
|
case WM_CHAR:
|
|
{
|
|
const char scanCode = (char)( ( lParam >> 16 ) & 0xFF );
|
|
if ( scanCode != 0x29 ) // never send an event for the console key ('~' or '`')
|
|
WIN_QueEvent( g_wv.sysMsgTime, SE_CHAR, wParam, 0, 0, NULL );
|
|
}
|
|
break;
|
|
|
|
case WM_HOTKEY:
|
|
if ( g_wv.minimizeHotKeyValid && (int)wParam == g_wv.minimizeHotKeyId )
|
|
{
|
|
if ( g_wv.activeApp && !CL_VideoRecording() )
|
|
{
|
|
ShowWindow( hWnd, SW_MINIMIZE );
|
|
}
|
|
else
|
|
{
|
|
ShowWindow( hWnd, SW_RESTORE );
|
|
SetForegroundWindow( hWnd );
|
|
SetFocus( hWnd );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_SETFOCUS:
|
|
if ( g_wv.cdsDevModeValid ) // is there a valid mode to restore?
|
|
{
|
|
WIN_SetGameDisplaySettings();
|
|
if ( g_wv.cdsDevModeValid ) // was the mode successfully restored?
|
|
{
|
|
const RECT& rect = g_wv.monitorRects[g_wv.monitor];
|
|
const DEVMODE& dm = g_wv.cdsDevMode;
|
|
SetWindowPos( hWnd, NULL, (int)rect.left, (int)rect.top, (int)dm.dmPelsWidth, (int)dm.dmPelsHeight, SWP_NOZORDER );
|
|
}
|
|
}
|
|
g_wv.activeApp = (qbool)!IsIconic( hWnd );
|
|
g_wv.forceUnmute = qfalse;
|
|
break;
|
|
|
|
case WM_KILLFOCUS:
|
|
g_wv.activeApp = qfalse;
|
|
if ( g_wv.cdsDevModeValid )
|
|
WIN_SetDesktopDisplaySettings();
|
|
break;
|
|
|
|
default:
|
|
// this is complicated because Win32 seems to pack multiple mouse events into
|
|
// one update sometimes, so we always check all states and look for events
|
|
if ( uMsg == WM_INPUT || (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST) || uMsg == WM_MOUSEWHEEL )
|
|
if ( IN_ProcessMessage(uMsg, wParam, lParam) )
|
|
return 0;
|
|
break;
|
|
}
|
|
|
|
return DefWindowProc( hWnd, uMsg, wParam, lParam );
|
|
}
|
|
|