hi,
the attached patch fixes some glitches when switching to fullscreen mode
using ctrl+alt+f or when booting using -full-screen.
up to now the VM simply dies if one of the following situations occur:
* user switches from windowed to fullscreen mode using a resolution
which is too high (meaning higher than the maximum resolution of the
display)
* guest boots in fullscreen mode using a resolution which is too high
* guest is in fullscreen mode and the user switches to a resolution
which is too high
IMO this is not what the "normal" user would expect.
This patch changes the behaviour as follows:
* deny switching to fullscreen mode if the resolution is too high and
print a message to the console
* use windowed mode as fallback option if we are already in
fullscreen mode and the new resolution is too high and print a message
to the console
cheers,
Andi
--- qemu/sdl.c 2007-11-17 18:14:38.000000000 +0100
+++ qemu/sdl.c 2008-02-26 13:32:29.000000000 +0100
@@ -56,46 +56,60 @@ static void sdl_update(DisplayState *ds,
SDL_UpdateRect(screen, x, y, w, h);
}
-static void sdl_resize(DisplayState *ds, int w, int h)
+static int sdl_resize2(DisplayState *ds, int w, int h, int full_screen, int no_frame)
{
+ SDL_Surface *screen_tmp;
int flags;
- // printf("resizing to %d %d\n", w, h);
+ //printf("trying to resize from w=%d h=%d %s to w=%d h=%d %s\n", width, height, gui_fullscreen ? "fullscreen" : "windowed", w, h, full_screen ? "fullscreen" : "windowed");
flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
- if (gui_fullscreen)
+ if (full_screen)
flags |= SDL_FULLSCREEN;
- if (gui_noframe)
+ if (no_frame)
flags |= SDL_NOFRAME;
- width = w;
- height = h;
-
- again:
- screen = SDL_SetVideoMode(w, h, 0, flags);
- if (!screen) {
- fprintf(stderr, "Could not open SDL display\n");
- exit(1);
- }
- if (!screen->pixels && (flags & SDL_HWSURFACE) && (flags & SDL_FULLSCREEN)) {
- flags &= ~SDL_HWSURFACE;
- goto again;
+ if (!(screen_tmp = SDL_SetVideoMode(w, h, 0, flags))) {
+ //fprintf(stderr, "Could not open SDL display (try #1)\n");
+ return -1;
+ } else if (!screen_tmp->pixels && (flags & SDL_HWSURFACE) && (flags & SDL_FULLSCREEN)) {
+ screen_tmp = SDL_SetVideoMode(w, h, 0, flags & ~SDL_HWSURFACE);
}
- if (!screen->pixels) {
- fprintf(stderr, "Could not open SDL display\n");
- exit(1);
- }
- ds->data = screen->pixels;
- ds->linesize = screen->pitch;
- ds->depth = screen->format->BitsPerPixel;
- if (screen->format->Bshift > screen->format->Rshift) {
- ds->bgr = 1;
+ if (!screen_tmp || !screen_tmp->pixels) {
+ //fprintf(stderr, "Could not open SDL display (try #2)\n");
+ return -1;
} else {
- ds->bgr = 0;
+ screen = screen_tmp;
+ gui_fullscreen = full_screen;
+ gui_noframe = no_frame;
+
+ ds->data = screen->pixels;
+ ds->linesize = screen->pitch;
+ ds->depth = screen->format->BitsPerPixel;
+ if (screen->format->Bshift > screen->format->Rshift) {
+ ds->bgr = 1;
+ } else {
+ ds->bgr = 0;
+ }
+ ds->width = width = w;
+ ds->height = height = h;
+ }
+}
+
+static void sdl_resize(DisplayState *ds, int w, int h)
+{
+ if (sdl_resize2(ds, w, h, gui_fullscreen, gui_noframe) == -1) {
+ fprintf(stderr, "Could not resize display to %d x %d (%s)\n",
+ w, h, gui_fullscreen ? "fullscreen" : "windowed");
+
+ /* if we are in fullscreen mode use windowed mode as fallback */
+ if (!gui_fullscreen || sdl_resize2(ds, w, h, 0, gui_noframe) == -1) {
+ exit(1);
+ } else {
+ fprintf(stderr, "Using windowed mode as fallback\n");
+ }
}
- ds->width = w;
- ds->height = h;
}
/* generic keyboard conversion */
@@ -330,17 +344,21 @@ static void sdl_send_mouse_event(int dz)
static void toggle_full_screen(DisplayState *ds)
{
- gui_fullscreen = !gui_fullscreen;
- sdl_resize(ds, screen->w, screen->h);
- if (gui_fullscreen) {
- gui_saved_grab = gui_grab;
- sdl_grab_start();
- } else {
- if (!gui_saved_grab)
- sdl_grab_end();
+ if (sdl_resize2(ds, screen->w, screen->h, !gui_fullscreen, gui_noframe) != -1) {
+ if (gui_fullscreen) {
+ gui_saved_grab = gui_grab;
+ sdl_grab_start();
+ } else {
+ if (!gui_saved_grab)
+ sdl_grab_end();
+ }
+ vga_hw_invalidate();
+ vga_hw_update();
+ }
+ else {
+ fprintf(stderr, "Could not switch to %s mode\n",
+ !gui_fullscreen ? "fullscreen" : "windowed");
}
- vga_hw_invalidate();
- vga_hw_update();
}
static void sdl_refresh(DisplayState *ds)
@@ -603,14 +621,14 @@ void sdl_display_init(DisplayState *ds,
exit(1);
}
- if (no_frame)
- gui_noframe = 1;
-
flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
if (SDL_Init (flags)) {
fprintf(stderr, "Could not initialize SDL - exiting\n");
exit(1);
}
+
+ atexit(sdl_cleanup);
+
#ifndef _WIN32
/* NOTE: we still want Ctrl-C to work, so we undo the SDL redirections */
signal(SIGINT, SIG_DFL);
@@ -624,7 +642,10 @@ void sdl_display_init(DisplayState *ds,
ds->mouse_set = sdl_mouse_warp;
ds->cursor_define = sdl_mouse_define;
- sdl_resize(ds, 640, 400);
+ if (sdl_resize2(ds, 640, 400, full_screen, no_frame) == -1) {
+ fprintf(stderr, "Could not resize display in sdl_display_init()\n");
+ exit(1);
+ }
sdl_update_caption();
SDL_EnableKeyRepeat(250, 50);
SDL_EnableUNICODE(1);
@@ -633,9 +654,7 @@ void sdl_display_init(DisplayState *ds,
sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
sdl_cursor_normal = SDL_GetCursor();
- atexit(sdl_cleanup);
- if (full_screen) {
- gui_fullscreen = 1;
+ if (gui_fullscreen) {
gui_fullscreen_initial_grab = 1;
sdl_grab_start();
}