ui/sdl2: implement display cleanup
Replace the atexit() handler with a proper cleanup callback. Extend sdl_cleanup() to unregister display listeners, free keyboard state, destroy windows, and clean up all cursor resources. Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-ID: <20260623-b4-ui-v4-17-4656aec3398d@redhat.com>
Marc-André Lureau committed
Jun 23, 2026 at 11:44 UTC
2f73d8a6037815a5923e7292353104917e8f1d3c
1 file changed
+19
-4
ui/sdl2.c
+19
-4
@@ -790,9 +790,25 @@ static void sdl_mouse_define(DisplayChangeListener *dcl,
790
791
static void sdl_cleanup(void)
792
{
793
- if (guest_sprite) {
794
- SDL_FreeCursor(guest_sprite);
793
+ int i;
794
+
795
+ if (!sdl2_console) {
796
+ return;
797
}
798
+
799
+ qemu_remove_mouse_mode_change_notifier(&mouse_mode_notifier);
800
+
801
+ for (i = 0; i < sdl2_num_outputs; i++) {
802
+ qemu_console_unregister_listener(&sdl2_console[i].dcl);
803
+ qkbd_state_free(sdl2_console[i].kbd);
804
+ sdl2_window_destroy(&sdl2_console[i]);
805
+ }
806
+ g_clear_pointer(&sdl2_console, g_free);
807
+ sdl2_num_outputs = 0;
808
+
809
+ g_clear_pointer(&guest_sprite, SDL_FreeCursor);
810
+ g_clear_pointer(&guest_sprite_surface, SDL_FreeSurface);
811
+ g_clear_pointer(&sdl_cursor_hidden, SDL_FreeCursor);
812
SDL_QuitSubSystem(SDL_INIT_VIDEO);
813
}
814
@@ -998,8 +1014,6 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
1014
sdl_grab_start(&sdl2_console[0]);
1015
}
1016
1001
- atexit(sdl_cleanup);
1002
-
1017
/* SDL's event polling (in dpy_refresh) must happen on the main thread. */
1018
qemu_main = NULL;
1019
}
@@ -1008,6 +1022,7 @@ static QemuDisplay qemu_display_sdl2 = {
1022
.type = DISPLAY_TYPE_SDL,
1023
.early_init = sdl2_display_early_init,
1024
.init = sdl2_display_init,
1025
+ .cleanup = sdl_cleanup,
1026
};
1027
1028
static void register_sdl1(void)