diff --git a/include/context_win.h b/include/context_win.h index 513b0478a..421adf954 100644 --- a/include/context_win.h +++ b/include/context_win.h @@ -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); diff --git a/include/in_win.h b/include/in_win.h index 650b0ab2f..347d3ab8f 100644 --- a/include/in_win.h +++ b/include/in_win.h @@ -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); diff --git a/include/winquake.h b/include/winquake.h index ccb3d2db9..5ac5a66ac 100644 --- a/include/winquake.h +++ b/include/winquake.h @@ -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 */ diff --git a/libs/audio/cd_win.c b/libs/audio/cd_win.c index 1be03d248..142a0df69 100644 --- a/libs/audio/cd_win.c +++ b/libs/audio/cd_win.c @@ -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, diff --git a/libs/video/targets/context_win.c b/libs/video/targets/context_win.c index 384822f70..3ebd3ac94 100644 --- a/libs/video/targets/context_win.c +++ b/libs/video/targets/context_win.c @@ -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); } } diff --git a/libs/video/targets/in_win.c b/libs/video/targets/in_win.c index 9de639f8a..d398a6fd5 100644 --- a/libs/video/targets/in_win.c +++ b/libs/video/targets/in_win.c @@ -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 = { diff --git a/libs/video/targets/vid_win.c b/libs/video/targets/vid_win.c index ba530fc75..359628515 100644 --- a/libs/video/targets/vid_win.c +++ b/libs/video/targets/vid_win.c @@ -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