Statistics
| Branch: | Revision:

root / sdl.c @ d7585251

History | View | Annotate | Download (24.8 kB)

1 0f0b7264 bellard
/*
2 0f0b7264 bellard
 * QEMU SDL display driver
3 5fafdf24 ths
 *
4 0f0b7264 bellard
 * Copyright (c) 2003 Fabrice Bellard
5 5fafdf24 ths
 *
6 0f0b7264 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 0f0b7264 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 0f0b7264 bellard
 * in the Software without restriction, including without limitation the rights
9 0f0b7264 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 0f0b7264 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 0f0b7264 bellard
 * furnished to do so, subject to the following conditions:
12 0f0b7264 bellard
 *
13 0f0b7264 bellard
 * The above copyright notice and this permission notice shall be included in
14 0f0b7264 bellard
 * all copies or substantial portions of the Software.
15 0f0b7264 bellard
 *
16 0f0b7264 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 0f0b7264 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 0f0b7264 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 0f0b7264 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 0f0b7264 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 0f0b7264 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 0f0b7264 bellard
 * THE SOFTWARE.
23 0f0b7264 bellard
 */
24 0f0b7264 bellard
#include <SDL.h>
25 c9985aa8 aliguori
#include <SDL_syswm.h>
26 0f0b7264 bellard
27 67b915a5 bellard
#ifndef _WIN32
28 67b915a5 bellard
#include <signal.h>
29 67b915a5 bellard
#endif
30 0f0b7264 bellard
31 511d2b14 blueswir1
#include "qemu-common.h"
32 511d2b14 blueswir1
#include "console.h"
33 511d2b14 blueswir1
#include "sysemu.h"
34 511d2b14 blueswir1
#include "x_keymap.h"
35 511d2b14 blueswir1
36 7d957bd8 aliguori
static DisplayChangeListener *dcl;
37 7d957bd8 aliguori
static SDL_Surface *real_screen;
38 7d957bd8 aliguori
static SDL_Surface *guest_screen = NULL;
39 0f0b7264 bellard
static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
40 8a7ddc38 bellard
static int last_vm_running;
41 8e9c4afe bellard
static int gui_saved_grab;
42 8e9c4afe bellard
static int gui_fullscreen;
43 43523e93 ths
static int gui_noframe;
44 8e9c4afe bellard
static int gui_key_modifier_pressed;
45 8e9c4afe bellard
static int gui_keysym;
46 d63d307f bellard
static int gui_fullscreen_initial_grab;
47 32ff25bf bellard
static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
48 32ff25bf bellard
static uint8_t modifiers_state[256];
49 09b26c5e bellard
static int width, height;
50 09b26c5e bellard
static SDL_Cursor *sdl_cursor_normal;
51 09b26c5e bellard
static SDL_Cursor *sdl_cursor_hidden;
52 09b26c5e bellard
static int absolute_enabled = 0;
53 d34cab9f ths
static int guest_cursor = 0;
54 d34cab9f ths
static int guest_x, guest_y;
55 d34cab9f ths
static SDL_Cursor *guest_sprite = 0;
56 7b5d76da aliguori
static uint8_t allocator;
57 7b5d76da aliguori
static uint8_t hostbpp;
58 0f0b7264 bellard
59 0f0b7264 bellard
static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
60 0f0b7264 bellard
{
61 898712a8 bellard
    //    printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
62 7b5d76da aliguori
    if (guest_screen) {
63 7b5d76da aliguori
        SDL_Rect rec;
64 7b5d76da aliguori
        rec.x = x;
65 7b5d76da aliguori
        rec.y = y;
66 7b5d76da aliguori
        rec.w = w;
67 7b5d76da aliguori
        rec.h = h;
68 7b5d76da aliguori
        SDL_BlitSurface(guest_screen, &rec, real_screen, &rec);
69 7b5d76da aliguori
    }
70 6e60065f pbrook
    SDL_UpdateRect(real_screen, x, y, w, h);
71 7d957bd8 aliguori
}
72 7d957bd8 aliguori
73 7d957bd8 aliguori
static void sdl_setdata(DisplayState *ds)
74 7d957bd8 aliguori
{
75 7d957bd8 aliguori
    SDL_Rect rec;
76 7d957bd8 aliguori
    rec.x = 0;
77 7d957bd8 aliguori
    rec.y = 0;
78 7d957bd8 aliguori
    rec.w = real_screen->w;
79 7d957bd8 aliguori
    rec.h = real_screen->h;
80 7d957bd8 aliguori
81 7d957bd8 aliguori
    if (guest_screen != NULL) SDL_FreeSurface(guest_screen);
82 7d957bd8 aliguori
83 7d957bd8 aliguori
    guest_screen = SDL_CreateRGBSurfaceFrom(ds_get_data(ds), ds_get_width(ds), ds_get_height(ds),
84 7d957bd8 aliguori
                                            ds_get_bits_per_pixel(ds), ds_get_linesize(ds),
85 7d957bd8 aliguori
                                            ds->surface->pf.rmask, ds->surface->pf.gmask,
86 7d957bd8 aliguori
                                            ds->surface->pf.bmask, ds->surface->pf.amask);
87 0f0b7264 bellard
}
88 0f0b7264 bellard
89 649c9078 balrog
static void do_sdl_resize(int new_width, int new_height, int bpp)
90 0f0b7264 bellard
{
91 0f0b7264 bellard
    int flags;
92 0f0b7264 bellard
93 0f0b7264 bellard
    //    printf("resizing to %d %d\n", w, h);
94 0f0b7264 bellard
95 0f0b7264 bellard
    flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
96 8e9c4afe bellard
    if (gui_fullscreen)
97 8e9c4afe bellard
        flags |= SDL_FULLSCREEN;
98 43523e93 ths
    if (gui_noframe)
99 43523e93 ths
        flags |= SDL_NOFRAME;
100 9903da21 bellard
101 649c9078 balrog
    width = new_width;
102 649c9078 balrog
    height = new_height;
103 7b5d76da aliguori
    real_screen = SDL_SetVideoMode(width, height, bpp, flags);
104 7d957bd8 aliguori
    if (!real_screen) {
105 0f0b7264 bellard
        fprintf(stderr, "Could not open SDL display\n");
106 0f0b7264 bellard
        exit(1);
107 0f0b7264 bellard
    }
108 7b5d76da aliguori
}
109 7b5d76da aliguori
110 7b5d76da aliguori
static void sdl_resize(DisplayState *ds)
111 7b5d76da aliguori
{
112 7b5d76da aliguori
    if  (!allocator) {
113 7b5d76da aliguori
        do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
114 7b5d76da aliguori
        sdl_setdata(ds);
115 7b5d76da aliguori
    } else {
116 7b5d76da aliguori
        if (guest_screen != NULL) {
117 7b5d76da aliguori
            SDL_FreeSurface(guest_screen);
118 7b5d76da aliguori
            guest_screen = NULL;
119 7b5d76da aliguori
        }
120 7b5d76da aliguori
    }
121 7b5d76da aliguori
}
122 7b5d76da aliguori
123 7b5d76da aliguori
static PixelFormat sdl_to_qemu_pixelformat(SDL_PixelFormat *sdl_pf)
124 7b5d76da aliguori
{
125 7b5d76da aliguori
    PixelFormat qemu_pf;
126 7b5d76da aliguori
127 7b5d76da aliguori
    memset(&qemu_pf, 0x00, sizeof(PixelFormat));
128 7b5d76da aliguori
129 7b5d76da aliguori
    qemu_pf.bits_per_pixel = sdl_pf->BitsPerPixel;
130 7b5d76da aliguori
    qemu_pf.bytes_per_pixel = sdl_pf->BytesPerPixel;
131 7b5d76da aliguori
    qemu_pf.depth = (qemu_pf.bits_per_pixel) == 32 ? 24 : (qemu_pf.bits_per_pixel);
132 7b5d76da aliguori
133 7b5d76da aliguori
    qemu_pf.rmask = sdl_pf->Rmask;
134 7b5d76da aliguori
    qemu_pf.gmask = sdl_pf->Gmask;
135 7b5d76da aliguori
    qemu_pf.bmask = sdl_pf->Bmask;
136 7b5d76da aliguori
    qemu_pf.amask = sdl_pf->Amask;
137 7b5d76da aliguori
138 7b5d76da aliguori
    qemu_pf.rshift = sdl_pf->Rshift;
139 7b5d76da aliguori
    qemu_pf.gshift = sdl_pf->Gshift;
140 7b5d76da aliguori
    qemu_pf.bshift = sdl_pf->Bshift;
141 7b5d76da aliguori
    qemu_pf.ashift = sdl_pf->Ashift;
142 7b5d76da aliguori
143 7b5d76da aliguori
    qemu_pf.rbits = 8 - sdl_pf->Rloss;
144 7b5d76da aliguori
    qemu_pf.gbits = 8 - sdl_pf->Gloss;
145 7b5d76da aliguori
    qemu_pf.bbits = 8 - sdl_pf->Bloss;
146 7b5d76da aliguori
    qemu_pf.abits = 8 - sdl_pf->Aloss;
147 7b5d76da aliguori
148 7b5d76da aliguori
    qemu_pf.rmax = ((1 << qemu_pf.rbits) - 1);
149 7b5d76da aliguori
    qemu_pf.gmax = ((1 << qemu_pf.gbits) - 1);
150 7b5d76da aliguori
    qemu_pf.bmax = ((1 << qemu_pf.bbits) - 1);
151 7b5d76da aliguori
    qemu_pf.amax = ((1 << qemu_pf.abits) - 1);
152 7b5d76da aliguori
153 7b5d76da aliguori
    return qemu_pf;
154 7b5d76da aliguori
}
155 7b5d76da aliguori
156 7b5d76da aliguori
static DisplaySurface* sdl_create_displaysurface(int width, int height)
157 7b5d76da aliguori
{
158 7b5d76da aliguori
    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
159 7b5d76da aliguori
    if (surface == NULL) {
160 7b5d76da aliguori
        fprintf(stderr, "sdl_create_displaysurface: malloc failed\n");
161 7b5d76da aliguori
        exit(1);
162 7b5d76da aliguori
    }
163 7b5d76da aliguori
164 7b5d76da aliguori
    surface->width = width;
165 7b5d76da aliguori
    surface->height = height;
166 7d957bd8 aliguori
167 7b5d76da aliguori
    if (hostbpp == 16)
168 7b5d76da aliguori
        do_sdl_resize(width, height, 16);
169 7b5d76da aliguori
    else
170 7b5d76da aliguori
        do_sdl_resize(width, height, 32);
171 7b5d76da aliguori
172 7b5d76da aliguori
    surface->pf = sdl_to_qemu_pixelformat(real_screen->format);
173 7b5d76da aliguori
    surface->linesize = real_screen->pitch;
174 7b5d76da aliguori
    surface->data = real_screen->pixels;
175 7b5d76da aliguori
176 7b5d76da aliguori
#ifdef WORDS_BIGENDIAN
177 7b5d76da aliguori
    surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
178 7b5d76da aliguori
#else
179 7b5d76da aliguori
    surface->flags = QEMU_ALLOCATED_FLAG;
180 7b5d76da aliguori
#endif
181 7b5d76da aliguori
    allocator = 1;
182 7b5d76da aliguori
183 7b5d76da aliguori
    return surface;
184 7b5d76da aliguori
}
185 7b5d76da aliguori
186 7b5d76da aliguori
static void sdl_free_displaysurface(DisplaySurface *surface)
187 7b5d76da aliguori
{
188 7b5d76da aliguori
    allocator = 0;
189 7b5d76da aliguori
    if (surface == NULL)
190 7b5d76da aliguori
        return;
191 7b5d76da aliguori
    qemu_free(surface);
192 7b5d76da aliguori
}
193 7b5d76da aliguori
194 7b5d76da aliguori
static DisplaySurface* sdl_resize_displaysurface(DisplaySurface *surface, int width, int height)
195 7b5d76da aliguori
{
196 7b5d76da aliguori
    sdl_free_displaysurface(surface);
197 7b5d76da aliguori
    return sdl_create_displaysurface(width, height);
198 0f0b7264 bellard
}
199 0f0b7264 bellard
200 3d11d0eb bellard
/* generic keyboard conversion */
201 e58d12ed bellard
202 3d11d0eb bellard
#include "sdl_keysym.h"
203 3d11d0eb bellard
204 3d11d0eb bellard
static kbd_layout_t *kbd_layout = NULL;
205 3d11d0eb bellard
206 3d11d0eb bellard
static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev)
207 e58d12ed bellard
{
208 3d11d0eb bellard
    int keysym;
209 3d11d0eb bellard
    /* workaround for X11+SDL bug with AltGR */
210 3d11d0eb bellard
    keysym = ev->keysym.sym;
211 3d11d0eb bellard
    if (keysym == 0 && ev->keysym.scancode == 113)
212 3d11d0eb bellard
        keysym = SDLK_MODE;
213 60659e3b bellard
    /* For Japanese key '\' and '|' */
214 60659e3b bellard
    if (keysym == 92 && ev->keysym.scancode == 133) {
215 60659e3b bellard
        keysym = 0xa5;
216 60659e3b bellard
    }
217 3d11d0eb bellard
    return keysym2scancode(kbd_layout, keysym);
218 e58d12ed bellard
}
219 e58d12ed bellard
220 3d11d0eb bellard
/* specific keyboard conversions from scan codes */
221 3d11d0eb bellard
222 3d11d0eb bellard
#if defined(_WIN32)
223 e58d12ed bellard
224 e58d12ed bellard
static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
225 e58d12ed bellard
{
226 e58d12ed bellard
    return ev->keysym.scancode;
227 e58d12ed bellard
}
228 e58d12ed bellard
229 e58d12ed bellard
#else
230 e58d12ed bellard
231 5368a422 aliguori
#if defined(SDL_VIDEO_DRIVER_X11)
232 5368a422 aliguori
#include <X11/XKBlib.h>
233 5368a422 aliguori
234 5368a422 aliguori
static int check_for_evdev(void)
235 5368a422 aliguori
{
236 5368a422 aliguori
    SDL_SysWMinfo info;
237 5368a422 aliguori
    XkbDescPtr desc;
238 5368a422 aliguori
    int has_evdev = 0;
239 5368a422 aliguori
    const char *keycodes;
240 5368a422 aliguori
241 5368a422 aliguori
    SDL_VERSION(&info.version);
242 5368a422 aliguori
    if (!SDL_GetWMInfo(&info))
243 5368a422 aliguori
        return 0;
244 5368a422 aliguori
245 5368a422 aliguori
    desc = XkbGetKeyboard(info.info.x11.display,
246 5368a422 aliguori
                          XkbGBN_AllComponentsMask,
247 5368a422 aliguori
                          XkbUseCoreKbd);
248 5368a422 aliguori
    if (desc == NULL || desc->names == NULL)
249 5368a422 aliguori
        return 0;
250 5368a422 aliguori
251 5368a422 aliguori
    keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes);
252 5368a422 aliguori
    if (keycodes == NULL)
253 5368a422 aliguori
        fprintf(stderr, "could not lookup keycode name\n");
254 5368a422 aliguori
    else if (strstart(keycodes, "evdev_", NULL))
255 5368a422 aliguori
        has_evdev = 1;
256 5368a422 aliguori
    else if (!strstart(keycodes, "xfree86_", NULL))
257 5368a422 aliguori
        fprintf(stderr,
258 5368a422 aliguori
                "unknown keycodes `%s', please report to qemu-devel@nongnu.org\n",
259 5368a422 aliguori
                keycodes);
260 5368a422 aliguori
261 5368a422 aliguori
    XkbFreeClientMap(desc, XkbGBN_AllComponentsMask, True);
262 5368a422 aliguori
263 5368a422 aliguori
    return has_evdev;
264 5368a422 aliguori
}
265 5368a422 aliguori
#else
266 5368a422 aliguori
static int check_for_evdev(void)
267 5368a422 aliguori
{
268 5368a422 aliguori
        return 0;
269 5368a422 aliguori
}
270 5368a422 aliguori
#endif
271 5368a422 aliguori
272 e58d12ed bellard
static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
273 e58d12ed bellard
{
274 e58d12ed bellard
    int keycode;
275 5368a422 aliguori
    static int has_evdev = -1;
276 5368a422 aliguori
277 5368a422 aliguori
    if (has_evdev == -1)
278 5368a422 aliguori
        has_evdev = check_for_evdev();
279 e58d12ed bellard
280 e58d12ed bellard
    keycode = ev->keysym.scancode;
281 e58d12ed bellard
282 e58d12ed bellard
    if (keycode < 9) {
283 e58d12ed bellard
        keycode = 0;
284 e58d12ed bellard
    } else if (keycode < 97) {
285 e58d12ed bellard
        keycode -= 8; /* just an offset */
286 5368a422 aliguori
    } else if (keycode < 158) {
287 e58d12ed bellard
        /* use conversion table */
288 5368a422 aliguori
        if (has_evdev)
289 5368a422 aliguori
            keycode = translate_evdev_keycode(keycode - 97);
290 5368a422 aliguori
        else
291 5368a422 aliguori
            keycode = translate_xfree86_keycode(keycode - 97);
292 5368a422 aliguori
    } else if (keycode == 208) { /* Hiragana_Katakana */
293 5368a422 aliguori
        keycode = 0x70;
294 5368a422 aliguori
    } else if (keycode == 211) { /* backslash */
295 5368a422 aliguori
        keycode = 0x73;
296 e58d12ed bellard
    } else {
297 e58d12ed bellard
        keycode = 0;
298 e58d12ed bellard
    }
299 e58d12ed bellard
    return keycode;
300 e58d12ed bellard
}
301 e58d12ed bellard
302 e58d12ed bellard
#endif
303 e58d12ed bellard
304 32ff25bf bellard
static void reset_keys(void)
305 32ff25bf bellard
{
306 32ff25bf bellard
    int i;
307 32ff25bf bellard
    for(i = 0; i < 256; i++) {
308 32ff25bf bellard
        if (modifiers_state[i]) {
309 32ff25bf bellard
            if (i & 0x80)
310 32ff25bf bellard
                kbd_put_keycode(0xe0);
311 32ff25bf bellard
            kbd_put_keycode(i | 0x80);
312 32ff25bf bellard
            modifiers_state[i] = 0;
313 32ff25bf bellard
        }
314 32ff25bf bellard
    }
315 32ff25bf bellard
}
316 32ff25bf bellard
317 0f0b7264 bellard
static void sdl_process_key(SDL_KeyboardEvent *ev)
318 0f0b7264 bellard
{
319 32ff25bf bellard
    int keycode, v;
320 de2200d3 bellard
321 de2200d3 bellard
    if (ev->keysym.sym == SDLK_PAUSE) {
322 de2200d3 bellard
        /* specific case */
323 de2200d3 bellard
        v = 0;
324 de2200d3 bellard
        if (ev->type == SDL_KEYUP)
325 de2200d3 bellard
            v |= 0x80;
326 de2200d3 bellard
        kbd_put_keycode(0xe1);
327 de2200d3 bellard
        kbd_put_keycode(0x1d | v);
328 de2200d3 bellard
        kbd_put_keycode(0x45 | v);
329 de2200d3 bellard
        return;
330 de2200d3 bellard
    }
331 de2200d3 bellard
332 3d11d0eb bellard
    if (kbd_layout) {
333 3d11d0eb bellard
        keycode = sdl_keyevent_to_keycode_generic(ev);
334 3d11d0eb bellard
    } else {
335 3d11d0eb bellard
        keycode = sdl_keyevent_to_keycode(ev);
336 3d11d0eb bellard
    }
337 de2200d3 bellard
338 de2200d3 bellard
    switch(keycode) {
339 de2200d3 bellard
    case 0x00:
340 de2200d3 bellard
        /* sent when leaving window: reset the modifiers state */
341 32ff25bf bellard
        reset_keys();
342 de2200d3 bellard
        return;
343 de2200d3 bellard
    case 0x2a:                          /* Left Shift */
344 de2200d3 bellard
    case 0x36:                          /* Right Shift */
345 de2200d3 bellard
    case 0x1d:                          /* Left CTRL */
346 de2200d3 bellard
    case 0x9d:                          /* Right CTRL */
347 de2200d3 bellard
    case 0x38:                          /* Left ALT */
348 de2200d3 bellard
    case 0xb8:                         /* Right ALT */
349 0f0b7264 bellard
        if (ev->type == SDL_KEYUP)
350 de2200d3 bellard
            modifiers_state[keycode] = 0;
351 de2200d3 bellard
        else
352 de2200d3 bellard
            modifiers_state[keycode] = 1;
353 de2200d3 bellard
        break;
354 de2200d3 bellard
    case 0x45: /* num lock */
355 de2200d3 bellard
    case 0x3a: /* caps lock */
356 de2200d3 bellard
        /* SDL does not send the key up event, so we generate it */
357 de2200d3 bellard
        kbd_put_keycode(keycode);
358 de2200d3 bellard
        kbd_put_keycode(keycode | 0x80);
359 de2200d3 bellard
        return;
360 0f0b7264 bellard
    }
361 de2200d3 bellard
362 de2200d3 bellard
    /* now send the key code */
363 de2200d3 bellard
    if (keycode & 0x80)
364 de2200d3 bellard
        kbd_put_keycode(0xe0);
365 de2200d3 bellard
    if (ev->type == SDL_KEYUP)
366 de2200d3 bellard
        kbd_put_keycode(keycode | 0x80);
367 de2200d3 bellard
    else
368 de2200d3 bellard
        kbd_put_keycode(keycode & 0x7f);
369 0f0b7264 bellard
}
370 0f0b7264 bellard
371 8a7ddc38 bellard
static void sdl_update_caption(void)
372 8a7ddc38 bellard
{
373 8a7ddc38 bellard
    char buf[1024];
374 c35734b2 ths
    const char *status = "";
375 c35734b2 ths
376 c35734b2 ths
    if (!vm_running)
377 c35734b2 ths
        status = " [Stopped]";
378 3780e197 ths
    else if (gui_grab) {
379 3780e197 ths
        if (!alt_grab)
380 3780e197 ths
            status = " - Press Ctrl-Alt to exit grab";
381 3780e197 ths
        else
382 3780e197 ths
            status = " - Press Ctrl-Alt-Shift to exit grab";
383 3780e197 ths
    }
384 c35734b2 ths
385 c35734b2 ths
    if (qemu_name)
386 c35734b2 ths
        snprintf(buf, sizeof(buf), "QEMU (%s)%s", qemu_name, status);
387 c35734b2 ths
    else
388 c35734b2 ths
        snprintf(buf, sizeof(buf), "QEMU%s", status);
389 c35734b2 ths
390 8a7ddc38 bellard
    SDL_WM_SetCaption(buf, "QEMU");
391 8a7ddc38 bellard
}
392 8a7ddc38 bellard
393 09b26c5e bellard
static void sdl_hide_cursor(void)
394 09b26c5e bellard
{
395 9467cd46 balrog
    if (!cursor_hide)
396 9467cd46 balrog
        return;
397 9467cd46 balrog
398 8785a8dd bellard
    if (kbd_mouse_is_absolute()) {
399 8785a8dd bellard
        SDL_ShowCursor(1);
400 8785a8dd bellard
        SDL_SetCursor(sdl_cursor_hidden);
401 8785a8dd bellard
    } else {
402 8785a8dd bellard
        SDL_ShowCursor(0);
403 8785a8dd bellard
    }
404 09b26c5e bellard
}
405 09b26c5e bellard
406 09b26c5e bellard
static void sdl_show_cursor(void)
407 09b26c5e bellard
{
408 9467cd46 balrog
    if (!cursor_hide)
409 9467cd46 balrog
        return;
410 9467cd46 balrog
411 09b26c5e bellard
    if (!kbd_mouse_is_absolute()) {
412 8785a8dd bellard
        SDL_ShowCursor(1);
413 d34cab9f ths
        if (guest_cursor &&
414 d34cab9f ths
                (gui_grab || kbd_mouse_is_absolute() || absolute_enabled))
415 d34cab9f ths
            SDL_SetCursor(guest_sprite);
416 d34cab9f ths
        else
417 d34cab9f ths
            SDL_SetCursor(sdl_cursor_normal);
418 09b26c5e bellard
    }
419 09b26c5e bellard
}
420 09b26c5e bellard
421 0f0b7264 bellard
static void sdl_grab_start(void)
422 0f0b7264 bellard
{
423 d34cab9f ths
    if (guest_cursor) {
424 d34cab9f ths
        SDL_SetCursor(guest_sprite);
425 08a2d4c4 balrog
        if (!kbd_mouse_is_absolute() && !absolute_enabled)
426 08a2d4c4 balrog
            SDL_WarpMouse(guest_x, guest_y);
427 d34cab9f ths
    } else
428 d34cab9f ths
        sdl_hide_cursor();
429 6bb81603 aliguori
430 6bb81603 aliguori
    if (SDL_WM_GrabInput(SDL_GRAB_ON) == SDL_GRAB_ON) {
431 6bb81603 aliguori
        gui_grab = 1;
432 6bb81603 aliguori
        sdl_update_caption();
433 6bb81603 aliguori
    } else
434 6bb81603 aliguori
        sdl_show_cursor();
435 0f0b7264 bellard
}
436 0f0b7264 bellard
437 0f0b7264 bellard
static void sdl_grab_end(void)
438 0f0b7264 bellard
{
439 0f0b7264 bellard
    SDL_WM_GrabInput(SDL_GRAB_OFF);
440 0f0b7264 bellard
    gui_grab = 0;
441 d34cab9f ths
    sdl_show_cursor();
442 8a7ddc38 bellard
    sdl_update_caption();
443 0f0b7264 bellard
}
444 0f0b7264 bellard
445 4c44bdcb aurel32
static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state)
446 0f0b7264 bellard
{
447 4c44bdcb aurel32
    int buttons;
448 0f0b7264 bellard
    buttons = 0;
449 0f0b7264 bellard
    if (state & SDL_BUTTON(SDL_BUTTON_LEFT))
450 0f0b7264 bellard
        buttons |= MOUSE_EVENT_LBUTTON;
451 0f0b7264 bellard
    if (state & SDL_BUTTON(SDL_BUTTON_RIGHT))
452 0f0b7264 bellard
        buttons |= MOUSE_EVENT_RBUTTON;
453 0f0b7264 bellard
    if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
454 0f0b7264 bellard
        buttons |= MOUSE_EVENT_MBUTTON;
455 09b26c5e bellard
456 09b26c5e bellard
    if (kbd_mouse_is_absolute()) {
457 09b26c5e bellard
        if (!absolute_enabled) {
458 09b26c5e bellard
            sdl_hide_cursor();
459 09b26c5e bellard
            if (gui_grab) {
460 09b26c5e bellard
                sdl_grab_end();
461 09b26c5e bellard
            }
462 09b26c5e bellard
            absolute_enabled = 1;
463 09b26c5e bellard
        }
464 09b26c5e bellard
465 4c44bdcb aurel32
       dx = x * 0x7FFF / (width - 1);
466 4c44bdcb aurel32
       dy = y * 0x7FFF / (height - 1);
467 455204eb ths
    } else if (absolute_enabled) {
468 455204eb ths
        sdl_show_cursor();
469 455204eb ths
        absolute_enabled = 0;
470 d34cab9f ths
    } else if (guest_cursor) {
471 4c44bdcb aurel32
        x -= guest_x;
472 4c44bdcb aurel32
        y -= guest_y;
473 4c44bdcb aurel32
        guest_x += x;
474 4c44bdcb aurel32
        guest_y += y;
475 4c44bdcb aurel32
        dx = x;
476 4c44bdcb aurel32
        dy = y;
477 09b26c5e bellard
    }
478 09b26c5e bellard
479 0f0b7264 bellard
    kbd_mouse_event(dx, dy, dz, buttons);
480 0f0b7264 bellard
}
481 0f0b7264 bellard
482 8e9c4afe bellard
static void toggle_full_screen(DisplayState *ds)
483 8e9c4afe bellard
{
484 8e9c4afe bellard
    gui_fullscreen = !gui_fullscreen;
485 7b5d76da aliguori
    do_sdl_resize(real_screen->w, real_screen->h, real_screen->format->BitsPerPixel);
486 8e9c4afe bellard
    if (gui_fullscreen) {
487 8e9c4afe bellard
        gui_saved_grab = gui_grab;
488 8e9c4afe bellard
        sdl_grab_start();
489 8e9c4afe bellard
    } else {
490 8e9c4afe bellard
        if (!gui_saved_grab)
491 8e9c4afe bellard
            sdl_grab_end();
492 8e9c4afe bellard
    }
493 95219897 pbrook
    vga_hw_invalidate();
494 95219897 pbrook
    vga_hw_update();
495 8e9c4afe bellard
}
496 8e9c4afe bellard
497 0f0b7264 bellard
static void sdl_refresh(DisplayState *ds)
498 0f0b7264 bellard
{
499 0f0b7264 bellard
    SDL_Event ev1, *ev = &ev1;
500 8e9c4afe bellard
    int mod_state;
501 4c44bdcb aurel32
    int buttonstate = SDL_GetMouseState(NULL, NULL);
502 3b46e624 ths
503 8a7ddc38 bellard
    if (last_vm_running != vm_running) {
504 8a7ddc38 bellard
        last_vm_running = vm_running;
505 8a7ddc38 bellard
        sdl_update_caption();
506 8a7ddc38 bellard
    }
507 8a7ddc38 bellard
508 95219897 pbrook
    vga_hw_update();
509 3bee8bd0 aurel32
    SDL_EnableUNICODE(!is_graphic_console());
510 457831f4 bellard
511 0f0b7264 bellard
    while (SDL_PollEvent(ev)) {
512 0f0b7264 bellard
        switch (ev->type) {
513 0f0b7264 bellard
        case SDL_VIDEOEXPOSE:
514 7d957bd8 aliguori
            sdl_update(ds, 0, 0, real_screen->w, real_screen->h);
515 0f0b7264 bellard
            break;
516 0f0b7264 bellard
        case SDL_KEYDOWN:
517 0f0b7264 bellard
        case SDL_KEYUP:
518 0f0b7264 bellard
            if (ev->type == SDL_KEYDOWN) {
519 3780e197 ths
                if (!alt_grab) {
520 3780e197 ths
                    mod_state = (SDL_GetModState() & gui_grab_code) ==
521 3780e197 ths
                                gui_grab_code;
522 3780e197 ths
                } else {
523 3780e197 ths
                    mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
524 3780e197 ths
                                (gui_grab_code | KMOD_LSHIFT);
525 3780e197 ths
                }
526 8e9c4afe bellard
                gui_key_modifier_pressed = mod_state;
527 457831f4 bellard
                if (gui_key_modifier_pressed) {
528 32ff25bf bellard
                    int keycode;
529 32ff25bf bellard
                    keycode = sdl_keyevent_to_keycode(&ev->key);
530 32ff25bf bellard
                    switch(keycode) {
531 32ff25bf bellard
                    case 0x21: /* 'f' key on US keyboard */
532 457831f4 bellard
                        toggle_full_screen(ds);
533 457831f4 bellard
                        gui_keysym = 1;
534 457831f4 bellard
                        break;
535 5fafdf24 ths
                    case 0x02 ... 0x0a: /* '1' to '9' keys */
536 dfd92d3a bellard
                        /* Reset the modifiers sent to the current console */
537 dfd92d3a bellard
                        reset_keys();
538 32ff25bf bellard
                        console_select(keycode - 0x02);
539 95219897 pbrook
                        if (!is_graphic_console()) {
540 457831f4 bellard
                            /* display grab if going to a text console */
541 457831f4 bellard
                            if (gui_grab)
542 457831f4 bellard
                                sdl_grab_end();
543 457831f4 bellard
                        }
544 457831f4 bellard
                        gui_keysym = 1;
545 457831f4 bellard
                        break;
546 457831f4 bellard
                    default:
547 457831f4 bellard
                        break;
548 457831f4 bellard
                    }
549 95219897 pbrook
                } else if (!is_graphic_console()) {
550 457831f4 bellard
                    int keysym;
551 457831f4 bellard
                    keysym = 0;
552 457831f4 bellard
                    if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
553 457831f4 bellard
                        switch(ev->key.keysym.sym) {
554 457831f4 bellard
                        case SDLK_UP: keysym = QEMU_KEY_CTRL_UP; break;
555 457831f4 bellard
                        case SDLK_DOWN: keysym = QEMU_KEY_CTRL_DOWN; break;
556 457831f4 bellard
                        case SDLK_LEFT: keysym = QEMU_KEY_CTRL_LEFT; break;
557 457831f4 bellard
                        case SDLK_RIGHT: keysym = QEMU_KEY_CTRL_RIGHT; break;
558 457831f4 bellard
                        case SDLK_HOME: keysym = QEMU_KEY_CTRL_HOME; break;
559 457831f4 bellard
                        case SDLK_END: keysym = QEMU_KEY_CTRL_END; break;
560 457831f4 bellard
                        case SDLK_PAGEUP: keysym = QEMU_KEY_CTRL_PAGEUP; break;
561 457831f4 bellard
                        case SDLK_PAGEDOWN: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
562 457831f4 bellard
                        default: break;
563 457831f4 bellard
                        }
564 457831f4 bellard
                    } else {
565 457831f4 bellard
                        switch(ev->key.keysym.sym) {
566 457831f4 bellard
                        case SDLK_UP: keysym = QEMU_KEY_UP; break;
567 457831f4 bellard
                        case SDLK_DOWN: keysym = QEMU_KEY_DOWN; break;
568 457831f4 bellard
                        case SDLK_LEFT: keysym = QEMU_KEY_LEFT; break;
569 457831f4 bellard
                        case SDLK_RIGHT: keysym = QEMU_KEY_RIGHT; break;
570 457831f4 bellard
                        case SDLK_HOME: keysym = QEMU_KEY_HOME; break;
571 457831f4 bellard
                        case SDLK_END: keysym = QEMU_KEY_END; break;
572 457831f4 bellard
                        case SDLK_PAGEUP: keysym = QEMU_KEY_PAGEUP; break;
573 457831f4 bellard
                        case SDLK_PAGEDOWN: keysym = QEMU_KEY_PAGEDOWN; break;
574 e91c8a77 ths
                        case SDLK_BACKSPACE: keysym = QEMU_KEY_BACKSPACE; break;
575 e91c8a77 ths
                        case SDLK_DELETE: keysym = QEMU_KEY_DELETE; break;
576 457831f4 bellard
                        default: break;
577 457831f4 bellard
                        }
578 457831f4 bellard
                    }
579 457831f4 bellard
                    if (keysym) {
580 457831f4 bellard
                        kbd_put_keysym(keysym);
581 457831f4 bellard
                    } else if (ev->key.keysym.unicode != 0) {
582 457831f4 bellard
                        kbd_put_keysym(ev->key.keysym.unicode);
583 457831f4 bellard
                    }
584 8e9c4afe bellard
                }
585 8e9c4afe bellard
            } else if (ev->type == SDL_KEYUP) {
586 3780e197 ths
                if (!alt_grab) {
587 3780e197 ths
                    mod_state = (ev->key.keysym.mod & gui_grab_code);
588 3780e197 ths
                } else {
589 3780e197 ths
                    mod_state = (ev->key.keysym.mod &
590 3780e197 ths
                                 (gui_grab_code | KMOD_LSHIFT));
591 3780e197 ths
                }
592 8e9c4afe bellard
                if (!mod_state) {
593 8e9c4afe bellard
                    if (gui_key_modifier_pressed) {
594 5b311878 pbrook
                        gui_key_modifier_pressed = 0;
595 457831f4 bellard
                        if (gui_keysym == 0) {
596 32ff25bf bellard
                            /* exit/enter grab if pressing Ctrl-Alt */
597 c66b0d4c bellard
                            if (!gui_grab) {
598 c66b0d4c bellard
                                /* if the application is not active,
599 c66b0d4c bellard
                                   do not try to enter grab state. It
600 c66b0d4c bellard
                                   prevents
601 c66b0d4c bellard
                                   'SDL_WM_GrabInput(SDL_GRAB_ON)'
602 c66b0d4c bellard
                                   from blocking all the application
603 c66b0d4c bellard
                                   (SDL bug). */
604 c66b0d4c bellard
                                if (SDL_GetAppState() & SDL_APPACTIVE)
605 c66b0d4c bellard
                                    sdl_grab_start();
606 c66b0d4c bellard
                            } else {
607 8e9c4afe bellard
                                sdl_grab_end();
608 c66b0d4c bellard
                            }
609 32ff25bf bellard
                            /* SDL does not send back all the
610 32ff25bf bellard
                               modifiers key, so we must correct it */
611 32ff25bf bellard
                            reset_keys();
612 8e9c4afe bellard
                            break;
613 8e9c4afe bellard
                        }
614 8e9c4afe bellard
                        gui_keysym = 0;
615 8e9c4afe bellard
                    }
616 0f0b7264 bellard
                }
617 0f0b7264 bellard
            }
618 5fafdf24 ths
            if (is_graphic_console() && !gui_keysym)
619 457831f4 bellard
                sdl_process_key(&ev->key);
620 0f0b7264 bellard
            break;
621 0f0b7264 bellard
        case SDL_QUIT:
622 5b08fc10 aliguori
            if (!no_quit)
623 731345e1 balrog
                qemu_system_shutdown_request();
624 0f0b7264 bellard
            break;
625 0f0b7264 bellard
        case SDL_MOUSEMOTION:
626 455204eb ths
            if (gui_grab || kbd_mouse_is_absolute() ||
627 455204eb ths
                absolute_enabled) {
628 4c44bdcb aurel32
                sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, 0,
629 4c44bdcb aurel32
                       ev->motion.x, ev->motion.y, ev->motion.state);
630 0f0b7264 bellard
            }
631 0f0b7264 bellard
            break;
632 0f0b7264 bellard
        case SDL_MOUSEBUTTONDOWN:
633 0f0b7264 bellard
        case SDL_MOUSEBUTTONUP:
634 0f0b7264 bellard
            {
635 0f0b7264 bellard
                SDL_MouseButtonEvent *bev = &ev->button;
636 09b26c5e bellard
                if (!gui_grab && !kbd_mouse_is_absolute()) {
637 0f0b7264 bellard
                    if (ev->type == SDL_MOUSEBUTTONDOWN &&
638 4c44bdcb aurel32
                        (bev->button == SDL_BUTTON_LEFT)) {
639 0f0b7264 bellard
                        /* start grabbing all events */
640 0f0b7264 bellard
                        sdl_grab_start();
641 0f0b7264 bellard
                    }
642 0f0b7264 bellard
                } else {
643 18a6d284 bellard
                    int dz;
644 18a6d284 bellard
                    dz = 0;
645 4c44bdcb aurel32
                    if (ev->type == SDL_MOUSEBUTTONDOWN) {
646 4c44bdcb aurel32
                        buttonstate |= SDL_BUTTON(bev->button);
647 4c44bdcb aurel32
                    } else {
648 4c44bdcb aurel32
                        buttonstate &= ~SDL_BUTTON(bev->button);
649 4c44bdcb aurel32
                    }
650 18a6d284 bellard
#ifdef SDL_BUTTON_WHEELUP
651 09b26c5e bellard
                    if (bev->button == SDL_BUTTON_WHEELUP && ev->type == SDL_MOUSEBUTTONDOWN) {
652 18a6d284 bellard
                        dz = -1;
653 09b26c5e bellard
                    } else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type == SDL_MOUSEBUTTONDOWN) {
654 18a6d284 bellard
                        dz = 1;
655 18a6d284 bellard
                    }
656 3b46e624 ths
#endif
657 4c44bdcb aurel32
                    sdl_send_mouse_event(0, 0, dz, bev->x, bev->y, buttonstate);
658 0f0b7264 bellard
                }
659 0f0b7264 bellard
            }
660 0f0b7264 bellard
            break;
661 0294ffb9 bellard
        case SDL_ACTIVEEVENT:
662 5b311878 pbrook
            if (gui_grab && ev->active.state == SDL_APPINPUTFOCUS &&
663 5b311878 pbrook
                !ev->active.gain && !gui_fullscreen_initial_grab) {
664 0294ffb9 bellard
                sdl_grab_end();
665 0294ffb9 bellard
            }
666 f442e08b aurel32
            if (ev->active.state & SDL_APPACTIVE) {
667 f442e08b aurel32
                if (ev->active.gain) {
668 f442e08b aurel32
                    /* Back to default interval */
669 7d957bd8 aliguori
                    dcl->gui_timer_interval = 0;
670 7d957bd8 aliguori
                    dcl->idle = 0;
671 f442e08b aurel32
                } else {
672 f442e08b aurel32
                    /* Sleeping interval */
673 7d957bd8 aliguori
                    dcl->gui_timer_interval = 500;
674 7d957bd8 aliguori
                    dcl->idle = 1;
675 f442e08b aurel32
                }
676 f442e08b aurel32
            }
677 0294ffb9 bellard
            break;
678 0f0b7264 bellard
        default:
679 0f0b7264 bellard
            break;
680 0f0b7264 bellard
        }
681 0f0b7264 bellard
    }
682 0f0b7264 bellard
}
683 0f0b7264 bellard
684 d34cab9f ths
static void sdl_fill(DisplayState *ds, int x, int y, int w, int h, uint32_t c)
685 d34cab9f ths
{
686 d34cab9f ths
    SDL_Rect dst = { x, y, w, h };
687 7d957bd8 aliguori
    SDL_FillRect(real_screen, &dst, c);
688 d34cab9f ths
}
689 d34cab9f ths
690 d34cab9f ths
static void sdl_mouse_warp(int x, int y, int on)
691 d34cab9f ths
{
692 d34cab9f ths
    if (on) {
693 d34cab9f ths
        if (!guest_cursor)
694 d34cab9f ths
            sdl_show_cursor();
695 d34cab9f ths
        if (gui_grab || kbd_mouse_is_absolute() || absolute_enabled) {
696 d34cab9f ths
            SDL_SetCursor(guest_sprite);
697 08a2d4c4 balrog
            if (!kbd_mouse_is_absolute() && !absolute_enabled)
698 08a2d4c4 balrog
                SDL_WarpMouse(x, y);
699 d34cab9f ths
        }
700 d34cab9f ths
    } else if (gui_grab)
701 d34cab9f ths
        sdl_hide_cursor();
702 d34cab9f ths
    guest_cursor = on;
703 d34cab9f ths
    guest_x = x, guest_y = y;
704 d34cab9f ths
}
705 d34cab9f ths
706 d34cab9f ths
static void sdl_mouse_define(int width, int height, int bpp,
707 d34cab9f ths
                             int hot_x, int hot_y,
708 d34cab9f ths
                             uint8_t *image, uint8_t *mask)
709 d34cab9f ths
{
710 d34cab9f ths
    uint8_t sprite[256], *line;
711 d34cab9f ths
    int x, y, dst, bypl, src = 0;
712 d34cab9f ths
    if (guest_sprite)
713 d34cab9f ths
        SDL_FreeCursor(guest_sprite);
714 d34cab9f ths
715 d34cab9f ths
    memset(sprite, 0, 256);
716 d34cab9f ths
    bypl = ((width * bpp + 31) >> 5) << 2;
717 d34cab9f ths
    for (y = 0, dst = 0; y < height; y ++, image += bypl) {
718 d34cab9f ths
        line = image;
719 d34cab9f ths
        for (x = 0; x < width; x ++, dst ++) {
720 d34cab9f ths
            switch (bpp) {
721 d34cab9f ths
            case 24:
722 d34cab9f ths
                src = *(line ++); src |= *(line ++); src |= *(line ++);
723 d34cab9f ths
                break;
724 d34cab9f ths
            case 16:
725 d34cab9f ths
            case 15:
726 d34cab9f ths
                src = *(line ++); src |= *(line ++);
727 d34cab9f ths
                break;
728 d34cab9f ths
            case 8:
729 d34cab9f ths
                src = *(line ++);
730 d34cab9f ths
                break;
731 d34cab9f ths
            case 4:
732 d34cab9f ths
                src = 0xf & (line[x >> 1] >> ((x & 1)) << 2);
733 d34cab9f ths
                break;
734 d34cab9f ths
            case 2:
735 d34cab9f ths
                src = 3 & (line[x >> 2] >> ((x & 3)) << 1);
736 d34cab9f ths
                break;
737 d34cab9f ths
            case 1:
738 d34cab9f ths
                src = 1 & (line[x >> 3] >> (x & 7));
739 d34cab9f ths
                break;
740 d34cab9f ths
            }
741 d34cab9f ths
            if (!src)
742 d34cab9f ths
                sprite[dst >> 3] |= (1 << (~dst & 7)) & mask[dst >> 3];
743 d34cab9f ths
        }
744 d34cab9f ths
    }
745 d34cab9f ths
    guest_sprite = SDL_CreateCursor(sprite, mask, width, height, hot_x, hot_y);
746 d34cab9f ths
747 d34cab9f ths
    if (guest_cursor &&
748 d34cab9f ths
            (gui_grab || kbd_mouse_is_absolute() || absolute_enabled))
749 d34cab9f ths
        SDL_SetCursor(guest_sprite);
750 d34cab9f ths
}
751 d34cab9f ths
752 5fafdf24 ths
static void sdl_cleanup(void)
753 898712a8 bellard
{
754 d34cab9f ths
    if (guest_sprite)
755 d34cab9f ths
        SDL_FreeCursor(guest_sprite);
756 898712a8 bellard
    SDL_Quit();
757 898712a8 bellard
}
758 898712a8 bellard
759 43523e93 ths
void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
760 0f0b7264 bellard
{
761 0f0b7264 bellard
    int flags;
762 09b26c5e bellard
    uint8_t data = 0;
763 7b5d76da aliguori
    DisplayAllocator *da;
764 7b5d76da aliguori
    const SDL_VideoInfo *vi;
765 0f0b7264 bellard
766 3d11d0eb bellard
#if defined(__APPLE__)
767 3d11d0eb bellard
    /* always use generic keymaps */
768 3d11d0eb bellard
    if (!keyboard_layout)
769 3d11d0eb bellard
        keyboard_layout = "en-us";
770 3d11d0eb bellard
#endif
771 3d11d0eb bellard
    if(keyboard_layout) {
772 0483755a aliguori
        kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
773 3d11d0eb bellard
        if (!kbd_layout)
774 3d11d0eb bellard
            exit(1);
775 3d11d0eb bellard
    }
776 3d11d0eb bellard
777 43523e93 ths
    if (no_frame)
778 43523e93 ths
        gui_noframe = 1;
779 43523e93 ths
780 0f0b7264 bellard
    flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
781 0f0b7264 bellard
    if (SDL_Init (flags)) {
782 0f0b7264 bellard
        fprintf(stderr, "Could not initialize SDL - exiting\n");
783 0f0b7264 bellard
        exit(1);
784 0f0b7264 bellard
    }
785 7b5d76da aliguori
    vi = SDL_GetVideoInfo();
786 7b5d76da aliguori
    hostbpp = vi->vfmt->BitsPerPixel;
787 0ae04d73 bellard
788 7d957bd8 aliguori
    dcl = qemu_mallocz(sizeof(DisplayChangeListener));
789 7d957bd8 aliguori
    dcl->dpy_update = sdl_update;
790 7d957bd8 aliguori
    dcl->dpy_resize = sdl_resize;
791 7d957bd8 aliguori
    dcl->dpy_refresh = sdl_refresh;
792 7d957bd8 aliguori
    dcl->dpy_setdata = sdl_setdata;
793 7d957bd8 aliguori
    dcl->dpy_fill = sdl_fill;
794 d34cab9f ths
    ds->mouse_set = sdl_mouse_warp;
795 d34cab9f ths
    ds->cursor_define = sdl_mouse_define;
796 7d957bd8 aliguori
    register_displaychangelistener(ds, dcl);
797 0f0b7264 bellard
798 7b5d76da aliguori
    da = qemu_mallocz(sizeof(DisplayAllocator));
799 7b5d76da aliguori
    da->create_displaysurface = sdl_create_displaysurface;
800 7b5d76da aliguori
    da->resize_displaysurface = sdl_resize_displaysurface;
801 7b5d76da aliguori
    da->free_displaysurface = sdl_free_displaysurface;
802 7b5d76da aliguori
    if (register_displayallocator(ds, da) == da) {
803 7b5d76da aliguori
        DisplaySurface *surf;
804 7b5d76da aliguori
        surf = sdl_create_displaysurface(ds_get_width(ds), ds_get_height(ds));
805 7b5d76da aliguori
        defaultallocator_free_displaysurface(ds->surface);
806 7b5d76da aliguori
        ds->surface = surf;
807 7b5d76da aliguori
        dpy_resize(ds);
808 7b5d76da aliguori
    }
809 7b5d76da aliguori
810 8a7ddc38 bellard
    sdl_update_caption();
811 0f0b7264 bellard
    SDL_EnableKeyRepeat(250, 50);
812 0f0b7264 bellard
    gui_grab = 0;
813 898712a8 bellard
814 09b26c5e bellard
    sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
815 09b26c5e bellard
    sdl_cursor_normal = SDL_GetCursor();
816 09b26c5e bellard
817 898712a8 bellard
    atexit(sdl_cleanup);
818 d63d307f bellard
    if (full_screen) {
819 d63d307f bellard
        gui_fullscreen = 1;
820 d63d307f bellard
        gui_fullscreen_initial_grab = 1;
821 d63d307f bellard
        sdl_grab_start();
822 d63d307f bellard
    }
823 0f0b7264 bellard
}