From 12959a1bd1f2c6cfd2d2cf4d8f635d35a17442eb Mon Sep 17 00:00:00 2001
From: Randy Heit <rheit@zdoom.fake>
Date: Wed, 27 May 2009 22:17:11 +0000
Subject: [PATCH] - EV_GUI_Key(Down|Up|Repeat) events no longer provide shifted
 key codes   in data2. This was just unnecessary overhead that wasn't really
 needed   anywhere. - Moved GUI-mode input into a separate function to make
 the code easier to   read.

SVN r1617 (trunk)
---
 docs/rh-log.txt       |   5 +
 src/win32/i_input.cpp | 221 +++++++++++++++++++++---------------------
 2 files changed, 115 insertions(+), 111 deletions(-)

diff --git a/docs/rh-log.txt b/docs/rh-log.txt
index 5394ddcb68..d2b7da7359 100644
--- a/docs/rh-log.txt
+++ b/docs/rh-log.txt
@@ -1,4 +1,9 @@
 May 27, 2009
+- EV_GUI_Key(Down|Up|Repeat) events no longer provide shifted key codes
+  in data2. This was just unnecessary overhead that wasn't really needed
+  anywhere.
+- Moved GUI-mode input into a separate function to make the code easier to
+  read.
 - Removed HaveFocus variable in preference of using GetForegroundWindow().
 - Added Raw Input keyboard handling.
 
diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp
index e3273fd114..6290663e0e 100644
--- a/src/win32/i_input.cpp
+++ b/src/win32/i_input.cpp
@@ -295,8 +295,6 @@ static FBaseCVar * const JoyConfigVars[] =
 	&joy_upspeed
 };
 
-static BYTE KeyState[256];
-
 extern int chatmodeon;
 
 static void I_CheckGUICapture ()
@@ -322,6 +320,105 @@ static void I_CheckGUICapture ()
 	}
 }
 
+bool GUIWndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
+{
+	event_t ev = { EV_GUI_Event };
+
+	*result = 0;
+
+	switch (message)
+	{
+	case WM_KEYDOWN:
+	case WM_SYSKEYDOWN:
+	case WM_KEYUP:
+	case WM_SYSKEYUP:
+		if (message == WM_KEYUP || message == WM_SYSKEYUP)
+		{
+			ev.subtype = EV_GUI_KeyUp;
+		}
+		else
+		{
+			ev.subtype = (lParam & 0x40000000) ? EV_GUI_KeyRepeat : EV_GUI_KeyDown;
+		}
+		if (GetKeyState(VK_SHIFT) & 0x8000)		ev.data3 |= GKM_SHIFT;
+		if (GetKeyState(VK_CONTROL) & 0x8000)	ev.data3 |= GKM_CTRL;
+		if (GetKeyState(VK_MENU) & 0x8000)		ev.data3 |= GKM_ALT;
+		if ( (ev.data1 = MapVirtualKey(wParam, 2)) )
+		{
+			D_PostEvent(&ev);
+		}
+		else
+		{
+			switch (wParam)
+			{
+			case VK_PRIOR:	ev.data1 = GK_PGUP;		break;
+			case VK_NEXT:	ev.data1 = GK_PGDN;		break;
+			case VK_END:	ev.data1 = GK_END;		break;
+			case VK_HOME:	ev.data1 = GK_HOME;		break;
+			case VK_LEFT:	ev.data1 = GK_LEFT;		break;
+			case VK_RIGHT:	ev.data1 = GK_RIGHT;	break;
+			case VK_UP:		ev.data1 = GK_UP;		break;
+			case VK_DOWN:	ev.data1 = GK_DOWN;		break;
+			case VK_DELETE:	ev.data1 = GK_DEL;		break;
+			case VK_ESCAPE:	ev.data1 = GK_ESCAPE;	break;
+			case VK_F1:		ev.data1 = GK_F1;		break;
+			case VK_F2:		ev.data1 = GK_F2;		break;
+			case VK_F3:		ev.data1 = GK_F3;		break;
+			case VK_F4:		ev.data1 = GK_F4;		break;
+			case VK_F5:		ev.data1 = GK_F5;		break;
+			case VK_F6:		ev.data1 = GK_F6;		break;
+			case VK_F7:		ev.data1 = GK_F7;		break;
+			case VK_F8:		ev.data1 = GK_F8;		break;
+			case VK_F9:		ev.data1 = GK_F9;		break;
+			case VK_F10:	ev.data1 = GK_F10;		break;
+			case VK_F11:	ev.data1 = GK_F11;		break;
+			case VK_F12:	ev.data1 = GK_F12;		break;
+			}
+			if (ev.data1 != 0)
+			{
+				D_PostEvent(&ev);
+			}
+		}
+		// Return false for key downs so that we can handle special hotkeys
+		// in the main WndProc.
+		return ev.subtype == EV_GUI_KeyUp;
+
+	case WM_CHAR:
+	case WM_SYSCHAR:
+		if (wParam >= ' ')		// only send displayable characters
+		{
+			ev.subtype = EV_GUI_Char;
+			ev.data1 = wParam;
+			ev.data2 = (message == WM_SYSCHAR);
+			D_PostEvent(&ev);
+			return true;
+		}
+		break;
+
+	case WM_LBUTTONDOWN:
+	case WM_LBUTTONUP:
+	case WM_RBUTTONDOWN:
+	case WM_RBUTTONUP:
+	case WM_MBUTTONDOWN:
+	case WM_MBUTTONUP:
+		if (message >= WM_LBUTTONDOWN && message <= WM_LBUTTONDBLCLK)
+		{
+			ev.subtype = message - WM_LBUTTONDOWN + EV_GUI_LButtonDown;
+		}
+		else if (message >= WM_RBUTTONDOWN && message <= WM_RBUTTONDBLCLK)
+		{
+			ev.subtype = message - WM_RBUTTONDOWN + EV_GUI_RButtonDown;
+		}
+		else if (message >= WM_MBUTTONDOWN && message <= WM_MBUTTONDBLCLK)
+		{
+			ev.subtype = message - WM_MBUTTONDOWN + EV_GUI_MButtonDown;
+		}
+		D_PostEvent(&ev);
+		return true;
+	}
+	return false;
+}
+
 bool CallHook(FInputDevice *device, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
 {
 	if (device == NULL)
@@ -344,6 +441,11 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 	{
 		return result;
 	}
+	if (GUICapture && GUIWndProcHook(hWnd, message, wParam, lParam, &result))
+	{
+		return result;
+	}
+
 	event_t event;
 
 	memset (&event, 0, sizeof(event));
@@ -386,131 +488,28 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 		InvalidateRect (Window, NULL, FALSE);
 		break;
 
-	// Being forced to separate my keyboard input handler into
-	// two pieces like this really stinks. (IMHO)
 	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);
-			return 0;
-		}
-		// Intentional fall-through
-	case WM_KEYUP:
-		GetKeyboardState (KeyState);
-		if (GUICapture)
-		{
-			event.type = EV_GUI_Event;
-			if (message == WM_KEYUP)
-			{
-				event.subtype = EV_GUI_KeyUp;
-			}
-			else
-			{
-				event.subtype = (lParam & 0x40000000) ? EV_GUI_KeyRepeat : EV_GUI_KeyDown;
-			}
-			event.data3 = ((KeyState[VK_SHIFT]&128) ? GKM_SHIFT : 0) |
-						  ((KeyState[VK_CONTROL]&128) ? GKM_CTRL : 0) |
-						  ((KeyState[VK_MENU]&128) ? GKM_ALT : 0);
-			if ( (event.data1 = MapVirtualKey (wParam, 2)) )
-			{
-				ToAscii (wParam, (lParam >> 16) & 255, KeyState, (LPWORD)&event.data2, 0);
-				D_PostEvent (&event);
-			}
-			else
-			{
-				switch (wParam)
-				{
-				case VK_PRIOR:	event.data1 = GK_PGUP;		break;
-				case VK_NEXT:	event.data1 = GK_PGDN;		break;
-				case VK_END:	event.data1 = GK_END;		break;
-				case VK_HOME:	event.data1 = GK_HOME;		break;
-				case VK_LEFT:	event.data1 = GK_LEFT;		break;
-				case VK_RIGHT:	event.data1 = GK_RIGHT;		break;
-				case VK_UP:		event.data1 = GK_UP;		break;
-				case VK_DOWN:	event.data1 = GK_DOWN;		break;
-				case VK_DELETE:	event.data1 = GK_DEL;		break;
-				case VK_ESCAPE:	event.data1 = GK_ESCAPE;	break;
-				case VK_F1:		event.data1 = GK_F1;		break;
-				case VK_F2:		event.data1 = GK_F2;		break;
-				case VK_F3:		event.data1 = GK_F3;		break;
-				case VK_F4:		event.data1 = GK_F4;		break;
-				case VK_F5:		event.data1 = GK_F5;		break;
-				case VK_F6:		event.data1 = GK_F6;		break;
-				case VK_F7:		event.data1 = GK_F7;		break;
-				case VK_F8:		event.data1 = GK_F8;		break;
-				case VK_F9:		event.data1 = GK_F9;		break;
-				case VK_F10:	event.data1 = GK_F10;		break;
-				case VK_F11:	event.data1 = GK_F11;		break;
-				case VK_F12:	event.data1 = GK_F12;		break;
-				}
-				if (event.data1 != 0)
-				{
-					event.data2 = event.data1;
-					D_PostEvent (&event);
-				}
-			}
 		}
 		break;
 
-	case WM_CHAR:
-		if (GUICapture && wParam >= ' ')	// only send displayable characters
-		{
-			event.type = EV_GUI_Event;
-			event.subtype = EV_GUI_Char;
-			event.data1 = wParam;
-			D_PostEvent (&event);
-		}
-		break;
-
-	case WM_SYSCHAR:
-		if (GUICapture && wParam >= '0' && wParam <= '9')	// make chat macros work
-		{
-			event.type = EV_GUI_Event;
-			event.subtype = EV_GUI_Char;
-			event.data1 = wParam;
-			event.data2 = 1;
-			D_PostEvent (&event);
-		}
-		if (wParam == '\r' && k_allowfullscreentoggle)
+	case WM_SYSKEYDOWN:
+		// Pressing Alt+Enter can toggle between fullscreen and windowed.
+		if (wParam == VK_RETURN && k_allowfullscreentoggle && !(lParam & 0x40000000))
 		{
 			ToggleFullscreen = !ToggleFullscreen;
 		}
 		break;
 
 	case WM_SYSCOMMAND:
+		// Prevent activation of the window menu with Alt+Space
+		if ((wParam & 0xFFF0) != SC_KEYMENU)
 		{
-			WPARAM cmdType = wParam & 0xfff0;
-
-			// Prevent activation of the window menu with Alt-Space
-			if (cmdType != SC_KEYMENU)
-				return DefWindowProc (hWnd, message, wParam, lParam);
-		}
-		break;
-
-	case WM_LBUTTONDOWN:
-	case WM_LBUTTONUP:
-	case WM_RBUTTONDOWN:
-	case WM_RBUTTONUP:
-	case WM_MBUTTONDOWN:
-	case WM_MBUTTONUP:
-		if (GUICapture)
-		{
-			event.type = EV_GUI_Event;
-			if (message >= WM_LBUTTONDOWN && message <= WM_LBUTTONDBLCLK)
-			{
-				event.subtype = message - WM_LBUTTONDOWN + EV_GUI_LButtonDown;
-			}
-			else if (message >= WM_RBUTTONDOWN && message <= WM_RBUTTONDBLCLK)
-			{
-				event.subtype = message - WM_RBUTTONDOWN + EV_GUI_RButtonDown;
-			}
-			else if (message >= WM_MBUTTONDOWN && message <= WM_MBUTTONDBLCLK)
-			{
-				event.subtype = message - WM_MBUTTONDOWN + EV_GUI_MButtonDown;
-			}
-			D_PostEvent (&event);
+			return DefWindowProc (hWnd, message, wParam, lParam);
 		}
 		break;