From 20ca6c73ed41691643456a7897b7f9e772fa3483 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Fri, 9 Jun 2023 05:02:34 +0300 Subject: [PATCH 37/37] sdl2: Make 'fullscreen' option change to take effect runtime No need to restart the client. See osdn #48198 Signed-off-by: Marko Lindqvist --- client/gui-sdl2/graphics.c | 94 +++++++++++++++++++++++++------------- client/gui-sdl2/graphics.h | 45 +++++++++--------- client/gui-sdl2/gui_main.c | 31 ++++++++++++- 3 files changed, 113 insertions(+), 57 deletions(-) diff --git a/client/gui-sdl2/graphics.c b/client/gui-sdl2/graphics.c index f9d42a137b..913a31b255 100644 --- a/client/gui-sdl2/graphics.c +++ b/client/gui-sdl2/graphics.c @@ -56,7 +56,7 @@ struct sdl2_data main_data; -static SDL_Surface *main_surface; +static SDL_Surface *main_surface = NULL; static bool render_dirty = TRUE; @@ -511,7 +511,8 @@ void init_sdl(int flags) main_data.guis = NULL; main_data.gui = NULL; main_data.map = NULL; - main_data.dummy = NULL; /* can't create yet -- hope we don't need it */ + main_data.dummy = NULL; /* Can't create yet -- hope we don't need it */ + main_data.renderer = NULL; main_data.rects_count = 0; main_data.guis_count = 0; @@ -537,46 +538,26 @@ void init_sdl(int flags) } /**********************************************************************//** - Free screen buffers + Free existing surfaces **************************************************************************/ -void quit_sdl(void) +static void free_surfaces(void) { - FC_FREE(main_data.guis); - gui_layer_destroy(&main_data.gui); - FREESURFACE(main_data.map); - FREESURFACE(main_data.dummy); - SDL_DestroyTexture(main_data.maintext); - SDL_DestroyRenderer(main_data.renderer); - FREESURFACE(main_surface); + if (main_data.renderer != NULL) { + SDL_DestroyRenderer(main_data.renderer); + main_data.renderer = NULL; + + FREESURFACE(main_surface); + } } /**********************************************************************//** - Switch to given video mode. + Create new main window surfaces. **************************************************************************/ -bool set_video_mode(unsigned width, unsigned height, unsigned flags_in) +bool create_surfaces(int width, int height) { unsigned flags; - main_data.screen = SDL_CreateWindow(_("SDL2 Client for Freeciv"), - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - width, height, - 0); - - if (main_data.screen == NULL) { - log_fatal(_("Failed to create main window: %s"), SDL_GetError()); - return FALSE; - } - - if (flags_in & SDL_WINDOW_FULLSCREEN) { - SDL_DisplayMode mode; - - /* Use SDL_WINDOW_FULLSCREEN_DESKTOP instead of real SDL_WINDOW_FULLSCREEN */ - SDL_SetWindowFullscreen(main_data.screen, SDL_WINDOW_FULLSCREEN_DESKTOP); - SDL_GetWindowDisplayMode(main_data.screen, &mode); - width = mode.w; - height = mode.h; - } + free_surfaces(); if (is_bigendian()) { main_surface = SDL_CreateRGBSurface(0, width, height, 32, @@ -635,6 +616,53 @@ bool set_video_mode(unsigned width, unsigned height, unsigned flags_in) return TRUE; } +/**********************************************************************//** + Free screen buffers +**************************************************************************/ +void quit_sdl(void) +{ + FC_FREE(main_data.guis); + gui_layer_destroy(&main_data.gui); + FREESURFACE(main_data.map); + FREESURFACE(main_data.dummy); + SDL_DestroyTexture(main_data.maintext); + + free_surfaces(); +} + +/**********************************************************************//** + Switch to given video mode. +**************************************************************************/ +bool set_video_mode(unsigned width, unsigned height, unsigned flags_in) +{ + main_data.screen = SDL_CreateWindow(_("SDL2 Client for Freeciv"), + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + width, height, + 0); + + if (main_data.screen == NULL) { + log_fatal(_("Failed to create main window: %s"), SDL_GetError()); + return FALSE; + } + + if (flags_in & SDL_WINDOW_FULLSCREEN) { + SDL_DisplayMode mode; + + /* Use SDL_WINDOW_FULLSCREEN_DESKTOP instead of real SDL_WINDOW_FULLSCREEN */ + SDL_SetWindowFullscreen(main_data.screen, SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_GetWindowDisplayMode(main_data.screen, &mode); + width = mode.w; + height = mode.h; + } + + if (!create_surfaces(width, height)) { + return FALSE; + } + + return TRUE; +} + /**********************************************************************//** Render from main surface with screen renderer. **************************************************************************/ diff --git a/client/gui-sdl2/graphics.h b/client/gui-sdl2/graphics.h index 9cc21ddbff..1e6cdf4b93 100644 --- a/client/gui-sdl2/graphics.h +++ b/client/gui-sdl2/graphics.h @@ -190,7 +190,7 @@ #endif /* USE_DUFFS_LOOP */ -/* shrink surface on 320x240 screen*/ +/* Shrink surface on 320x240 screen */ #ifdef GUI_SDL2_SMALL_SCREEN #define DEFAULT_ZOOM 0.5 #define adj_surf(surf) zoomSurface((surf), DEFAULT_ZOOM, DEFAULT_ZOOM, 0) @@ -283,6 +283,7 @@ void create_line(SDL_Surface *dest, Sint16 x0, Sint16 y0, Sint16 x1, Sint16 y1, void init_sdl(int f); void quit_sdl(void); bool set_video_mode(unsigned width, unsigned height, unsigned flags); +bool create_surfaces(int width, int height); void update_main_screen(void); @@ -317,43 +318,43 @@ void get_smaller_surface_rect(SDL_Surface *surf, SDL_Rect *rect); #define crop_rect_from_screen(rect) \ crop_rect_from_surface(main_data.screen, &rect) -/* free surface with check and clear pointer */ -#define FREESURFACE(ptr) \ -do { \ - if (ptr) { \ - SDL_FreeSurface(ptr); \ - ptr = NULL; \ - } \ +/* Free surface with check and clear pointer */ +#define FREESURFACE(ptr) \ +do { \ + if (ptr) { \ + SDL_FreeSurface(ptr); \ + ptr = NULL; \ + } \ } while (FALSE) /* - * lock surface + * Lock surface */ -#define lock_surf(surf) \ -do { \ - if (SDL_MUSTLOCK(surf)) { \ - SDL_LockSurface(surf); \ - } \ +#define lock_surf(surf) \ +do { \ + if (SDL_MUSTLOCK(surf)) { \ + SDL_LockSurface(surf); \ + } \ } while (FALSE) /* - * unlock surface + * Unlock surface */ -#define unlock_surf(surf) \ -do { \ - if (SDL_MUSTLOCK(surf)) { \ - SDL_UnlockSurface(surf); \ - } \ +#define unlock_surf(surf) \ +do { \ + if (SDL_MUSTLOCK(surf)) { \ + SDL_UnlockSurface(surf); \ + } \ } while (FALSE) /* - * lock screen surface + * Lock screen surface */ #define lock_screen() lock_surf(main_data.screen) /* - * unlock screen surface + * Unlock screen surface */ #define unlock_screen() unlock_surf(main_data.screen) diff --git a/client/gui-sdl2/gui_main.c b/client/gui-sdl2/gui_main.c index 0a59ae088b..2b190322fc 100644 --- a/client/gui-sdl2/gui_main.c +++ b/client/gui-sdl2/gui_main.c @@ -902,6 +902,33 @@ static void resize_window_callback(struct option *poption) update_queue_add(real_resize_window_callback, NULL); } +/**********************************************************************//** + Change fullscreen status after option changed. +**************************************************************************/ +static void fullscreen_callback(struct option *poption) +{ + SDL_DisplayMode mode; + + if (gui_options.gui_sdl2_fullscreen) { + SDL_SetWindowFullscreen(main_data.screen, SDL_WINDOW_FULLSCREEN_DESKTOP); + } else { + SDL_SetWindowFullscreen(main_data.screen, 0); + } + + SDL_GetWindowDisplayMode(main_data.screen, &mode); + + if (!create_surfaces(mode.w, mode.h)) { + /* Try to revert */ + if (!gui_options.gui_sdl2_fullscreen) { + SDL_SetWindowFullscreen(main_data.screen, SDL_WINDOW_FULLSCREEN_DESKTOP); + } else { + SDL_SetWindowFullscreen(main_data.screen, 0); + } + } + + update_queue_add(real_resize_window_callback, NULL); +} + /**********************************************************************//** Extra initializers for client options. Here we make set the callback for the specific gui-sdl2 options. @@ -917,7 +944,7 @@ void options_extra_init(void) log_error("Didn't find option %s!", #var); \ } - option_var_set_callback(gui_sdl2_fullscreen, resize_window_callback); + option_var_set_callback(gui_sdl2_fullscreen, fullscreen_callback); option_var_set_callback(gui_sdl2_screen, resize_window_callback); #undef option_var_set_callback } @@ -1081,7 +1108,7 @@ void ui_exit(void) { #if defined UNDER_CE && defined GUI_SDL2_SMALL_SCREEN - /* change back to window mode to restore the title bar */ + /* Change back to window mode to restore the title bar */ set_video_mode(320, 240, SDL_SWSURFACE | SDL_ANYFORMAT); #endif -- 2.39.2