@samitouri / QOSamiQemu / commits / 2f73d8a603

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)