1 #include "kvm/sdl.h" 2 3 #include "kvm/framebuffer.h" 4 #include "kvm/i8042.h" 5 #include "kvm/util.h" 6 #include "kvm/kvm.h" 7 #include "kvm/kvm-cpu.h" 8 #include "kvm/vesa.h" 9 10 #include <SDL/SDL.h> 11 #include <pthread.h> 12 #include <signal.h> 13 #include <linux/err.h> 14 15 #define FRAME_RATE 25 16 17 #define SCANCODE_UNKNOWN 0 18 #define SCANCODE_NORMAL 1 19 #define SCANCODE_ESCAPED 2 20 #define SCANCODE_KEY_PAUSE 3 21 #define SCANCODE_KEY_PRNTSCRN 4 22 23 struct set2_scancode { 24 u8 code; 25 u8 type; 26 }; 27 28 #define DEFINE_SC(_code) {\ 29 .code = _code,\ 30 .type = SCANCODE_NORMAL,\ 31 } 32 33 /* escaped scancodes */ 34 #define DEFINE_ESC(_code) {\ 35 .code = _code,\ 36 .type = SCANCODE_ESCAPED,\ 37 } 38 39 static const struct set2_scancode keymap[256] = { 40 [9] = DEFINE_SC(0x76), /* <esc> */ 41 [10] = DEFINE_SC(0x16), /* 1 */ 42 [11] = DEFINE_SC(0x1e), /* 2 */ 43 [12] = DEFINE_SC(0x26), /* 3 */ 44 [13] = DEFINE_SC(0x25), /* 4 */ 45 [14] = DEFINE_SC(0x2e), /* 5 */ 46 [15] = DEFINE_SC(0x36), /* 6 */ 47 [16] = DEFINE_SC(0x3d), /* 7 */ 48 [17] = DEFINE_SC(0x3e), /* 8 */ 49 [18] = DEFINE_SC(0x46), /* 9 */ 50 [19] = DEFINE_SC(0x45), /* 9 */ 51 [20] = DEFINE_SC(0x4e), /* - */ 52 [21] = DEFINE_SC(0x55), /* + */ 53 [22] = DEFINE_SC(0x66), /* <backspace> */ 54 [23] = DEFINE_SC(0x0d), /* <tab> */ 55 [24] = DEFINE_SC(0x15), /* q */ 56 [25] = DEFINE_SC(0x1d), /* w */ 57 [26] = DEFINE_SC(0x24), /* e */ 58 [27] = DEFINE_SC(0x2d), /* r */ 59 [28] = DEFINE_SC(0x2c), /* t */ 60 [29] = DEFINE_SC(0x35), /* y */ 61 [30] = DEFINE_SC(0x3c), /* u */ 62 [31] = DEFINE_SC(0x43), /* i */ 63 [32] = DEFINE_SC(0x44), /* o */ 64 [33] = DEFINE_SC(0x4d), /* p */ 65 [34] = DEFINE_SC(0x54), /* [ */ 66 [35] = DEFINE_SC(0x5b), /* ] */ 67 [36] = DEFINE_SC(0x5a), /* <enter> */ 68 [37] = DEFINE_SC(0x14), /* <left ctrl> */ 69 [38] = DEFINE_SC(0x1c), /* a */ 70 [39] = DEFINE_SC(0x1b), /* s */ 71 [40] = DEFINE_SC(0x23), /* d */ 72 [41] = DEFINE_SC(0x2b), /* f */ 73 [42] = DEFINE_SC(0x34), /* g */ 74 [43] = DEFINE_SC(0x33), /* h */ 75 [44] = DEFINE_SC(0x3b), /* j */ 76 [45] = DEFINE_SC(0x42), /* k */ 77 [46] = DEFINE_SC(0x4b), /* l */ 78 [47] = DEFINE_SC(0x4c), /* ; */ 79 [48] = DEFINE_SC(0x52), /* ' */ 80 [49] = DEFINE_SC(0x0e), /* ` */ 81 [50] = DEFINE_SC(0x12), /* <left shift> */ 82 [51] = DEFINE_SC(0x5d), /* \ */ 83 [52] = DEFINE_SC(0x1a), /* z */ 84 [53] = DEFINE_SC(0x22), /* x */ 85 [54] = DEFINE_SC(0x21), /* c */ 86 [55] = DEFINE_SC(0x2a), /* v */ 87 [56] = DEFINE_SC(0x32), /* b */ 88 [57] = DEFINE_SC(0x31), /* n */ 89 [58] = DEFINE_SC(0x3a), /* m */ 90 [59] = DEFINE_SC(0x41), /* < */ 91 [60] = DEFINE_SC(0x49), /* > */ 92 [61] = DEFINE_SC(0x4a), /* / */ 93 [62] = DEFINE_SC(0x59), /* <right shift> */ 94 [63] = DEFINE_SC(0x7c), /* keypad * */ 95 [64] = DEFINE_SC(0x11), /* <left alt> */ 96 [65] = DEFINE_SC(0x29), /* <space> */ 97 98 [67] = DEFINE_SC(0x05), /* <F1> */ 99 [68] = DEFINE_SC(0x06), /* <F2> */ 100 [69] = DEFINE_SC(0x04), /* <F3> */ 101 [70] = DEFINE_SC(0x0c), /* <F4> */ 102 [71] = DEFINE_SC(0x03), /* <F5> */ 103 [72] = DEFINE_SC(0x0b), /* <F6> */ 104 [73] = DEFINE_SC(0x83), /* <F7> */ 105 [74] = DEFINE_SC(0x0a), /* <F8> */ 106 [75] = DEFINE_SC(0x01), /* <F9> */ 107 [76] = DEFINE_SC(0x09), /* <F10> */ 108 109 [79] = DEFINE_SC(0x6c), /* keypad 7 */ 110 [80] = DEFINE_SC(0x75), /* keypad 8 */ 111 [81] = DEFINE_SC(0x7d), /* keypad 9 */ 112 [82] = DEFINE_SC(0x7b), /* keypad - */ 113 [83] = DEFINE_SC(0x6b), /* keypad 4 */ 114 [84] = DEFINE_SC(0x73), /* keypad 5 */ 115 [85] = DEFINE_SC(0x74), /* keypad 6 */ 116 [86] = DEFINE_SC(0x79), /* keypad + */ 117 [87] = DEFINE_SC(0x69), /* keypad 1 */ 118 [88] = DEFINE_SC(0x72), /* keypad 2 */ 119 [89] = DEFINE_SC(0x7a), /* keypad 3 */ 120 [90] = DEFINE_SC(0x70), /* keypad 0 */ 121 [91] = DEFINE_SC(0x71), /* keypad . */ 122 123 [94] = DEFINE_SC(0x61), /* <INT 1> */ 124 [95] = DEFINE_SC(0x78), /* <F11> */ 125 [96] = DEFINE_SC(0x07), /* <F12> */ 126 127 [104] = DEFINE_ESC(0x5a), /* keypad <enter> */ 128 [105] = DEFINE_ESC(0x14), /* <right ctrl> */ 129 [106] = DEFINE_ESC(0x4a), /* keypad / */ 130 [108] = DEFINE_ESC(0x11), /* <right alt> */ 131 [110] = DEFINE_ESC(0x6c), /* <home> */ 132 [111] = DEFINE_ESC(0x75), /* <up> */ 133 [112] = DEFINE_ESC(0x7d), /* <pag up> */ 134 [113] = DEFINE_ESC(0x6b), /* <left> */ 135 [114] = DEFINE_ESC(0x74), /* <right> */ 136 [115] = DEFINE_ESC(0x69), /* <end> */ 137 [116] = DEFINE_ESC(0x72), /* <down> */ 138 [117] = DEFINE_ESC(0x7a), /* <pag down> */ 139 [118] = DEFINE_ESC(0x70), /* <ins> */ 140 [119] = DEFINE_ESC(0x71), /* <delete> */ 141 }; 142 static bool running, done; 143 144 static const struct set2_scancode *to_code(u8 scancode) 145 { 146 return &keymap[scancode]; 147 } 148 149 static void key_press(const struct set2_scancode *sc) 150 { 151 switch (sc->type) { 152 case SCANCODE_ESCAPED: 153 kbd_queue(0xe0); 154 /* fallthrough */ 155 case SCANCODE_NORMAL: 156 kbd_queue(sc->code); 157 break; 158 case SCANCODE_KEY_PAUSE: 159 kbd_queue(0xe1); 160 kbd_queue(0x14); 161 kbd_queue(0x77); 162 kbd_queue(0xe1); 163 kbd_queue(0xf0); 164 kbd_queue(0x14); 165 kbd_queue(0x77); 166 break; 167 case SCANCODE_KEY_PRNTSCRN: 168 kbd_queue(0xe0); 169 kbd_queue(0x12); 170 kbd_queue(0xe0); 171 kbd_queue(0x7c); 172 break; 173 } 174 } 175 176 static void key_release(const struct set2_scancode *sc) 177 { 178 switch (sc->type) { 179 case SCANCODE_ESCAPED: 180 kbd_queue(0xe0); 181 /* fallthrough */ 182 case SCANCODE_NORMAL: 183 kbd_queue(0xf0); 184 kbd_queue(sc->code); 185 break; 186 case SCANCODE_KEY_PAUSE: 187 /* nothing to do */ 188 break; 189 case SCANCODE_KEY_PRNTSCRN: 190 kbd_queue(0xe0); 191 kbd_queue(0xf0); 192 kbd_queue(0x7c); 193 kbd_queue(0xe0); 194 kbd_queue(0xf0); 195 kbd_queue(0x12); 196 break; 197 } 198 } 199 200 static void *sdl__thread(void *p) 201 { 202 Uint32 rmask, gmask, bmask, amask; 203 struct framebuffer *fb = p; 204 SDL_Surface *guest_screen; 205 SDL_Surface *screen; 206 SDL_Event ev; 207 Uint32 flags; 208 209 kvm__set_thread_name("kvm-sdl-worker"); 210 211 if (SDL_Init(SDL_INIT_VIDEO) != 0) 212 die("Unable to initialize SDL"); 213 214 rmask = 0x000000ff; 215 gmask = 0x0000ff00; 216 bmask = 0x00ff0000; 217 amask = 0x00000000; 218 219 guest_screen = SDL_CreateRGBSurfaceFrom(fb->mem, fb->width, fb->height, fb->depth, fb->width * fb->depth / 8, rmask, gmask, bmask, amask); 220 if (!guest_screen) 221 die("Unable to create SDL RBG surface"); 222 223 flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL | SDL_DOUBLEBUF; 224 225 SDL_WM_SetCaption("KVM tool", "KVM tool"); 226 227 screen = SDL_SetVideoMode(fb->width, fb->height, fb->depth, flags); 228 if (!screen) 229 die("Unable to set SDL video mode"); 230 231 SDL_EnableKeyRepeat(200, 50); 232 233 while (running) { 234 SDL_BlitSurface(guest_screen, NULL, screen, NULL); 235 SDL_Flip(screen); 236 237 while (SDL_PollEvent(&ev)) { 238 switch (ev.type) { 239 case SDL_KEYDOWN: { 240 const struct set2_scancode *sc = to_code(ev.key.keysym.scancode); 241 if (sc->type == SCANCODE_UNKNOWN) { 242 pr_warning("key '%d' not found in keymap", ev.key.keysym.scancode); 243 break; 244 } 245 key_press(sc); 246 break; 247 } 248 case SDL_KEYUP: { 249 const struct set2_scancode *sc = to_code(ev.key.keysym.scancode); 250 if (sc->type == SCANCODE_UNKNOWN) 251 break; 252 key_release(sc); 253 break; 254 } 255 case SDL_QUIT: 256 goto exit; 257 } 258 } 259 260 SDL_Delay(1000 / FRAME_RATE); 261 } 262 263 if (running == false && done == false) { 264 done = true; 265 return NULL; 266 } 267 exit: 268 done = true; 269 kvm_cpu__reboot(fb->kvm); 270 271 return NULL; 272 } 273 274 static int sdl__start(struct framebuffer *fb) 275 { 276 pthread_t thread; 277 278 running = true; 279 280 if (pthread_create(&thread, NULL, sdl__thread, fb) != 0) 281 return -1; 282 283 return 0; 284 } 285 286 static int sdl__stop(struct framebuffer *fb) 287 { 288 running = false; 289 while (done == false) 290 sleep(0); 291 292 return 0; 293 } 294 295 static struct fb_target_operations sdl_ops = { 296 .start = sdl__start, 297 .stop = sdl__stop, 298 }; 299 300 int sdl__init(struct kvm *kvm) 301 { 302 struct framebuffer *fb; 303 304 if (!kvm->cfg.sdl) 305 return 0; 306 307 fb = vesa__init(kvm); 308 if (IS_ERR(fb)) { 309 pr_err("vesa__init() failed with error %ld\n", PTR_ERR(fb)); 310 return PTR_ERR(fb); 311 } 312 313 return fb__attach(fb, &sdl_ops); 314 } 315 dev_init(sdl__init); 316 317 int sdl__exit(struct kvm *kvm) 318 { 319 if (kvm->cfg.sdl) 320 return sdl__stop(NULL); 321 322 return 0; 323 } 324 dev_exit(sdl__exit); 325