diff mbox

kvm tools, ui: Add simple keyboard support to SDL UI

Message ID 1307460189-8104-1-git-send-email-penberg@kernel.org (mailing list archive)
State New, archived
Headers show

Commit Message

Pekka Enberg June 7, 2011, 3:23 p.m. UTC
This patch wires up hw/i8042.c to the SDL UI for simple guest keyboard support.

Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: John Floren <john@jfloren.net>
Cc: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
---
 tools/kvm/kvm-run.c |    1 +
 tools/kvm/ui/sdl.c  |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/tools/kvm/kvm-run.c b/tools/kvm/kvm-run.c
index 8398287..b688ef7 100644
--- a/tools/kvm/kvm-run.c
+++ b/tools/kvm/kvm-run.c
@@ -643,6 +643,7 @@  int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 	}
 
 	if (sdl) {
+		kbd__init(kvm);
 		if (fb)
 			sdl__init(fb);
 	}
diff --git a/tools/kvm/ui/sdl.c b/tools/kvm/ui/sdl.c
index bc69ed9..878df1d 100644
--- a/tools/kvm/ui/sdl.c
+++ b/tools/kvm/ui/sdl.c
@@ -1,6 +1,7 @@ 
 #include "kvm/sdl.h"
 
 #include "kvm/framebuffer.h"
+#include "kvm/i8042.h"
 #include "kvm/util.h"
 
 #include <SDL/SDL.h>
@@ -13,6 +14,63 @@  static void sdl__write(struct framebuffer *fb, u64 addr, u8 *data, u32 len)
 	memcpy(&fb->mem[addr - fb->mem_addr], data, len);
 }
 
+static u8 keymap[255] = {
+	[10]		= 0x16,		/* 1 */
+	[11]		= 0x1e,		/* 2 */
+	[12]		= 0x26,		/* 3 */
+	[13]		= 0x25,		/* 4 */
+	[14]		= 0x27,		/* 5 */
+	[15]		= 0x36,		/* 6 */
+	[16]		= 0x3d,		/* 7 */
+	[17]		= 0x3e,		/* 8 */
+	[18]		= 0x46,		/* 9 */
+	[19]		= 0x45,		/* 9 */
+
+	[22]		= 0x66,		/* <backspace> */
+
+	[24]		= 0x15,		/* q */
+	[25]		= 0x1d,		/* w */
+	[26]		= 0x24,		/* e */
+	[27]		= 0x2d,		/* r */
+	[28]		= 0x2c,		/* t */
+	[29]		= 0x35,		/* y */
+	[30]		= 0x3c,		/* u */
+	[31]		= 0x43,		/* i */
+	[32]		= 0x44,		/* o */
+	[33]		= 0x4d,		/* p */
+
+	[36]		= 0x5a,		/* <enter> */
+
+	[38]		= 0x1c,		/* a */
+	[39]		= 0x1b,		/* s */
+	[40]		= 0x23,		/* d */
+	[41]		= 0x2b,		/* f */
+	[42]		= 0x34,		/* g */
+	[43]		= 0x33,		/* h */
+	[44]		= 0x3b,		/* j */
+	[45]		= 0x42,		/* k */
+	[46]		= 0x4b,		/* l */
+
+	[50]		= 0x12,		/* <left shift> */
+
+	[52]		= 0x1a,		/* z */
+	[53]		= 0x22,		/* x */
+	[54]		= 0x21,		/* c */
+	[55]		= 0x2a,		/* v */
+	[56]		= 0x32,		/* b */
+	[57]		= 0x31,		/* n */
+	[58]		= 0x3a,		/* m */
+
+	[61]		= 0x4e,		/* - */
+	[62]		= 0x59,		/* <right shift> */
+	[65]		= 0x29,		/* <space> */
+};
+
+static u8 to_code(u8 scancode)
+{
+	return keymap[scancode];
+}
+
 static void *sdl__thread(void *p)
 {
 	Uint32 rmask, gmask, bmask, amask;
@@ -43,12 +101,30 @@  static void *sdl__thread(void *p)
 	for (;;) {
 		SDL_BlitSurface(guest_screen, NULL, screen, NULL);
 		SDL_UpdateRect(screen, 0, 0, 0, 0);
+
 		while (SDL_PollEvent(&ev)) {
 			switch (ev.type) {
+			case SDL_KEYDOWN: {
+				u8 code = to_code(ev.key.keysym.scancode);
+				if (code)
+					kbd_queue(code);
+				else
+					pr_warning("key '%d' not found in keymap", ev.key.keysym.scancode);
+				break;
+			}
+			case SDL_KEYUP: {
+				u8 code = to_code(ev.key.keysym.scancode);
+				if (code) {
+					kbd_queue(0xf0);
+					kbd_queue(code);
+				}
+				break;
+			}
 			case SDL_QUIT:
 				goto exit;
 			}
 		}
+
 		SDL_Delay(1000 / FRAME_RATE);
 	}
 exit: