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
to_code(u8 scancode)144 static const struct set2_scancode *to_code(u8 scancode)
145 {
146 return &keymap[scancode];
147 }
148
key_press(const struct set2_scancode * sc)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
key_release(const struct set2_scancode * sc)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
sdl__thread(void * p)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__reboot(fb->kvm);
270
271 return NULL;
272 }
273
sdl__start(struct framebuffer * fb)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
sdl__stop(struct framebuffer * fb)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
sdl__init(struct kvm * kvm)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
sdl__exit(struct kvm * kvm)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