13f838fecSPekka Enberg #include "kvm/sdl.h" 23f838fecSPekka Enberg 33f838fecSPekka Enberg #include "kvm/framebuffer.h" 4*175f8e86SPekka 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 123f838fecSPekka Enberg static void sdl__write(struct framebuffer *fb, u64 addr, u8 *data, u32 len) 133f838fecSPekka Enberg { 143f838fecSPekka Enberg memcpy(&fb->mem[addr - fb->mem_addr], data, len); 153f838fecSPekka Enberg } 163f838fecSPekka Enberg 17*175f8e86SPekka Enberg static u8 keymap[255] = { 18*175f8e86SPekka Enberg [10] = 0x16, /* 1 */ 19*175f8e86SPekka Enberg [11] = 0x1e, /* 2 */ 20*175f8e86SPekka Enberg [12] = 0x26, /* 3 */ 21*175f8e86SPekka Enberg [13] = 0x25, /* 4 */ 22*175f8e86SPekka Enberg [14] = 0x27, /* 5 */ 23*175f8e86SPekka Enberg [15] = 0x36, /* 6 */ 24*175f8e86SPekka Enberg [16] = 0x3d, /* 7 */ 25*175f8e86SPekka Enberg [17] = 0x3e, /* 8 */ 26*175f8e86SPekka Enberg [18] = 0x46, /* 9 */ 27*175f8e86SPekka Enberg [19] = 0x45, /* 9 */ 28*175f8e86SPekka Enberg 29*175f8e86SPekka Enberg [22] = 0x66, /* <backspace> */ 30*175f8e86SPekka Enberg 31*175f8e86SPekka Enberg [24] = 0x15, /* q */ 32*175f8e86SPekka Enberg [25] = 0x1d, /* w */ 33*175f8e86SPekka Enberg [26] = 0x24, /* e */ 34*175f8e86SPekka Enberg [27] = 0x2d, /* r */ 35*175f8e86SPekka Enberg [28] = 0x2c, /* t */ 36*175f8e86SPekka Enberg [29] = 0x35, /* y */ 37*175f8e86SPekka Enberg [30] = 0x3c, /* u */ 38*175f8e86SPekka Enberg [31] = 0x43, /* i */ 39*175f8e86SPekka Enberg [32] = 0x44, /* o */ 40*175f8e86SPekka Enberg [33] = 0x4d, /* p */ 41*175f8e86SPekka Enberg 42*175f8e86SPekka Enberg [36] = 0x5a, /* <enter> */ 43*175f8e86SPekka Enberg 44*175f8e86SPekka Enberg [38] = 0x1c, /* a */ 45*175f8e86SPekka Enberg [39] = 0x1b, /* s */ 46*175f8e86SPekka Enberg [40] = 0x23, /* d */ 47*175f8e86SPekka Enberg [41] = 0x2b, /* f */ 48*175f8e86SPekka Enberg [42] = 0x34, /* g */ 49*175f8e86SPekka Enberg [43] = 0x33, /* h */ 50*175f8e86SPekka Enberg [44] = 0x3b, /* j */ 51*175f8e86SPekka Enberg [45] = 0x42, /* k */ 52*175f8e86SPekka Enberg [46] = 0x4b, /* l */ 53*175f8e86SPekka Enberg 54*175f8e86SPekka Enberg [50] = 0x12, /* <left shift> */ 55*175f8e86SPekka Enberg 56*175f8e86SPekka Enberg [52] = 0x1a, /* z */ 57*175f8e86SPekka Enberg [53] = 0x22, /* x */ 58*175f8e86SPekka Enberg [54] = 0x21, /* c */ 59*175f8e86SPekka Enberg [55] = 0x2a, /* v */ 60*175f8e86SPekka Enberg [56] = 0x32, /* b */ 61*175f8e86SPekka Enberg [57] = 0x31, /* n */ 62*175f8e86SPekka Enberg [58] = 0x3a, /* m */ 63*175f8e86SPekka Enberg 64*175f8e86SPekka Enberg [61] = 0x4e, /* - */ 65*175f8e86SPekka Enberg [62] = 0x59, /* <right shift> */ 66*175f8e86SPekka Enberg [65] = 0x29, /* <space> */ 67*175f8e86SPekka Enberg }; 68*175f8e86SPekka Enberg 69*175f8e86SPekka Enberg static u8 to_code(u8 scancode) 70*175f8e86SPekka Enberg { 71*175f8e86SPekka Enberg return keymap[scancode]; 72*175f8e86SPekka Enberg } 73*175f8e86SPekka Enberg 743f838fecSPekka Enberg static void *sdl__thread(void *p) 753f838fecSPekka Enberg { 763f838fecSPekka Enberg Uint32 rmask, gmask, bmask, amask; 773f838fecSPekka Enberg struct framebuffer *fb = p; 783f838fecSPekka Enberg SDL_Surface *guest_screen; 793f838fecSPekka Enberg SDL_Surface *screen; 803f838fecSPekka Enberg SDL_Event ev; 813f838fecSPekka Enberg Uint32 flags; 823f838fecSPekka Enberg 833f838fecSPekka Enberg if (SDL_Init(SDL_INIT_VIDEO) != 0) 843f838fecSPekka Enberg die("Unable to initialize SDL"); 853f838fecSPekka Enberg 863f838fecSPekka Enberg rmask = 0x000000ff; 873f838fecSPekka Enberg gmask = 0x0000ff00; 883f838fecSPekka Enberg bmask = 0x00ff0000; 893f838fecSPekka Enberg amask = 0x00000000; 903f838fecSPekka Enberg 913f838fecSPekka Enberg guest_screen = SDL_CreateRGBSurfaceFrom(fb->mem, fb->width, fb->height, fb->depth, fb->width * fb->depth / 8, rmask, gmask, bmask, amask); 923f838fecSPekka Enberg if (!guest_screen) 933f838fecSPekka Enberg die("Unable to create SDL RBG surface"); 943f838fecSPekka Enberg 953f838fecSPekka Enberg flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL; 963f838fecSPekka Enberg 973f838fecSPekka Enberg screen = SDL_SetVideoMode(fb->width, fb->height, fb->depth, flags); 983f838fecSPekka Enberg if (!screen) 993f838fecSPekka Enberg die("Unable to set SDL video mode"); 1003f838fecSPekka Enberg 1013f838fecSPekka Enberg for (;;) { 1023f838fecSPekka Enberg SDL_BlitSurface(guest_screen, NULL, screen, NULL); 1033f838fecSPekka Enberg SDL_UpdateRect(screen, 0, 0, 0, 0); 104*175f8e86SPekka Enberg 1053f838fecSPekka Enberg while (SDL_PollEvent(&ev)) { 1063f838fecSPekka Enberg switch (ev.type) { 107*175f8e86SPekka Enberg case SDL_KEYDOWN: { 108*175f8e86SPekka Enberg u8 code = to_code(ev.key.keysym.scancode); 109*175f8e86SPekka Enberg if (code) 110*175f8e86SPekka Enberg kbd_queue(code); 111*175f8e86SPekka Enberg else 112*175f8e86SPekka Enberg pr_warning("key '%d' not found in keymap", ev.key.keysym.scancode); 113*175f8e86SPekka Enberg break; 114*175f8e86SPekka Enberg } 115*175f8e86SPekka Enberg case SDL_KEYUP: { 116*175f8e86SPekka Enberg u8 code = to_code(ev.key.keysym.scancode); 117*175f8e86SPekka Enberg if (code) { 118*175f8e86SPekka Enberg kbd_queue(0xf0); 119*175f8e86SPekka Enberg kbd_queue(code); 120*175f8e86SPekka Enberg } 121*175f8e86SPekka Enberg break; 122*175f8e86SPekka Enberg } 1233f838fecSPekka Enberg case SDL_QUIT: 1243f838fecSPekka Enberg goto exit; 1253f838fecSPekka Enberg } 1263f838fecSPekka Enberg } 127*175f8e86SPekka Enberg 1283f838fecSPekka Enberg SDL_Delay(1000 / FRAME_RATE); 1293f838fecSPekka Enberg } 1303f838fecSPekka Enberg exit: 1313f838fecSPekka Enberg return NULL; 1323f838fecSPekka Enberg } 1333f838fecSPekka Enberg 1343f838fecSPekka Enberg static int sdl__start(struct framebuffer *fb) 1353f838fecSPekka Enberg { 1363f838fecSPekka Enberg pthread_t thread; 1373f838fecSPekka Enberg 1383f838fecSPekka Enberg if (pthread_create(&thread, NULL, sdl__thread, fb) != 0) 1393f838fecSPekka Enberg return -1; 1403f838fecSPekka Enberg 1413f838fecSPekka Enberg return 0; 1423f838fecSPekka Enberg } 1433f838fecSPekka Enberg 1443f838fecSPekka Enberg static struct fb_target_operations sdl_ops = { 1453f838fecSPekka Enberg .start = sdl__start, 1463f838fecSPekka Enberg .write = sdl__write, 1473f838fecSPekka Enberg }; 1483f838fecSPekka Enberg 1493f838fecSPekka Enberg void sdl__init(struct framebuffer *fb) 1503f838fecSPekka Enberg { 1513f838fecSPekka Enberg fb__attach(fb, &sdl_ops); 1523f838fecSPekka Enberg } 153