From 4dddc90545f4973249f1e0a0e1c0e81747866799 Mon Sep 17 00:00:00 2001
From: divverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Thu, 15 Apr 2010 10:09:45 +0000
Subject: [PATCH] block key events while in the event handler called from
 loading screens - might fix crashes in some cases

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10087 d7cf8633-e32d-0410-b094-e92efae38249
---
 cl_screen.c |  2 +-
 host.c      |  1 +
 keys.c      | 44 ++++++++++++++++++++++++++++++++++++++++++++
 keys.h      |  2 ++
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/cl_screen.c b/cl_screen.c
index c137b100..8fd9b4b9 100644
--- a/cl_screen.c
+++ b/cl_screen.c
@@ -2029,7 +2029,7 @@ void SCR_UpdateLoadingScreen (qboolean clear)
 	old_key_consoleactive = key_consoleactive;
 	key_dest = key_void;
 	key_consoleactive = false;
-	Sys_SendKeyEvents();
+	Key_EventQueue_Block(); Sys_SendKeyEvents();
 	key_dest = old_key_dest;
 	key_consoleactive = old_key_consoleactive;
 }
diff --git a/host.c b/host.c
index c9355237..58a212b3 100644
--- a/host.c
+++ b/host.c
@@ -679,6 +679,7 @@ void Host_Main(void)
 		cl.islocalgame = NetConn_IsLocalGame();
 
 		// get new key events
+		Key_EventQueue_Unblock();
 		SndSys_SendKeyEvents();
 		Sys_SendKeyEvents();
 
diff --git a/keys.c b/keys.c
index 9915313e..5339881f 100644
--- a/keys.c
+++ b/keys.c
@@ -1405,6 +1405,44 @@ Should NOT be called during an interrupt!
 static char tbl_keyascii[MAX_KEYS];
 static keydest_t tbl_keydest[MAX_KEYS];
 
+typedef struct eventqueueitem_s
+{
+	int key;
+	int ascii;
+	qboolean down;
+}
+eventqueueitem_t;
+static int events_blocked = 0;
+static eventqueueitem_t eventqueue[32];
+static unsigned eventqueue_idx = 0;
+
+static void Key_EventQueue_Add(int key, int ascii, qboolean down)
+{
+	if(eventqueue_idx < sizeof(eventqueue) / sizeof(*eventqueue))
+	{
+		eventqueue[eventqueue_idx].key = key;
+		eventqueue[eventqueue_idx].ascii = ascii;
+		eventqueue[eventqueue_idx].down = down;
+		++eventqueue_idx;
+	}
+}
+
+void Key_EventQueue_Block(void)
+{
+	// block key events until call to Unblock
+	events_blocked = true;
+}
+
+void Key_EventQueue_Unblock(void)
+{
+	// unblocks key events again
+	unsigned i;
+	events_blocked = false;
+	for(i = 0; i < eventqueue_idx; ++i)
+		Key_Event(eventqueue[i].key, eventqueue[i].ascii, eventqueue[i].down);
+	eventqueue_idx = 0;
+}
+
 void
 Key_Event (int key, int ascii, qboolean down)
 {
@@ -1415,6 +1453,12 @@ Key_Event (int key, int ascii, qboolean down)
 	if (key < 0 || key >= MAX_KEYS)
 		return;
 
+	if(events_blocked)
+	{
+		Key_EventQueue_Add(key, ascii, down);
+		return;
+	}
+
 	// get key binding
 	bind = keybindings[key_bmap][key];
 	if (!bind)
diff --git a/keys.h b/keys.h
index 2e5d859f..c270282b 100644
--- a/keys.h
+++ b/keys.h
@@ -346,6 +346,8 @@ void Key_Init_Cvars(void);
 void Key_Event(int key, int ascii, qboolean down);
 void Key_ClearStates (void);
 void Key_SetBinding (int keynum, int bindmap, const char *binding);
+void Key_EventQueue_Block(void);
+void Key_EventQueue_Unblock(void);
 
 #endif // __KEYS_H
 
-- 
2.39.5