LRESULT CALLBACK WndProc()

in doom_py/src/vizdoom/src/win32/i_input.cpp [385:662]


LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	LRESULT result;

	if (message == WM_INPUT)
	{
		if (MyGetRawInputData != NULL)
		{
			UINT size;

			if (!MyGetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)) &&
				size != 0)
			{
				BYTE *buffer = (BYTE *)alloca(size);
				if (MyGetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &size, sizeof(RAWINPUTHEADER)) == size)
				{
					int code = GET_RAWINPUT_CODE_WPARAM(wParam);
					if (Keyboard == NULL || !Keyboard->ProcessRawInput((RAWINPUT *)buffer, code))
					{
						if (Mouse == NULL || !Mouse->ProcessRawInput((RAWINPUT *)buffer, code))
						{
							if (JoyDevices[INPUT_RawPS2] != NULL)
							{
								JoyDevices[INPUT_RawPS2]->ProcessRawInput((RAWINPUT *)buffer, code);
							}
						}
					}
				}
			}
		}
		return DefWindowProc(hWnd, message, wParam, lParam);
	}

	if (CallHook(Keyboard, hWnd, message, wParam, lParam, &result))
	{
		return result;
	}
	if (CallHook(Mouse, hWnd, message, wParam, lParam, &result))
	{
		return result;
	}
	for (int i = 0; i < NUM_JOYDEVICES; ++i)
	{
		if (CallHook(JoyDevices[i], hWnd, message, wParam, lParam, &result))
		{
			return result;
		}
	}
	if (GUICapture && GUIWndProcHook(hWnd, message, wParam, lParam, &result))
	{
		return result;
	}

	if ((gamestate == GS_DEMOSCREEN || gamestate == GS_TITLELEVEL) && message == WM_LBUTTONDOWN)
	{
		if (GUIWndProcHook(hWnd, message, wParam, lParam, &result))
		{
			return result;
		}
	}


	switch (message)
	{
	case WM_DESTROY:
		SetPriorityClass (GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
		//PostQuitMessage (0);
		exit (0);
		break;

	case WM_HOTKEY:
		break;

	case WM_PAINT:
		if (screen != NULL && 0)
		{
			static_cast<BaseWinFB *> (screen)->PaintToWindow ();
		}
		return DefWindowProc (hWnd, message, wParam, lParam);

	case WM_SETTINGCHANGE:
		// If regional settings were changed, reget preferred languages
		if (wParam == 0 && lParam != 0 && strcmp ((const char *)lParam, "intl") == 0)
		{
			language.Callback ();
		}
		return 0;

	case WM_KILLFOCUS:
		I_CheckNativeMouse (true);	// Make sure mouse gets released right away
		break;

	case WM_SETFOCUS:
		I_CheckNativeMouse (false);
		break;

	case WM_SETCURSOR:
		if (!CursorState)
		{
			SetCursor(NULL); // turn off window cursor
			return TRUE;	// Prevent Windows from setting cursor to window class cursor
		}
		else
		{
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;

	case WM_SIZE:
		InvalidateRect (Window, NULL, FALSE);
		break;

	case WM_KEYDOWN:
		// When the EAX editor is open, pressing Ctrl+Tab will switch to it
		if (EAXEditWindow != 0 && wParam == VK_TAB && !(lParam & 0x40000000) &&
			(GetKeyState (VK_CONTROL) & 0x8000))
		{
			SetForegroundWindow (EAXEditWindow);
		}
		break;

	case WM_SYSKEYDOWN:
		// Pressing Alt+Enter can toggle between fullscreen and windowed.
		if (wParam == VK_RETURN && k_allowfullscreentoggle && !(lParam & 0x40000000))
		{
			ToggleFullscreen = !ToggleFullscreen;
		}
		// Pressing Alt+F4 quits the program.
		if (wParam == VK_F4 && !(lParam & 0x40000000))
		{
			PostQuitMessage(0);
		}
		break;

	case WM_SYSCOMMAND:
		// Prevent activation of the window menu with Alt+Space
		if ((wParam & 0xFFF0) != SC_KEYMENU)
		{
			return DefWindowProc (hWnd, message, wParam, lParam);
		}
		break;

	case WM_DISPLAYCHANGE:
	case WM_STYLECHANGED:
		if (SpawnEAXWindow)
		{
			SpawnEAXWindow = false;
			ShowEAXEditor ();
		}
		break;

	case WM_GETMINMAXINFO:
		if (screen && !VidResizing)
		{
			LPMINMAXINFO mmi = (LPMINMAXINFO)lParam;
			RECT rect = { 0, 0, screen->GetWidth(), screen->GetHeight() };
			AdjustWindowRectEx(&rect, WS_VISIBLE|WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW);
			mmi->ptMinTrackSize.x = rect.right - rect.left;
			mmi->ptMinTrackSize.y = rect.bottom - rect.top;
			return 0;
		}
		break;

	case WM_ACTIVATEAPP:
		AppActive = wParam;
		if (wParam)
		{
			SetPriorityClass (GetCurrentProcess (), INGAME_PRIORITY_CLASS);
		}
		else if (!noidle && !netgame)
		{
			SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS);
		}
		S_SetSoundPaused (wParam);
		break;

	case WM_WTSSESSION_CHANGE:
	case WM_POWERBROADCAST:
		{
			int oldstate = SessionState;

			if (message == WM_WTSSESSION_CHANGE && lParam == (LPARAM)SessionID)
			{
#ifdef _DEBUG
				OutputDebugString ("SessionID matched\n");
#endif
				// When using fast user switching, XP will lock a session before
				// disconnecting it, and the session will be unlocked before reconnecting it.
				// For our purposes, video output will only happen when the session is
				// both unlocked and connected (that is, SessionState is 0).
				switch (wParam)
				{
				case WTS_SESSION_LOCK:
					SessionState |= 1;
					break;
				case WTS_SESSION_UNLOCK:
					SessionState &= ~1;
					break;
				case WTS_CONSOLE_DISCONNECT:
					SessionState |= 2;
					//I_MovieDisableSound ();
					break;
				case WTS_CONSOLE_CONNECT:
					SessionState &= ~2;
					//I_MovieResumeSound ();
					break;
				}
			}
			else if (message == WM_POWERBROADCAST)
			{
				switch (wParam)
				{
				case PBT_APMSUSPEND:
					SessionState |= 4;
					break;
				case PBT_APMRESUMESUSPEND:
					SessionState &= ~4;
					break;
				}
			}

			if (GSnd != NULL)
			{
#if 0
				// Do we actually need this here?
				if (!oldstate && SessionState)
				{
					GSnd->SuspendSound ();
				}
				else if (oldstate && !SessionState)
				{
					GSnd->MovieResumeSound ();
				}
#endif
			}
#ifdef _DEBUG
			char foo[256];
			mysnprintf (foo, countof(foo), "Session Change: %ld %d\n", lParam, wParam);
			OutputDebugString (foo);
#endif
		}
		break;

	case WM_PALETTECHANGED:
		if ((HWND)wParam == Window)
			break;
		if (screen != NULL)
		{
			screen->PaletteChanged ();
		}
		return DefWindowProc (hWnd, message, wParam, lParam);

	case WM_QUERYNEWPALETTE:
		if (screen != NULL)
		{
			return screen->QueryNewPalette ();
		}
		return DefWindowProc (hWnd, message, wParam, lParam);

	case WM_ERASEBKGND:
		return true;

	case WM_DEVICECHANGE:
		if (wParam == DBT_DEVNODES_CHANGED ||
			wParam == DBT_DEVICEARRIVAL ||
			wParam == DBT_CONFIGCHANGED)
		{
			event_t ev = { EV_DeviceChange };
			D_PostEvent(&ev);
		}
		return DefWindowProc (hWnd, message, wParam, lParam);

	default:
		return DefWindowProc (hWnd, message, wParam, lParam);
	}

	return 0;
}