[win] Clean up event handling and a pile of dead code

The event handling changes take care of VagueLobster's segfaults on
startup for all renderers (vulkan will still be iffy depending on his
hardware: it dies on my GTX 965 M, probably due to memory and QF's
shadows). One nice side effect is it takes care of the broken CD audio
event handling (does anyone even care, though?).
This commit is contained in:
Bill Currie 2023-11-24 12:28:06 +09:00
parent 0a89c513b4
commit f721021fec
7 changed files with 231 additions and 229 deletions

View file

@ -44,16 +44,17 @@ extern int vid_ddraw;
extern int win_center_x, win_center_y;
extern RECT win_rect;
LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void Win_Activate (BOOL fActive, BOOL minimize);
bool Win_AddEvent (UINT event, LONG (*event_handler)(HWND, UINT, WPARAM, LPARAM));
bool Win_RemoveEvent (UINT event);
void Win_UnloadAllDrivers (void);
void Win_OpenDisplay (void);
void Win_CloseDisplay (void);
void Win_SetVidMode (int width, int height);
void Win_CreateWindow (int width, int height);
void Win_Init_Cvars (void);
void Win_UpdateWindowStatus (int x, int y);
void Win_SetCaption (const char *text);
bool Win_SetGamma (double gamma);

View file

@ -32,7 +32,9 @@
extern bool mouseactive;
extern float mouse_x, mouse_y;
extern unsigned uiWheelMessage;
void IN_Win_Preinit (void);
void IN_UpdateClipCursor (void);
void IN_ShowMouse (void);
void IN_HideMouse (void);

View file

@ -80,10 +80,6 @@ extern bool WinNT;
extern bool winsock_lib_initialized;
#ifdef SPLASH_SCREEN
extern HWND hwnd_dialog;
#endif
#undef E_POINTER
#endif /* _WIN32 */

View file

@ -141,9 +141,8 @@ I_CDAudio_GetAudioDiskInfo (void)
return 0;
}
#if 0
LONG
static I_CDAudio_MessageHandler (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static CDAudio_MessageHandler (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (lParam != wDeviceID)
return 1;
@ -169,13 +168,12 @@ static I_CDAudio_MessageHandler (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa
default:
Sys_MaskPrintf (SYS_snd, "Unexpected MM_MCINOTIFY type (%i)\n",
wParam);
(int) wParam);
return 1;
}
return 0;
}
#endif
static void
I_CDAudio_Pause (void)
@ -310,6 +308,7 @@ I_CDAudio_Shutdown (void)
if (!initialized)
return;
I_CDAudio_Stop ();
Win_RemoveEvent (MM_MCINOTIFY);
if (mciSendCommand (wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD_PTR) NULL))
Sys_MaskPrintf (SYS_snd, "CDAudio_Shutdown: MCI_CLOSE failed\n");
}
@ -465,6 +464,8 @@ I_CDAudio_Init (void)
MCI_SET_PARMS mciSetParms;
int n;
Win_AddEvent (MM_MCINOTIFY, CDAudio_MessageHandler);
mciOpenParms.lpstrDeviceType = "cdaudio";
dwReturn =
mciSendCommand (0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE,

View file

@ -41,6 +41,7 @@
#include "context_win.h"
#include "r_shared.h"
#include "in_win.h"
#include "vid_internal.h"
#include "vid_sw.h"
@ -56,6 +57,8 @@ sw_ctx_t *win_sw_context;
#define NO_MODE (MODE_WINDOWED - 1)
#define MODE_FULLSCREEN_DEFAULT (MODE_WINDOWED + 3)
#define WINDOW_CLASS PACKAGE_NAME "WindowClass"
int vid_ddraw;
static cvar_t vid_ddraw_cvar = {
.name = "vid_ddraw",
@ -284,6 +287,47 @@ static vmode_t badmode = {
.modedesc = "Bad mode",
};
static LONG (*event_handlers[WM_USER])(HWND, UINT, WPARAM, LPARAM);
bool
Win_AddEvent (UINT event, LONG (*event_handler)(HWND, UINT, WPARAM, LPARAM))
{
if (event >= WM_USER) {
Sys_MaskPrintf (SYS_vid, "event: %d, WM_USER: %d\n", event, WM_USER);
return false;
}
if (event_handlers[event]) {
return false;
}
event_handlers[event] = event_handler;
return true;
}
bool
Win_RemoveEvent (UINT event)
{
if (event >= WM_USER) {
Sys_MaskPrintf (SYS_vid, "event: %d, WM_USER: %d\n", event, WM_USER);
return false;
}
event_handlers[event] = 0;
return true;
}
static LONG WINAPI
Win_EventHandler (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == uiWheelMessage) {
uMsg = WM_MOUSEWHEEL;
}
if (uMsg < WM_USER && event_handlers[uMsg]) {
return event_handlers[uMsg] (hWnd, uMsg, wParam, lParam);
}
return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
static int VID_SetMode (int modenum, const byte *palette);
static void __attribute__ ((used))
@ -314,7 +358,7 @@ VID_CheckWindowXY (void)
}
#endif
void
static void
Win_UpdateWindowStatus (int window_x, int window_y)
{
win_rect.left = window_x;
@ -345,7 +389,7 @@ VID_InitModes (HINSTANCE hInstance)
/* Register the frame class */
wc.style = CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) MainWndProc;
wc.lpfnWndProc = (WNDPROC) Win_EventHandler;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
@ -353,7 +397,7 @@ VID_InitModes (HINSTANCE hInstance)
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = 0;
wc.lpszClassName = "WinQuake";
wc.lpszClassName = WINDOW_CLASS;
if (!RegisterClass (&wc))
Sys_Error ("Couldn't register window class");
@ -448,6 +492,8 @@ VID_GetDisplayModes (void)
void
Win_OpenDisplay (void)
{
global_hInstance = GetModuleHandle (0);
VID_InitModes (global_hInstance);
VID_GetDisplayModes ();
@ -458,11 +504,6 @@ Win_OpenDisplay (void)
startwindowed = 1;
vid_default = windowed_default;
}
#ifdef SPLASH_SCREEN
if (hwnd_dialog)
DestroyWindow (hwnd_dialog);
#endif
}
void
@ -816,10 +857,48 @@ VID_SetMode (int modenum, const byte *palette)
return true;
}
static long
notify_create (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return 1;
}
static long
notify_destroy (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (win_mainwindow) {
DestroyWindow (win_mainwindow);
}
PostQuitMessage (0);
return 1;
}
static long
notify_move (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
Win_UpdateWindowStatus ((int) LOWORD (lParam), (int) HIWORD (lParam));
return 1;
}
static long
notify_size (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
Sys_Printf ("notify_size: %p %d %016llx %016llx\n",
hWnd, uMsg, wParam, lParam);
return 1;
}
void
Win_CreateWindow (int width, int height)
{
IN_Win_Preinit ();
Win_AddEvent (WM_CREATE, notify_create);
Win_AddEvent (WM_DESTROY, notify_destroy);
Win_AddEvent (WM_MOVE, notify_move);
Win_AddEvent (WM_SIZE, notify_size);
RECT rect = {
.top = 0,
.left = 0,
@ -832,10 +911,10 @@ Win_CreateWindow (int width, int height)
// fullscreen so the "hardware already in use" dialog is visible if it
// gets displayed
// keep the window minimized until we're ready for the first real mode set
win_mainwindow = CreateWindowEx (ExWindowStyle,
"WinQuake",
"WinQuake",
WindowStyle,
win_mainwindow = CreateWindowExA (ExWindowStyle,
WINDOW_CLASS,
PACKAGE_STRING,
WS_OVERLAPPEDWINDOW,
0, 0,
rect.right - rect.left,
rect.bottom - rect.top,
@ -1111,7 +1190,7 @@ void
Win_SetCaption (const char *text)
{
if (win_mainwindow) {
SetWindowText (win_mainwindow, text);
SetWindowTextA (win_mainwindow, text);
}
}

View file

@ -60,7 +60,7 @@ HRESULT (WINAPI * pDirectInputCreate) (HINSTANCE hinst, DWORD dwVersion,
LPUNKNOWN punkOuter);
// mouse local variables
static unsigned uiWheelMessage;
unsigned uiWheelMessage = ~0u;
static unsigned mouse_buttons;
static POINT current_pos;
static bool mouseinitialized;
@ -69,6 +69,7 @@ static int originalmouseparms[3], newmouseparms[3] = { 0, 0, 1 };
static bool mouseparmsvalid, mouseactivatetoggle;
static bool mouseshowtoggle = 1;
static bool dinput_acquired;
static bool in_win_initialized;
static unsigned int mstate_di;
// misc locals
@ -696,6 +697,7 @@ in_win_init (void *data)
//Key_KeydestCallback (win_keydest_callback, 0);
Cmd_AddCommand ("in_paste_buffer", in_paste_buffer_f,
"Paste the contents of the C&P buffer to the console");
in_win_initialized = true;
}
static const char *
@ -1057,121 +1059,137 @@ Win_Activate (BOOL active, BOOL minimize)
}
}
/* main window procedure */
LONG WINAPI
MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static void
in_win_send_focus_event (int gain)
{
LONG lRet = 1;
int fActive, fMinimized, temp;
IE_event_t event = {
.type = gain ? ie_app_gain_focus : ie_app_lose_focus,
.when = Sys_LongTime (),
};
IE_Send_Event (&event);
}
if (uMsg == uiWheelMessage)
uMsg = WM_MOUSEWHEEL;
static LONG
event_focusin (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
in_win_send_focus_event (1);
return 1;
}
switch (uMsg) {
case WM_SETFOCUS:
//Key_FocusEvent (1);
break;
case WM_KILLFOCUS:
if (modestate == MS_FULLDIB)
ShowWindow (win_mainwindow, SW_SHOWMINNOACTIVE);
//Key_FocusEvent (0);
break;
case WM_CREATE:
break;
case WM_MOVE:
Win_UpdateWindowStatus ((int) LOWORD (lParam),
(int) HIWORD (lParam));
break;
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
event_key (lParam, 1);
break;
case WM_KEYUP:
case WM_SYSKEYUP:
event_key (lParam, 0);
break;
case WM_SYSCHAR:
// keep Alt-Space from happening
break;
// 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
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MOUSEMOVE:
temp = 0;
if (wParam & MK_LBUTTON)
temp |= 1;
if (wParam & MK_RBUTTON)
temp |= 2;
if (wParam & MK_MBUTTON)
temp |= 4;
event_button (temp);
break;
// JACK: This is the mouse wheel with the Intellimouse
// It's delta is either positive or neg, and we generate the proper
// Event.
case WM_MOUSEWHEEL:
temp = win_mouse.buttons & ~((1 << 3) | (1 << 4));;
if ((short) HIWORD (wParam) > 0) {
event_button (temp | (1 << 3));
} else {
event_button (temp | (1 << 4));
}
event_button (temp);
break;
case WM_SIZE:
break;
case WM_CLOSE:
if (MessageBox
(win_mainwindow,
"Are you sure you want to quit?", "Confirm Exit",
MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES) {
Sys_Quit ();
}
break;
case WM_ACTIVATE:
fActive = LOWORD (wParam);
fMinimized = (BOOL) HIWORD (wParam);
Win_Activate (!(fActive == WA_INACTIVE), fMinimized);
// fix leftover Alt from any Alt-Tab or the like that switched us
// away
IN_ClearStates ();
break;
case WM_DESTROY:
if (win_mainwindow)
DestroyWindow (win_mainwindow);
PostQuitMessage (0);
break;
case MM_MCINOTIFY:
//FIXME lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam);
break;
default:
/* pass all unhandled messages to DefWindowProc */
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
break;
static LONG
event_focusout (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (modestate == MS_FULLDIB) {
ShowWindow (win_mainwindow, SW_SHOWMINNOACTIVE);
}
in_win_send_focus_event (0);
return 1;
}
/* return 1 if handled message, 0 if not */
return lRet;
static LONG
event_keyup (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
event_key (lParam, 0);
return 1;
}
static LONG
event_keydown (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
event_key (lParam, 1);
return 1;
}
static LONG
event_syschar (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// absorb Alt-Space
return 1;
}
static LONG
event_mouse (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// 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
unsigned temp = 0;
if (wParam & MK_LBUTTON)
temp |= 1;
if (wParam & MK_RBUTTON)
temp |= 2;
if (wParam & MK_MBUTTON)
temp |= 4;
event_button (temp);
return 1;
}
static LONG
event_mousewheel (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// JACK: This is the mouse wheel with the Intellimouse
// It's delta is either positive or neg, and we generate the proper
// Event.
unsigned temp = win_mouse.buttons & ~((1 << 3) | (1 << 4));;
if ((short) HIWORD (wParam) > 0) {
event_button (temp | (1 << 3));
} else {
event_button (temp | (1 << 4));
}
event_button (temp);
return 1;
}
static LONG
event_close (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (MessageBox (win_mainwindow,
"Are you sure you want to quit?", "Confirm Exit",
MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES) {
Sys_Quit ();
}
return 1;
}
static long
event_activate (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int fActive = LOWORD (wParam);
int fMinimized = (BOOL) HIWORD (wParam);
Win_Activate (!(fActive == WA_INACTIVE), fMinimized);
// fix leftover Alt from any Alt-Tab or the like that switched us away
if (in_win_initialized) {
IN_ClearStates ();
}
return 1;
}
void
IN_Win_Preinit (void)
{
Win_AddEvent (WM_SETFOCUS, event_focusin);
Win_AddEvent (WM_SETFOCUS, event_focusout);
Win_AddEvent (WM_KEYDOWN, event_keydown);
Win_AddEvent (WM_SYSKEYDOWN, event_keydown);
Win_AddEvent (WM_KEYUP, event_keyup);
Win_AddEvent (WM_SYSKEYUP, event_keyup);
Win_AddEvent (WM_SYSCHAR, event_syschar);
Win_AddEvent (WM_LBUTTONDOWN, event_mouse);
Win_AddEvent (WM_LBUTTONUP, event_mouse);
Win_AddEvent (WM_RBUTTONDOWN, event_mouse);
Win_AddEvent (WM_RBUTTONUP, event_mouse);
Win_AddEvent (WM_MBUTTONDOWN, event_mouse);
Win_AddEvent (WM_MBUTTONUP, event_mouse);
Win_AddEvent (WM_MOUSEMOVE, event_mouse);
Win_AddEvent (WM_MOUSEWHEEL, event_mousewheel);
Win_AddEvent (WM_CLOSE, event_close);
Win_AddEvent (WM_ACTIVATE, event_activate);
}
static in_driver_t in_win_driver = {

View file

@ -195,98 +195,3 @@ VID_SetGamma (double gamma)
{
return Win_SetGamma (gamma);
}
#if 0
void
VID_Update (vrect_t *rects)
{
vrect_t rect;
RECT trect;
if (firstupdate) {
if (modestate == MS_WINDOWED) {
GetWindowRect (win_mainwindow, &trect);
if ((trect.left != vid_window_x) ||
(trect.top != vid_window_y)) {
if (COM_CheckParm ("-resetwinpos")) {
vid_window_x = 0.0;
vid_window_y = 0.0;
}
VID_CheckWindowXY ();
SetWindowPos (win_mainwindow, NULL, vid_window_x,
vid_window_y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW |
SWP_DRAWFRAME);
}
}
if ((_vid_default_mode_win != vid_default) &&
(!startwindowed
|| (_vid_default_mode_win < MODE_FULLSCREEN_DEFAULT))) {
firstupdate = 0;
if (COM_CheckParm ("-resetwinpos")) {
vid_window_x = 0.0;
vid_window_y = 0.0;
}
if ((_vid_default_mode_win < 0) ||
(_vid_default_mode_win >= nummodes)) {
_vid_default_mode_win = windowed_default;
}
vid_mode = _vid_default_mode_win;
}
}
// We've drawn the frame; copy it to the screen
FlipScreen (rects);
// check for a driver change
if ((vid_ddraw && !vid_usingddraw)
|| (!vid_ddraw && vid_usingddraw)) {
// reset the mode
force_mode_set = true;
VID_SetMode (vid_mode, vid_curpal);
force_mode_set = false;
// store back
if (vid_usingddraw)
Sys_Printf ("loaded DirectDraw driver\n");
else
Sys_Printf ("loaded GDI driver\n");
}
if (vid_testingmode) {
if (Sys_DoubleTime () >= vid_testendtime) {
VID_SetMode (vid_realmode, vid_curpal);
vid_testingmode = 0;
}
} else {
if (vid_mode != vid_realmode) {
VID_SetMode (vid_mode, vid_curpal);
vid_mode = vid_modenum;
// so if mode set fails, we don't keep on
// trying to set that mode
vid_realmode = vid_modenum;
}
}
// handle the mouse state when windowed if that's changed
if (modestate == MS_WINDOWED) {
if (_windowed_mouse != windowed_mouse) {
if (_windowed_mouse) {
IN_ActivateMouse ();
IN_HideMouse ();
} else {
IN_DeactivateMouse ();
IN_ShowMouse ();
}
windowed_mouse = _windowed_mouse;
}
}
}
#endif