Index: emu/all.h
===================================================================
--- emu/all.h	(revision fffab34326fd1cd2d7a46707916f38e2d7db16a3)
+++ emu/all.h	(revision ca779254fbf0fda55b10534a9472c19126ec3e68)
@@ -162,4 +162,3 @@
 extern void kbd_write(uint32_t off, int32_t sz, uint32_t val);
 
-extern void kbd_text(SDL_TextInputEvent *ev);
-extern void kbd_key(SDL_KeyboardEvent *ev);
+extern void kbd_key(SDL_KeyboardEvent *ev, bool dn);
Index: emu/kbd.c
===================================================================
--- emu/kbd.c	(revision fffab34326fd1cd2d7a46707916f38e2d7db16a3)
+++ emu/kbd.c	(revision ca779254fbf0fda55b10534a9472c19126ec3e68)
@@ -119,14 +119,12 @@
 #endif
 
-void kbd_key(SDL_KeyboardEvent *ev)
-{
-	static bool on[24];
-
+void kbd_key(SDL_KeyboardEvent *ev, bool dn)
+{
 	if ((ev->keysym.mod & KMOD_SHIFT) != 0 &&
 			ev->keysym.sym >= SDLK_a && ev->keysym.sym <= SDLK_x) {
 		int32_t i = ev->keysym.sym - SDLK_a;
-		on[i] = !on[i];
-
-		if (on[i]) {
+		ver2("kbd key %d %s", i, dn ? "dn" : "up");
+
+		if (dn) {
 			key_touch(1 + i, 0x7f);
 		}
@@ -135,38 +133,41 @@
 		}
 
-		ver2("kbd key %d %s", i, on[i] ? "on" : "off");
-	}
-}
-
-void kbd_text(SDL_TextInputEvent *ev)
-{
-	for (int32_t i = 0; ev->text[i] != 0; ++i) {
-		if (ev->text[i] >= '0' && ev->text[i] <= '9') {
-			ver2("kbd dat %c", ev->text[i]);
-			int32_t sig = 60 + ev->text[i] - '0';
-			but_on(sig);
-			but_off(sig);
-			continue;
-		}
-
-		switch (ev->text[i]) {
-		case 'x':
-			ver2("kbd x");
-			but_on(70);
-			but_off(70);
+		return;
+	}
+
+	int32_t sig;
+
+	if (ev->keysym.sym >= SDLK_0 && ev->keysym.sym <= '9') {
+		int32_t i = ev->keysym.sym - SDLK_0;
+		ver2("kbd dat %d %s", i, dn ? "dn" : "up");
+		sig = 60 + i;
+	}
+	else {
+		switch (ev->keysym.sym) {
+		case SDLK_x:
+			ver2("kbd x %s", dn ? "dn" : "up");
+			sig = 70;
 			break;
 
-		case 'e':
-			ver2("kbd e");
-			but_on(71);
-			but_off(71);
+		case SDLK_e:
+			ver2("kbd e %s", dn ? "dn" : "up");
+			sig = 71;
 			break;
 
-		case 'm':
-			ver2("kbd m");
-			but_on(72);
-			but_off(72);
+		case SDLK_m:
+			ver2("kbd m %s", dn ? "dn" : "up");
+			sig = 72;
 			break;
-		}
+
+		default:
+			return;
+		}
+	}
+
+	if (dn) {
+		but_on(sig);
+	}
+	else {
+		but_off(sig);
 	}
 }
Index: emu/sdl.c
===================================================================
--- emu/sdl.c	(revision fffab34326fd1cd2d7a46707916f38e2d7db16a3)
+++ emu/sdl.c	(revision ca779254fbf0fda55b10534a9472c19126ec3e68)
@@ -150,7 +150,4 @@
 					ser_text(&ev.text);
 				}
-				else if (win == vid_win) {
-					kbd_text(&ev.text);
-				}
 
 				continue;
@@ -164,5 +161,15 @@
 				}
 				else if (win == vid_win) {
-					kbd_key(&ev.key);
+					kbd_key(&ev.key, true);
+				}
+
+				continue;
+			}
+
+			if (ev.type == SDL_KEYUP) {
+				ver("sdl ev key up %d", (int32_t)ev.key.keysym.sym);
+
+				if (win == vid_win) {
+					kbd_key(&ev.key, false);
 				}
 
