13f838fecSPekka Enberg #include "kvm/sdl.h" 23f838fecSPekka Enberg 33f838fecSPekka Enberg #include "kvm/framebuffer.h" 4175f8e86SPekka Enberg #include "kvm/i8042.h" 53f838fecSPekka Enberg #include "kvm/util.h" 61c48f5f8SPekka Enberg #include "kvm/kvm.h" 73f838fecSPekka Enberg 83f838fecSPekka Enberg #include <SDL/SDL.h> 93f838fecSPekka Enberg #include <pthread.h> 101c48f5f8SPekka Enberg #include <signal.h> 113f838fecSPekka Enberg 123f838fecSPekka Enberg #define FRAME_RATE 25 133f838fecSPekka Enberg 14175f8e86SPekka Enberg static u8 keymap[255] = { 15175f8e86SPekka Enberg [10] = 0x16, /* 1 */ 16175f8e86SPekka Enberg [11] = 0x1e, /* 2 */ 17175f8e86SPekka Enberg [12] = 0x26, /* 3 */ 18175f8e86SPekka Enberg [13] = 0x25, /* 4 */ 19175f8e86SPekka Enberg [14] = 0x27, /* 5 */ 20175f8e86SPekka Enberg [15] = 0x36, /* 6 */ 21175f8e86SPekka Enberg [16] = 0x3d, /* 7 */ 22175f8e86SPekka Enberg [17] = 0x3e, /* 8 */ 23175f8e86SPekka Enberg [18] = 0x46, /* 9 */ 24175f8e86SPekka Enberg [19] = 0x45, /* 9 */ 25dada7106SSasha Levin [20] = 0x4e, /* - */ 26dada7106SSasha Levin [21] = 0x55, /* + */ 27175f8e86SPekka Enberg [22] = 0x66, /* <backspace> */ 28175f8e86SPekka Enberg 29175f8e86SPekka Enberg [24] = 0x15, /* q */ 30175f8e86SPekka Enberg [25] = 0x1d, /* w */ 31175f8e86SPekka Enberg [26] = 0x24, /* e */ 32175f8e86SPekka Enberg [27] = 0x2d, /* r */ 33175f8e86SPekka Enberg [28] = 0x2c, /* t */ 34175f8e86SPekka Enberg [29] = 0x35, /* y */ 35175f8e86SPekka Enberg [30] = 0x3c, /* u */ 36175f8e86SPekka Enberg [31] = 0x43, /* i */ 37175f8e86SPekka Enberg [32] = 0x44, /* o */ 38175f8e86SPekka Enberg [33] = 0x4d, /* p */ 39175f8e86SPekka Enberg 40175f8e86SPekka Enberg [36] = 0x5a, /* <enter> */ 41175f8e86SPekka Enberg 42175f8e86SPekka Enberg [38] = 0x1c, /* a */ 43175f8e86SPekka Enberg [39] = 0x1b, /* s */ 44175f8e86SPekka Enberg [40] = 0x23, /* d */ 45175f8e86SPekka Enberg [41] = 0x2b, /* f */ 46175f8e86SPekka Enberg [42] = 0x34, /* g */ 47175f8e86SPekka Enberg [43] = 0x33, /* h */ 48175f8e86SPekka Enberg [44] = 0x3b, /* j */ 49175f8e86SPekka Enberg [45] = 0x42, /* k */ 50175f8e86SPekka Enberg [46] = 0x4b, /* l */ 51175f8e86SPekka Enberg 52175f8e86SPekka Enberg [50] = 0x12, /* <left shift> */ 53dada7106SSasha Levin [51] = 0x5d, /* | */ 54dada7106SSasha Levin 55175f8e86SPekka Enberg 56175f8e86SPekka Enberg [52] = 0x1a, /* z */ 57175f8e86SPekka Enberg [53] = 0x22, /* x */ 58175f8e86SPekka Enberg [54] = 0x21, /* c */ 59175f8e86SPekka Enberg [55] = 0x2a, /* v */ 60175f8e86SPekka Enberg [56] = 0x32, /* b */ 61175f8e86SPekka Enberg [57] = 0x31, /* n */ 62175f8e86SPekka Enberg [58] = 0x3a, /* m */ 63dada7106SSasha Levin [59] = 0x41, /* < */ 64dada7106SSasha Levin [60] = 0x49, /* > */ 65dada7106SSasha Levin [61] = 0x4a, /* / */ 66175f8e86SPekka Enberg [62] = 0x59, /* <right shift> */ 67175f8e86SPekka Enberg [65] = 0x29, /* <space> */ 68175f8e86SPekka Enberg }; 69175f8e86SPekka Enberg 70175f8e86SPekka Enberg static u8 to_code(u8 scancode) 71175f8e86SPekka Enberg { 72175f8e86SPekka Enberg return keymap[scancode]; 73175f8e86SPekka Enberg } 74175f8e86SPekka Enberg 753f838fecSPekka Enberg static void *sdl__thread(void *p) 763f838fecSPekka Enberg { 773f838fecSPekka Enberg Uint32 rmask, gmask, bmask, amask; 783f838fecSPekka Enberg struct framebuffer *fb = p; 793f838fecSPekka Enberg SDL_Surface *guest_screen; 803f838fecSPekka Enberg SDL_Surface *screen; 813f838fecSPekka Enberg SDL_Event ev; 823f838fecSPekka Enberg Uint32 flags; 833f838fecSPekka Enberg 843f838fecSPekka Enberg if (SDL_Init(SDL_INIT_VIDEO) != 0) 853f838fecSPekka Enberg die("Unable to initialize SDL"); 863f838fecSPekka Enberg 873f838fecSPekka Enberg rmask = 0x000000ff; 883f838fecSPekka Enberg gmask = 0x0000ff00; 893f838fecSPekka Enberg bmask = 0x00ff0000; 903f838fecSPekka Enberg amask = 0x00000000; 913f838fecSPekka Enberg 923f838fecSPekka Enberg guest_screen = SDL_CreateRGBSurfaceFrom(fb->mem, fb->width, fb->height, fb->depth, fb->width * fb->depth / 8, rmask, gmask, bmask, amask); 933f838fecSPekka Enberg if (!guest_screen) 943f838fecSPekka Enberg die("Unable to create SDL RBG surface"); 953f838fecSPekka Enberg 96268d0f1bSSasha Levin flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL | SDL_DOUBLEBUF; 973f838fecSPekka Enberg 98*2a77516bSPekka Enberg SDL_WM_SetCaption("KVM tool", "KVM tool"); 99*2a77516bSPekka Enberg 1003f838fecSPekka Enberg screen = SDL_SetVideoMode(fb->width, fb->height, fb->depth, flags); 1013f838fecSPekka Enberg if (!screen) 1023f838fecSPekka Enberg die("Unable to set SDL video mode"); 1033f838fecSPekka Enberg 10468770058SLiming Wang SDL_EnableKeyRepeat(200, 50); 10568770058SLiming Wang 1063f838fecSPekka Enberg for (;;) { 1073f838fecSPekka Enberg SDL_BlitSurface(guest_screen, NULL, screen, NULL); 108268d0f1bSSasha Levin SDL_Flip(screen); 109175f8e86SPekka Enberg 1103f838fecSPekka Enberg while (SDL_PollEvent(&ev)) { 1113f838fecSPekka Enberg switch (ev.type) { 112175f8e86SPekka Enberg case SDL_KEYDOWN: { 113175f8e86SPekka Enberg u8 code = to_code(ev.key.keysym.scancode); 114175f8e86SPekka Enberg if (code) 115175f8e86SPekka Enberg kbd_queue(code); 116175f8e86SPekka Enberg else 117175f8e86SPekka Enberg pr_warning("key '%d' not found in keymap", ev.key.keysym.scancode); 118175f8e86SPekka Enberg break; 119175f8e86SPekka Enberg } 120175f8e86SPekka Enberg case SDL_KEYUP: { 121175f8e86SPekka Enberg u8 code = to_code(ev.key.keysym.scancode); 122175f8e86SPekka Enberg if (code) { 123175f8e86SPekka Enberg kbd_queue(0xf0); 124175f8e86SPekka Enberg kbd_queue(code); 125175f8e86SPekka Enberg } 126175f8e86SPekka Enberg break; 127175f8e86SPekka Enberg } 1283f838fecSPekka Enberg case SDL_QUIT: 1293f838fecSPekka Enberg goto exit; 1303f838fecSPekka Enberg } 1313f838fecSPekka Enberg } 132175f8e86SPekka Enberg 1333f838fecSPekka Enberg SDL_Delay(1000 / FRAME_RATE); 1343f838fecSPekka Enberg } 1353f838fecSPekka Enberg exit: 1361c48f5f8SPekka Enberg kill(0, SIGKVMSTOP); 1371c48f5f8SPekka Enberg 1383f838fecSPekka Enberg return NULL; 1393f838fecSPekka Enberg } 1403f838fecSPekka Enberg 1413f838fecSPekka Enberg static int sdl__start(struct framebuffer *fb) 1423f838fecSPekka Enberg { 1433f838fecSPekka Enberg pthread_t thread; 1443f838fecSPekka Enberg 1453f838fecSPekka Enberg if (pthread_create(&thread, NULL, sdl__thread, fb) != 0) 1463f838fecSPekka Enberg return -1; 1473f838fecSPekka Enberg 1483f838fecSPekka Enberg return 0; 1493f838fecSPekka Enberg } 1503f838fecSPekka Enberg 1513f838fecSPekka Enberg static struct fb_target_operations sdl_ops = { 1523f838fecSPekka Enberg .start = sdl__start, 1533f838fecSPekka Enberg }; 1543f838fecSPekka Enberg 1553f838fecSPekka Enberg void sdl__init(struct framebuffer *fb) 1563f838fecSPekka Enberg { 1573f838fecSPekka Enberg fb__attach(fb, &sdl_ops); 1583f838fecSPekka Enberg } 159