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" 63f838fecSPekka Enberg 73f838fecSPekka Enberg #include <SDL/SDL.h> 83f838fecSPekka Enberg #include <pthread.h> 93f838fecSPekka Enberg 103f838fecSPekka Enberg #define FRAME_RATE 25 113f838fecSPekka Enberg 12175f8e86SPekka Enberg static u8 keymap[255] = { 13175f8e86SPekka Enberg [10] = 0x16, /* 1 */ 14175f8e86SPekka Enberg [11] = 0x1e, /* 2 */ 15175f8e86SPekka Enberg [12] = 0x26, /* 3 */ 16175f8e86SPekka Enberg [13] = 0x25, /* 4 */ 17175f8e86SPekka Enberg [14] = 0x27, /* 5 */ 18175f8e86SPekka Enberg [15] = 0x36, /* 6 */ 19175f8e86SPekka Enberg [16] = 0x3d, /* 7 */ 20175f8e86SPekka Enberg [17] = 0x3e, /* 8 */ 21175f8e86SPekka Enberg [18] = 0x46, /* 9 */ 22175f8e86SPekka Enberg [19] = 0x45, /* 9 */ 23dada7106SSasha Levin [20] = 0x4e, /* - */ 24dada7106SSasha Levin [21] = 0x55, /* + */ 25175f8e86SPekka Enberg [22] = 0x66, /* <backspace> */ 26175f8e86SPekka Enberg 27175f8e86SPekka Enberg [24] = 0x15, /* q */ 28175f8e86SPekka Enberg [25] = 0x1d, /* w */ 29175f8e86SPekka Enberg [26] = 0x24, /* e */ 30175f8e86SPekka Enberg [27] = 0x2d, /* r */ 31175f8e86SPekka Enberg [28] = 0x2c, /* t */ 32175f8e86SPekka Enberg [29] = 0x35, /* y */ 33175f8e86SPekka Enberg [30] = 0x3c, /* u */ 34175f8e86SPekka Enberg [31] = 0x43, /* i */ 35175f8e86SPekka Enberg [32] = 0x44, /* o */ 36175f8e86SPekka Enberg [33] = 0x4d, /* p */ 37175f8e86SPekka Enberg 38175f8e86SPekka Enberg [36] = 0x5a, /* <enter> */ 39175f8e86SPekka Enberg 40175f8e86SPekka Enberg [38] = 0x1c, /* a */ 41175f8e86SPekka Enberg [39] = 0x1b, /* s */ 42175f8e86SPekka Enberg [40] = 0x23, /* d */ 43175f8e86SPekka Enberg [41] = 0x2b, /* f */ 44175f8e86SPekka Enberg [42] = 0x34, /* g */ 45175f8e86SPekka Enberg [43] = 0x33, /* h */ 46175f8e86SPekka Enberg [44] = 0x3b, /* j */ 47175f8e86SPekka Enberg [45] = 0x42, /* k */ 48175f8e86SPekka Enberg [46] = 0x4b, /* l */ 49175f8e86SPekka Enberg 50175f8e86SPekka Enberg [50] = 0x12, /* <left shift> */ 51dada7106SSasha Levin [51] = 0x5d, /* | */ 52dada7106SSasha Levin 53175f8e86SPekka Enberg 54175f8e86SPekka Enberg [52] = 0x1a, /* z */ 55175f8e86SPekka Enberg [53] = 0x22, /* x */ 56175f8e86SPekka Enberg [54] = 0x21, /* c */ 57175f8e86SPekka Enberg [55] = 0x2a, /* v */ 58175f8e86SPekka Enberg [56] = 0x32, /* b */ 59175f8e86SPekka Enberg [57] = 0x31, /* n */ 60175f8e86SPekka Enberg [58] = 0x3a, /* m */ 61dada7106SSasha Levin [59] = 0x41, /* < */ 62dada7106SSasha Levin [60] = 0x49, /* > */ 63dada7106SSasha Levin [61] = 0x4a, /* / */ 64175f8e86SPekka Enberg [62] = 0x59, /* <right shift> */ 65175f8e86SPekka Enberg [65] = 0x29, /* <space> */ 66175f8e86SPekka Enberg }; 67175f8e86SPekka Enberg 68175f8e86SPekka Enberg static u8 to_code(u8 scancode) 69175f8e86SPekka Enberg { 70175f8e86SPekka Enberg return keymap[scancode]; 71175f8e86SPekka Enberg } 72175f8e86SPekka Enberg 733f838fecSPekka Enberg static void *sdl__thread(void *p) 743f838fecSPekka Enberg { 753f838fecSPekka Enberg Uint32 rmask, gmask, bmask, amask; 763f838fecSPekka Enberg struct framebuffer *fb = p; 773f838fecSPekka Enberg SDL_Surface *guest_screen; 783f838fecSPekka Enberg SDL_Surface *screen; 793f838fecSPekka Enberg SDL_Event ev; 803f838fecSPekka Enberg Uint32 flags; 813f838fecSPekka Enberg 823f838fecSPekka Enberg if (SDL_Init(SDL_INIT_VIDEO) != 0) 833f838fecSPekka Enberg die("Unable to initialize SDL"); 843f838fecSPekka Enberg 853f838fecSPekka Enberg rmask = 0x000000ff; 863f838fecSPekka Enberg gmask = 0x0000ff00; 873f838fecSPekka Enberg bmask = 0x00ff0000; 883f838fecSPekka Enberg amask = 0x00000000; 893f838fecSPekka Enberg 903f838fecSPekka Enberg guest_screen = SDL_CreateRGBSurfaceFrom(fb->mem, fb->width, fb->height, fb->depth, fb->width * fb->depth / 8, rmask, gmask, bmask, amask); 913f838fecSPekka Enberg if (!guest_screen) 923f838fecSPekka Enberg die("Unable to create SDL RBG surface"); 933f838fecSPekka Enberg 94*268d0f1bSSasha Levin flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL | SDL_DOUBLEBUF; 953f838fecSPekka Enberg 963f838fecSPekka Enberg screen = SDL_SetVideoMode(fb->width, fb->height, fb->depth, flags); 973f838fecSPekka Enberg if (!screen) 983f838fecSPekka Enberg die("Unable to set SDL video mode"); 993f838fecSPekka Enberg 1003f838fecSPekka Enberg for (;;) { 1013f838fecSPekka Enberg SDL_BlitSurface(guest_screen, NULL, screen, NULL); 102*268d0f1bSSasha Levin SDL_Flip(screen); 103175f8e86SPekka Enberg 1043f838fecSPekka Enberg while (SDL_PollEvent(&ev)) { 1053f838fecSPekka Enberg switch (ev.type) { 106175f8e86SPekka Enberg case SDL_KEYDOWN: { 107175f8e86SPekka Enberg u8 code = to_code(ev.key.keysym.scancode); 108175f8e86SPekka Enberg if (code) 109175f8e86SPekka Enberg kbd_queue(code); 110175f8e86SPekka Enberg else 111175f8e86SPekka Enberg pr_warning("key '%d' not found in keymap", ev.key.keysym.scancode); 112175f8e86SPekka Enberg break; 113175f8e86SPekka Enberg } 114175f8e86SPekka Enberg case SDL_KEYUP: { 115175f8e86SPekka Enberg u8 code = to_code(ev.key.keysym.scancode); 116175f8e86SPekka Enberg if (code) { 117175f8e86SPekka Enberg kbd_queue(0xf0); 118175f8e86SPekka Enberg kbd_queue(code); 119175f8e86SPekka Enberg } 120175f8e86SPekka Enberg break; 121175f8e86SPekka Enberg } 1223f838fecSPekka Enberg case SDL_QUIT: 1233f838fecSPekka Enberg goto exit; 1243f838fecSPekka Enberg } 1253f838fecSPekka Enberg } 126175f8e86SPekka Enberg 1273f838fecSPekka Enberg SDL_Delay(1000 / FRAME_RATE); 1283f838fecSPekka Enberg } 1293f838fecSPekka Enberg exit: 1303f838fecSPekka Enberg return NULL; 1313f838fecSPekka Enberg } 1323f838fecSPekka Enberg 1333f838fecSPekka Enberg static int sdl__start(struct framebuffer *fb) 1343f838fecSPekka Enberg { 1353f838fecSPekka Enberg pthread_t thread; 1363f838fecSPekka Enberg 1373f838fecSPekka Enberg if (pthread_create(&thread, NULL, sdl__thread, fb) != 0) 1383f838fecSPekka Enberg return -1; 1393f838fecSPekka Enberg 1403f838fecSPekka Enberg return 0; 1413f838fecSPekka Enberg } 1423f838fecSPekka Enberg 1433f838fecSPekka Enberg static struct fb_target_operations sdl_ops = { 1443f838fecSPekka Enberg .start = sdl__start, 1453f838fecSPekka Enberg }; 1463f838fecSPekka Enberg 1473f838fecSPekka Enberg void sdl__init(struct framebuffer *fb) 1483f838fecSPekka Enberg { 1493f838fecSPekka Enberg fb__attach(fb, &sdl_ops); 1503f838fecSPekka Enberg } 151