From 350e15ee9f4afa6db06f4ea579e38d83569215c2 Mon Sep 17 00:00:00 2001
From: Nathan Heisey <nathanheisey@gmail.com>
Date: Tue, 26 Jul 2011 17:48:40 +0000
Subject: [PATCH] Corrected keyboard input support

---
 src/main/beos/SDL_BApp.h           |  12 +-
 src/video/bwindow/SDL_bkeyboard.cc | 184 +++++++++++++++++++++++++++++
 src/video/bwindow/SDL_bkeyboard.h  |  43 +++++++
 src/video/bwindow/SDL_bvideo.cc    |   6 +
 4 files changed, 244 insertions(+), 1 deletion(-)
 create mode 100644 src/video/bwindow/SDL_bkeyboard.cc
 create mode 100644 src/video/bwindow/SDL_bkeyboard.h

diff --git a/src/main/beos/SDL_BApp.h b/src/main/beos/SDL_BApp.h
index 2ab8c011..2360a1d3 100644
--- a/src/main/beos/SDL_BApp.h
+++ b/src/main/beos/SDL_BApp.h
@@ -23,6 +23,9 @@
 
 #include <InterfaceKit.h>
 
+#include "../../video/bwindow/SDL_bkeyboard.h"
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -33,6 +36,7 @@ extern "C" {
 
 /* Local includes */
 #include "../../events/SDL_events_c.h"
+#include "../../video/bwindow/SDL_bkeyboard.h"
 
 #ifdef __cplusplus
 }
@@ -252,7 +256,13 @@ private:
 		) {
 			return;
 		}
-		SDL_SendKeyboardKey(state, (SDL_Scancode)scancode);
+		
+		/* Make sure this isn't a repeated event (key pressed and held) */
+		if(state == SDL_PRESSED && BE_GetKeyState(scancode) == SDL_PRESSED) {
+			return;
+		}
+		BE_SetKeyState(scancode, state);
+		SDL_SendKeyboardKey(state, BE_GetScancodeFromBeKey(scancode));
 	}
 	
 	void _HandleMouseFocus(BMessage *msg) {
diff --git a/src/video/bwindow/SDL_bkeyboard.cc b/src/video/bwindow/SDL_bkeyboard.cc
new file mode 100644
index 00000000..c2c455be
--- /dev/null
+++ b/src/video/bwindow/SDL_bkeyboard.cc
@@ -0,0 +1,184 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2009 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+#include <SupportDefs.h>
+#include <support/UTF8.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "SDL_events.h"
+#include "SDL_keycode.h"
+
+#include "SDL_bkeyboard.h"
+
+
+#define KEYMAP_SIZE 128
+
+
+static SDL_Scancode keymap[KEYMAP_SIZE];
+static int8 keystate[KEYMAP_SIZE];
+
+void BE_InitOSKeymap() {
+		for( uint i = 0; i < SDL_TABLESIZE(keymap); ++i ) {
+			keymap[i] = SDL_SCANCODE_UNKNOWN;
+		}
+
+		for( uint i = 0; i < KEYMAP_SIZE; ++i ) {
+			keystate[i] = SDL_RELEASED;
+		}
+
+		keymap[0x01]		= SDL_GetScancodeFromKey(SDLK_ESCAPE);
+		keymap[B_F1_KEY]	= SDL_GetScancodeFromKey(SDLK_F1);
+		keymap[B_F2_KEY]	= SDL_GetScancodeFromKey(SDLK_F2);
+		keymap[B_F3_KEY]	= SDL_GetScancodeFromKey(SDLK_F3);
+		keymap[B_F4_KEY]	= SDL_GetScancodeFromKey(SDLK_F4);
+		keymap[B_F5_KEY]	= SDL_GetScancodeFromKey(SDLK_F5);
+		keymap[B_F6_KEY]	= SDL_GetScancodeFromKey(SDLK_F6);
+		keymap[B_F7_KEY]	= SDL_GetScancodeFromKey(SDLK_F7);
+		keymap[B_F8_KEY]	= SDL_GetScancodeFromKey(SDLK_F8);
+		keymap[B_F9_KEY]	= SDL_GetScancodeFromKey(SDLK_F9);
+		keymap[B_F10_KEY]	= SDL_GetScancodeFromKey(SDLK_F10);
+		keymap[B_F11_KEY]	= SDL_GetScancodeFromKey(SDLK_F11);
+		keymap[B_F12_KEY]	= SDL_GetScancodeFromKey(SDLK_F12);
+		keymap[B_PRINT_KEY]	= SDL_GetScancodeFromKey(SDLK_PRINTSCREEN);
+		keymap[B_SCROLL_KEY]	= SDL_GetScancodeFromKey(SDLK_SCROLLLOCK);
+		keymap[B_PAUSE_KEY]	= SDL_GetScancodeFromKey(SDLK_PAUSE);
+		keymap[0x11]		= SDL_GetScancodeFromKey(SDLK_BACKQUOTE);
+		keymap[0x12]		= SDL_GetScancodeFromKey(SDLK_1);
+		keymap[0x13]		= SDL_GetScancodeFromKey(SDLK_2);
+		keymap[0x14]		= SDL_GetScancodeFromKey(SDLK_3);
+		keymap[0x15]		= SDL_GetScancodeFromKey(SDLK_4);
+		keymap[0x16]		= SDL_GetScancodeFromKey(SDLK_5);
+		keymap[0x17]		= SDL_GetScancodeFromKey(SDLK_6);
+		keymap[0x18]		= SDL_GetScancodeFromKey(SDLK_7);
+		keymap[0x19]		= SDL_GetScancodeFromKey(SDLK_8);
+		keymap[0x1a]		= SDL_GetScancodeFromKey(SDLK_9);
+		keymap[0x1b]		= SDL_GetScancodeFromKey(SDLK_0);
+		keymap[0x1c]		= SDL_GetScancodeFromKey(SDLK_MINUS);
+		keymap[0x1d]		= SDL_GetScancodeFromKey(SDLK_EQUALS);
+		keymap[0x1e]		= SDL_GetScancodeFromKey(SDLK_BACKSPACE);
+		keymap[0x1f]		= SDL_GetScancodeFromKey(SDLK_INSERT);
+		keymap[0x20]		= SDL_GetScancodeFromKey(SDLK_HOME);
+		keymap[0x21]		= SDL_GetScancodeFromKey(SDLK_PAGEUP);
+		keymap[0x22]		= SDL_GetScancodeFromKey(SDLK_NUMLOCKCLEAR);
+		keymap[0x23]		= SDL_GetScancodeFromKey(SDLK_KP_DIVIDE);
+		keymap[0x24]		= SDL_GetScancodeFromKey(SDLK_KP_MULTIPLY);
+		keymap[0x25]		= SDL_GetScancodeFromKey(SDLK_KP_MINUS);
+		keymap[0x26]		= SDL_GetScancodeFromKey(SDLK_TAB);
+		keymap[0x27]		= SDL_GetScancodeFromKey(SDLK_q);
+		keymap[0x28]		= SDL_GetScancodeFromKey(SDLK_w);
+		keymap[0x29]		= SDL_GetScancodeFromKey(SDLK_e);
+		keymap[0x2a]		= SDL_GetScancodeFromKey(SDLK_r);
+		keymap[0x2b]		= SDL_GetScancodeFromKey(SDLK_t);
+		keymap[0x2c]		= SDL_GetScancodeFromKey(SDLK_y);
+		keymap[0x2d]		= SDL_GetScancodeFromKey(SDLK_u);
+		keymap[0x2e]		= SDL_GetScancodeFromKey(SDLK_i);
+		keymap[0x2f]		= SDL_GetScancodeFromKey(SDLK_o);
+		keymap[0x30]		= SDL_GetScancodeFromKey(SDLK_p);
+		keymap[0x31]		= SDL_GetScancodeFromKey(SDLK_LEFTBRACKET);
+		keymap[0x32]		= SDL_GetScancodeFromKey(SDLK_RIGHTBRACKET);
+		keymap[0x33]		= SDL_GetScancodeFromKey(SDLK_BACKSLASH);
+		keymap[0x34]		= SDL_GetScancodeFromKey(SDLK_DELETE);
+		keymap[0x35]		= SDL_GetScancodeFromKey(SDLK_END);
+		keymap[0x36]		= SDL_GetScancodeFromKey(SDLK_PAGEDOWN);
+		keymap[0x37]		= SDL_GetScancodeFromKey(SDLK_KP_7);
+		keymap[0x38]		= SDL_GetScancodeFromKey(SDLK_KP_8);
+		keymap[0x39]		= SDL_GetScancodeFromKey(SDLK_KP_9);
+		keymap[0x3a]		= SDL_GetScancodeFromKey(SDLK_KP_PLUS);
+		keymap[0x3b]		= SDL_GetScancodeFromKey(SDLK_CAPSLOCK);
+		keymap[0x3c]		= SDL_GetScancodeFromKey(SDLK_a);
+		keymap[0x3d]		= SDL_GetScancodeFromKey(SDLK_s);
+		keymap[0x3e]		= SDL_GetScancodeFromKey(SDLK_d);
+		keymap[0x3f]		= SDL_GetScancodeFromKey(SDLK_f);
+		keymap[0x40]		= SDL_GetScancodeFromKey(SDLK_g);
+		keymap[0x41]		= SDL_GetScancodeFromKey(SDLK_h);
+		keymap[0x42]		= SDL_GetScancodeFromKey(SDLK_j);
+		keymap[0x43]		= SDL_GetScancodeFromKey(SDLK_k);
+		keymap[0x44]		= SDL_GetScancodeFromKey(SDLK_l);
+		keymap[0x45]		= SDL_GetScancodeFromKey(SDLK_SEMICOLON);
+		keymap[0x46]		= SDL_GetScancodeFromKey(SDLK_QUOTE);
+		keymap[0x47]		= SDL_GetScancodeFromKey(SDLK_RETURN);
+		keymap[0x48]		= SDL_GetScancodeFromKey(SDLK_KP_4);
+		keymap[0x49]		= SDL_GetScancodeFromKey(SDLK_KP_5);
+		keymap[0x4a]		= SDL_GetScancodeFromKey(SDLK_KP_6);
+		keymap[0x4b]		= SDL_GetScancodeFromKey(SDLK_LSHIFT);
+		keymap[0x4c]		= SDL_GetScancodeFromKey(SDLK_z);
+		keymap[0x4d]		= SDL_GetScancodeFromKey(SDLK_x);
+		keymap[0x4e]		= SDL_GetScancodeFromKey(SDLK_c);
+		keymap[0x4f]		= SDL_GetScancodeFromKey(SDLK_v);
+		keymap[0x50]		= SDL_GetScancodeFromKey(SDLK_b);
+		keymap[0x51]		= SDL_GetScancodeFromKey(SDLK_n);
+		keymap[0x52]		= SDL_GetScancodeFromKey(SDLK_m);
+		keymap[0x53]		= SDL_GetScancodeFromKey(SDLK_COMMA);
+		keymap[0x54]		= SDL_GetScancodeFromKey(SDLK_PERIOD);
+		keymap[0x55]		= SDL_GetScancodeFromKey(SDLK_SLASH);
+		keymap[0x56]		= SDL_GetScancodeFromKey(SDLK_RSHIFT);
+		keymap[0x57]		= SDL_GetScancodeFromKey(SDLK_UP);
+		keymap[0x58]		= SDL_GetScancodeFromKey(SDLK_KP_1);
+		keymap[0x59]		= SDL_GetScancodeFromKey(SDLK_KP_2);
+		keymap[0x5a]		= SDL_GetScancodeFromKey(SDLK_KP_3);
+		keymap[0x5b]		= SDL_GetScancodeFromKey(SDLK_KP_ENTER);
+		keymap[0x5c]		= SDL_GetScancodeFromKey(SDLK_LCTRL);
+		keymap[0x5d]		= SDL_GetScancodeFromKey(SDLK_LALT);
+		keymap[0x5e]		= SDL_GetScancodeFromKey(SDLK_SPACE);
+		keymap[0x5f]		= SDL_GetScancodeFromKey(SDLK_RALT);
+		keymap[0x60]		= SDL_GetScancodeFromKey(SDLK_RCTRL);
+		keymap[0x61]		= SDL_GetScancodeFromKey(SDLK_LEFT);
+		keymap[0x62]		= SDL_GetScancodeFromKey(SDLK_DOWN);
+		keymap[0x63]		= SDL_GetScancodeFromKey(SDLK_RIGHT);
+		keymap[0x64]		= SDL_GetScancodeFromKey(SDLK_KP_0);
+		keymap[0x65]		= SDL_GetScancodeFromKey(SDLK_KP_PERIOD);
+		keymap[0x66]		= SDL_GetScancodeFromKey(SDLK_LGUI);	/* FIXME: Is this the right translation? */
+		keymap[0x67]		= SDL_GetScancodeFromKey(SDLK_RGUI);	/* FIXME: Is this the right translation? */
+		keymap[0x68]		= SDL_GetScancodeFromKey(SDLK_MENU);
+		keymap[0x69]		= SDL_GetScancodeFromKey(SDLK_UNKNOWN);	/* FIXME: I couldn't find a translation */
+		keymap[0x6a]		= SDL_GetScancodeFromKey(SDLK_KP_EQUALS);
+		keymap[0x6b]		= SDL_GetScancodeFromKey(SDLK_POWER);
+}
+
+SDL_Scancode BE_GetScancodeFromBeKey(int32 bkey) {
+	if(bkey > 0 && bkey < SDL_TABLESIZE(keymap)) {
+		return keymap[bkey];
+	} else {
+		return SDL_SCANCODE_UNKNOWN;
+	}
+}
+
+int8 BE_GetKeyState(int32 bkey) {
+	if(bkey > 0 && bkey < KEYMAP_SIZE) {
+		return keystate[bkey];
+	} else {
+		return SDL_RELEASED;
+	}
+}
+
+void BE_SetKeyState(int32 bkey, int8 state) {
+	if(bkey > 0 && bkey < KEYMAP_SIZE) {
+		keystate[bkey] = state;
+	}
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/video/bwindow/SDL_bkeyboard.h b/src/video/bwindow/SDL_bkeyboard.h
new file mode 100644
index 00000000..bad9eeaa
--- /dev/null
+++ b/src/video/bwindow/SDL_bkeyboard.h
@@ -0,0 +1,43 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2009 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+#ifndef SDL_BKEYBOARD_H
+#define SDL_BKEYBOARD_H
+
+#include <SupportDefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../../../include/SDL_keyboard.h"
+
+extern void BE_InitOSKeymap();
+extern SDL_Scancode BE_GetScancodeFromBeKey(int32 bkey);
+extern int8 BE_GetKeyState(int32 bkey);
+extern void BE_SetKeyState(int32 bkey, int8 state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/video/bwindow/SDL_bvideo.cc b/src/video/bwindow/SDL_bvideo.cc
index 8fa88bd5..cdf10bb4 100644
--- a/src/video/bwindow/SDL_bvideo.cc
+++ b/src/video/bwindow/SDL_bvideo.cc
@@ -26,6 +26,7 @@
 extern "C" {
 #endif
 
+#include "SDL_bkeyboard.h"
 #include "SDL_bwindow.h"
 #include "SDL_bclipboard.h"
 #include "SDL_bvideo.h"
@@ -159,8 +160,13 @@ int BE_VideoInit(_THIS)
 		return -1;
 	}
 	
+	/* Initialize video modes */
 	BE_InitModes(_this);
 
+	/* Init the keymap */
+	BE_InitOSKeymap();
+	
+	
 #if SDL_VIDEO_OPENGL
         /* testgl application doesn't load library, just tries to load symbols */
         /* is it correct? if so we have to load library here */
-- 
2.18.1